You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/03/15 09:53:48 UTC
[james-project] branch master updated (5d3a0ed -> 0b3f900)
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git.
from 5d3a0ed MAILBOX-405 Document SubscribeAll task
new a8ae074 JAMES-3492, switch to elasticsearch 7 in guice modules
new 49203a0 JAMES-3492 Adapt ElasticSearchIntegrationTest
new 699ec42 JAMES-3492 Replace deprecated CreateIndexRequest
new 5f902b1 JAMES-3492 Remove mapping check
new bb08901 JAMES-3492 Migrate to Java time date format
new 92c9d58 JAMES-3492 Search no longer need to fetch individual fields
new 1e34bea JAMES-3492 Adapt other implementations of AbstractMessageSearchIndexTest
new b62784d JAMES-3492 Adapt ElasticSearchSearcherTest
new 55098c4 JAMES-3492 Mapping should be created at the same time as index
new d9150fb JAMES-3492 Check Mapping existence by GetMappingsAPI
new 810149b JAMES-3492 Add missing dependency
new decee0c JAMES-3492 Adapt ElasticSearchQuotaMailboxListenerTest
new d3b31b4 JAMES-3492 Use assertion with Awaitility in QuotaSearcherContract
new 6ec3409 JAMES-3492 Remove NodeMappingFactory & tests
new 0e3e8a1 JAMES-3492, switch to elasticsearch 7 in poms
new 42b7c5f JAMES-3492, disable failing tests
new 1272705 JAMES-3492, change ElasticSearchStartUpCheck.java to use v7
new f94b6c0 JAMES-3492, fix tests, wait for elasticsearch flushes to complete for test assertions
new 0c22bdc JAMES-3492, applied sortpom:sort
new af6706f JAMES-3492, remove mistakingly added dependency
new a825edb JAMES-3502, was using old elastic module
new 9376e1e JAMES-3502, remove elastic six modules
new ad3d344 JAMES-3502, fix indent in tests
new 6f7a428 JAMES-3492, pass JamesWithNonCompatibleElasticSearchServerTest
new 8c0079e JAMES-3492, add upgrade instructions
new 1df64b0 JAMES-3492, add upgrade instructions
new 1c9578f JAMES-3492, upgrade documentation
new 08fb0bf JAMES-3492, add note about need of separate Elasticsearch 6 instance for reporting metrics to Elasticsearch
new aa56c6e JAMES-3499 Distributed guice module should not depend on activemq
new 5b0cd79 JAMES-3499 Clean dependencies: webadmin-mailbox
new a30dff6 JAMES-3499 Fix LDAP related dockerfiles
new 0b3f900 JAMES-3506 Avoid a full body read within VacationMailet
The 32 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
README.adoc | 4 +-
backends-common/cassandra/pom.xml | 2 +-
.../james/backends/es/v7/IndexCreationFactory.java | 40 +-
.../james/backends/es/v7/NodeMappingFactory.java | 84 --
.../backends/es/v7/NodeMappingFactoryAuthTest.java | 115 --
.../backends/es/v7/NodeMappingFactoryTest.java | 103 --
.../backends/es/v7/search/ScrolledSearchTest.java | 1 -
backends-common/elasticsearch/pom.xml | 122 --
.../org/apache/james/backends/es/AliasName.java | 49 -
.../apache/james/backends/es/ClientProvider.java | 219 ----
.../james/backends/es/DeleteByQueryPerformer.java | 90 --
.../org/apache/james/backends/es/DocumentId.java | 59 -
.../backends/es/ElasticSearchConfiguration.java | 623 ----------
.../backends/es/ElasticSearchHealthCheck.java | 81 --
.../james/backends/es/ElasticSearchIndexer.java | 137 ---
.../james/backends/es/IndexCreationFactory.java | 200 ---
.../org/apache/james/backends/es/IndexName.java | 58 -
.../james/backends/es/NodeMappingFactory.java | 85 --
.../backends/es/ReactorElasticSearchClient.java | 179 ---
.../apache/james/backends/es/ReadAliasName.java | 26 -
.../org/apache/james/backends/es/RoutingKey.java | 63 -
.../james/backends/es/UpdatedRepresentation.java | 69 --
.../apache/james/backends/es/WriteAliasName.java | 26 -
.../james/backends/es/search/ScrolledSearch.java | 108 --
.../apache/james/backends/es/AliasNameTest.java | 32 -
...iderImplConnectionAuthESIgnoreSSLCheckTest.java | 47 -
...ImplConnectionAuthESOverrideTrustStoreTest.java | 48 -
.../es/ClientProviderImplConnectionContract.java | 93 --
.../ClientProviderImplConnectionNoAuthESTest.java | 31 -
.../james/backends/es/ClientProviderTest.java | 33 -
.../es/DockerAuthElasticSearchSingleton.java | 28 -
.../james/backends/es/DockerElasticSearch.java | 356 ------
.../backends/es/DockerElasticSearchExtension.java | 63 -
.../james/backends/es/DockerElasticSearchRule.java | 49 -
.../backends/es/DockerElasticSearchSingleton.java | 28 -
.../apache/james/backends/es/DocumentIdTest.java | 46 -
.../backends/es/ElasticSearchClusterExtension.java | 118 --
.../es/ElasticSearchConfigurationTest.java | 687 -----------
.../es/ElasticSearchHealthCheckConnectionTest.java | 61 -
.../backends/es/ElasticSearchHealthCheckTest.java | 80 --
.../backends/es/ElasticSearchIndexerTest.java | 292 -----
.../backends/es/IndexCreationFactoryTest.java | 77 --
.../backends/es/NodeMappingFactoryAuthTest.java | 114 --
.../james/backends/es/NodeMappingFactoryTest.java | 102 --
.../apache/james/backends/es/RoutingKeyTest.java | 46 -
.../backends/es/search/ScrolledSearchTest.java | 199 ---
.../src/test/resources/auth-es/NginxDockerfile | 5 -
.../src/test/resources/auth-es/README.md | 30 -
.../src/test/resources/auth-es/default.crt | 19 -
.../src/test/resources/auth-es/default.key | 27 -
.../src/test/resources/auth-es/nginx-conf/passwd | 2 -
.../auth-es/nginx-conf/reverse_elasticsearch.conf | 12 -
.../src/test/resources/auth-es/server.jks | Bin 1074 -> 0 bytes
backends-common/pom.xml | 1 -
dockerfiles/run/docker-compose-branch-master.yml | 2 +-
dockerfiles/run/docker-compose.yml | 2 +-
dockerfiles/run/guice/cassandra-ldap/Dockerfile | 4 +-
.../run/guice/cassandra-rabbitmq-ldap/Dockerfile | 4 +-
.../pages/distributed/configure/elasticsearch.adoc | 2 +-
.../servers/pages/distributed/operate/guide.adoc | 10 +-
.../servers/pages/distributed/operate/logging.adoc | 4 +-
.../servers/pages/distributed/run-docker.adoc | 2 +-
docs/modules/servers/pages/distributed/run.adoc | 6 +-
event-bus/api/pom.xml | 6 +-
event-bus/in-vm/pom.xml | 6 +-
event-bus/pom.xml | 6 +-
examples/custom-listeners/pom.xml | 136 +--
examples/custom-mailets/pom.xml | 77 +-
examples/pom.xml | 48 +-
.../elasticsearch/v7/MailboxIndexCreationUtil.java | 10 +-
.../elasticsearch/v7/MailboxMappingFactory.java | 38 +-
.../elasticsearch/v7/query/CriterionConverter.java | 2 +-
.../elasticsearch/v7/query/SortConverter.java | 10 +-
.../v7/search/ElasticSearchSearcher.java | 3 -
.../v7/ElasticSearchIntegrationTest.java | 178 +--
.../v7/search/ElasticSearchSearcherTest.java | 27 +-
mailbox/elasticsearch/pom.xml | 172 ---
.../ElasticSearchMailboxConfiguration.java | 178 ---
.../mailbox/elasticsearch/IndexAttachments.java | 24 -
.../MailboxElasticSearchConstants.java | 35 -
.../elasticsearch/MailboxIdRoutingKeyFactory.java | 30 -
.../elasticsearch/MailboxIndexCreationUtil.java | 56 -
.../elasticsearch/MailboxMappingFactory.java | 318 -----
.../ElasticSearchListeningMessageSearchIndex.java | 261 ----
.../james/mailbox/elasticsearch/json/EMailer.java | 76 --
.../james/mailbox/elasticsearch/json/EMailers.java | 52 -
.../elasticsearch/json/HeaderCollection.java | 260 ----
.../elasticsearch/json/IndexableMessage.java | 411 -------
.../elasticsearch/json/JsonMessageConstants.java | 76 --
.../json/MessageToElasticSearchJson.java | 85 --
.../elasticsearch/json/MessageUpdateJson.java | 81 --
.../james/mailbox/elasticsearch/json/MimePart.java | 310 -----
.../json/MimePartContainerBuilder.java | 52 -
.../mailbox/elasticsearch/json/MimePartParser.java | 144 ---
.../json/RootMimePartContainerBuilder.java | 98 --
.../elasticsearch/json/SerializableMessage.java | 25 -
.../james/mailbox/elasticsearch/json/Subjects.java | 50 -
.../elasticsearch/query/CriterionConverter.java | 303 -----
.../query/DateResolutionFormatter.java | 69 --
.../elasticsearch/query/QueryConverter.java | 79 --
.../mailbox/elasticsearch/query/SortConverter.java | 75 --
.../search/ElasticSearchSearcher.java | 153 ---
mailbox/elasticsearch/src/reporting-site/site.xml | 29 -
.../ElasticSearchIntegrationTest.java | 400 ------
.../ElasticSearchMailboxConfigurationTest.java | 227 ----
.../MailboxIdRoutingKeyFactoryTest.java | 34 -
...asticSearchListeningMessageSearchIndexTest.java | 457 -------
.../mailbox/elasticsearch/json/EMailerTest.java | 32 -
.../mailbox/elasticsearch/json/EMailersTest.java | 68 --
.../mailbox/elasticsearch/json/FieldImpl.java | 65 -
.../elasticsearch/json/HeaderCollectionTest.java | 328 -----
.../elasticsearch/json/IndexableMessageTest.java | 307 -----
.../json/MessageToElasticSearchJsonTest.java | 425 -------
.../mailbox/elasticsearch/json/MimePartTest.java | 52 -
.../mailbox/elasticsearch/json/SubjectsTest.java | 66 -
.../query/DateResolutionFormatterTest.java | 75 --
.../elasticsearch/query/SearchQueryTest.java | 68 --
.../search/ElasticSearchSearcherTest.java | 173 ---
.../src/test/resources/eml/bodyMakeTikaToFail.eml | 1272 --------------------
.../test/resources/eml/emailWith3Attachments.eml | 50 -
.../src/test/resources/eml/htmlContent.txt | 26 -
.../test/resources/eml/mailCustomDateHeader.eml | 9 -
.../test/resources/eml/mailCustomStringHeader.eml | 9 -
.../src/test/resources/eml/mailWithHeaders.eml | 14 -
.../search/LuceneMessageSearchIndexTest.java | 6 +-
.../plugin/quota-search-elasticsearch-v7/pom.xml | 6 +
.../elasticsearch/v7/QuotaRatioMappingFactory.java | 12 +-
.../v7/QuotaSearchIndexCreationUtil.java | 17 +-
.../v7/ElasticSearchQuotaSearcherTest.java | 96 +-
.../ElasticSearchQuotaMailboxListenerTest.java | 29 +-
mailbox/plugin/quota-search-elasticsearch/pom.xml | 137 ---
.../ElasticSearchQuotaConfiguration.java | 151 ---
.../elasticsearch/ElasticSearchQuotaSearcher.java | 109 --
.../search/elasticsearch/QuotaQueryConverter.java | 103 --
.../QuotaRatioElasticSearchConstants.java | 35 -
.../elasticsearch/QuotaRatioMappingFactory.java | 66 -
.../QuotaSearchIndexCreationUtil.java | 56 -
.../elasticsearch/UserRoutingKeyFactory.java | 30 -
.../events/ElasticSearchQuotaMailboxListener.java | 86 --
.../elasticsearch/json/JsonMessageConstants.java | 28 -
.../elasticsearch/json/QuotaRatioAsJson.java | 120 --
.../json/QuotaRatioToElasticSearchJson.java | 49 -
.../ElasticSearchQuotaConfigurationTest.java | 103 --
...lasticSearchQuotaSearchTestSystemExtension.java | 106 --
.../ElasticSearchQuotaSearcherTest.java | 88 --
.../elasticsearch/QuotaQueryConverterTest.java | 83 --
.../elasticsearch/UserRoutingKeyFactoryTest.java | 34 -
.../ElasticSearchQuotaMailboxListenerTest.java | 111 --
.../elasticsearch/json/QuotaRatioAsJsonTest.java | 109 --
.../json/QuotaRatioToElasticSearchJsonTest.java | 79 --
.../src/test/resources/quotaRatio.json | 1 -
.../src/test/resources/quotaRatioNoDomain.json | 1 -
mailbox/plugin/quota-search-scanning/pom.xml | 5 +
mailbox/plugin/quota-search/pom.xml | 5 +
.../james/quota/search/QuotaSearcherContract.java | 122 +-
mailbox/pom.xml | 2 -
.../store/search/SimpleMessageSearchIndexTest.java | 6 +-
.../search/AbstractMessageSearchIndexTest.java | 68 +-
mailbox/tika/pom.xml | 2 +-
.../james/imap/scripts/UidSearchAtomsIndexer.test | 2 +
mpt/impl/imap-mailbox/elasticsearch/pom.xml | 6 +-
.../host/ElasticSearchHostSystem.java | 28 +-
.../smtp/cassandra-rabbitmq-object-storage/pom.xml | 2 +-
mpt/impl/smtp/cassandra/pom.xml | 2 +-
pom.xml | 21 +-
server/app/pom.xml | 16 +-
server/blob/blob-gc/pom.xml | 6 +-
server/blob/blob-storage-strategy/pom.xml | 4 +-
server/container/guice/cassandra-guice/pom.xml | 6 +-
.../apache/james/DockerElasticSearchExtension.java | 6 +-
.../org/apache/james/DockerElasticSearchRule.java | 4 +-
.../test/java/org/apache/james/ESReporterTest.java | 5 +-
...esWithNonCompatibleElasticSearchServerTest.java | 10 +-
.../modules/TestDockerESMetricReporterModule.java | 2 +-
.../modules/TestDockerElasticSearchModule.java | 4 +-
.../container/guice/cassandra-ldap-guice/pom.xml | 2 +-
.../guice/cassandra-rabbitmq-guice/pom.xml | 4 +-
.../guice/cassandra-rabbitmq-ldap-guice/pom.xml | 2 +-
server/container/guice/cassandra/pom.xml | 2 +-
server/container/guice/data-ldap/pom.xml | 6 +-
server/container/guice/distributed/pom.xml | 4 -
server/container/guice/elasticsearch/pom.xml | 4 +-
.../modules/mailbox/ElasticSearchClientModule.java | 12 +-
.../mailbox/ElasticSearchMailboxModule.java | 26 +-
.../mailbox/ElasticSearchQuotaSearcherModule.java | 18 +-
.../modules/mailbox/ElasticSearchStartUpCheck.java | 12 +-
server/container/guice/es-metric-reporter/pom.xml | 2 +-
.../server/ElasticSearchMetricReporterModule.java | 4 +-
server/container/guice/sieve-file/pom.xml | 3 +-
server/container/guice/sieve-jpa/pom.xml | 3 +-
.../container/metrics/metrics-es-reporter/pom.xml | 103 --
.../apache/james/metrics/es/ESMetricReporter.java | 69 --
.../james/metrics/es/ESReporterConfiguration.java | 114 --
.../metric/es/DockerElasticSearchExtension.java | 73 --
.../apache/james/metric/es/ES2ReporterTest.java | 31 -
.../apache/james/metric/es/ES6ReporterTest.java | 29 -
.../metric/es/ESReportedConfigurationTest.java | 87 --
.../apache/james/metric/es/ESReporterContract.java | 128 --
.../AutomaticallySentMailDetectorImpl.java | 66 +-
.../AutomaticallySentMailDetectorImplTest.java | 2 +
server/mailet/mock-smtp-server/pom.xml | 6 +-
server/pom.xml | 1 -
.../pom.xml | 4 +-
.../pom.xml | 5 +-
.../distributed-webadmin-integration-test/pom.xml | 4 +-
...RabbitMQReindexingWithEventDeadLettersTest.java | 2 +-
.../webadmin-integration-test-common/pom.xml | 2 +-
server/protocols/webadmin/webadmin-mailbox/pom.xml | 7 +-
.../routes/ElasticSearchQuotaSearchExtension.java | 22 +-
.../james/webadmin/routes/MailboxesRoutesTest.java | 27 +-
.../webadmin/routes/UserMailboxesRoutesTest.java | 27 +-
.../james/webadmin/routes/UserQuotaRoutesTest.java | 194 +--
.../install/guice-cassandra-rabbitmq-swift.md | 6 +-
.../markdown/server/install/guice-cassandra.md | 6 +-
.../server/manage-guice-distributed-james.md | 2 +-
src/site/xdoc/server/config-elasticsearch.xml | 9 +-
src/site/xdoc/server/quick-start-cassandra.xml | 2 +-
upgrade-instructions.md | 28 +
218 files changed, 777 insertions(+), 16079 deletions(-)
delete mode 100644 backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
delete mode 100644 backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java
delete mode 100644 backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java
delete mode 100644 backends-common/elasticsearch/pom.xml
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/AliasName.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DocumentId.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchHealthCheck.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexName.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReactorElasticSearchClient.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReadAliasName.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/RoutingKey.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/UpdatedRepresentation.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/WriteAliasName.java
delete mode 100644 backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/search/ScrolledSearch.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/AliasNameTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionContract.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionNoAuthESTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerAuthElasticSearchSingleton.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchExtension.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchRule.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DocumentIdTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckConnectionTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryAuthTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/RoutingKeyTest.java
delete mode 100644 backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrolledSearchTest.java
delete mode 100644 backends-common/elasticsearch/src/test/resources/auth-es/NginxDockerfile
delete mode 100644 backends-common/elasticsearch/src/test/resources/auth-es/README.md
delete mode 100644 backends-common/elasticsearch/src/test/resources/auth-es/default.crt
delete mode 100644 backends-common/elasticsearch/src/test/resources/auth-es/default.key
delete mode 100644 backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/passwd
delete mode 100644 backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/reverse_elasticsearch.conf
delete mode 100644 backends-common/elasticsearch/src/test/resources/auth-es/server.jks
delete mode 100644 mailbox/elasticsearch/pom.xml
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfiguration.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/IndexAttachments.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticSearchConstants.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactory.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIndexCreationUtil.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailer.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailers.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartContainerBuilder.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartParser.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/RootMimePartContainerBuilder.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/SerializableMessage.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/Subjects.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatter.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
delete mode 100644 mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
delete mode 100644 mailbox/elasticsearch/src/reporting-site/site.xml
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfigurationTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactoryTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailerTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailersTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/FieldImpl.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/SubjectsTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatterTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/SearchQueryTest.java
delete mode 100644 mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
delete mode 100644 mailbox/elasticsearch/src/test/resources/eml/bodyMakeTikaToFail.eml
delete mode 100644 mailbox/elasticsearch/src/test/resources/eml/emailWith3Attachments.eml
delete mode 100644 mailbox/elasticsearch/src/test/resources/eml/htmlContent.txt
delete mode 100644 mailbox/elasticsearch/src/test/resources/eml/mailCustomDateHeader.eml
delete mode 100644 mailbox/elasticsearch/src/test/resources/eml/mailCustomStringHeader.eml
delete mode 100644 mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/pom.xml
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactory.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactoryTest.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatio.json
delete mode 100644 mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatioNoDomain.json
delete mode 100644 server/container/metrics/metrics-es-reporter/pom.xml
delete mode 100644 server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESMetricReporter.java
delete mode 100644 server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESReporterConfiguration.java
delete mode 100644 server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/DockerElasticSearchExtension.java
delete mode 100644 server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java
delete mode 100644 server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java
delete mode 100644 server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReportedConfigurationTest.java
delete mode 100644 server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReporterContract.java
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 28/32: JAMES-3492,
add note about need of separate Elasticsearch 6 instance for
reporting metrics to Elasticsearch
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 08fb0bf4f148a1472f83fbbf1e0fd02b43f55c0e
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Fri Mar 12 10:30:39 2021 +0200
JAMES-3492, add note about need of separate Elasticsearch 6 instance for reporting metrics to Elasticsearch
---
src/site/xdoc/server/config-elasticsearch.xml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/site/xdoc/server/config-elasticsearch.xml b/src/site/xdoc/server/config-elasticsearch.xml
index 5a7fa6f..bf52fc43 100644
--- a/src/site/xdoc/server/config-elasticsearch.xml
+++ b/src/site/xdoc/server/config-elasticsearch.xml
@@ -127,6 +127,11 @@
For configuring the metric reporting on ElasticSearch :
+ <p>
+ In server version 3.6.0 james moved from Elasticsearch 6 to 7 and the metric reporting on Elasticsearch is deprecated.
+ You can still use metric reporting on Elasticsearch but that requires you to run a separate Elasticsearch 6 instance and use that in your Elasticsearch metric reporting configuration.
+ </p>
+
<dl>
<dt><strong>elasticsearch.http.host</strong></dt>
<dd>Host to report metrics on. Defaults to master host. Compatible with 6.x hosts</dd>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 19/32: JAMES-3492, applied sortpom:sort
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 0c22bdc1051c06d56d6059e7f355527658135b2c
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Wed Mar 10 20:40:14 2021 +0200
JAMES-3492, applied sortpom:sort
---
backends-common/cassandra/pom.xml | 2 +-
event-bus/api/pom.xml | 6 +-
event-bus/in-vm/pom.xml | 6 +-
event-bus/pom.xml | 6 +-
examples/custom-listeners/pom.xml | 136 ++++++++++-----------
examples/custom-mailets/pom.xml | 77 ++++++------
examples/pom.xml | 48 ++++----
mailbox/tika/pom.xml | 2 +-
pom.xml | 8 +-
server/app/pom.xml | 16 +--
server/blob/blob-gc/pom.xml | 6 +-
server/blob/blob-storage-strategy/pom.xml | 4 +-
server/container/guice/data-ldap/pom.xml | 6 +-
server/container/guice/sieve-file/pom.xml | 3 +-
server/container/guice/sieve-jpa/pom.xml | 3 +-
server/mailet/mock-smtp-server/pom.xml | 6 +-
.../pom.xml | 2 +-
.../pom.xml | 3 +-
.../distributed-webadmin-integration-test/pom.xml | 2 +-
19 files changed, 158 insertions(+), 184 deletions(-)
diff --git a/backends-common/cassandra/pom.xml b/backends-common/cassandra/pom.xml
index 735a566..361dd64 100644
--- a/backends-common/cassandra/pom.xml
+++ b/backends-common/cassandra/pom.xml
@@ -84,7 +84,7 @@
<artifactId>commons-beanutils</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
+ <dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
diff --git a/event-bus/api/pom.xml b/event-bus/api/pom.xml
index 6a577f1..36cfa78 100644
--- a/event-bus/api/pom.xml
+++ b/event-bus/api/pom.xml
@@ -17,9 +17,7 @@
specific language governing permissions and limitations
under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.james</groupId>
@@ -79,4 +77,4 @@
<scope>test</scope>
</dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/event-bus/in-vm/pom.xml b/event-bus/in-vm/pom.xml
index 00a3536..5124273 100644
--- a/event-bus/in-vm/pom.xml
+++ b/event-bus/in-vm/pom.xml
@@ -17,9 +17,7 @@
specific language governing permissions and limitations
under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.james</groupId>
@@ -75,4 +73,4 @@
<scope>test</scope>
</dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/event-bus/pom.xml b/event-bus/pom.xml
index 95a420c..49f19b9 100644
--- a/event-bus/pom.xml
+++ b/event-bus/pom.xml
@@ -17,9 +17,7 @@
specific language governing permissions and limitations
under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.james</groupId>
@@ -37,4 +35,4 @@
<module>distributed</module>
<module>in-vm</module>
</modules>
-</project>
\ No newline at end of file
+</project>
diff --git a/examples/custom-listeners/pom.xml b/examples/custom-listeners/pom.xml
index 48359f3..1491ef5 100644
--- a/examples/custom-listeners/pom.xml
+++ b/examples/custom-listeners/pom.xml
@@ -18,74 +18,70 @@
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.james.examples</groupId>
- <artifactId>examples</artifactId>
- <version>3.6.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>custom-listeners</artifactId>
-
- <name>Apache James :: Examples :: Custom Listeners</name>
-
- <dependencies>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-api</artifactId>
- <version>${james.baseVersion}</version>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-api</artifactId>
- <version>${james.baseVersion}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <version>${james.baseVersion}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <version>${james.baseVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>event-bus-api</artifactId>
- <version>${james.baseVersion}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>metrics-tests</artifactId>
- <version>${james.baseVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>testing-base</artifactId>
- <version>${james.baseVersion}</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>11</source>
- <target>11</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.james.examples</groupId>
+ <artifactId>examples</artifactId>
+ <version>3.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>custom-listeners</artifactId>
+ <name>Apache James :: Examples :: Custom Listeners</name>
+ <dependencies>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>apache-james-mailbox-api</artifactId>
+ <version>${james.baseVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>apache-james-mailbox-api</artifactId>
+ <version>${james.baseVersion}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>apache-james-mailbox-memory</artifactId>
+ <version>${james.baseVersion}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>apache-james-mailbox-memory</artifactId>
+ <version>${james.baseVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>event-bus-api</artifactId>
+ <version>${james.baseVersion}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>metrics-tests</artifactId>
+ <version>${james.baseVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>testing-base</artifactId>
+ <version>${james.baseVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>11</source>
+ <target>11</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/examples/custom-mailets/pom.xml b/examples/custom-mailets/pom.xml
index 22093a4..812c6a4 100644
--- a/examples/custom-mailets/pom.xml
+++ b/examples/custom-mailets/pom.xml
@@ -18,44 +18,41 @@
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.james.examples</groupId>
- <artifactId>examples</artifactId>
- <version>3.6.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>custom-mailets</artifactId>
- <name>Apache James :: Examples :: Custom Mailets</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>apache-mailet-api</artifactId>
- <version>${james.baseVersion}</version>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-mailet-base</artifactId>
- <version>${james.baseVersion}</version>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-util</artifactId>
- <version>${james.baseVersion}</version>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>11</source>
- <target>11</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.james.examples</groupId>
+ <artifactId>examples</artifactId>
+ <version>3.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>custom-mailets</artifactId>
+ <name>Apache James :: Examples :: Custom Mailets</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>apache-mailet-api</artifactId>
+ <version>${james.baseVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>apache-mailet-base</artifactId>
+ <version>${james.baseVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>james-server-util</artifactId>
+ <version>${james.baseVersion}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>11</source>
+ <target>11</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/examples/pom.xml b/examples/pom.xml
index 2a913a7..843f552 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -18,30 +18,26 @@
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache</groupId>
- <artifactId>apache</artifactId>
- <version>23</version>
- <relativePath></relativePath>
- </parent>
-
- <groupId>org.apache.james.examples</groupId>
- <artifactId>examples</artifactId>
- <version>3.6.0-SNAPSHOT</version>
- <packaging>pom</packaging>
-
- <name>Apache James :: Examples</name>
-
- <modules>
- <module>custom-listeners</module>
- <module>custom-mailets</module>
- </modules>
-
- <properties>
- <james.groupId>org.apache.james</james.groupId>
- <james.baseVersion>${project.version}</james.baseVersion>
- <maven.compiler.target>1.11</maven.compiler.target>
- <maven.compiler.source>1.11</maven.compiler.source>
- </properties>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>23</version>
+ <relativePath></relativePath>
+ </parent>
+ <groupId>org.apache.james.examples</groupId>
+ <artifactId>examples</artifactId>
+ <version>3.6.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Apache James :: Examples</name>
+ <modules>
+ <module>custom-listeners</module>
+ <module>custom-mailets</module>
+ </modules>
+ <properties>
+ <james.groupId>org.apache.james</james.groupId>
+ <james.baseVersion>${project.version}</james.baseVersion>
+ <maven.compiler.target>1.11</maven.compiler.target>
+ <maven.compiler.source>1.11</maven.compiler.source>
+ </properties>
</project>
diff --git a/mailbox/tika/pom.xml b/mailbox/tika/pom.xml
index 09d8c78..a2e53e4 100644
--- a/mailbox/tika/pom.xml
+++ b/mailbox/tika/pom.xml
@@ -110,5 +110,5 @@
<scope>test</scope>
</dependency>
</dependencies>
-
+
</project>
diff --git a/pom.xml b/pom.xml
index 8443fb2..d7b5a91 100644
--- a/pom.xml
+++ b/pom.xml
@@ -765,14 +765,14 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch</artifactId>
<version>${project.version}</version>
+ <type>test-jar</type>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
<version>${project.version}</version>
- <type>test-jar</type>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
@@ -3554,7 +3554,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
- <excludedGroups></excludedGroups>
+ <excludedGroups />
<groups>unstable</groups>
</configuration>
</plugin>
diff --git a/server/app/pom.xml b/server/app/pom.xml
index 157e7a4..0d96ef9 100644
--- a/server/app/pom.xml
+++ b/server/app/pom.xml
@@ -844,21 +844,21 @@
<!-- this is only needed because windows freak out on long cmd lines, so we strip of the absolute path
from the lib dir to make windows happy again
-->
- <replace file="${project.build.directory}/appassembler/bin/run.bat" token="%BASEDIR%\lib" value="..\lib"></replace>
- <replace file="${project.build.directory}/appassembler/bin/run.sh" token="setenv" value="setenv.sh"></replace>
+ <replace file="${project.build.directory}/appassembler/bin/run.bat" token="%BASEDIR%\lib" value="..\lib" />
+ <replace file="${project.build.directory}/appassembler/bin/run.sh" token="setenv" value="setenv.sh" />
<!-- this is needed because appassembler is not really smart on some settings -->
- <replace file="${project.build.directory}/appassembler/jsw/james/conf/wrapper.conf" token="lib/wrapper.jar" value="%REPO_DIR%/wrapper.jar"></replace>
- <replace file="${project.build.directory}/appassembler/jsw/james/bin/james" token="logs" value="var"></replace>
- <replace file="${project.build.directory}/appassembler/jsw/james/bin/james" token="setenv" value="setenv.sh"></replace>
+ <replace file="${project.build.directory}/appassembler/jsw/james/conf/wrapper.conf" token="lib/wrapper.jar" value="%REPO_DIR%/wrapper.jar" />
+ <replace file="${project.build.directory}/appassembler/jsw/james/bin/james" token="logs" value="var" />
+ <replace file="${project.build.directory}/appassembler/jsw/james/bin/james" token="setenv" value="setenv.sh" />
<!-- copy the linux wrapper-linux-x86-32 to wrapper, so use it as default if no matching wrapper was found -->
- <copy file="${project.build.directory}/appassembler/jsw/james/bin/wrapper-linux-x86-32" tofile="${project.build.directory}/appassembler/jsw/james/bin/wrapper"></copy>
+ <copy file="${project.build.directory}/appassembler/jsw/james/bin/wrapper-linux-x86-32" tofile="${project.build.directory}/appassembler/jsw/james/bin/wrapper" />
<!-- this is only needed because windows freak out on long cmd lines, so we strip of the absolute path
from the lib dir to make windows happy again
-->
- <replace file="${project.build.directory}/appassembler/bin/james-cli.bat" token="%BASEDIR%\lib" value="..\lib"></replace>
- <replace file="${project.build.directory}/appassembler/bin/james-cli.sh" token="setenv" value="setenv.sh"></replace>
+ <replace file="${project.build.directory}/appassembler/bin/james-cli.bat" token="%BASEDIR%\lib" value="..\lib" />
+ <replace file="${project.build.directory}/appassembler/bin/james-cli.sh" token="setenv" value="setenv.sh" />
</tasks>
</configuration>
diff --git a/server/blob/blob-gc/pom.xml b/server/blob/blob-gc/pom.xml
index a396e74..75d5a58 100644
--- a/server/blob/blob-gc/pom.xml
+++ b/server/blob/blob-gc/pom.xml
@@ -31,10 +31,8 @@
<packaging>jar</packaging>
<name>Apache James :: Server :: Blob :: Deduplicating Blob Storage Garbage collection</name>
- <description>
- Garbage collector for the deduplicating blob store
- to ensure their effective deletion.
- </description>
+ <description>Garbage collector for the deduplicating blob store
+ to ensure their effective deletion.</description>
<dependencies>
<dependency>
diff --git a/server/blob/blob-storage-strategy/pom.xml b/server/blob/blob-storage-strategy/pom.xml
index 3cf0b1e..f191251 100644
--- a/server/blob/blob-storage-strategy/pom.xml
+++ b/server/blob/blob-storage-strategy/pom.xml
@@ -31,9 +31,7 @@
<packaging>jar</packaging>
<name>Apache James :: Server :: Blob :: Deduplicating Blob Storage</name>
- <description>
- An implementation of BlobStore which deduplicates the stored blobs.
- </description>
+ <description>An implementation of BlobStore which deduplicates the stored blobs.</description>
<dependencies>
<dependency>
diff --git a/server/container/guice/data-ldap/pom.xml b/server/container/guice/data-ldap/pom.xml
index 745758b..61220c7 100644
--- a/server/container/guice/data-ldap/pom.xml
+++ b/server/container/guice/data-ldap/pom.xml
@@ -17,9 +17,7 @@
specific language governing permissions and limitations
under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -57,4 +55,4 @@
<artifactId>guice</artifactId>
</dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/server/container/guice/sieve-file/pom.xml b/server/container/guice/sieve-file/pom.xml
index 43d04f5..cbe5211 100644
--- a/server/container/guice/sieve-file/pom.xml
+++ b/server/container/guice/sieve-file/pom.xml
@@ -30,7 +30,7 @@
<artifactId>james-server-guice-sieve-file</artifactId>
<packaging>jar</packaging>
- <name>Apache James :: Server :: Guice :: Sieve :: File </name>
+ <name>Apache James :: Server :: Guice :: Sieve :: File</name>
<description>Sieve File modules for Guice implementation of James server</description>
<dependencies>
@@ -50,5 +50,4 @@
</dependency>
</dependencies>
-
</project>
diff --git a/server/container/guice/sieve-jpa/pom.xml b/server/container/guice/sieve-jpa/pom.xml
index 27b5019..ad106f9 100644
--- a/server/container/guice/sieve-jpa/pom.xml
+++ b/server/container/guice/sieve-jpa/pom.xml
@@ -30,7 +30,7 @@
<artifactId>james-server-guice-sieve-jpa</artifactId>
<packaging>jar</packaging>
- <name>Apache James :: Server :: Guice :: Sieve :: JPA </name>
+ <name>Apache James :: Server :: Guice :: Sieve :: JPA</name>
<description>Sieve JPA modules for Guice implementation of James server</description>
<dependencies>
@@ -50,5 +50,4 @@
</dependency>
</dependencies>
-
</project>
diff --git a/server/mailet/mock-smtp-server/pom.xml b/server/mailet/mock-smtp-server/pom.xml
index 9acfed5..f550851 100644
--- a/server/mailet/mock-smtp-server/pom.xml
+++ b/server/mailet/mock-smtp-server/pom.xml
@@ -31,10 +31,8 @@
<packaging>jar</packaging>
<name>Apache James :: Server :: Mailet :: Mock SMTP Server</name>
- <description>
- Provide a standalone mock SMTP server that could be configured over HTTP.
- Dockerized it can be used for advanced error testing for SMTP clients.
- </description>
+ <description>Provide a standalone mock SMTP server that could be configured over HTTP.
+ Dockerized it can be used for advanced error testing for SMTP clients.</description>
<dependencies>
<dependency>
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
index 1b87ea7..cf7f235 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
@@ -181,7 +181,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
- <excludedGroups></excludedGroups>
+ <excludedGroups />
<groups combine.self="override">org.apache.james.junit.categories.Unstable</groups>
</configuration>
</plugin>
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml
index 64f7b6a..aca843e 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml
@@ -25,6 +25,7 @@
<artifactId>jmap-rfc-8621-integration-tests</artifactId>
<version>3.6.0-SNAPSHOT</version>
</parent>
+
<artifactId>distributed-jmap-rfc-8621-integration-tests</artifactId>
<name>Apache James :: Server :: JMAP RFC-8621 :: Distributed Integration Testing</name>
<description>Distributed Integration testing for JMAP RFC-8621</description>
@@ -145,7 +146,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
- <excludedGroups></excludedGroups>
+ <excludedGroups />
<groups>unstable</groups>
</configuration>
</plugin>
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml
index 5e62c86..fcb60e2 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml
@@ -117,7 +117,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
- <excludedGroups></excludedGroups>
+ <excludedGroups />
<groups combine.self="override">BasicFeature&unstable</groups>
</configuration>
</plugin>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 22/32: JAMES-3502, remove elastic six modules
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 9376e1ec83dfd1ac419465dd9c7d72185e482113
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Thu Mar 11 10:25:18 2021 +0200
JAMES-3502, remove elastic six modules
---
backends-common/elasticsearch/pom.xml | 122 ----
.../org/apache/james/backends/es/AliasName.java | 49 --
.../apache/james/backends/es/ClientProvider.java | 219 -------
.../james/backends/es/DeleteByQueryPerformer.java | 90 ---
.../org/apache/james/backends/es/DocumentId.java | 59 --
.../backends/es/ElasticSearchConfiguration.java | 623 -------------------
.../backends/es/ElasticSearchHealthCheck.java | 81 ---
.../james/backends/es/ElasticSearchIndexer.java | 137 ----
.../james/backends/es/IndexCreationFactory.java | 200 ------
.../org/apache/james/backends/es/IndexName.java | 58 --
.../james/backends/es/NodeMappingFactory.java | 85 ---
.../backends/es/ReactorElasticSearchClient.java | 179 ------
.../apache/james/backends/es/ReadAliasName.java | 26 -
.../org/apache/james/backends/es/RoutingKey.java | 63 --
.../james/backends/es/UpdatedRepresentation.java | 69 ---
.../apache/james/backends/es/WriteAliasName.java | 26 -
.../james/backends/es/search/ScrolledSearch.java | 108 ----
.../apache/james/backends/es/AliasNameTest.java | 32 -
...iderImplConnectionAuthESIgnoreSSLCheckTest.java | 47 --
...ImplConnectionAuthESOverrideTrustStoreTest.java | 48 --
.../es/ClientProviderImplConnectionContract.java | 93 ---
.../ClientProviderImplConnectionNoAuthESTest.java | 31 -
.../james/backends/es/ClientProviderTest.java | 33 -
.../es/DockerAuthElasticSearchSingleton.java | 28 -
.../james/backends/es/DockerElasticSearch.java | 356 -----------
.../backends/es/DockerElasticSearchExtension.java | 63 --
.../james/backends/es/DockerElasticSearchRule.java | 49 --
.../backends/es/DockerElasticSearchSingleton.java | 28 -
.../apache/james/backends/es/DocumentIdTest.java | 46 --
.../backends/es/ElasticSearchClusterExtension.java | 118 ----
.../es/ElasticSearchConfigurationTest.java | 687 ---------------------
.../es/ElasticSearchHealthCheckConnectionTest.java | 61 --
.../backends/es/ElasticSearchHealthCheckTest.java | 80 ---
.../backends/es/ElasticSearchIndexerTest.java | 292 ---------
.../backends/es/IndexCreationFactoryTest.java | 77 ---
.../backends/es/NodeMappingFactoryAuthTest.java | 114 ----
.../james/backends/es/NodeMappingFactoryTest.java | 102 ---
.../apache/james/backends/es/RoutingKeyTest.java | 46 --
.../backends/es/search/ScrolledSearchTest.java | 199 ------
.../src/test/resources/auth-es/NginxDockerfile | 5 -
.../src/test/resources/auth-es/README.md | 30 -
.../src/test/resources/auth-es/default.crt | 19 -
.../src/test/resources/auth-es/default.key | 27 -
.../src/test/resources/auth-es/nginx-conf/passwd | 2 -
.../auth-es/nginx-conf/reverse_elasticsearch.conf | 12 -
.../src/test/resources/auth-es/server.jks | Bin 1074 -> 0 bytes
backends-common/pom.xml | 1 -
mailbox/plugin/quota-search-elasticsearch/pom.xml | 137 ----
.../ElasticSearchQuotaConfiguration.java | 151 -----
.../elasticsearch/ElasticSearchQuotaSearcher.java | 109 ----
.../search/elasticsearch/QuotaQueryConverter.java | 103 ---
.../QuotaRatioElasticSearchConstants.java | 35 --
.../elasticsearch/QuotaRatioMappingFactory.java | 66 --
.../QuotaSearchIndexCreationUtil.java | 56 --
.../elasticsearch/UserRoutingKeyFactory.java | 30 -
.../events/ElasticSearchQuotaMailboxListener.java | 86 ---
.../elasticsearch/json/JsonMessageConstants.java | 28 -
.../elasticsearch/json/QuotaRatioAsJson.java | 120 ----
.../json/QuotaRatioToElasticSearchJson.java | 49 --
.../ElasticSearchQuotaConfigurationTest.java | 103 ---
...lasticSearchQuotaSearchTestSystemExtension.java | 106 ----
.../ElasticSearchQuotaSearcherTest.java | 88 ---
.../elasticsearch/QuotaQueryConverterTest.java | 83 ---
.../elasticsearch/UserRoutingKeyFactoryTest.java | 34 -
.../ElasticSearchQuotaMailboxListenerTest.java | 111 ----
.../elasticsearch/json/QuotaRatioAsJsonTest.java | 109 ----
.../json/QuotaRatioToElasticSearchJsonTest.java | 79 ---
.../src/test/resources/quotaRatio.json | 1 -
.../src/test/resources/quotaRatioNoDomain.json | 1 -
mailbox/pom.xml | 2 -
pom.xml | 29 +-
.../container/metrics/metrics-es-reporter/pom.xml | 103 ---
.../apache/james/metrics/es/ESMetricReporter.java | 69 ---
.../james/metrics/es/ESReporterConfiguration.java | 114 ----
.../metric/es/DockerElasticSearchExtension.java | 73 ---
.../apache/james/metric/es/ES2ReporterTest.java | 31 -
.../apache/james/metric/es/ES6ReporterTest.java | 29 -
.../metric/es/ESReportedConfigurationTest.java | 87 ---
.../apache/james/metric/es/ESReporterContract.java | 128 ----
server/pom.xml | 1 -
80 files changed, 1 insertion(+), 7270 deletions(-)
diff --git a/backends-common/elasticsearch/pom.xml b/backends-common/elasticsearch/pom.xml
deleted file mode 100644
index 9620615..0000000
--- a/backends-common/elasticsearch/pom.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.james</groupId>
- <artifactId>james-backends-common</artifactId>
- <version>3.6.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>apache-james-backends-es</artifactId>
-
- <dependencies>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-core</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-testing</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>testing-base</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.github.fge</groupId>
- <artifactId>throwing-lambdas</artifactId>
- </dependency>
- <dependency>
- <groupId>io.github.openfeign</groupId>
- <artifactId>feign-core</artifactId>
- </dependency>
- <dependency>
- <groupId>io.github.openfeign</groupId>
- <artifactId>feign-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>javax.annotation-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-configuration2</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-to-slf4j</artifactId>
- <version>2.12.1</version>
- </dependency>
- <dependency>
- <groupId>org.awaitility</groupId>
- <artifactId>awaitility</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>6.4.3</version>
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.testcontainers</groupId>
- <artifactId>testcontainers</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <reuseForks>true</reuseForks>
- <forkCount>2</forkCount>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/AliasName.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/AliasName.java
deleted file mode 100644
index 3f1438d..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/AliasName.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.util.Objects;
-
-public class AliasName {
- private final String value;
-
- protected AliasName(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof AliasName) {
- AliasName aliasName = (AliasName) o;
-
- return Objects.equals(this.value, aliasName.value);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(value);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java
deleted file mode 100644
index b73fbd3..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProvider.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.backends.es;
-
-import java.io.IOException;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.time.Duration;
-import java.time.LocalDateTime;
-
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
-
-import org.apache.commons.lang3.NotImplementedException;
-import org.apache.commons.lang3.time.DurationFormatUtils;
-import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.conn.ssl.DefaultHostnameVerifier;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
-import org.apache.http.ssl.SSLContextBuilder;
-import org.apache.http.ssl.TrustStrategy;
-import org.apache.james.backends.es.ElasticSearchConfiguration.HostScheme;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.HostNameVerifier;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLValidationStrategy;
-import org.elasticsearch.client.RestClient;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-import reactor.util.retry.Retry;
-
-public class ClientProvider implements Provider<ReactorElasticSearchClient> {
-
- private static class HttpAsyncClientConfigurer {
-
- private static final TrustStrategy TRUST_ALL = (x509Certificates, authType) -> true;
- private static final HostnameVerifier ACCEPT_ANY_HOSTNAME = (hostname, sslSession) -> true;
-
- private final ElasticSearchConfiguration configuration;
-
- private HttpAsyncClientConfigurer(ElasticSearchConfiguration configuration) {
- this.configuration = configuration;
- }
-
- private HttpAsyncClientBuilder configure(HttpAsyncClientBuilder builder) {
- configureAuthentication(builder);
- configureHostScheme(builder);
-
- return builder;
- }
-
- private void configureHostScheme(HttpAsyncClientBuilder builder) {
- HostScheme scheme = configuration.getHostScheme();
-
- switch (scheme) {
- case HTTP:
- return;
- case HTTPS:
- configureSSLOptions(builder);
- return;
- default:
- throw new NotImplementedException(
- String.format("unrecognized hostScheme '%s'", scheme.name()));
- }
- }
-
- private void configureSSLOptions(HttpAsyncClientBuilder builder) {
- try {
- builder
- .setSSLContext(sslContext())
- .setSSLHostnameVerifier(hostnameVerifier());
- } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | IOException e) {
- throw new RuntimeException("Cannot set SSL options to the builder", e);
- }
- }
-
- private SSLContext sslContext() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException,
- CertificateException, IOException {
-
- SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
-
- SSLValidationStrategy strategy = configuration.getSslConfiguration()
- .getStrategy();
-
- switch (strategy) {
- case DEFAULT:
- return sslContextBuilder.build();
- case IGNORE:
- return sslContextBuilder.loadTrustMaterial(TRUST_ALL)
- .build();
- case OVERRIDE:
- return applyTrustStore(sslContextBuilder)
- .build();
- default:
- throw new NotImplementedException(
- String.format("unrecognized strategy '%s'", strategy.name()));
- }
- }
-
- private HostnameVerifier hostnameVerifier() {
- HostNameVerifier hostnameVerifier = configuration.getSslConfiguration()
- .getHostNameVerifier();
-
- switch (hostnameVerifier) {
- case DEFAULT:
- return new DefaultHostnameVerifier();
- case ACCEPT_ANY_HOSTNAME:
- return ACCEPT_ANY_HOSTNAME;
- default:
- throw new NotImplementedException(
- String.format("unrecognized HostNameVerifier '%s'", hostnameVerifier.name()));
- }
- }
-
- private SSLContextBuilder applyTrustStore(SSLContextBuilder sslContextBuilder) throws CertificateException, NoSuchAlgorithmException,
- KeyStoreException, IOException {
-
- SSLTrustStore trustStore = configuration.getSslConfiguration()
- .getTrustStore()
- .orElseThrow(() -> new IllegalStateException("SSLTrustStore cannot to be empty"));
-
- return sslContextBuilder
- .loadTrustMaterial(trustStore.getFile(), trustStore.getPassword());
- }
-
- private void configureAuthentication(HttpAsyncClientBuilder builder) {
- configuration.getCredential()
- .ifPresent(credential -> {
- CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(AuthScope.ANY,
- new UsernamePasswordCredentials(credential.getUsername(), String.valueOf(credential.getPassword())));
- builder.setDefaultCredentialsProvider(credentialsProvider);
- });
- }
- }
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ClientProvider.class);
-
- private final ElasticSearchConfiguration configuration;
- private final RestHighLevelClient elasticSearchRestHighLevelClient;
- private final HttpAsyncClientConfigurer httpAsyncClientConfigurer;
- private final ReactorElasticSearchClient client;
-
- @Inject
- @VisibleForTesting
- ClientProvider(ElasticSearchConfiguration configuration) {
- this.httpAsyncClientConfigurer = new HttpAsyncClientConfigurer(configuration);
- this.configuration = configuration;
- this.elasticSearchRestHighLevelClient = connect(configuration);
- this.client = new ReactorElasticSearchClient(this.elasticSearchRestHighLevelClient);
- }
-
- private RestHighLevelClient connect(ElasticSearchConfiguration configuration) {
- Duration waitDelay = Duration.ofMillis(configuration.getMinDelay());
- boolean suppressLeadingZeroElements = true;
- boolean suppressTrailingZeroElements = true;
- return Mono.fromCallable(() -> connectToCluster(configuration))
- .doOnError(e -> LOGGER.warn("Error establishing ElasticSearch connection. Next retry scheduled in {}",
- DurationFormatUtils.formatDurationWords(waitDelay.toMillis(), suppressLeadingZeroElements, suppressTrailingZeroElements), e))
- .retryWhen(Retry.backoff(configuration.getMaxRetries(), waitDelay).scheduler(Schedulers.elastic()))
- .publishOn(Schedulers.elastic())
- .block();
- }
-
- private RestHighLevelClient connectToCluster(ElasticSearchConfiguration configuration) {
- LOGGER.info("Trying to connect to ElasticSearch service at {}", LocalDateTime.now());
-
- return new RestHighLevelClient(
- RestClient
- .builder(hostsToHttpHosts())
- .setHttpClientConfigCallback(httpAsyncClientConfigurer::configure)
- .setMaxRetryTimeoutMillis(Math.toIntExact(configuration.getRequestTimeout().toMillis())));
- }
-
- private HttpHost[] hostsToHttpHosts() {
- return configuration.getHosts().stream()
- .map(host -> new HttpHost(host.getHostName(), host.getPort(), configuration.getHostScheme().name()))
- .toArray(HttpHost[]::new);
- }
-
- @Override
- public ReactorElasticSearchClient get() {
- return client;
- }
-
- @PreDestroy
- public void close() throws IOException {
- elasticSearchRestHighLevelClient.close();
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java
deleted file mode 100644
index 547ecb6..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DeleteByQueryPerformer.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.apache.james.util.ReactorUtils.DEFAULT_CONCURRENCY;
-
-import org.apache.james.backends.es.search.ScrolledSearch;
-import org.elasticsearch.action.bulk.BulkRequest;
-import org.elasticsearch.action.bulk.BulkResponse;
-import org.elasticsearch.action.delete.DeleteRequest;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import reactor.core.publisher.Mono;
-
-public class DeleteByQueryPerformer {
- private static final TimeValue TIMEOUT = new TimeValue(60000);
-
- private final ReactorElasticSearchClient client;
- private final int batchSize;
- private final WriteAliasName aliasName;
-
- @VisibleForTesting
- DeleteByQueryPerformer(ReactorElasticSearchClient client, int batchSize, WriteAliasName aliasName) {
- this.client = client;
- this.batchSize = batchSize;
- this.aliasName = aliasName;
- }
-
- public Mono<Void> perform(QueryBuilder queryBuilder, RoutingKey routingKey) {
- SearchRequest searchRequest = prepareSearch(queryBuilder, routingKey);
-
- return new ScrolledSearch(client, searchRequest).searchResponses()
- .filter(searchResponse -> searchResponse.getHits().getHits().length > 0)
- .flatMap(searchResponse -> deleteRetrievedIds(searchResponse, routingKey), DEFAULT_CONCURRENCY)
- .then();
- }
-
- private SearchRequest prepareSearch(QueryBuilder queryBuilder, RoutingKey routingKey) {
- return new SearchRequest(aliasName.getValue())
- .types(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .scroll(TIMEOUT)
- .source(searchSourceBuilder(queryBuilder))
- .routing(routingKey.asString());
- }
-
- private SearchSourceBuilder searchSourceBuilder(QueryBuilder queryBuilder) {
- return new SearchSourceBuilder()
- .query(queryBuilder)
- .size(batchSize);
- }
-
- private Mono<BulkResponse> deleteRetrievedIds(SearchResponse searchResponse, RoutingKey routingKey) {
- BulkRequest request = new BulkRequest();
-
- for (SearchHit hit : searchResponse.getHits()) {
- request.add(
- new DeleteRequest(aliasName.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(hit.getId())
- .routing(routingKey.asString()));
- }
-
- return client.bulk(request, RequestOptions.DEFAULT);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DocumentId.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DocumentId.java
deleted file mode 100644
index 7633208..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/DocumentId.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.util.Objects;
-
-import org.elasticsearch.common.Strings;
-
-import com.google.common.base.Preconditions;
-
-public class DocumentId {
-
- public static DocumentId fromString(String value) {
- return new DocumentId(value);
- }
-
- private final String value;
-
- private DocumentId(String value) {
- Preconditions.checkArgument(!Strings.isNullOrEmpty(value), "DocumentId must be specified");
- this.value = value;
- }
-
- public String asString() {
- return value;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof DocumentId) {
- DocumentId that = (DocumentId) o;
-
- return Objects.equals(this.value, that.value);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(value);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java
deleted file mode 100644
index 8f520d6..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchConfiguration.java
+++ /dev/null
@@ -1,623 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLValidationStrategy.OVERRIDE;
-
-import java.io.File;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.time.Duration;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import org.apache.commons.configuration2.Configuration;
-import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.HostNameVerifier;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLValidationStrategy;
-import org.apache.james.util.Host;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-public class ElasticSearchConfiguration {
-
- public enum HostScheme {
- HTTP("http"),
- HTTPS("https");
-
- public static HostScheme of(String schemeValue) {
- Preconditions.checkNotNull(schemeValue);
-
- return Arrays.stream(values())
- .filter(hostScheme -> hostScheme.value.toLowerCase(Locale.US)
- .equals(schemeValue.toLowerCase(Locale.US)))
- .findFirst()
- .orElseThrow(() -> new IllegalArgumentException(
- String.format("Unknown HostScheme '%s'", schemeValue)));
- }
-
- private final String value;
-
- HostScheme(String value) {
- this.value = value;
- }
- }
-
- public static class Credential {
-
- public static Credential of(String username, String password) {
- return new Credential(username, password);
- }
-
- private final String username;
- private final char[] password;
-
- private Credential(String username, String password) {
- Preconditions.checkNotNull(username, "username cannot be null when password is specified");
- Preconditions.checkNotNull(password, "password cannot be null when username is specified");
-
- this.username = username;
- this.password = password.toCharArray();
- }
-
- public String getUsername() {
- return username;
- }
-
- public char[] getPassword() {
- return password;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof Credential) {
- Credential that = (Credential) o;
-
- return Objects.equals(this.username, that.username)
- && Arrays.equals(this.password, that.password);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(username, Arrays.hashCode(password));
- }
- }
-
- public static class SSLConfiguration {
-
- public enum SSLValidationStrategy {
- DEFAULT,
- IGNORE,
- OVERRIDE;
-
- static SSLValidationStrategy from(String rawValue) {
- Preconditions.checkNotNull(rawValue);
-
- return Stream.of(values())
- .filter(strategy -> strategy.name().equalsIgnoreCase(rawValue))
- .findAny()
- .orElseThrow(() -> new IllegalArgumentException(String.format("invalid strategy '%s'", rawValue)));
-
- }
- }
-
- public enum HostNameVerifier {
- DEFAULT,
- ACCEPT_ANY_HOSTNAME;
-
- static HostNameVerifier from(String rawValue) {
- Preconditions.checkNotNull(rawValue);
-
- return Stream.of(values())
- .filter(verifier -> verifier.name().equalsIgnoreCase(rawValue))
- .findAny()
- .orElseThrow(() -> new IllegalArgumentException(String.format("invalid HostNameVerifier '%s'", rawValue)));
-
- }
- }
-
- public static class SSLTrustStore {
-
- public static SSLTrustStore of(String filePath, String password) {
- return new SSLTrustStore(filePath, password);
- }
-
- private final File file;
- private final char[] password;
-
- private SSLTrustStore(String filePath, String password) {
- Preconditions.checkNotNull(filePath, "%s cannot be null when %s is specified",
- ELASTICSEARCH_HTTPS_TRUST_STORE_PATH, ELASTICSEARCH_HTTPS_TRUST_STORE_PASSWORD);
- Preconditions.checkNotNull(password,
- "%s cannot be null when %s is specified",
- ELASTICSEARCH_HTTPS_TRUST_STORE_PASSWORD, ELASTICSEARCH_HTTPS_TRUST_STORE_PATH);
- Preconditions.checkArgument(Files.exists(Paths.get(filePath)),
- "the file '%s' from property '%s' doesn't exist", filePath, ELASTICSEARCH_HTTPS_TRUST_STORE_PATH);
-
- this.file = new File(filePath);
- this.password = password.toCharArray();
- }
-
- public File getFile() {
- return file;
- }
-
- public char[] getPassword() {
- return password;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof SSLTrustStore) {
- SSLTrustStore that = (SSLTrustStore) o;
-
- return Objects.equals(this.file, that.file)
- && Arrays.equals(this.password, that.password);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(file, Arrays.hashCode(password));
- }
- }
-
- static class Builder {
-
- interface RequireSSLStrategyTrustStore {
- RequireHostNameVerifier sslStrategy(SSLValidationStrategy strategy, Optional<SSLTrustStore> trustStore);
-
- default RequireHostNameVerifier strategyIgnore() {
- return sslStrategy(SSLValidationStrategy.IGNORE, Optional.empty());
- }
-
- default RequireHostNameVerifier strategyOverride(SSLTrustStore trustStore) {
- return sslStrategy(SSLValidationStrategy.OVERRIDE, Optional.of(trustStore));
- }
-
- default RequireHostNameVerifier strategyDefault() {
- return sslStrategy(SSLValidationStrategy.DEFAULT, Optional.empty());
- }
- }
-
- interface RequireHostNameVerifier {
- ReadyToBuild hostNameVerifier(HostNameVerifier hostNameVerifier);
-
- default ReadyToBuild acceptAnyHostNameVerifier() {
- return hostNameVerifier(HostNameVerifier.ACCEPT_ANY_HOSTNAME);
- }
-
- default ReadyToBuild defaultHostNameVerifier() {
- return hostNameVerifier(HostNameVerifier.DEFAULT);
- }
- }
-
- static class ReadyToBuild {
- private final SSLValidationStrategy sslValidationStrategy;
- private final HostNameVerifier hostNameVerifier;
- private Optional<SSLTrustStore> sslTrustStore;
-
- private ReadyToBuild(SSLValidationStrategy sslValidationStrategy, HostNameVerifier hostNameVerifier, Optional<SSLTrustStore> sslTrustStore) {
- this.sslValidationStrategy = sslValidationStrategy;
- this.hostNameVerifier = hostNameVerifier;
- this.sslTrustStore = sslTrustStore;
- }
-
- public ReadyToBuild sslTrustStore(SSLTrustStore sslTrustStore) {
- this.sslTrustStore = Optional.of(sslTrustStore);
- return this;
- }
-
- public SSLConfiguration build() {
- return new SSLConfiguration(sslValidationStrategy, hostNameVerifier, sslTrustStore);
- }
- }
- }
-
- static SSLConfiguration defaultBehavior() {
- return new SSLConfiguration(SSLValidationStrategy.DEFAULT, HostNameVerifier.DEFAULT, Optional.empty());
- }
-
- static Builder.RequireSSLStrategyTrustStore builder() {
- return (strategy, trustStore) -> hostNameVerifier -> new Builder.ReadyToBuild(strategy, hostNameVerifier, trustStore);
- }
-
- private final SSLValidationStrategy strategy;
- private final HostNameVerifier hostNameVerifier;
- private final Optional<SSLTrustStore> trustStore;
-
- private SSLConfiguration(SSLValidationStrategy strategy, HostNameVerifier hostNameVerifier, Optional<SSLTrustStore> trustStore) {
- Preconditions.checkNotNull(strategy);
- Preconditions.checkNotNull(trustStore);
- Preconditions.checkNotNull(hostNameVerifier);
- Preconditions.checkArgument(strategy != OVERRIDE || trustStore.isPresent(), "%s strategy requires trustStore to be present", OVERRIDE.name());
-
- this.strategy = strategy;
- this.trustStore = trustStore;
- this.hostNameVerifier = hostNameVerifier;
- }
-
- public SSLValidationStrategy getStrategy() {
- return strategy;
- }
-
- public Optional<SSLTrustStore> getTrustStore() {
- return trustStore;
- }
-
- public HostNameVerifier getHostNameVerifier() {
- return hostNameVerifier;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof SSLConfiguration) {
- SSLConfiguration that = (SSLConfiguration) o;
-
- return Objects.equals(this.strategy, that.strategy)
- && Objects.equals(this.trustStore, that.trustStore)
- && Objects.equals(this.hostNameVerifier, that.hostNameVerifier);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(strategy, trustStore, hostNameVerifier);
- }
- }
-
- public static class Builder {
-
- private final ImmutableList.Builder<Host> hosts;
- private Optional<Integer> nbShards;
- private Optional<Integer> nbReplica;
- private Optional<Integer> waitForActiveShards;
- private Optional<Integer> minDelay;
- private Optional<Integer> maxRetries;
- private Optional<Duration> requestTimeout;
- private Optional<HostScheme> hostScheme;
- private Optional<Credential> credential;
- private Optional<SSLConfiguration> sslTrustConfiguration;
-
- public Builder() {
- hosts = ImmutableList.builder();
- nbShards = Optional.empty();
- nbReplica = Optional.empty();
- waitForActiveShards = Optional.empty();
- minDelay = Optional.empty();
- maxRetries = Optional.empty();
- requestTimeout = Optional.empty();
- hostScheme = Optional.empty();
- credential = Optional.empty();
- sslTrustConfiguration = Optional.empty();
- }
-
- public Builder addHost(Host host) {
- this.hosts.add(host);
- return this;
- }
-
- public Builder addHosts(Collection<Host> hosts) {
- this.hosts.addAll(hosts);
- return this;
- }
-
- public Builder nbShards(int nbShards) {
- Preconditions.checkArgument(nbShards > 0, "You need the number of shards to be strictly positive");
- this.nbShards = Optional.of(nbShards);
- return this;
- }
-
- public Builder nbReplica(int nbReplica) {
- Preconditions.checkArgument(nbReplica >= 0, "You need the number of replica to be positive");
- this.nbReplica = Optional.of(nbReplica);
- return this;
- }
-
- public Builder waitForActiveShards(int waitForActiveShards) {
- Preconditions.checkArgument(waitForActiveShards >= 0, "You need the number of waitForActiveShards to be positive");
- this.waitForActiveShards = Optional.of(waitForActiveShards);
- return this;
- }
-
- public Builder minDelay(Optional<Integer> minDelay) {
- this.minDelay = minDelay;
- return this;
- }
-
- public Builder maxRetries(Optional<Integer> maxRetries) {
- this.maxRetries = maxRetries;
- return this;
- }
-
- public Builder requestTimeout(Optional<Duration> requestTimeout) {
- this.requestTimeout = requestTimeout;
- return this;
- }
-
- public Builder hostScheme(Optional<HostScheme> hostScheme) {
- this.hostScheme = hostScheme;
- return this;
- }
-
- public Builder credential(Optional<Credential> credential) {
- this.credential = credential;
- return this;
- }
-
- public Builder sslTrustConfiguration(SSLConfiguration sslConfiguration) {
- this.sslTrustConfiguration = Optional.of(sslConfiguration);
- return this;
- }
-
- public Builder sslTrustConfiguration(Optional<SSLConfiguration> sslTrustStore) {
- this.sslTrustConfiguration = sslTrustStore;
- return this;
- }
-
- public ElasticSearchConfiguration build() {
- ImmutableList<Host> hosts = this.hosts.build();
- Preconditions.checkState(!hosts.isEmpty(), "You need to specify ElasticSearch host");
- return new ElasticSearchConfiguration(
- hosts,
- nbShards.orElse(DEFAULT_NB_SHARDS),
- nbReplica.orElse(DEFAULT_NB_REPLICA),
- waitForActiveShards.orElse(DEFAULT_WAIT_FOR_ACTIVE_SHARDS),
- minDelay.orElse(DEFAULT_CONNECTION_MIN_DELAY),
- maxRetries.orElse(DEFAULT_CONNECTION_MAX_RETRIES),
- requestTimeout.orElse(DEFAULT_REQUEST_TIMEOUT),
- hostScheme.orElse(DEFAULT_SCHEME),
- credential,
- sslTrustConfiguration.orElse(DEFAULT_SSL_TRUST_CONFIGURATION));
- }
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static final String ELASTICSEARCH_HOSTS = "elasticsearch.hosts";
- public static final String ELASTICSEARCH_MASTER_HOST = "elasticsearch.masterHost";
- public static final String ELASTICSEARCH_PORT = "elasticsearch.port";
- public static final String ELASTICSEARCH_HOST_SCHEME = "elasticsearch.hostScheme";
- public static final String ELASTICSEARCH_HTTPS_SSL_VALIDATION_STRATEGY = "elasticsearch.hostScheme.https.sslValidationStrategy";
- public static final String ELASTICSEARCH_HTTPS_HOSTNAME_VERIFIER = "elasticsearch.hostScheme.https.hostNameVerifier";
- public static final String ELASTICSEARCH_HTTPS_TRUST_STORE_PATH = "elasticsearch.hostScheme.https.trustStorePath";
- public static final String ELASTICSEARCH_HTTPS_TRUST_STORE_PASSWORD = "elasticsearch.hostScheme.https.trustStorePassword";
- public static final String ELASTICSEARCH_USER = "elasticsearch.user";
- public static final String ELASTICSEARCH_PASSWORD = "elasticsearch.password";
- public static final String ELASTICSEARCH_NB_REPLICA = "elasticsearch.nb.replica";
- public static final String WAIT_FOR_ACTIVE_SHARDS = "elasticsearch.index.waitForActiveShards";
- public static final String ELASTICSEARCH_NB_SHARDS = "elasticsearch.nb.shards";
- public static final String ELASTICSEARCH_RETRY_CONNECTION_MIN_DELAY = "elasticsearch.retryConnection.minDelay";
- public static final String ELASTICSEARCH_RETRY_CONNECTION_MAX_RETRIES = "elasticsearch.retryConnection.maxRetries";
-
- public static final int DEFAULT_CONNECTION_MAX_RETRIES = 7;
- public static final int DEFAULT_CONNECTION_MIN_DELAY = 3000;
- public static final Duration DEFAULT_REQUEST_TIMEOUT = Duration.ofSeconds(30);
- public static final int DEFAULT_NB_SHARDS = 5;
- public static final int DEFAULT_NB_REPLICA = 1;
- public static final int DEFAULT_WAIT_FOR_ACTIVE_SHARDS = 1;
- public static final int DEFAULT_PORT = 9200;
- public static final String LOCALHOST = "127.0.0.1";
- public static final Optional<Integer> DEFAULT_PORT_AS_OPTIONAL = Optional.of(DEFAULT_PORT);
- public static final HostScheme DEFAULT_SCHEME = HostScheme.HTTP;
- public static final SSLConfiguration DEFAULT_SSL_TRUST_CONFIGURATION = SSLConfiguration.defaultBehavior();
-
- public static final ElasticSearchConfiguration DEFAULT_CONFIGURATION = builder()
- .addHost(Host.from(LOCALHOST, DEFAULT_PORT))
- .build();
-
- public static ElasticSearchConfiguration fromProperties(Configuration configuration) throws ConfigurationException {
- return builder()
- .addHosts(getHosts(configuration))
- .hostScheme(getHostScheme(configuration))
- .credential(getCredential(configuration))
- .sslTrustConfiguration(sslTrustConfiguration(configuration))
- .nbShards(configuration.getInteger(ELASTICSEARCH_NB_SHARDS, DEFAULT_NB_SHARDS))
- .nbReplica(configuration.getInteger(ELASTICSEARCH_NB_REPLICA, DEFAULT_NB_REPLICA))
- .waitForActiveShards(configuration.getInteger(WAIT_FOR_ACTIVE_SHARDS, DEFAULT_WAIT_FOR_ACTIVE_SHARDS))
- .minDelay(Optional.ofNullable(configuration.getInteger(ELASTICSEARCH_RETRY_CONNECTION_MIN_DELAY, null)))
- .maxRetries(Optional.ofNullable(configuration.getInteger(ELASTICSEARCH_RETRY_CONNECTION_MAX_RETRIES, null)))
- .build();
- }
-
- private static SSLConfiguration sslTrustConfiguration(Configuration configuration) {
- SSLValidationStrategy sslStrategy = Optional
- .ofNullable(configuration.getString(ELASTICSEARCH_HTTPS_SSL_VALIDATION_STRATEGY))
- .map(SSLValidationStrategy::from)
- .orElse(SSLValidationStrategy.DEFAULT);
-
- HostNameVerifier hostNameVerifier = Optional
- .ofNullable(configuration.getString(ELASTICSEARCH_HTTPS_HOSTNAME_VERIFIER))
- .map(HostNameVerifier::from)
- .orElse(HostNameVerifier.DEFAULT);
-
- return SSLConfiguration.builder()
- .sslStrategy(sslStrategy, getSSLTrustStore(configuration))
- .hostNameVerifier(hostNameVerifier)
- .build();
- }
-
- private static Optional<SSLTrustStore> getSSLTrustStore(Configuration configuration) {
- String trustStorePath = configuration.getString(ELASTICSEARCH_HTTPS_TRUST_STORE_PATH);
- String trustStorePassword = configuration.getString(ELASTICSEARCH_HTTPS_TRUST_STORE_PASSWORD);
-
- if (trustStorePath == null && trustStorePassword == null) {
- return Optional.empty();
- }
-
- return Optional.of(SSLTrustStore.of(trustStorePath, trustStorePassword));
- }
-
- private static Optional<HostScheme> getHostScheme(Configuration configuration) {
- return Optional.ofNullable(configuration.getString(ELASTICSEARCH_HOST_SCHEME))
- .map(HostScheme::of);
- }
-
- private static Optional<Credential> getCredential(Configuration configuration) {
- String username = configuration.getString(ELASTICSEARCH_USER);
- String password = configuration.getString(ELASTICSEARCH_PASSWORD);
-
- if (username == null && password == null) {
- return Optional.empty();
- }
-
- return Optional.of(Credential.of(username, password));
- }
-
- private static ImmutableList<Host> getHosts(Configuration propertiesReader) throws ConfigurationException {
- Optional<String> masterHost = Optional.ofNullable(
- propertiesReader.getString(ELASTICSEARCH_MASTER_HOST, null));
- Optional<Integer> masterPort = Optional.ofNullable(
- propertiesReader.getInteger(ELASTICSEARCH_PORT, null));
- List<String> multiHosts = Arrays.asList(propertiesReader.getStringArray(ELASTICSEARCH_HOSTS));
-
- validateHostsConfigurationOptions(masterHost, masterPort, multiHosts);
-
- if (masterHost.isPresent()) {
- return ImmutableList.of(
- Host.from(masterHost.get(),
- masterPort.get()));
- } else {
- return multiHosts.stream()
- .map(ipAndPort -> Host.parse(ipAndPort, DEFAULT_PORT_AS_OPTIONAL))
- .collect(Guavate.toImmutableList());
- }
- }
-
- @VisibleForTesting
- static void validateHostsConfigurationOptions(Optional<String> masterHost,
- Optional<Integer> masterPort,
- List<String> multiHosts) throws ConfigurationException {
- if (masterHost.isPresent() != masterPort.isPresent()) {
- throw new ConfigurationException(ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + " should be specified together");
- }
- if (!multiHosts.isEmpty() && masterHost.isPresent()) {
- throw new ConfigurationException("You should choose between mono host set up and " + ELASTICSEARCH_HOSTS);
- }
- if (multiHosts.isEmpty() && !masterHost.isPresent()) {
- throw new ConfigurationException("You should specify either (" + ELASTICSEARCH_MASTER_HOST + " and " + ELASTICSEARCH_PORT + ") or " + ELASTICSEARCH_HOSTS);
- }
- }
-
- private final ImmutableList<Host> hosts;
- private final int nbShards;
- private final int nbReplica;
- private final int waitForActiveShards;
- private final int minDelay;
- private final int maxRetries;
- private final Duration requestTimeout;
- private final HostScheme hostScheme;
- private final Optional<Credential> credential;
- private final SSLConfiguration sslConfiguration;
-
- private ElasticSearchConfiguration(ImmutableList<Host> hosts, int nbShards, int nbReplica, int waitForActiveShards, int minDelay, int maxRetries, Duration requestTimeout,
- HostScheme hostScheme, Optional<Credential> credential, SSLConfiguration sslConfiguration) {
- this.hosts = hosts;
- this.nbShards = nbShards;
- this.nbReplica = nbReplica;
- this.waitForActiveShards = waitForActiveShards;
- this.minDelay = minDelay;
- this.maxRetries = maxRetries;
- this.requestTimeout = requestTimeout;
- this.hostScheme = hostScheme;
- this.credential = credential;
- this.sslConfiguration = sslConfiguration;
- }
-
- public ImmutableList<Host> getHosts() {
- return hosts;
- }
-
- public int getNbShards() {
- return nbShards;
- }
-
- public int getNbReplica() {
- return nbReplica;
- }
-
- public int getWaitForActiveShards() {
- return waitForActiveShards;
- }
-
- public int getMinDelay() {
- return minDelay;
- }
-
- public int getMaxRetries() {
- return maxRetries;
- }
-
- public Duration getRequestTimeout() {
- return requestTimeout;
- }
-
- public HostScheme getHostScheme() {
- return hostScheme;
- }
-
- public Optional<Credential> getCredential() {
- return credential;
- }
-
- public SSLConfiguration getSslConfiguration() {
- return sslConfiguration;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof ElasticSearchConfiguration) {
- ElasticSearchConfiguration that = (ElasticSearchConfiguration) o;
-
- return Objects.equals(this.nbShards, that.nbShards)
- && Objects.equals(this.nbReplica, that.nbReplica)
- && Objects.equals(this.waitForActiveShards, that.waitForActiveShards)
- && Objects.equals(this.minDelay, that.minDelay)
- && Objects.equals(this.maxRetries, that.maxRetries)
- && Objects.equals(this.hosts, that.hosts)
- && Objects.equals(this.requestTimeout, that.requestTimeout)
- && Objects.equals(this.hostScheme, that.hostScheme)
- && Objects.equals(this.credential, that.credential)
- && Objects.equals(this.sslConfiguration, that.sslConfiguration);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(hosts, nbShards, nbReplica, waitForActiveShards, minDelay, maxRetries, requestTimeout,
- hostScheme, credential, sslConfiguration);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchHealthCheck.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchHealthCheck.java
deleted file mode 100644
index fc23ef5..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchHealthCheck.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.io.IOException;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.commons.lang3.NotImplementedException;
-import org.apache.james.core.healthcheck.ComponentName;
-import org.apache.james.core.healthcheck.HealthCheck;
-import org.apache.james.core.healthcheck.Result;
-import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
-import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
-import org.elasticsearch.client.Requests;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import reactor.core.publisher.Mono;
-
-public class ElasticSearchHealthCheck implements HealthCheck {
- private static final ComponentName COMPONENT_NAME = new ComponentName("ElasticSearch Backend");
-
- private final Set<IndexName> indexNames;
- private final ReactorElasticSearchClient client;
-
- @Inject
- ElasticSearchHealthCheck(ReactorElasticSearchClient client, Set<IndexName> indexNames) {
- this.client = client;
- this.indexNames = indexNames;
- }
-
- @Override
- public ComponentName componentName() {
- return COMPONENT_NAME;
- }
-
- @Override
- public Mono<Result> check() {
- String[] indices = indexNames.stream()
- .map(IndexName::getValue)
- .toArray(String[]::new);
- ClusterHealthRequest request = Requests.clusterHealthRequest(indices);
-
- return client.health(request)
- .map(this::toHealthCheckResult)
- .onErrorResume(IOException.class, e -> Mono.just(
- Result.unhealthy(COMPONENT_NAME, "Error while contacting cluster", e)));
- }
-
- @VisibleForTesting
- Result toHealthCheckResult(ClusterHealthResponse response) {
- switch (response.getStatus()) {
- case GREEN:
- case YELLOW:
- return Result.healthy(COMPONENT_NAME);
- case RED:
- return Result.unhealthy(COMPONENT_NAME, response.getClusterName() + " status is RED");
- default:
- throw new NotImplementedException("Un-handled ElasticSearch cluster status");
- }
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java
deleted file mode 100644
index 049dcd5..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ElasticSearchIndexer.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.backends.es;
-
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-import org.elasticsearch.action.bulk.BulkRequest;
-import org.elasticsearch.action.bulk.BulkResponse;
-import org.elasticsearch.action.delete.DeleteRequest;
-import org.elasticsearch.action.get.GetRequest;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.action.index.IndexRequest;
-import org.elasticsearch.action.index.IndexResponse;
-import org.elasticsearch.action.update.UpdateRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.common.ValidationException;
-import org.elasticsearch.common.xcontent.XContentType;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-
-import reactor.core.publisher.Mono;
-
-public class ElasticSearchIndexer {
- private static final int DEBUG_MAX_LENGTH_CONTENT = 1000;
- private static final int DEFAULT_BATCH_SIZE = 100;
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchIndexer.class);
-
- private final ReactorElasticSearchClient client;
- private final AliasName aliasName;
- private final DeleteByQueryPerformer deleteByQueryPerformer;
-
- public ElasticSearchIndexer(ReactorElasticSearchClient client,
- WriteAliasName aliasName) {
- this(client, aliasName, DEFAULT_BATCH_SIZE);
- }
-
- @VisibleForTesting
- public ElasticSearchIndexer(ReactorElasticSearchClient client,
- WriteAliasName aliasName,
- int batchSize) {
- this.client = client;
- this.deleteByQueryPerformer = new DeleteByQueryPerformer(client, batchSize, aliasName);
- this.aliasName = aliasName;
- }
-
- public Mono<IndexResponse> index(DocumentId id, String content, RoutingKey routingKey) {
- checkArgument(content);
- logContent(id, content);
- return client.index(new IndexRequest(aliasName.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id.asString())
- .source(content, XContentType.JSON)
- .routing(routingKey.asString()),
- RequestOptions.DEFAULT);
- }
-
- private void logContent(DocumentId id, String content) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Indexing {}: {}", id.asString(), StringUtils.left(content, DEBUG_MAX_LENGTH_CONTENT));
- }
- }
-
- public Mono<BulkResponse> update(List<UpdatedRepresentation> updatedDocumentParts, RoutingKey routingKey) {
- Preconditions.checkNotNull(updatedDocumentParts);
- Preconditions.checkNotNull(routingKey);
- BulkRequest request = new BulkRequest();
- updatedDocumentParts.forEach(updatedDocumentPart -> request.add(
- new UpdateRequest(aliasName.getValue(),
- NodeMappingFactory.DEFAULT_MAPPING_NAME,
- updatedDocumentPart.getId().asString())
- .doc(updatedDocumentPart.getUpdatedDocumentPart(), XContentType.JSON)
- .routing(routingKey.asString())));
-
- return client.bulk(request, RequestOptions.DEFAULT)
- .onErrorResume(ValidationException.class, exception -> {
- LOGGER.warn("Error while updating index", exception);
- return Mono.empty();
- });
- }
-
- public Mono<BulkResponse> delete(List<DocumentId> ids, RoutingKey routingKey) {
- BulkRequest request = new BulkRequest();
- ids.forEach(id -> request.add(
- new DeleteRequest(aliasName.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id.asString())
- .routing(routingKey.asString())));
-
- return client.bulk(request, RequestOptions.DEFAULT)
- .onErrorResume(ValidationException.class, exception -> {
- LOGGER.warn("Error while deleting index", exception);
- return Mono.empty();
- });
- }
-
- public Mono<Void> deleteAllMatchingQuery(QueryBuilder queryBuilder, RoutingKey routingKey) {
- return deleteByQueryPerformer.perform(queryBuilder, routingKey);
- }
-
- private void checkArgument(String content) {
- Preconditions.checkArgument(content != null, "content should be provided");
- }
-
- public Mono<GetResponse> get(DocumentId id, RoutingKey routingKey) {
- return Mono.fromRunnable(() -> {
- Preconditions.checkNotNull(id);
- Preconditions.checkNotNull(routingKey);
- })
- .then(client.get(new GetRequest(aliasName.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id.asString())
- .routing(routingKey.asString()),
- RequestOptions.DEFAULT));
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
deleted file mode 100644
index 07e41e8..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-import java.io.IOException;
-
-import javax.inject.Inject;
-
-import org.elasticsearch.ElasticsearchStatusException;
-import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
-import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
-import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.github.fge.lambdas.Throwing;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-public class IndexCreationFactory {
-
- public static class AliasSpecificationStep {
- private final int nbShards;
- private final int nbReplica;
- private final int waitForActiveShards;
- private final IndexName indexName;
- private final ImmutableList.Builder<AliasName> aliases;
-
- AliasSpecificationStep(int nbShards, int nbReplica, int waitForActiveShards, IndexName indexName) {
- this.nbShards = nbShards;
- this.nbReplica = nbReplica;
- this.waitForActiveShards = waitForActiveShards;
- this.indexName = indexName;
- this.aliases = ImmutableList.builder();
- }
-
- public AliasSpecificationStep addAlias(AliasName aliasName) {
- Preconditions.checkNotNull(aliasName);
- this.aliases.add(aliasName);
- return this;
- }
-
- public ReactorElasticSearchClient createIndexAndAliases(ReactorElasticSearchClient client) {
- return new IndexCreationPerformer(nbShards, nbReplica, waitForActiveShards, indexName, aliases.build()).createIndexAndAliases(client);
- }
- }
-
- static class IndexCreationPerformer {
- private final int nbShards;
- private final int nbReplica;
- private final int waitForActiveShards;
- private final IndexName indexName;
- private final ImmutableList<AliasName> aliases;
-
- public IndexCreationPerformer(int nbShards, int nbReplica, int waitForActiveShards, IndexName indexName, ImmutableList<AliasName> aliases) {
- this.nbShards = nbShards;
- this.nbReplica = nbReplica;
- this.waitForActiveShards = waitForActiveShards;
- this.indexName = indexName;
- this.aliases = aliases;
- }
-
- public ReactorElasticSearchClient createIndexAndAliases(ReactorElasticSearchClient client) {
- Preconditions.checkNotNull(indexName);
- try {
- createIndexIfNeeded(client, indexName, generateSetting(nbShards, nbReplica, waitForActiveShards));
- aliases.forEach(Throwing.<AliasName>consumer(alias -> createAliasIfNeeded(client, indexName, alias))
- .sneakyThrow());
- } catch (IOException e) {
- LOGGER.error("Error while creating index : ", e);
- }
- return client;
- }
-
- private void createAliasIfNeeded(ReactorElasticSearchClient client, IndexName indexName, AliasName aliasName) throws IOException {
- if (!aliasExist(client, aliasName)) {
- client.indices()
- .updateAliases(
- new IndicesAliasesRequest().addAliasAction(
- new AliasActions(AliasActions.Type.ADD)
- .index(indexName.getValue())
- .alias(aliasName.getValue())),
- RequestOptions.DEFAULT);
- }
- }
-
- private boolean aliasExist(ReactorElasticSearchClient client, AliasName aliasName) throws IOException {
- return client.indices()
- .existsAlias(new GetAliasesRequest().aliases(aliasName.getValue()), RequestOptions.DEFAULT);
- }
-
- private void createIndexIfNeeded(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder settings) throws IOException {
- try {
- client.indices()
- .create(
- new CreateIndexRequest(indexName.getValue())
- .source(settings), RequestOptions.DEFAULT);
- } catch (ElasticsearchStatusException exception) {
- if (exception.getMessage().contains(INDEX_ALREADY_EXISTS_EXCEPTION_MESSAGE)) {
- LOGGER.info("Index [{}] already exists", indexName.getValue());
- } else {
- throw exception;
- }
- }
- }
-
- private XContentBuilder generateSetting(int nbShards, int nbReplica, int waitForActiveShards) throws IOException {
- return jsonBuilder()
- .startObject()
- .startObject("settings")
- .field("number_of_shards", nbShards)
- .field("number_of_replicas", nbReplica)
- .field("index.write.wait_for_active_shards", waitForActiveShards)
- .startObject("analysis")
- .startObject("normalizer")
- .startObject(CASE_INSENSITIVE)
- .field("type", "custom")
- .startArray("char_filter")
- .endArray()
- .startArray("filter")
- .value("lowercase")
- .value("asciifolding")
- .endArray()
- .endObject()
- .endObject()
- .startObject("analyzer")
- .startObject(KEEP_MAIL_AND_URL)
- .field("tokenizer", "uax_url_email")
- .startArray("filter")
- .value("lowercase")
- .value("stop")
- .endArray()
- .endObject()
- .startObject(SNOWBALL_KEEP_MAIL_AND_URL)
- .field("tokenizer", "uax_url_email")
- .startArray("filter")
- .value("lowercase")
- .value("stop")
- .value(ENGLISH_SNOWBALL)
- .endArray()
- .endObject()
- .endObject()
- .startObject("filter")
- .startObject(ENGLISH_SNOWBALL)
- .field("type", "snowball")
- .field("language", "English")
- .endObject()
- .endObject()
- .endObject()
- .endObject()
- .endObject();
- }
- }
-
- private static final Logger LOGGER = LoggerFactory.getLogger(IndexCreationFactory.class);
- private static final String INDEX_ALREADY_EXISTS_EXCEPTION_MESSAGE = "type=resource_already_exists_exception";
-
- private final int nbShards;
- private final int nbReplica;
- private final int waitForActiveShards;
-
- public static final String CASE_INSENSITIVE = "case_insensitive";
- public static final String KEEP_MAIL_AND_URL = "keep_mail_and_url";
- public static final String SNOWBALL_KEEP_MAIL_AND_URL = "snowball_keep_mail_and_token";
- public static final String ENGLISH_SNOWBALL = "english_snowball";
-
- @Inject
- public IndexCreationFactory(ElasticSearchConfiguration configuration) {
- this.nbShards = configuration.getNbShards();
- this.nbReplica = configuration.getNbReplica();
- this.waitForActiveShards = configuration.getWaitForActiveShards();
- }
-
- public AliasSpecificationStep useIndex(IndexName indexName) {
- Preconditions.checkNotNull(indexName);
- return new AliasSpecificationStep(nbShards, nbReplica, waitForActiveShards, indexName);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexName.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexName.java
deleted file mode 100644
index bfdddba..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexName.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.util.Objects;
-
-import com.google.common.base.MoreObjects;
-
-public class IndexName {
- private final String value;
-
- public IndexName(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof IndexName) {
- IndexName indexName = (IndexName) o;
-
- return Objects.equals(this.value, indexName.value);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(value);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("value", value)
- .toString();
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
deleted file mode 100644
index e7408e9..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.io.IOException;
-
-import org.apache.http.HttpStatus;
-import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.ResponseException;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-
-public class NodeMappingFactory {
-
- public static final String DEFAULT_MAPPING_NAME = "_doc";
- public static final String BOOLEAN = "boolean";
- public static final String TYPE = "type";
- public static final String LONG = "long";
- public static final String DOUBLE = "double";
- public static final String INDEX = "index";
- public static final String NOT_ANALYZED = "not_analyzed";
- public static final String STRING = "string";
- public static final String TEXT = "text";
- public static final String KEYWORD = "keyword";
- public static final String PROPERTIES = "properties";
- public static final String ROUTING = "_routing";
- public static final String REQUIRED = "required";
- public static final String DATE = "date";
- public static final String FORMAT = "format";
- public static final String NESTED = "nested";
- public static final String FIELDS = "fields";
- public static final String RAW = "raw";
- public static final String ANALYZER = "analyzer";
- public static final String NORMALIZER = "normalizer";
- public static final String SEARCH_ANALYZER = "search_analyzer";
- public static final String SNOWBALL = "snowball";
- public static final String IGNORE_ABOVE = "ignore_above";
-
- public static ReactorElasticSearchClient applyMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
- if (!mappingAlreadyExist(client, indexName)) {
- createMapping(client, indexName, mappingsSources);
- }
- return client;
- }
-
- // ElasticSearch 6.3.2 does not support field master_timeout that is set up by 6.4.3 REST client when relying on getMapping
- @SuppressWarnings("deprecation")
- public static boolean mappingAlreadyExist(ReactorElasticSearchClient client, IndexName indexName) throws IOException {
- try {
- client.getLowLevelClient().performRequest("GET", "/" + indexName.getValue() + "/_mapping/" + NodeMappingFactory.DEFAULT_MAPPING_NAME);
- return true;
- } catch (ResponseException e) {
- if (e.getResponse().getStatusLine().getStatusCode() != HttpStatus.SC_NOT_FOUND) {
- throw e;
- }
- }
- return false;
- }
-
- public static void createMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
- client.indices().putMapping(
- new PutMappingRequest(indexName.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .source(mappingsSources),
- RequestOptions.DEFAULT);
- }
-
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReactorElasticSearchClient.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReactorElasticSearchClient.java
deleted file mode 100644
index fc6d26e..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReactorElasticSearchClient.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.io.IOException;
-import java.util.function.Consumer;
-
-import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
-import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
-import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
-import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptResponse;
-import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
-import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse;
-import org.elasticsearch.action.bulk.BulkRequest;
-import org.elasticsearch.action.bulk.BulkResponse;
-import org.elasticsearch.action.delete.DeleteRequest;
-import org.elasticsearch.action.delete.DeleteResponse;
-import org.elasticsearch.action.explain.ExplainRequest;
-import org.elasticsearch.action.explain.ExplainResponse;
-import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
-import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
-import org.elasticsearch.action.get.GetRequest;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.action.index.IndexRequest;
-import org.elasticsearch.action.index.IndexResponse;
-import org.elasticsearch.action.main.MainResponse;
-import org.elasticsearch.action.search.ClearScrollRequest;
-import org.elasticsearch.action.search.ClearScrollResponse;
-import org.elasticsearch.action.search.MultiSearchRequest;
-import org.elasticsearch.action.search.MultiSearchResponse;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.action.search.SearchScrollRequest;
-import org.elasticsearch.client.IndicesClient;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.RestClient;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.index.rankeval.RankEvalRequest;
-import org.elasticsearch.index.rankeval.RankEvalResponse;
-import org.elasticsearch.script.mustache.MultiSearchTemplateRequest;
-import org.elasticsearch.script.mustache.MultiSearchTemplateResponse;
-import org.elasticsearch.script.mustache.SearchTemplateRequest;
-import org.elasticsearch.script.mustache.SearchTemplateResponse;
-
-import reactor.core.publisher.Mono;
-import reactor.core.publisher.MonoSink;
-import reactor.core.scheduler.Schedulers;
-
-public class ReactorElasticSearchClient implements AutoCloseable {
- private final RestHighLevelClient client;
-
- public ReactorElasticSearchClient(RestHighLevelClient client) {
- this.client = client;
- }
-
- public Mono<BulkResponse> bulk(BulkRequest bulkRequest, RequestOptions options) {
- return toReactor(listener -> client.bulkAsync(bulkRequest, options, listener));
- }
-
- public Mono<ClearScrollResponse> clearScroll(ClearScrollRequest clearScrollRequest, RequestOptions options) {
- return toReactor(listener -> client.clearScrollAsync(clearScrollRequest, options, listener));
- }
-
- public DeleteResponse delete(DeleteRequest deleteRequest, RequestOptions options) throws IOException {
- return client.delete(deleteRequest, options);
- }
-
- public Mono<DeleteStoredScriptResponse> deleteScript(DeleteStoredScriptRequest request, RequestOptions options) {
- return toReactor(listener -> client.deleteScriptAsync(request, options, listener));
- }
-
- public Mono<ExplainResponse> explain(ExplainRequest explainRequest, RequestOptions options) {
- return toReactor(listener -> client.explainAsync(explainRequest, options, listener));
- }
-
- public Mono<FieldCapabilitiesResponse> fieldCaps(FieldCapabilitiesRequest fieldCapabilitiesRequest, RequestOptions options) {
- return toReactor(listener -> client.fieldCapsAsync(fieldCapabilitiesRequest, options, listener));
- }
-
- public RestClient getLowLevelClient() {
- return client.getLowLevelClient();
- }
-
- public Mono<GetStoredScriptResponse> getScript(GetStoredScriptRequest request, RequestOptions options) {
- return toReactor(listener -> client.getScriptAsync(request, options, listener));
- }
-
- public Mono<IndexResponse> index(IndexRequest indexRequest, RequestOptions options) {
- return toReactor(listener -> client.indexAsync(indexRequest, options, listener));
- }
-
- public IndicesClient indices() {
- return client.indices();
- }
-
- public MainResponse info(RequestOptions options) throws IOException {
- return client.info(options);
- }
-
- public Mono<MultiSearchResponse> msearch(MultiSearchRequest multiSearchRequest, RequestOptions options) {
- return toReactor(listener -> client.msearchAsync(multiSearchRequest, options, listener));
- }
-
- public Mono<MultiSearchTemplateResponse> msearchTemplate(MultiSearchTemplateRequest multiSearchTemplateRequest, RequestOptions options) {
- return toReactor(listener -> client.msearchTemplateAsync(multiSearchTemplateRequest, options, listener));
- }
-
- public Mono<RankEvalResponse> rankEval(RankEvalRequest rankEvalRequest, RequestOptions options) {
- return toReactor(listener -> client.rankEvalAsync(rankEvalRequest, options, listener));
- }
-
- public Mono<SearchResponse> scroll(SearchScrollRequest searchScrollRequest, RequestOptions options) {
- return toReactor(listener -> client.scrollAsync(searchScrollRequest, options, listener));
- }
-
- @Deprecated
- public Mono<SearchResponse> search(SearchRequest searchRequest) {
- return toReactor(listener -> client.searchAsync(searchRequest, listener));
- }
-
- public Mono<SearchResponse> search(SearchRequest searchRequest, RequestOptions options) {
- return toReactor(listener -> client.searchAsync(searchRequest, options, listener));
- }
-
- public Mono<ClusterHealthResponse> health(ClusterHealthRequest request) {
- return toReactor(listener -> client.cluster()
- .healthAsync(request, RequestOptions.DEFAULT, listener));
- }
-
- public Mono<SearchTemplateResponse> searchTemplate(SearchTemplateRequest searchTemplateRequest, RequestOptions options) {
- return toReactor(listener -> client.searchTemplateAsync(searchTemplateRequest, options, listener));
- }
-
- public Mono<GetResponse> get(GetRequest getRequest, RequestOptions options) {
- return toReactor(listener -> client.getAsync(getRequest, options, listener));
- }
-
- @Override
- public void close() throws IOException {
- client.close();
- }
-
- private static <T> Mono<T> toReactor(Consumer<ActionListener<T>> async) {
- return Mono.<T>create(sink -> async.accept(getListener(sink)))
- .publishOn(Schedulers.elastic());
- }
-
- private static <T> ActionListener<T> getListener(MonoSink<T> sink) {
- return new ActionListener<T>() {
- @Override
- public void onResponse(T t) {
- sink.success(t);
- }
-
- @Override
- public void onFailure(Exception e) {
- sink.error(e);
- }
- };
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReadAliasName.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReadAliasName.java
deleted file mode 100644
index 22c47d6..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ReadAliasName.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-public class ReadAliasName extends AliasName {
- public ReadAliasName(String value) {
- super(value);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/RoutingKey.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/RoutingKey.java
deleted file mode 100644
index 6ce3598..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/RoutingKey.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.util.Objects;
-
-import org.elasticsearch.common.Strings;
-
-import com.google.common.base.Preconditions;
-
-public class RoutingKey {
- public interface Factory<T> {
- RoutingKey from(T t);
- }
-
- public static RoutingKey fromString(String value) {
- return new RoutingKey(value);
- }
-
-
- private final String value;
-
- private RoutingKey(String value) {
- Preconditions.checkArgument(!Strings.isNullOrEmpty(value), "RoutingKey must be specified");
- this.value = value;
- }
-
- public String asString() {
- return value;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof RoutingKey) {
- RoutingKey that = (RoutingKey) o;
-
- return Objects.equals(this.value, that.value);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(value);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/UpdatedRepresentation.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/UpdatedRepresentation.java
deleted file mode 100644
index a14605c..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/UpdatedRepresentation.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.backends.es;
-
-import java.util.Objects;
-
-import org.elasticsearch.common.Strings;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-
-public class UpdatedRepresentation {
- private final DocumentId id;
- private final String updatedDocumentPart;
-
- public UpdatedRepresentation(DocumentId id, String updatedDocumentPart) {
- Preconditions.checkNotNull(id);
- Preconditions.checkArgument(!Strings.isNullOrEmpty(updatedDocumentPart), "Updated document must be specified");
- this.id = id;
- this.updatedDocumentPart = updatedDocumentPart;
- }
-
- public DocumentId getId() {
- return id;
- }
-
- public String getUpdatedDocumentPart() {
- return updatedDocumentPart;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof UpdatedRepresentation) {
- UpdatedRepresentation other = (UpdatedRepresentation) o;
- return Objects.equals(id, other.id)
- && Objects.equals(updatedDocumentPart, other.updatedDocumentPart);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(id, updatedDocumentPart);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("id", id)
- .add("updatedDocumentPart", updatedDocumentPart)
- .toString();
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/WriteAliasName.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/WriteAliasName.java
deleted file mode 100644
index 4c829c9..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/WriteAliasName.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-public class WriteAliasName extends AliasName {
- public WriteAliasName(String value) {
- super(value);
- }
-}
diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/search/ScrolledSearch.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/search/ScrolledSearch.java
deleted file mode 100644
index cf8a83b..0000000
--- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/search/ScrolledSearch.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es.search;
-
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
-
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.elasticsearch.action.search.ClearScrollRequest;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.action.search.SearchScrollRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.search.SearchHit;
-
-import com.github.fge.lambdas.Throwing;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.FluxSink;
-import reactor.core.publisher.Mono;
-
-public class ScrolledSearch {
-
- private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
-
- private final ReactorElasticSearchClient client;
- private final SearchRequest searchRequest;
-
- public ScrolledSearch(ReactorElasticSearchClient client, SearchRequest searchRequest) {
- this.client = client;
- this.searchRequest = searchRequest;
- }
-
- public Flux<SearchHit> searchHits() {
- return searchResponses()
- .concatMap(searchResponse -> Flux.just(searchResponse.getHits().getHits()));
- }
-
- public Flux<SearchResponse> searchResponses() {
- return Flux.push(sink -> {
- AtomicReference<Optional<String>> scrollId = new AtomicReference<>(Optional.empty());
- sink.onRequest(numberOfRequestedElements -> next(sink, scrollId, numberOfRequestedElements));
-
- sink.onDispose(() -> close(scrollId));
- });
- }
-
- private void next(FluxSink<SearchResponse> sink, AtomicReference<Optional<String>> scrollId, long numberOfRequestedElements) {
- if (numberOfRequestedElements <= 0) {
- return;
- }
-
- Consumer<SearchResponse> onResponse = searchResponse -> {
- scrollId.set(Optional.of(searchResponse.getScrollId()));
- sink.next(searchResponse);
-
- boolean noHitsLeft = searchResponse.getHits().getHits().length == 0;
- if (noHitsLeft) {
- sink.complete();
- } else {
- next(sink, scrollId, numberOfRequestedElements - 1);
- }
- };
-
- Consumer<Throwable> onFailure = sink::error;
-
- buildRequest(scrollId.get())
- .subscribe(onResponse, onFailure);
- }
-
- private Mono<SearchResponse> buildRequest(Optional<String> scrollId) {
- return scrollId.map(id ->
- client.scroll(
- new SearchScrollRequest()
- .scrollId(scrollId.get())
- .scroll(TIMEOUT),
- RequestOptions.DEFAULT))
- .orElseGet(() -> client.search(searchRequest, RequestOptions.DEFAULT));
- }
-
- public void close(AtomicReference<Optional<String>> scrollId) {
- scrollId.get().map(id -> {
- ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
- clearScrollRequest.addScrollId(id);
- return clearScrollRequest;
- }).ifPresent(Throwing.<ClearScrollRequest>consumer(clearScrollRequest -> client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT).subscribe()).sneakyThrow());
- }
-
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/AliasNameTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/AliasNameTest.java
deleted file mode 100644
index 9acdd47..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/AliasNameTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class AliasNameTest {
- @Test
- void aliasNameShouldRespectBeanContract() {
- EqualsVerifier.forClass(AliasName.class)
- .verify();
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java
deleted file mode 100644
index a97c6a3..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESIgnoreSSLCheckTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.apache.james.backends.es.ElasticSearchClusterExtension.ElasticSearchCluster;
-
-import java.util.Optional;
-
-import org.apache.james.backends.es.ElasticSearchConfiguration.HostScheme;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class ClientProviderImplConnectionAuthESIgnoreSSLCheckTest implements ClientProviderImplConnectionContract {
-
- @RegisterExtension
- static ElasticSearchClusterExtension extension = new ElasticSearchClusterExtension(new ElasticSearchCluster(
- DockerAuthElasticSearchSingleton.INSTANCE,
- new DockerElasticSearch.WithAuth()));
-
- @Override
- public ElasticSearchConfiguration.Builder configurationBuilder() {
- return ElasticSearchConfiguration.builder()
- .credential(Optional.of(DockerElasticSearch.WithAuth.DEFAULT_CREDENTIAL))
- .hostScheme(Optional.of(HostScheme.HTTPS))
- .sslTrustConfiguration(SSLConfiguration.builder()
- .strategyIgnore()
- .acceptAnyHostNameVerifier()
- .build());
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java
deleted file mode 100644
index 7493681..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionAuthESOverrideTrustStoreTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.util.Optional;
-
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-public class ClientProviderImplConnectionAuthESOverrideTrustStoreTest implements ClientProviderImplConnectionContract {
-
- private static final String TRUST_STORE_PASSWORD = "mypass";
- private static final String TRUST_STORE_FILE_PATH = "src/test/resources/auth-es/server.jks";
-
- @RegisterExtension
- static ElasticSearchClusterExtension extension = new ElasticSearchClusterExtension(new ElasticSearchClusterExtension.ElasticSearchCluster(
- DockerAuthElasticSearchSingleton.INSTANCE,
- new DockerElasticSearch.WithAuth()));
-
- @Override
- public ElasticSearchConfiguration.Builder configurationBuilder() {
- return ElasticSearchConfiguration.builder()
- .credential(Optional.of(DockerElasticSearch.WithAuth.DEFAULT_CREDENTIAL))
- .hostScheme(Optional.of(ElasticSearchConfiguration.HostScheme.HTTPS))
- .sslTrustConfiguration(SSLConfiguration.builder()
- .strategyOverride(SSLTrustStore.of(TRUST_STORE_FILE_PATH, TRUST_STORE_PASSWORD))
- .acceptAnyHostNameVerifier()
- .build());
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionContract.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionContract.java
deleted file mode 100644
index 4a4328c..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionContract.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.james.backends.es.ElasticSearchClusterExtension.ElasticSearchCluster;
-import org.awaitility.Awaitility;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-interface ClientProviderImplConnectionContract {
-
- Logger LOGGER = LoggerFactory.getLogger(ClientProviderImplConnectionContract.class);
-
- @Test
- default void connectingASingleServerShouldWork(ElasticSearchCluster esCluster) {
- ElasticSearchConfiguration configuration = configurationBuilder()
- .addHost(esCluster.es1.getHttpHost())
- .build();
-
- Awaitility.await()
- .atMost(1, TimeUnit.MINUTES)
- .pollInterval(5, TimeUnit.SECONDS)
- .until(() -> isConnected(new ClientProvider(configuration)));
- }
-
- @Test
- default void connectingAClusterShouldWork(ElasticSearchCluster esCluster) {
- ElasticSearchConfiguration configuration = configurationBuilder()
- .addHosts(esCluster.getHosts())
- .build();
-
- Awaitility.await()
- .atMost(1, TimeUnit.MINUTES)
- .pollInterval(5, TimeUnit.SECONDS)
- .until(() -> isConnected(new ClientProvider(configuration)));
- }
-
- @Test
- default void connectingAClusterWithAFailedNodeShouldWork(ElasticSearchCluster esCluster) {
- ElasticSearchConfiguration configuration = configurationBuilder()
- .addHosts(esCluster.getHosts())
- .build();
-
- esCluster.es2.stop();
-
- Awaitility.await()
- .atMost(1, TimeUnit.MINUTES)
- .pollInterval(5, TimeUnit.SECONDS)
- .until(() -> isConnected(new ClientProvider(configuration)));
- }
-
- default boolean isConnected(ClientProvider clientProvider) {
- try (ReactorElasticSearchClient client = clientProvider.get()) {
- client.search(
- new SearchRequest()
- .source(new SearchSourceBuilder().query(QueryBuilders.existsQuery("any"))),
- RequestOptions.DEFAULT).block();
- return true;
- } catch (Exception e) {
- LOGGER.info("Caught exception while trying to connect", e);
- return false;
- }
- }
-
- default ElasticSearchConfiguration.Builder configurationBuilder() {
- return ElasticSearchConfiguration.builder();
- }
-}
-
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionNoAuthESTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionNoAuthESTest.java
deleted file mode 100644
index 6fa92d3..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplConnectionNoAuthESTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import org.apache.james.backends.es.ElasticSearchClusterExtension.ElasticSearchCluster;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class ClientProviderImplConnectionNoAuthESTest implements ClientProviderImplConnectionContract {
-
- @RegisterExtension
- static ElasticSearchClusterExtension extension = new ElasticSearchClusterExtension(new ElasticSearchCluster(
- DockerElasticSearchSingleton.INSTANCE,
- new DockerElasticSearch.NoAuth()));
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderTest.java
deleted file mode 100644
index ca80592..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.junit.jupiter.api.Test;
-
-class ClientProviderTest {
-
- @Test
- void constructorShouldThrowOnNull() {
- assertThatThrownBy(() -> new ClientProvider(null))
- .isInstanceOf(NullPointerException.class);
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerAuthElasticSearchSingleton.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerAuthElasticSearchSingleton.java
deleted file mode 100644
index 5346ef4..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerAuthElasticSearchSingleton.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-public class DockerAuthElasticSearchSingleton {
- public static DockerElasticSearch INSTANCE = new DockerElasticSearch.WithAuth();
-
- static {
- INSTANCE.start();
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java
deleted file mode 100644
index 71e2635..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.apache.james.backends.es.DockerElasticSearch.Fixture.ES_HTTP_PORT;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.cert.X509Certificate;
-import java.time.Duration;
-import java.util.Optional;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.http.HttpStatus;
-import org.apache.james.backends.es.ElasticSearchConfiguration.Credential;
-import org.apache.james.backends.es.ElasticSearchConfiguration.HostScheme;
-import org.apache.james.util.Host;
-import org.apache.james.util.docker.DockerContainer;
-import org.apache.james.util.docker.Images;
-import org.apache.james.util.docker.RateLimiters;
-import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.containers.Network;
-import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy;
-import org.testcontainers.images.builder.ImageFromDockerfile;
-
-import com.google.common.collect.ImmutableMap;
-
-import feign.Client;
-import feign.Feign;
-import feign.Logger;
-import feign.RequestLine;
-import feign.Response;
-import feign.auth.BasicAuthRequestInterceptor;
-import feign.slf4j.Slf4jLogger;
-
-public interface DockerElasticSearch {
-
- interface ElasticSearchAPI {
-
- class Builder {
- private static final HostnameVerifier ACCEPT_ANY_HOST = (hostname, sslSession) -> true;
- private static final TrustManager[] TRUST_ALL = new TrustManager[] {
- new X509TrustManager() {
-
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[0];
- }
-
- public void checkClientTrusted(X509Certificate[] certs, String authType) {
- }
-
- public void checkServerTrusted(X509Certificate[] certs, String authType) {
- }
- }
- };
-
- private final Feign.Builder requestBuilder;
- private final URL esURL;
-
- public Builder(URL esURL) {
- this.esURL = esURL;
- this.requestBuilder = Feign.builder()
- .logger(new Slf4jLogger(ElasticSearchAPI.class))
- .logLevel(Logger.Level.FULL);
- }
-
- public Builder credential(Credential credential) {
- requestBuilder.requestInterceptor(
- new BasicAuthRequestInterceptor(credential.getUsername(), String.valueOf(credential.getPassword())));
- return this;
- }
-
- public Builder disableSSLValidation() throws Exception {
- SSLContext sc = SSLContext.getInstance("SSL");
- sc.init(null, TRUST_ALL, new java.security.SecureRandom());
- SSLSocketFactory factory = sc.getSocketFactory();
- HttpsURLConnection.setDefaultSSLSocketFactory(factory);
- Client ignoredSSLClient = new Client.Default(factory, ACCEPT_ANY_HOST);
-
- requestBuilder.client(ignoredSSLClient);
-
- return this;
- }
-
- public ElasticSearchAPI build() {
- return requestBuilder.target(ElasticSearchAPI.class, esURL.toString());
- }
- }
-
- static Builder builder(URL esURL) {
- return new Builder(esURL);
- }
-
- @RequestLine("DELETE /_all")
- Response deleteAllIndexes();
-
- @RequestLine("POST /_flush?force&wait_if_ongoing=true")
- Response flush();
- }
-
- interface Fixture {
- int ES_HTTP_PORT = 9200;
- }
-
- class NoAuth implements DockerElasticSearch {
-
- static DockerContainer defaultContainer(String imageName) {
- return DockerContainer.fromName(imageName)
- .withTmpFs(ImmutableMap.of("/usr/share/elasticsearch/data", "rw,size=200m"))
- .withExposedPorts(ES_HTTP_PORT)
- .withEnv("discovery.type", "single-node")
- .withAffinityToContainer()
- .waitingFor(new HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND));
- }
-
- private final DockerContainer eSContainer;
-
- public NoAuth() {
- this(Images.ELASTICSEARCH_6);
- }
-
- public NoAuth(String imageName) {
- this.eSContainer = defaultContainer(imageName);
- }
-
- public NoAuth(DockerContainer eSContainer) {
- this.eSContainer = eSContainer;
- }
-
- public void start() {
- if (!isRunning()) {
- eSContainer.start();
- }
- }
-
- public void stop() {
- eSContainer.stop();
- }
-
- public int getHttpPort() {
- return eSContainer.getMappedPort(ES_HTTP_PORT);
- }
-
- public String getIp() {
- return eSContainer.getHostIp();
- }
-
- public Host getHttpHost() {
- return Host.from(getIp(), getHttpPort());
- }
-
- public void pause() {
- eSContainer.pause();
- }
-
- public void unpause() {
- eSContainer.unpause();
- }
-
- @Override
- public boolean isRunning() {
- return eSContainer.isRunning();
- }
- }
-
- class WithAuth implements DockerElasticSearch {
-
- private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WithAuth.class);
-
- private static final String DEFAULT_USERNAME = "elasticsearch";
- private static final String DEFAULT_PASSWORD = "secret";
- public static final Credential DEFAULT_CREDENTIAL =
- Credential.of(DEFAULT_USERNAME, DEFAULT_PASSWORD);
-
- private final DockerElasticSearch.NoAuth elasticSearch;
- private final DockerContainer nginx;
- private final Network network;
-
- public WithAuth() {
- this(Images.ELASTICSEARCH_6);
- }
-
- WithAuth(String imageName) {
- this.network = Network.newNetwork();
- this.elasticSearch = new DockerElasticSearch.NoAuth(
- DockerElasticSearch.NoAuth
- .defaultContainer(imageName)
- .withLogConsumer(frame -> LOGGER.debug("[ElasticSearch] " + frame.getUtf8String()))
- .withNetwork(network)
- .withNetworkAliases("elasticsearch"));
-
- this.nginx = new DockerContainer(
- new GenericContainer<>(
- new ImageFromDockerfile()
- .withFileFromClasspath("conf/nginx-conf/", "auth-es/nginx-conf/")
- .withFileFromClasspath("conf/default.crt", "auth-es/default.crt")
- .withFileFromClasspath("conf/default.key", "auth-es/default.key")
- .withFileFromClasspath("Dockerfile", "auth-es/NginxDockerfile")))
- .withExposedPorts(ES_HTTP_PORT)
- .withLogConsumer(frame -> LOGGER.debug("[NGINX] " + frame.getUtf8String()))
- .withNetwork(network);
- }
-
-
- public void start() {
- elasticSearch.start();
- nginx.start();
- }
-
- public void stop() {
- nginx.stop();
- elasticSearch.stop();
- }
-
- public int getHttpPort() {
- return nginx.getMappedPort(ES_HTTP_PORT);
- }
-
- public String getIp() {
- return nginx.getHostIp();
- }
-
- @Override
- public ElasticSearchAPI esAPI() {
- try {
- return ElasticSearchAPI.builder(getUrl())
- .credential(DEFAULT_CREDENTIAL)
- .disableSSLValidation()
- .build();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public URL getUrl() {
- try {
- return new URL("https://" + getIp() + ":" + getHttpPort());
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public ElasticSearchConfiguration configuration(Optional<Duration> requestTimeout) {
- return configurationBuilder(requestTimeout)
- .hostScheme(Optional.of(HostScheme.HTTPS))
- .build();
- }
-
- public void pause() {
- nginx.pause();
- elasticSearch.pause();
- }
-
- public void unpause() {
- elasticSearch.unpause();
- nginx.unpause();
- }
-
- @Override
- public boolean isRunning() {
- return nginx.isRunning() && elasticSearch.isRunning();
- }
- }
-
- void start();
-
- void stop();
-
- int getHttpPort();
-
- String getIp();
-
- void pause();
-
- void unpause();
-
- boolean isRunning();
-
- default URL getUrl() {
- try {
- return new URL("http://" + getIp() + ":" + getHttpPort());
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
- default Host getHttpHost() {
- return Host.from(getIp(), getHttpPort());
- }
-
- default void cleanUpData() {
- if (esAPI().deleteAllIndexes().status() != HttpStatus.SC_OK) {
- throw new IllegalStateException("Failed to delete all data from ElasticSearch");
- }
- }
-
- default void flushIndices() {
- if (esAPI().flush().status() != HttpStatus.SC_OK) {
- throw new IllegalStateException("Failed to flush ElasticSearch");
- }
- }
-
- default ElasticSearchConfiguration configuration(Optional<Duration> requestTimeout) {
- return configurationBuilder(requestTimeout)
- .build();
- }
-
- default ElasticSearchConfiguration.Builder configurationBuilder(Optional<Duration> requestTimeout) {
- return ElasticSearchConfiguration.builder()
- .addHost(getHttpHost())
- .requestTimeout(requestTimeout);
- }
-
- default ElasticSearchConfiguration configuration() {
- return configuration(Optional.empty());
- }
-
- default ClientProvider clientProvider() {
- return new ClientProvider(configuration(Optional.empty()));
- }
-
- default ClientProvider clientProvider(Duration requestTimeout) {
- return new ClientProvider(configuration(Optional.of(requestTimeout)));
- }
-
- default ElasticSearchAPI esAPI() {
- return ElasticSearchAPI.builder(getUrl())
- .build();
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchExtension.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchExtension.java
deleted file mode 100644
index 438517a..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchExtension.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-
-public class DockerElasticSearchExtension implements AfterEachCallback, BeforeEachCallback, ParameterResolver {
-
- private final DockerElasticSearch elasticSearch = DockerElasticSearchSingleton.INSTANCE;
-
- @Override
- public void afterEach(ExtensionContext context) {
- elasticSearch.cleanUpData();
- }
-
- @Override
- public void beforeEach(ExtensionContext extensionContext) {
- if (!elasticSearch.isRunning()) {
- elasticSearch.unpause();
- }
- awaitForElasticSearch();
- }
-
- @Override
- public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return (parameterContext.getParameter().getType() == DockerElasticSearch.class);
- }
-
- @Override
- public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return elasticSearch;
- }
-
- public void awaitForElasticSearch() {
- elasticSearch.flushIndices();
- }
-
- public DockerElasticSearch getDockerElasticSearch() {
- return elasticSearch;
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchRule.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchRule.java
deleted file mode 100644
index 0f0d3d2..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchRule.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import org.junit.rules.ExternalResource;
-
-public class DockerElasticSearchRule extends ExternalResource {
-
- private final DockerElasticSearch dockerElasticSearch = DockerElasticSearchSingleton.INSTANCE;
-
- @Override
- protected void before() {
- dockerElasticSearch.start();
- }
-
- @Override
- protected void after() {
- dockerElasticSearch.cleanUpData();
- }
-
- public ClientProvider clientProvider() {
- return dockerElasticSearch.clientProvider();
- }
-
- public void awaitForElasticSearch() {
- dockerElasticSearch.flushIndices();
- }
-
- public DockerElasticSearch getDockerElasticSearch() {
- return dockerElasticSearch;
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java
deleted file mode 100644
index 2175b34..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearchSingleton.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-public class DockerElasticSearchSingleton {
- public static DockerElasticSearch INSTANCE = new DockerElasticSearch.NoAuth();
-
- static {
- INSTANCE.start();
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DocumentIdTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DocumentIdTest.java
deleted file mode 100644
index bc9306b..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DocumentIdTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class DocumentIdTest {
- @Test
- void documentIdShouldRespectBeanContract() {
- EqualsVerifier.forClass(DocumentId.class)
- .verify();
- }
-
- @Test
- void fromStringShouldThrowWhenNull() {
- assertThatThrownBy(() -> DocumentId.fromString(null))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void fromStringShouldThrowWhenEmpty() {
- assertThatThrownBy(() -> DocumentId.fromString(""))
- .isInstanceOf(IllegalArgumentException.class);
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java
deleted file mode 100644
index 2a2dde3..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import java.util.List;
-import java.util.function.Function;
-import java.util.stream.Stream;
-
-import org.apache.james.util.Host;
-import org.junit.jupiter.api.extension.AfterAllCallback;
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-
-import com.google.common.collect.ImmutableList;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-
-class ElasticSearchClusterExtension implements AfterAllCallback, BeforeAllCallback, AfterEachCallback, ParameterResolver {
-
- static class ElasticSearchCluster {
- DockerElasticSearch es1;
- DockerElasticSearch es2;
-
- ElasticSearchCluster(DockerElasticSearch es1, DockerElasticSearch es2) {
- this.es1 = es1;
- this.es2 = es2;
- }
-
- void start() {
- doInParallel(es1::start, es2::start);
- }
-
- void cleanUp() {
- doInParallel(() -> {
- if (es1.isRunning()) {
- es1.cleanUpData();
- }
- },
- () -> {
- if (es2.isRunning()) {
- es2.cleanUpData();
- }
- });
- }
-
- void stop() {
- doInParallel(es2::stop);
- }
-
- List<Host> getHosts() {
- return ImmutableList.of(es1.getHttpHost(), es2.getHttpHost());
- }
-
- private void doInParallel(Runnable...runnables) {
- Flux.fromStream(Stream.of(runnables)
- .map(Mono::fromRunnable))
- .parallel(runnables.length)
- .runOn(Schedulers.elastic())
- .flatMap(Function.identity())
- .then()
- .block();
- }
- }
-
- private final ElasticSearchCluster esCluster;
-
- ElasticSearchClusterExtension(ElasticSearchCluster esCluster) {
- this.esCluster = esCluster;
- }
-
- @Override
- public void beforeAll(ExtensionContext extensionContext) throws Exception {
- esCluster.start();
- }
-
- @Override
- public void afterEach(ExtensionContext extensionContext) throws Exception {
- esCluster.cleanUp();
- }
-
- @Override
- public void afterAll(ExtensionContext extensionContext) throws Exception {
- esCluster.stop();
- }
-
- @Override
- public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return parameterContext.getParameter().getType() == ElasticSearchCluster.class;
- }
-
- @Override
- public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return esCluster;
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java
deleted file mode 100644
index 35bf3f4..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchConfigurationTest.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.util.Optional;
-
-import org.apache.commons.configuration2.PropertiesConfiguration;
-import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
-import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.backends.es.ElasticSearchConfiguration.Credential;
-import org.apache.james.backends.es.ElasticSearchConfiguration.HostScheme;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration;
-import org.apache.james.backends.es.ElasticSearchConfiguration.SSLConfiguration.SSLTrustStore;
-import org.apache.james.util.Host;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableList;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class ElasticSearchConfigurationTest {
-
- @Nested
- class HostSchemeTest {
-
- @Test
- void shouldMatchBeanContact() {
- EqualsVerifier.forClass(HostScheme.class)
- .verify();
- }
- }
-
- @Nested
- class CredentialTest {
-
- @Test
- void shouldMatchBeanContact() {
- EqualsVerifier.forClass(Credential.class)
- .verify();
- }
- }
-
- @Nested
- class SSLConfigurationTest {
-
- @Test
- void sslTrustStoreShouldMatchBeanContact() {
- EqualsVerifier.forClass(SSLTrustStore.class)
- .verify();
- }
-
- @Test
- void shouldMatchBeanContact() {
- EqualsVerifier.forClass(SSLConfiguration.class)
- .verify();
- }
-
- @Test
- void getSSLConfigurationShouldReturnDefaultValueWhenEmpty() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.defaultBehavior());
- }
-
- @Test
- void getSSLConfigurationShouldReturnConfiguredValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- String trustStorePath = "src/test/resources/auth-es/server.jks";
- String trustStorePassword = "secret";
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "override");
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePath", trustStorePath);
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePassword", trustStorePassword);
- configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", "default");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.builder()
- .strategyOverride(SSLTrustStore.of(trustStorePath, trustStorePassword))
- .defaultHostNameVerifier()
- .build());
- }
-
- @Nested
- class WithSSLValidationStrategy {
-
- @Test
- void getSSLConfigurationShouldAcceptCaseInsensitiveStrategy() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "DEfault");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.defaultBehavior());
- }
-
- @Test
- void fromPropertiesShouldThrowWhenInvalidStrategy() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "invalid");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("invalid strategy 'invalid'");
- }
- }
-
- @Nested
- class WithHostNameVerifier {
-
- @Test
- void getSSLConfigurationShouldReturnConfiguredValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", "DEFAULT");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.builder()
- .strategyDefault()
- .defaultHostNameVerifier()
- .build());
- }
-
- @Test
- void getSSLConfigurationShouldAcceptCaseInsensitiveVerifier() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", "Accept_Any_Hostname");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.builder()
- .strategyDefault()
- .acceptAnyHostNameVerifier()
- .build());
- }
-
- @Test
- void fromPropertiesShouldThrowWhenInvalidVerifier() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", "invalid");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("invalid HostNameVerifier 'invalid'");
- }
- }
-
- @Nested
- class WhenDefault {
-
- @Test
- void getSSLConfigurationShouldReturnConfiguredValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "default");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.defaultBehavior());
- }
- }
-
- @Nested
- class WhenIgnore {
-
- @Test
- void getSSLConfigurationShouldReturnConfiguredValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "ignore");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.builder()
- .strategyIgnore()
- .defaultHostNameVerifier()
- .build());
- }
- }
-
- @Nested
- class WhenOverride {
-
- @Test
- void fromPropertiesShouldThrowWhenOnlyTrustStorePathProvided() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "override");
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePath", "/home/james/ServerTrustStore.jks");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(NullPointerException.class)
- .hasMessage("elasticsearch.hostScheme.https.trustStorePassword cannot be null when elasticsearch.hostScheme.https.trustStorePath is specified");
- }
-
- @Test
- void fromPropertiesShouldThrowWhenOnlyTrustStorePasswordProvided() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "override");
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePassword", "secret");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(NullPointerException.class)
- .hasMessage("elasticsearch.hostScheme.https.trustStorePath cannot be null when elasticsearch.hostScheme.https.trustStorePassword is specified");
- }
-
- @Test
- void fromPropertiesShouldThrowWhenTrustStoreIsNotProvided() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "override");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("OVERRIDE strategy requires trustStore to be present");
- }
-
- @Test
- void fromPropertiesShouldThrowWhenTrustStorePathDoesntExist() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "override");
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePath", "/home/james/ServerTrustStore.jks");
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePassword", "password");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("the file '/home/james/ServerTrustStore.jks' from property 'elasticsearch.hostScheme.https.trustStorePath' doesn't exist");
- }
-
- @Test
- void getSSLConfigurationShouldReturnConfiguredValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- String trustStorePath = "src/test/resources/auth-es/server.jks";
- String trustStorePassword = "secret";
-
- configuration.addProperty("elasticsearch.hostScheme.https.sslValidationStrategy", "override");
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePath", trustStorePath);
- configuration.addProperty("elasticsearch.hostScheme.https.trustStorePassword", trustStorePassword);
- configuration.addProperty("elasticsearch.hostScheme.https.hostNameVerifier", "default");
-
- assertThat(ElasticSearchConfiguration.fromProperties(configuration)
- .getSslConfiguration())
- .isEqualTo(SSLConfiguration.builder()
- .strategyOverride(SSLTrustStore.of(trustStorePath, trustStorePassword))
- .defaultHostNameVerifier()
- .build());
- }
- }
- }
-
- @Test
- void elasticSearchConfigurationShouldRespectBeanContract() {
- EqualsVerifier.forClass(ElasticSearchConfiguration.class)
- .verify();
- }
-
- @Test
- void getNbReplicaShouldReturnConfiguredValue() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- int value = 36;
- configuration.addProperty("elasticsearch.nb.replica", value);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getNbReplica())
- .isEqualTo(value);
- }
-
- @Test
- void getNbReplicaShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getNbReplica())
- .isEqualTo(ElasticSearchConfiguration.DEFAULT_NB_REPLICA);
- }
-
- @Test
- void getWaitForActiveShardsShouldReturnConfiguredValue() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- int value = 36;
- configuration.addProperty("elasticsearch.index.waitForActiveShards", value);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWaitForActiveShards())
- .isEqualTo(value);
- }
-
- @Test
- void getWaitForActiveShardsShouldReturnConfiguredValueWhenZero() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- int value = 0;
- configuration.addProperty("elasticsearch.index.waitForActiveShards", value);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWaitForActiveShards())
- .isEqualTo(value);
- }
-
- @Test
- void getWaitForActiveShardsShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- int expectedValue = 1;
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWaitForActiveShards())
- .isEqualTo(expectedValue);
- }
-
- @Test
- void getNbShardsShouldReturnConfiguredValue() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- int value = 36;
- configuration.addProperty("elasticsearch.nb.shards", value);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getNbShards())
- .isEqualTo(value);
- }
-
- @Test
- void getNbShardsShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getNbShards())
- .isEqualTo(ElasticSearchConfiguration.DEFAULT_NB_SHARDS);
- }
-
- @Test
- void getMaxRetriesShouldReturnConfiguredValue() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- int value = 36;
- configuration.addProperty("elasticsearch.retryConnection.maxRetries", value);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getMaxRetries())
- .isEqualTo(value);
- }
-
- @Test
- void getMaxRetriesShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getMaxRetries())
- .isEqualTo(ElasticSearchConfiguration.DEFAULT_CONNECTION_MAX_RETRIES);
- }
-
- @Test
- void getMinDelayShouldReturnConfiguredValue() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- int value = 36;
- configuration.addProperty("elasticsearch.retryConnection.minDelay", value);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getMinDelay())
- .isEqualTo(value);
- }
-
- @Test
- void getMinDelayShouldReturnDefaultValueWhenMissing() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getMinDelay())
- .isEqualTo(ElasticSearchConfiguration.DEFAULT_CONNECTION_MIN_DELAY);
- }
-
- @Test
- void getHostsShouldReturnConfiguredHostsWhenNoPort() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String hostname = "myHost";
- configuration.addProperty("elasticsearch.hosts", hostname);
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getHosts())
- .containsOnly(Host.from(hostname, ElasticSearchConfiguration.DEFAULT_PORT));
- }
-
- @Test
- void getHostsShouldReturnConfiguredHostsWhenListIsUsed() throws ConfigurationException {
- String hostname = "myHost";
- String hostname2 = "myOtherHost";
- int port = 2154;
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
- configuration.addProperty("elasticsearch.hosts", hostname + "," + hostname2 + ":" + port);
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getHosts())
- .containsOnly(Host.from(hostname, ElasticSearchConfiguration.DEFAULT_PORT),
- Host.from(hostname2, port));
- }
-
- @Test
- void getHostsShouldReturnConfiguredHosts() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String hostname = "myHost";
- int port = 2154;
- configuration.addProperty("elasticsearch.hosts", hostname + ":" + port);
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getHosts())
- .containsOnly(Host.from(hostname, port));
- }
-
- @Test
- void getHostsShouldReturnConfiguredMasterHost() throws ConfigurationException {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String hostname = "myHost";
- configuration.addProperty("elasticsearch.masterHost", hostname);
- int port = 9200;
- configuration.addProperty("elasticsearch.port", port);
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getHosts())
- .containsOnly(Host.from(hostname, port));
- }
-
- @Test
- void validateHostsConfigurationOptionsShouldThrowWhenNoHostSpecify() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.validateHostsConfigurationOptions(
- Optional.empty(),
- Optional.empty(),
- ImmutableList.of()))
- .isInstanceOf(ConfigurationException.class)
- .hasMessage("You should specify either (" + ElasticSearchConfiguration.ELASTICSEARCH_MASTER_HOST +
- " and " + ElasticSearchConfiguration.ELASTICSEARCH_PORT +
- ") or " + ElasticSearchConfiguration.ELASTICSEARCH_HOSTS);
- }
-
- @Test
- void validateHostsConfigurationOptionsShouldThrowWhenMonoAndMultiHostSpecified() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.validateHostsConfigurationOptions(
- Optional.of("localhost"),
- Optional.of(9200),
- ImmutableList.of("localhost:9200")))
- .isInstanceOf(ConfigurationException.class)
- .hasMessage("You should choose between mono host set up and " + ElasticSearchConfiguration.ELASTICSEARCH_HOSTS);
- }
-
- @Test
- void validateHostsConfigurationOptionsShouldThrowWhenMonoHostWithoutPort() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.validateHostsConfigurationOptions(
- Optional.of("localhost"),
- Optional.empty(),
- ImmutableList.of()))
- .isInstanceOf(ConfigurationException.class)
- .hasMessage(ElasticSearchConfiguration.ELASTICSEARCH_MASTER_HOST +
- " and " + ElasticSearchConfiguration.ELASTICSEARCH_PORT + " should be specified together");
- }
-
- @Test
- void validateHostsConfigurationOptionsShouldThrowWhenMonoHostWithoutAddress() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.validateHostsConfigurationOptions(
- Optional.empty(),
- Optional.of(9200),
- ImmutableList.of()))
- .isInstanceOf(ConfigurationException.class)
- .hasMessage(ElasticSearchConfiguration.ELASTICSEARCH_MASTER_HOST + " and " +
- ElasticSearchConfiguration.ELASTICSEARCH_PORT + " should be specified together");
- }
-
- @Test
- void validateHostsConfigurationOptionsShouldAcceptMonoHostConfiguration() throws Exception {
- ElasticSearchConfiguration.validateHostsConfigurationOptions(
- Optional.of("localhost"),
- Optional.of(9200),
- ImmutableList.of());
- }
-
- @Test
- void validateHostsConfigurationOptionsShouldAcceptMultiHostConfiguration() throws Exception {
- ElasticSearchConfiguration.validateHostsConfigurationOptions(
- Optional.empty(),
- Optional.empty(),
- ImmutableList.of("localhost:9200"));
- }
-
- @Test
- void nbReplicaShouldThrowWhenNegative() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.builder()
- .nbReplica(-1))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void waitForActiveShardsShouldThrowWhenNegative() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.builder()
- .waitForActiveShards(-1))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void nbShardsShouldThrowWhenNegative() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.builder()
- .nbShards(-1))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void nbShardsShouldThrowWhenZero() {
- assertThatThrownBy(() ->
- ElasticSearchConfiguration.builder()
- .nbShards(0))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void getCredentialShouldReturnConfiguredValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- String user = "johndoe";
- String password = "secret";
- configuration.addProperty("elasticsearch.user", user);
- configuration.addProperty("elasticsearch.password", password);
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getCredential())
- .contains(Credential.of(user, password));
- }
-
- @Test
- void getCredentialShouldReturnEmptyWhenNotConfigured() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getCredential())
- .isEmpty();
- }
-
- @Test
- void fromPropertiesShouldThrowWhenOnlyUsername() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.user", "username");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(NullPointerException.class)
- .hasMessage("password cannot be null when username is specified");
- }
-
- @Test
- void fromPropertiesShouldThrowWhenOnlyPassword() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.password", "password");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(NullPointerException.class)
- .hasMessage("username cannot be null when password is specified");
- }
-
- @Test
- void getHostSchemeShouldReturnConfiguredValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme", "https");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getHostScheme())
- .isEqualTo(HostScheme.HTTPS);
- }
-
- @Test
- void getHostSchemeShouldBeCaseInsensitive() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme", "HTTPs");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getHostScheme())
- .isEqualTo(HostScheme.HTTPS);
- }
-
- @Test
- void getHostSchemeShouldReturnHttpWhenNotConfigured() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchConfiguration elasticSearchConfiguration = ElasticSearchConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getHostScheme())
- .isEqualTo(HostScheme.HTTP);
- }
-
- @Test
- void fromPropertiesShouldThrowWhenInvalidValue() throws Exception {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- configuration.addProperty("elasticsearch.hostScheme", "invalid-protocol");
-
- assertThatThrownBy(() -> ElasticSearchConfiguration.fromProperties(configuration))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("Unknown HostScheme 'invalid-protocol'");
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckConnectionTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckConnectionTest.java
deleted file mode 100644
index 70bfa3b..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckConnectionTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.time.Duration;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import com.google.common.collect.ImmutableSet;
-
-class ElasticSearchHealthCheckConnectionTest {
- private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(5);
-
- @RegisterExtension
- public DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
- private ElasticSearchHealthCheck elasticSearchHealthCheck;
-
- @BeforeEach
- void setUp() {
- ReactorElasticSearchClient client = elasticSearch.getDockerElasticSearch().clientProvider(REQUEST_TIMEOUT).get();
-
- elasticSearchHealthCheck = new ElasticSearchHealthCheck(client, ImmutableSet.of());
- }
-
- @Test
- void checkShouldSucceedWhenElasticSearchIsRunning() {
- assertThat(elasticSearchHealthCheck.check().block().isHealthy()).isTrue();
- }
-
- @Test
- void checkShouldFailWhenElasticSearchIsPaused() {
-
- elasticSearch.getDockerElasticSearch().pause();
-
- try {
- assertThat(elasticSearchHealthCheck.check().block().isUnHealthy()).isTrue();
- } finally {
- elasticSearch.getDockerElasticSearch().unpause();
- }
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckTest.java
deleted file mode 100644
index 2c2b786..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchHealthCheckTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
-import org.elasticsearch.cluster.ClusterName;
-import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.block.ClusterBlocks;
-import org.elasticsearch.cluster.health.ClusterHealthStatus;
-import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.RoutingTable;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableSet;
-
-class ElasticSearchHealthCheckTest {
- private ElasticSearchHealthCheck healthCheck;
-
- @BeforeEach
- void setup() {
- healthCheck = new ElasticSearchHealthCheck(null, ImmutableSet.of());
- }
-
- @Test
- void checkShouldReturnHealthyWhenElasticSearchClusterHealthStatusIsGreen() {
- FakeClusterHealthResponse response = new FakeClusterHealthResponse(ClusterHealthStatus.GREEN);
-
- assertThat(healthCheck.toHealthCheckResult(response).isHealthy()).isTrue();
- }
-
- @Test
- void checkShouldReturnUnHealthyWhenElasticSearchClusterHealthStatusIsRed() {
- FakeClusterHealthResponse response = new FakeClusterHealthResponse(ClusterHealthStatus.RED);
-
- assertThat(healthCheck.toHealthCheckResult(response).isUnHealthy()).isTrue();
- }
-
- @Test
- void checkShouldReturnHealthyWhenElasticSearchClusterHealthStatusIsYellow() {
- FakeClusterHealthResponse response = new FakeClusterHealthResponse(ClusterHealthStatus.YELLOW);
-
- assertThat(healthCheck.toHealthCheckResult(response).isHealthy()).isTrue();
- }
-
- private static class FakeClusterHealthResponse extends ClusterHealthResponse {
- private final ClusterHealthStatus status;
-
- private FakeClusterHealthResponse(ClusterHealthStatus clusterHealthStatus) {
- super("fake-cluster", new String[0],
- new ClusterState(new ClusterName("fake-cluster"), 0, null, null, RoutingTable.builder().build(),
- DiscoveryNodes.builder().build(),
- ClusterBlocks.builder().build(), null, false));
- this.status = clusterHealthStatus;
- }
-
- @Override
- public ClusterHealthStatus getStatus() {
- return this.status;
- }
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java
deleted file mode 100644
index 3fa569c..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchIndexerTest.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-
-import java.io.IOException;
-import java.time.Duration;
-
-import org.awaitility.Awaitility;
-import org.awaitility.core.ConditionFactory;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import com.google.common.collect.ImmutableList;
-
-class ElasticSearchIndexerTest {
- public static RoutingKey useDocumentId(DocumentId documentId) {
- return RoutingKey.fromString(documentId.asString());
- }
-
- private static final int MINIMUM_BATCH_SIZE = 1;
- private static final IndexName INDEX_NAME = new IndexName("index_name");
- private static final WriteAliasName ALIAS_NAME = new WriteAliasName("alias_name");
-
- private static final ConditionFactory CALMLY_AWAIT = Awaitility
- .with().pollInterval(Duration.ofMillis(100))
- .and().pollDelay(Duration.ofMillis(100))
- .await();
- private static final RoutingKey ROUTING = RoutingKey.fromString("routing");
- private static final DocumentId DOCUMENT_ID = DocumentId.fromString("1");
-
- @RegisterExtension
- public DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
- private ElasticSearchIndexer testee;
- private ReactorElasticSearchClient client;
-
- @BeforeEach
- void setup() {
- client = elasticSearch.getDockerElasticSearch().clientProvider().get();
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- testee = new ElasticSearchIndexer(client, ALIAS_NAME, MINIMUM_BATCH_SIZE);
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void indexMessageShouldWork() {
- DocumentId documentId = DocumentId.fromString("1");
- String content = "{\"message\": \"trying out Elasticsearch\"}";
-
- testee.index(documentId, content, useDocumentId(documentId)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchResponse searchResponse = client.search(
- new SearchRequest(INDEX_NAME.getValue())
- .source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("message", "trying"))),
- RequestOptions.DEFAULT)
- .block();
- assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
- }
-
- @Test
- void indexMessageShouldThrowWhenJsonIsNull() {
- assertThatThrownBy(() -> testee.index(DOCUMENT_ID, null, ROUTING))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void updateMessages() {
- String content = "{\"message\": \"trying out Elasticsearch\",\"field\":\"Should be unchanged\"}";
-
- testee.index(DOCUMENT_ID, content, useDocumentId(DOCUMENT_ID)).block();
- elasticSearch.awaitForElasticSearch();
-
- testee.update(ImmutableList.of(new UpdatedRepresentation(DOCUMENT_ID, "{\"message\": \"mastering out Elasticsearch\"}")), useDocumentId(DOCUMENT_ID)).block();
- elasticSearch.awaitForElasticSearch();
-
-
- SearchResponse searchResponse = client.search(
- new SearchRequest(INDEX_NAME.getValue())
- .source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("message", "mastering"))),
- RequestOptions.DEFAULT)
- .block();
- assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
-
- SearchResponse searchResponse2 = client.search(
- new SearchRequest(INDEX_NAME.getValue())
- .source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("field", "unchanged"))),
- RequestOptions.DEFAULT)
- .block();
- assertThat(searchResponse2.getHits().getTotalHits()).isEqualTo(1);
- }
-
- @Test
- void updateMessageShouldThrowWhenJsonIsNull() {
- assertThatThrownBy(() -> testee.update(ImmutableList.of(
- new UpdatedRepresentation(DOCUMENT_ID, null)), ROUTING).block())
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void updateMessageShouldThrowWhenIdIsNull() {
- assertThatThrownBy(() -> testee.update(ImmutableList.of(
- new UpdatedRepresentation(null, "{\"message\": \"mastering out Elasticsearch\"}")), ROUTING).block())
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void updateMessageShouldThrowWhenJsonIsEmpty() {
- assertThatThrownBy(() -> testee.update(ImmutableList.of(
- new UpdatedRepresentation(DOCUMENT_ID, "")), ROUTING).block())
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void updateMessageShouldThrowWhenRoutingKeyIsNull() {
- assertThatThrownBy(() -> testee.update(ImmutableList.of(
- new UpdatedRepresentation(DOCUMENT_ID, "{\"message\": \"mastering out Elasticsearch\"}")), null).block())
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void deleteByQueryShouldWorkOnSingleMessage() {
- DocumentId documentId = DocumentId.fromString("1:2");
- String content = "{\"message\": \"trying out Elasticsearch\", \"property\":\"1\"}";
- RoutingKey routingKey = useDocumentId(documentId);
-
- testee.index(documentId, content, routingKey).block();
- elasticSearch.awaitForElasticSearch();
-
- testee.deleteAllMatchingQuery(termQuery("property", "1"), routingKey).block();
- elasticSearch.awaitForElasticSearch();
-
- CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
- .until(() -> client.search(
- new SearchRequest(INDEX_NAME.getValue())
- .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
- RequestOptions.DEFAULT)
- .block()
- .getHits().getTotalHits() == 0);
- }
-
- @Test
- void deleteByQueryShouldWorkWhenMultipleMessages() {
- DocumentId documentId = DocumentId.fromString("1:1");
- String content = "{\"message\": \"trying out Elasticsearch\", \"property\":\"1\"}";
-
- testee.index(documentId, content, ROUTING).block();
-
- DocumentId documentId2 = DocumentId.fromString("1:2");
- String content2 = "{\"message\": \"trying out Elasticsearch 2\", \"property\":\"1\"}";
-
- testee.index(documentId2, content2, ROUTING).block();
-
- DocumentId documentId3 = DocumentId.fromString("2:3");
- String content3 = "{\"message\": \"trying out Elasticsearch 3\", \"property\":\"2\"}";
-
- testee.index(documentId3, content3, ROUTING).block();
- elasticSearch.awaitForElasticSearch();
-
- testee.deleteAllMatchingQuery(termQuery("property", "1"), ROUTING).block();
- elasticSearch.awaitForElasticSearch();
-
- CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
- .until(() -> client.search(
- new SearchRequest(INDEX_NAME.getValue())
- .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
- RequestOptions.DEFAULT)
- .block()
- .getHits().getTotalHits() == 1);
- }
-
- @Test
- void deleteMessage() {
- DocumentId documentId = DocumentId.fromString("1:2");
- String content = "{\"message\": \"trying out Elasticsearch\"}";
-
- testee.index(documentId, content, useDocumentId(documentId)).block();
- elasticSearch.awaitForElasticSearch();
-
- testee.delete(ImmutableList.of(documentId), useDocumentId(documentId)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchResponse searchResponse = client.search(
- new SearchRequest(INDEX_NAME.getValue())
- .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
- RequestOptions.DEFAULT)
- .block();
- assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(0);
- }
-
- @Test
- void deleteShouldWorkWhenMultipleMessages() {
- DocumentId documentId = DocumentId.fromString("1:1");
- String content = "{\"message\": \"trying out Elasticsearch\", \"mailboxId\":\"1\"}";
-
- testee.index(documentId, content, ROUTING).block();
-
- DocumentId documentId2 = DocumentId.fromString("1:2");
- String content2 = "{\"message\": \"trying out Elasticsearch 2\", \"mailboxId\":\"1\"}";
-
- testee.index(documentId2, content2, ROUTING).block();
-
- DocumentId documentId3 = DocumentId.fromString("2:3");
- String content3 = "{\"message\": \"trying out Elasticsearch 3\", \"mailboxId\":\"2\"}";
-
- testee.index(documentId3, content3, ROUTING).block();
- elasticSearch.awaitForElasticSearch();
-
- testee.delete(ImmutableList.of(documentId, documentId3), ROUTING).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchResponse searchResponse = client.search(
- new SearchRequest(INDEX_NAME.getValue())
- .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
- RequestOptions.DEFAULT)
- .block();
- assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
- }
-
- @Test
- void updateMessagesShouldNotThrowWhenEmptyList() {
- assertThatCode(() -> testee.update(ImmutableList.of(), ROUTING).block())
- .doesNotThrowAnyException();
- }
-
- @Test
- void deleteMessagesShouldNotThrowWhenEmptyList() {
- assertThatCode(() -> testee.delete(ImmutableList.of(), ROUTING).block())
- .doesNotThrowAnyException();
- }
-
- @Test
- void getShouldWork() {
- DocumentId documentId = DocumentId.fromString("1");
- String content = "{\"message\":\"trying out Elasticsearch\"}";
-
- testee.index(documentId, content, useDocumentId(documentId)).block();
- elasticSearch.awaitForElasticSearch();
-
- GetResponse getResponse = testee.get(documentId, useDocumentId(documentId)).block();
-
- assertThat(getResponse.getSourceAsString()).isEqualTo(content);
- }
-
- @Test
- void getShouldThrowWhenIdIsNull() {
- assertThatThrownBy(() -> testee.get(null, ROUTING).block())
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void getShouldThrowWhenRoutingKeyIsNull() {
- assertThatThrownBy(() -> testee.get(DOCUMENT_ID, null).block())
- .isInstanceOf(NullPointerException.class);
- }
-}
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java
deleted file mode 100644
index 6ff2f7e..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/IndexCreationFactoryTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.io.IOException;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class IndexCreationFactoryTest {
- private static final IndexName INDEX_NAME = new IndexName("index");
- private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-
- @RegisterExtension
- public DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
- private ReactorElasticSearchClient client;
-
- @BeforeEach
- void setUp() {
- client = elasticSearch.getDockerElasticSearch().clientProvider().get();
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void createIndexAndAliasShouldNotThrowWhenCalledSeveralTime() {
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- }
-
- @Test
- void useIndexShouldThrowWhenNull() {
- assertThatThrownBy(() ->
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(null))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void addAliasShouldThrowWhenNull() {
- assertThatThrownBy(() ->
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(null))
- .isInstanceOf(NullPointerException.class);
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryAuthTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryAuthTest.java
deleted file mode 100644
index 8c29fca..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryAuthTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-import java.io.IOException;
-import java.util.Optional;
-
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class NodeMappingFactoryAuthTest {
- private static final String MESSAGE = "message";
- private static final IndexName INDEX_NAME = new IndexName("index");
- private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-
- @RegisterExtension
- static ElasticSearchClusterExtension extension = new ElasticSearchClusterExtension(new ElasticSearchClusterExtension.ElasticSearchCluster(
- DockerAuthElasticSearchSingleton.INSTANCE,
- new DockerElasticSearch.WithAuth()));
-
- private ReactorElasticSearchClient client;
-
- @BeforeEach
- void setUp(ElasticSearchClusterExtension.ElasticSearchCluster esCluster) throws Exception {
- client = new ClientProvider(ElasticSearchConfiguration.builder()
- .credential(Optional.of(DockerElasticSearch.WithAuth.DEFAULT_CREDENTIAL))
- .hostScheme(Optional.of(ElasticSearchConfiguration.HostScheme.HTTPS))
- .sslTrustConfiguration(ElasticSearchConfiguration.SSLConfiguration.builder()
- .strategyIgnore()
- .acceptAnyHostNameVerifier()
- .build())
- .addHost(esCluster.es1.getHttpHost())
- .build()).get();
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void applyMappingShouldNotThrowWhenCalledSeveralTime() throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
- }
-
- @Test
- void applyMappingShouldNotThrowWhenIncrementalChanges(ElasticSearchClusterExtension.ElasticSearchCluster esCluster) throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
-
- esCluster.es1.flushIndices();
-
- assertThatCode(() -> NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getOtherMappingsSources()))
- .doesNotThrowAnyException();
- }
-
- private XContentBuilder getMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .endObject()
- .endObject()
- .endObject();
- }
-
- private XContentBuilder getOtherMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .field(NodeMappingFactory.INDEX, false)
- .endObject()
- .endObject()
- .endObject();
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java
deleted file mode 100644
index e686473..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/NodeMappingFactoryTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-import java.io.IOException;
-
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class NodeMappingFactoryTest {
- private static final String MESSAGE = "message";
- private static final IndexName INDEX_NAME = new IndexName("index");
- private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-
- @RegisterExtension
- public DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
- private ReactorElasticSearchClient client;
-
- @BeforeEach
- void setUp() throws Exception {
- client = elasticSearch.getDockerElasticSearch().clientProvider().get();
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void applyMappingShouldNotThrowWhenCalledSeveralTime() throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
- }
-
- @Test
- void applyMappingShouldNotThrowWhenIncrementalChanges() throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
-
- elasticSearch.awaitForElasticSearch();
-
- assertThatCode(() -> NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getOtherMappingsSources()))
- .doesNotThrowAnyException();
- }
-
- private XContentBuilder getMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .endObject()
- .endObject()
- .endObject();
- }
-
- private XContentBuilder getOtherMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .field(NodeMappingFactory.INDEX, false)
- .endObject()
- .endObject()
- .endObject();
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/RoutingKeyTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/RoutingKeyTest.java
deleted file mode 100644
index cfa4d4e..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/RoutingKeyTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class RoutingKeyTest {
- @Test
- void routingKeyShouldRespectBeanContract() {
- EqualsVerifier.forClass(RoutingKey.class)
- .verify();
- }
-
- @Test
- void fromStringShouldThrowWhenNull() {
- assertThatThrownBy(() -> RoutingKey.fromString(null))
- .isInstanceOf(IllegalArgumentException.class);
- }
-
- @Test
- void fromStringShouldThrowWhenEmpty() {
- assertThatThrownBy(() -> RoutingKey.fromString(""))
- .isInstanceOf(IllegalArgumentException.class);
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrolledSearchTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrolledSearchTest.java
deleted file mode 100644
index 23c5663..0000000
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/search/ScrolledSearchTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es.search;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-import static org.awaitility.Durations.FIVE_SECONDS;
-
-import java.io.IOException;
-
-import org.apache.james.backends.es.DockerElasticSearchExtension;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.IndexCreationFactory;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.backends.es.ReadAliasName;
-import org.awaitility.core.ConditionFactory;
-import org.elasticsearch.action.index.IndexRequest;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class ScrolledSearchTest {
- private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
- private static final int SIZE = 2;
- private static final String MESSAGE = "message";
- private static final IndexName INDEX_NAME = new IndexName("index");
- private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-
- private static final ConditionFactory WAIT_CONDITION = await().timeout(FIVE_SECONDS);
-
- @RegisterExtension
- public DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
- private ReactorElasticSearchClient client;
-
- @BeforeEach
- void setUp() {
- client = elasticSearch.getDockerElasticSearch().clientProvider().get();
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- elasticSearch.awaitForElasticSearch();
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void scrollIterableShouldWorkWhenEmpty() {
- SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
- .scroll(TIMEOUT)
- .source(new SearchSourceBuilder()
- .query(QueryBuilders.matchAllQuery())
- .size(SIZE));
-
- assertThat(new ScrolledSearch(client, searchRequest).searchHits().collectList().block())
- .isEmpty();
- }
-
- @Test
- void scrollIterableShouldWorkWhenOneElement() throws Exception {
- String id = "1";
- client.index(new IndexRequest(INDEX_NAME.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id)
- .source(MESSAGE, "Sample message"),
- RequestOptions.DEFAULT)
- .block();
-
- elasticSearch.awaitForElasticSearch();
- WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id));
-
- SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
- .scroll(TIMEOUT)
- .source(new SearchSourceBuilder()
- .query(QueryBuilders.matchAllQuery())
- .size(SIZE));
-
- assertThat(new ScrolledSearch(client, searchRequest).searchHits().collectList().block())
- .extracting(SearchHit::getId)
- .containsOnly(id);
- }
-
- @Test
- void scrollIterableShouldWorkWhenSizeElement() {
- String id1 = "1";
- client.index(new IndexRequest(INDEX_NAME.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id1)
- .source(MESSAGE, "Sample message"),
- RequestOptions.DEFAULT)
- .block();
-
- String id2 = "2";
- client.index(new IndexRequest(INDEX_NAME.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id2)
- .source(MESSAGE, "Sample message"),
- RequestOptions.DEFAULT)
- .block();
-
- elasticSearch.awaitForElasticSearch();
- WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id1, id2));
-
- SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
- .scroll(TIMEOUT)
- .source(new SearchSourceBuilder()
- .query(QueryBuilders.matchAllQuery())
- .size(SIZE));
-
- assertThat(new ScrolledSearch(client, searchRequest).searchHits().collectList().block())
- .extracting(SearchHit::getId)
- .containsOnly(id1, id2);
- }
-
- @Test
- void scrollIterableShouldWorkWhenMoreThanSizeElement() {
- String id1 = "1";
- client.index(new IndexRequest(INDEX_NAME.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id1)
- .source(MESSAGE, "Sample message"),
- RequestOptions.DEFAULT)
- .block();
-
- String id2 = "2";
- client.index(new IndexRequest(INDEX_NAME.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id2)
- .source(MESSAGE, "Sample message"),
- RequestOptions.DEFAULT)
- .block();
-
- String id3 = "3";
- client.index(new IndexRequest(INDEX_NAME.getValue())
- .type(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .id(id3)
- .source(MESSAGE, "Sample message"),
- RequestOptions.DEFAULT)
- .block();
-
- elasticSearch.awaitForElasticSearch();
- WAIT_CONDITION.untilAsserted(() -> hasIdsInIndex(client, id1, id2, id3));
-
- SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
- .scroll(TIMEOUT)
- .source(new SearchSourceBuilder()
- .query(QueryBuilders.matchAllQuery())
- .size(SIZE));
-
- assertThat(new ScrolledSearch(client, searchRequest).searchHits().collectList().block())
- .extracting(SearchHit::getId)
- .containsOnly(id1, id2, id3);
- }
-
- private void hasIdsInIndex(ReactorElasticSearchClient client, String... ids) {
- SearchRequest searchRequest = new SearchRequest(INDEX_NAME.getValue())
- .scroll(TIMEOUT)
- .source(new SearchSourceBuilder()
- .query(QueryBuilders.matchAllQuery()));
-
- SearchHit[] hits = client.search(searchRequest, RequestOptions.DEFAULT)
- .block()
- .getHits()
- .getHits();
-
- assertThat(hits)
- .extracting(SearchHit::getId)
- .contains(ids);
- }
-}
diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/NginxDockerfile b/backends-common/elasticsearch/src/test/resources/auth-es/NginxDockerfile
deleted file mode 100644
index 5a0f976..0000000
--- a/backends-common/elasticsearch/src/test/resources/auth-es/NginxDockerfile
+++ /dev/null
@@ -1,5 +0,0 @@
-FROM nginx:1.15.1
-
-COPY conf/nginx-conf/ /etc/nginx/conf.d/
-COPY conf/default.crt /etc/ssl/certs/default.crt
-COPY conf/default.key /etc/ssl/private/default.key
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/README.md b/backends-common/elasticsearch/src/test/resources/auth-es/README.md
deleted file mode 100644
index 5dd42de..0000000
--- a/backends-common/elasticsearch/src/test/resources/auth-es/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-## Resources explanation
-
-### nginx-conf
-
-Contains nginx configuration files:
- - reverse_elasticsearch.conf: allow nginx to be the proxy connecting to ElasticSearch
- - passwd: Nginx credentials file store, each record follows the format: `username:encrypted-password`
-
-### default.crt & default.key
-
-public (.crt) and private (.key) of the self signed SSL certification. It will be loaded by nginx
-
-### server.jks
-
-Once you use a http client connect to nginx by `https` protocol,
-the default behavior of the client is rejecting the connection because
-self signed SSL certification provided by nginx is not recognized by the
-client. To deal with this problem, there are two ways to configure the client:
-
- - Not recommended in production, ignore SSL Validation
- - Configure the client to use local TrustStore file containing the .crt,
- then it should trust nginx.
-
-The `server.jks` is generated by the command
-```
-keytool -import -v -trustcacerts -file default.crt -keystore server.jks -keypass mypass -storepass mypass
-```
-
-With:
- - password: `mypass`
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/default.crt b/backends-common/elasticsearch/src/test/resources/auth-es/default.crt
deleted file mode 100644
index d9aa6ca..0000000
--- a/backends-common/elasticsearch/src/test/resources/auth-es/default.crt
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDBjCCAe4CCQDbp5K1cKRJgjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
-VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
-cyBQdHkgTHRkMB4XDTE4MDcwMjEyNDkxMloXDTE5MDcwMjEyNDkxMlowRTELMAkG
-A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
-IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AMMgzSF3uTnjSPwX9i1FEhdpKCDWAfWdg/arMWI1wdNjaz5jwA0Y4hPXN14ArIkH
-ZCb9NPJZbUzcryeTvwEbZ8zqQ5+ghiGfGh9PFcz+RArOY2pPnIHOXVZaBIWxkzlF
-atdJodNhbkxt+gmPi5xFlwDqPMijnAOI4gLcxQPG7mWyRpoD8YUzmMNFTJr1xFAV
-XcJU+FJPP9zhOFRkGXnDupp8z9RYew+b39VGga6zHFGIP+iIMVJnEmW2/TQ1KE52
-b5B45bfGxlF7k003kIeaZsHbaIshdNMIz+w4bzywXNXyAfZccRGfraNXuSv0jAPS
-O+nF9yyAocnz3QXOsmSGz28CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAFRDXedF9
-hjuEmLjETBwhh5Zgg102GDJp58ZBkLE1IaT4mrbK90mhpzxsaxbuqOdu3PXJV4tc
-SEocxj5hk5ivVZiWk/j8YJmB8ZOUKdeOxc1tfratlonJ85AY+6m02+FhjUnWobmg
-HVBepFTJt1iaTgOpVf8YpbYW+L6+kWV9C2CtT3WUhxtllKjokbF+YVN7LnDlbynM
-80+aGm+rdg+TUusg+T/2FeVlDyBgbqagBcCQCQacWD2+zzL28XB3PwRE6oU/tKuu
-rbCsGZE0WH8Pc7p6J/alRr+foQiu7KKJKJ8pO1qdy716DlmPIDN23iZROIu1GKKl
-ZIKfyefPUcwHyw==
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/default.key b/backends-common/elasticsearch/src/test/resources/auth-es/default.key
deleted file mode 100644
index ebc29bb..0000000
--- a/backends-common/elasticsearch/src/test/resources/auth-es/default.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAwyDNIXe5OeNI/Bf2LUUSF2koINYB9Z2D9qsxYjXB02NrPmPA
-DRjiE9c3XgCsiQdkJv008lltTNyvJ5O/ARtnzOpDn6CGIZ8aH08VzP5ECs5jak+c
-gc5dVloEhbGTOUVq10mh02FuTG36CY+LnEWXAOo8yKOcA4jiAtzFA8buZbJGmgPx
-hTOYw0VMmvXEUBVdwlT4Uk8/3OE4VGQZecO6mnzP1Fh7D5vf1UaBrrMcUYg/6Igx
-UmcSZbb9NDUoTnZvkHjlt8bGUXuTTTeQh5pmwdtoiyF00wjP7DhvPLBc1fIB9lxx
-EZ+to1e5K/SMA9I76cX3LIChyfPdBc6yZIbPbwIDAQABAoIBAQC+DHmeyjQPDK8u
-UcxE5UwsnxAlgysfZY59Ntn/dKpW0DNI7fDFEOJJPsm/ddqWECvcyavDC5SoUx0J
-6B4V3vJnpBe/JqLdpk/UBLwQD+qHt+MeTXH6/9rq2vwilwT0uAbKrv29mtzJ9ied
-HkF1MFZV3s7bAHdY/f5bmVkOR7g0NQ6QLuXYiLDSHpu/7dMVBNS9qMNL292cZbpi
-KJZUvyrK6jSOh9Dt3fmWVdjRp5nGd/Z0r32A8UdoWiQ3cXe9uwXVxz8+ZGkP4t44
-Ob+YcgHUEz6iI2o7nqWpNtPI+hBWH1YK/Szlay3rTZSKvkNG1Sdwm1UhoJqNFucC
-7ZWkH8GxAoGBAOSpP9lrB0sXCGwhD3xbAYCZsTgomSQ13X6/daKdN9fxpegK7v5r
-baojBoSvIKiKezHzMiL5IiEhESXEvXQigFNORdf9mFs9Z9ec4I/96dQNYM4d1QtM
-nz3dABt62po8ROCA4Y26ar+OmcJ2kv0RPuJCDGkrY1Is7SNTtGi+HW55AoGBANp1
-MJi3VHS9oEF8dslgLkZMZWPgcwJK2Y3wYIkatmxuVkWYdRFPqWWwlXUU17KH7eqm
-iEONLNyI7g/duFFTbz52MkeMpX6xarXddYkS2HMDUqSTgt3T+ULHVhTtlEEBXg6m
-5cx/eg8niJ6VH+vFtRcYrActLg751mjNgz8fmBMnAoGBAMwj4fHsIIXEWWuXlGi0
-IsI59EKr1BTE1isLKS11aN6sSS7BXB7dr/k97drVMrXldBjjArbAbtze1Z0/aNhe
-2OwGrEopiDSkvKl8z+sdh/0duHgroADHdj9Xp3nhE3qxJdi8lyHd9OFxoQpAq/es
-xtRenQ/jgXdizo9EcoM0f7gZAoGARw6ZSQNQyEwpxUM7zBKp2pnc3NjT7+nyy7Vl
-YRM8RRa6nxaQ9ZmIyxfd9WBbLKoEHDAg4IAaGH29mZGP83wFEjcV8anw5r3ErPUk
-1vo3R2nMRtXoWkkpqav29wW0FFTiiDeHRbYtOKKuUI7G/ESpu6J9yjPK6HohYKOA
-Tlbzez8CgYAFhpoeHO2X06pEsFeI6rMtc0rS0EHuVuqfjjyEMOyQZ8BsCWzDZBDW
-N9rxd0yz80H1Q33dwzrkiVu15e+JMNb5I80Ou0t+LQVYpvhtM89yKoLFk2HqL+eH
-wQJ/Fszj8fwdwx+k2DEve8MVHSx/w9CpwM7B2yGxcUFKi/JSM1rQEw==
------END RSA PRIVATE KEY-----
\ No newline at end of file
diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/passwd b/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/passwd
deleted file mode 100644
index c489f73..0000000
--- a/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/passwd
+++ /dev/null
@@ -1,2 +0,0 @@
-# the default credential: elasticsearch:secret
-elasticsearch:$apr1$m5FvKpw7$EZ9UEUCilHyKTIqQ57nWG1
diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/reverse_elasticsearch.conf b/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/reverse_elasticsearch.conf
deleted file mode 100644
index 77573cf..0000000
--- a/backends-common/elasticsearch/src/test/resources/auth-es/nginx-conf/reverse_elasticsearch.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-server {
- listen 9200 ssl;
- ssl_certificate /etc/ssl/certs/default.crt;
- ssl_certificate_key /etc/ssl/private/default.key;
- server_name reverse_elasticsearch;
- auth_basic "Restricted Area";
- auth_basic_user_file /etc/nginx/conf.d/passwd;
-
- location / {
- proxy_pass http://elasticsearch:9200;
- }
-}
diff --git a/backends-common/elasticsearch/src/test/resources/auth-es/server.jks b/backends-common/elasticsearch/src/test/resources/auth-es/server.jks
deleted file mode 100644
index 10ef996..0000000
Binary files a/backends-common/elasticsearch/src/test/resources/auth-es/server.jks and /dev/null differ
diff --git a/backends-common/pom.xml b/backends-common/pom.xml
index 6b829dc..46f9986 100644
--- a/backends-common/pom.xml
+++ b/backends-common/pom.xml
@@ -35,7 +35,6 @@
<modules>
<module>cassandra</module>
- <module>elasticsearch</module>
<module>elasticsearch-v7</module>
<module>jpa</module>
<module>rabbitmq</module>
diff --git a/mailbox/plugin/quota-search-elasticsearch/pom.xml b/mailbox/plugin/quota-search-elasticsearch/pom.xml
deleted file mode 100644
index cfe9651..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/pom.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.james</groupId>
- <artifactId>apache-james-mailbox</artifactId>
- <version>3.6.0-SNAPSHOT</version>
- <relativePath>../../pom.xml</relativePath>
- </parent>
-
- <artifactId>apache-james-mailbox-quota-search-elasticsearch</artifactId>
- <name>Apache James :: Mailbox :: Plugin :: Quota Search :: ElasticSearch</name>
- <description>Apache James Mailbox ElasticSearch implementation for quota search</description>
-
- <dependencies>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-api</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-quota-search</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-quota-search</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>event-bus-api</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-core</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-data-memory</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-testing</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>metrics-tests</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>testing-base</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.datatype</groupId>
- <artifactId>jackson-datatype-jdk8</artifactId>
- </dependency>
- <dependency>
- <groupId>net.javacrumbs.json-unit</groupId>
- <artifactId>json-unit-assertj</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-migrationsupport</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
deleted file mode 100644
index 1c9e371..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfiguration.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.james.quota.search.elasticsearch;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import org.apache.commons.configuration2.Configuration;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
-
-public class ElasticSearchQuotaConfiguration {
-
- public static class Builder {
-
- private Optional<IndexName> indexQuotaRatioName;
- private Optional<ReadAliasName> readAliasQuotaRatioName;
- private Optional<WriteAliasName> writeAliasQuotaRatioName;
-
- public Builder() {
- indexQuotaRatioName = Optional.empty();
- readAliasQuotaRatioName = Optional.empty();
- writeAliasQuotaRatioName = Optional.empty();
- }
-
- public Builder indexQuotaRatioName(IndexName indexQuotaRatioName) {
- return indexQuotaRatioName(Optional.of(indexQuotaRatioName));
- }
-
- public Builder indexQuotaRatioName(Optional<IndexName> indexQuotaRatioName) {
- this.indexQuotaRatioName = indexQuotaRatioName;
- return this;
- }
-
- public Builder readAliasQuotaRatioName(ReadAliasName readAliasQuotaRatioName) {
- return readAliasQuotaRatioName(Optional.of(readAliasQuotaRatioName));
- }
-
- public Builder readAliasQuotaRatioName(Optional<ReadAliasName> readAliasQuotaRatioName) {
- this.readAliasQuotaRatioName = readAliasQuotaRatioName;
- return this;
- }
-
- public Builder writeAliasQuotaRatioName(WriteAliasName writeAliasQuotaRatioName) {
- return writeAliasQuotaRatioName(Optional.of(writeAliasQuotaRatioName));
- }
-
- public Builder writeAliasQuotaRatioName(Optional<WriteAliasName> writeAliasQuotaRatioName) {
- this.writeAliasQuotaRatioName = writeAliasQuotaRatioName;
- return this;
- }
-
-
- public ElasticSearchQuotaConfiguration build() {
- return new ElasticSearchQuotaConfiguration(
- indexQuotaRatioName.orElse(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_INDEX),
- readAliasQuotaRatioName.orElse(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS),
- writeAliasQuotaRatioName.orElse(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS));
- }
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static final String ELASTICSEARCH_INDEX_QUOTA_RATIO_NAME = "elasticsearch.index.quota.ratio.name";
- public static final String ELASTICSEARCH_ALIAS_READ_QUOTA_RATIO_NAME = "elasticsearch.alias.read.quota.ratio.name";
- public static final String ELASTICSEARCH_ALIAS_WRITE_QUOTA_RATIO_NAME = "elasticsearch.alias.write.quota.ratio.name";
-
- public static final ElasticSearchQuotaConfiguration DEFAULT_CONFIGURATION = builder().build();
-
- public static ElasticSearchQuotaConfiguration fromProperties(Configuration configuration) {
- return builder()
- .indexQuotaRatioName(computeQuotaSearchIndexName(configuration))
- .readAliasQuotaRatioName(computeQuotaSearchReadAlias(configuration))
- .writeAliasQuotaRatioName(computeQuotaSearchWriteAlias(configuration))
- .build();
- }
-
- public static Optional<IndexName> computeQuotaSearchIndexName(Configuration configuration) {
- return Optional.ofNullable(configuration.getString(ELASTICSEARCH_INDEX_QUOTA_RATIO_NAME))
- .map(IndexName::new);
- }
-
- public static Optional<WriteAliasName> computeQuotaSearchWriteAlias(Configuration configuration) {
- return Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_WRITE_QUOTA_RATIO_NAME))
- .map(WriteAliasName::new);
- }
-
- public static Optional<ReadAliasName> computeQuotaSearchReadAlias(Configuration configuration) {
- return Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_READ_QUOTA_RATIO_NAME))
- .map(ReadAliasName::new);
- }
-
- private final IndexName indexQuotaRatioName;
- private final ReadAliasName readAliasQuotaRatioName;
- private final WriteAliasName writeAliasQuotaRatioName;
-
- private ElasticSearchQuotaConfiguration(IndexName indexQuotaRatioName, ReadAliasName readAliasQuotaRatioName, WriteAliasName writeAliasQuotaRatioName) {
- this.indexQuotaRatioName = indexQuotaRatioName;
- this.readAliasQuotaRatioName = readAliasQuotaRatioName;
- this.writeAliasQuotaRatioName = writeAliasQuotaRatioName;
- }
-
- public IndexName getIndexQuotaRatioName() {
- return indexQuotaRatioName;
- }
-
- public ReadAliasName getReadAliasQuotaRatioName() {
- return readAliasQuotaRatioName;
- }
-
- public WriteAliasName getWriteAliasQuotaRatioName() {
- return writeAliasQuotaRatioName;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof ElasticSearchQuotaConfiguration) {
- ElasticSearchQuotaConfiguration that = (ElasticSearchQuotaConfiguration) o;
-
- return Objects.equals(this.indexQuotaRatioName, that.indexQuotaRatioName)
- && Objects.equals(this.readAliasQuotaRatioName, that.readAliasQuotaRatioName)
- && Objects.equals(this.writeAliasQuotaRatioName, that.writeAliasQuotaRatioName);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(indexQuotaRatioName, readAliasQuotaRatioName);
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
deleted file mode 100644
index 8765345..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcher.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.USER;
-
-import java.util.List;
-
-import org.apache.james.backends.es.AliasName;
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.search.ScrolledSearch;
-import org.apache.james.core.Username;
-import org.apache.james.quota.search.QuotaQuery;
-import org.apache.james.quota.search.QuotaSearcher;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.elasticsearch.search.sort.SortBuilders;
-import org.elasticsearch.search.sort.SortOrder;
-
-import com.github.steveash.guavate.Guavate;
-
-import reactor.core.publisher.Flux;
-
-public class ElasticSearchQuotaSearcher implements QuotaSearcher {
- private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
-
- private final ReactorElasticSearchClient client;
- private final AliasName readAlias;
- private final QuotaQueryConverter quotaQueryConverter;
-
- public ElasticSearchQuotaSearcher(ReactorElasticSearchClient client, ReadAliasName readAlias) {
- this.client = client;
- this.readAlias = readAlias;
- this.quotaQueryConverter = new QuotaQueryConverter();
- }
-
- @Override
- public List<Username> search(QuotaQuery query) {
- try {
- return searchHits(query)
- .map(SearchHit::getId)
- .map(Username::of)
- .collect(Guavate.toImmutableList())
- .block();
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception while executing " + query, e);
- }
- }
-
- private Flux<SearchHit> searchHits(QuotaQuery query) {
- if (query.getLimit().isLimited()) {
- return executeSingleSearch(query);
- } else {
- return executeScrolledSearch(query);
- }
- }
-
- private Flux<SearchHit> executeSingleSearch(QuotaQuery query) {
- SearchSourceBuilder searchSourceBuilder = searchSourceBuilder(query)
- .from(query.getOffset().getValue());
- query.getLimit().getValue()
- .ifPresent(searchSourceBuilder::size);
-
- SearchRequest searchRequest = new SearchRequest(readAlias.getValue())
- .types(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .source(searchSourceBuilder);
-
- return client.search(searchRequest, RequestOptions.DEFAULT)
- .flatMapMany(searchResponse -> Flux.fromArray(searchResponse.getHits().getHits()));
- }
-
- private Flux<SearchHit> executeScrolledSearch(QuotaQuery query) {
- return new ScrolledSearch(client,
- new SearchRequest(readAlias.getValue())
- .types(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .source(searchSourceBuilder(query))
- .scroll(TIMEOUT))
- .searchHits()
- .skip(query.getOffset().getValue());
- }
-
- private SearchSourceBuilder searchSourceBuilder(QuotaQuery query) {
- return new SearchSourceBuilder()
- .query(quotaQueryConverter.from(query))
- .sort(SortBuilders.fieldSort(USER).order(SortOrder.ASC));
- }
-}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
deleted file mode 100644
index a67d063..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.DOMAIN;
-import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.QUOTA_RATIO;
-import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
-import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import org.apache.james.quota.search.QuotaClause;
-import org.apache.james.quota.search.QuotaClause.And;
-import org.apache.james.quota.search.QuotaClause.HasDomain;
-import org.apache.james.quota.search.QuotaClause.LessThan;
-import org.apache.james.quota.search.QuotaClause.MoreThan;
-import org.apache.james.quota.search.QuotaQuery;
-import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.RangeQueryBuilder;
-import org.elasticsearch.index.query.TermQueryBuilder;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-
-class QuotaQueryConverter {
- private final Map<Class<? extends QuotaClause>, Function<QuotaClause, QueryBuilder>> clauseConverter;
-
- QuotaQueryConverter() {
- Builder<Class<? extends QuotaClause>, Function<QuotaClause, QueryBuilder>> builder = ImmutableMap.builder();
-
- builder.put(HasDomain.class, this::convertHasDomain);
- builder.put(And.class, this::disableNestedAnd);
- builder.put(MoreThan.class, this::convertMoreThan);
- builder.put(LessThan.class, this::convertLessThan);
-
- clauseConverter = builder.build();
- }
-
- QueryBuilder from(QuotaQuery query) {
- List<QuotaClause> clauses = query.getClause().getClauses();
- if (clauses.isEmpty()) {
- return matchAllQuery();
- }
- if (clauses.size() == 1) {
- return singleClauseAsESQuery(clauses.get(0));
- }
-
- return clausesAsAndESQuery(clauses);
- }
-
- private BoolQueryBuilder clausesAsAndESQuery(List<QuotaClause> clauses) {
- BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
- clauses.stream()
- .map(this::singleClauseAsESQuery)
- .forEach(boolQueryBuilder::must);
- return boolQueryBuilder;
- }
-
- private QueryBuilder disableNestedAnd(QuotaClause clause) {
- throw new IllegalArgumentException("Nested \"And\" clauses are not supported");
- }
-
- private TermQueryBuilder convertHasDomain(QuotaClause clause) {
- HasDomain hasDomain = (HasDomain) clause;
- return termQuery(DOMAIN, hasDomain.getDomain().asString());
- }
-
- private RangeQueryBuilder convertMoreThan(QuotaClause clause) {
- MoreThan moreThan = (MoreThan) clause;
- return rangeQuery(QUOTA_RATIO).gte(moreThan.getQuotaBoundary().getRatio());
- }
-
- private RangeQueryBuilder convertLessThan(QuotaClause clause) {
- LessThan lessThan = (LessThan) clause;
- return rangeQuery(QUOTA_RATIO).lte(lessThan.getQuotaBoundary().getRatio());
- }
-
- private QueryBuilder singleClauseAsESQuery(QuotaClause clause) {
- return clauseConverter.get(clause.getClass()).apply(clause);
- }
-
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
deleted file mode 100644
index e8e1904..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioElasticSearchConstants.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.james.quota.search.elasticsearch;
-
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
-
-public interface QuotaRatioElasticSearchConstants {
-
- interface InjectionNames {
- String QUOTA_RATIO = "quotaRatio";
- }
-
- WriteAliasName DEFAULT_QUOTA_RATIO_WRITE_ALIAS = new WriteAliasName("quota_ratio_write_alias");
- ReadAliasName DEFAULT_QUOTA_RATIO_READ_ALIAS = new ReadAliasName("quota_ratio_read_alias");
- IndexName DEFAULT_QUOTA_RATIO_INDEX = new IndexName("quota_ratio_v1");
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
deleted file mode 100644
index fc6ad52..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaRatioMappingFactory.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.apache.james.backends.es.NodeMappingFactory.DOUBLE;
-import static org.apache.james.backends.es.NodeMappingFactory.KEYWORD;
-import static org.apache.james.backends.es.NodeMappingFactory.PROPERTIES;
-import static org.apache.james.backends.es.NodeMappingFactory.REQUIRED;
-import static org.apache.james.backends.es.NodeMappingFactory.ROUTING;
-import static org.apache.james.backends.es.NodeMappingFactory.TYPE;
-import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.DOMAIN;
-import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.QUOTA_RATIO;
-import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.USER;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-import java.io.IOException;
-
-import org.elasticsearch.common.xcontent.XContentBuilder;
-
-class QuotaRatioMappingFactory {
-
- public static XContentBuilder getMappingContent() {
- try {
- return jsonBuilder()
- .startObject()
- .startObject(ROUTING)
- .field(REQUIRED, true)
- .endObject()
-
- .startObject(PROPERTIES)
-
- .startObject(USER)
- .field(TYPE, KEYWORD)
- .endObject()
-
- .startObject(DOMAIN)
- .field(TYPE, KEYWORD)
- .endObject()
-
- .startObject(QUOTA_RATIO)
- .field(TYPE, DOUBLE)
- .endObject()
- .endObject()
- .endObject();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
deleted file mode 100644
index cf1aad6..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/QuotaSearchIndexCreationUtil.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import java.io.IOException;
-
-import org.apache.james.backends.es.AliasName;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.IndexCreationFactory;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-
-public class QuotaSearchIndexCreationUtil {
-
- public static ReactorElasticSearchClient prepareClient(ReactorElasticSearchClient client,
- AliasName readAlias,
- AliasName writeAlias,
- IndexName indexName,
- ElasticSearchConfiguration configuration) throws IOException {
-
- return NodeMappingFactory.applyMapping(
- new IndexCreationFactory(configuration)
- .useIndex(indexName)
- .addAlias(readAlias)
- .addAlias(writeAlias)
- .createIndexAndAliases(client),
- indexName,
- QuotaRatioMappingFactory.getMappingContent());
- }
-
- public static ReactorElasticSearchClient prepareDefaultClient(ReactorElasticSearchClient client, ElasticSearchConfiguration configuration) throws IOException {
- return prepareClient(client,
- QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS,
- QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
- QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_INDEX,
- configuration);
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactory.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactory.java
deleted file mode 100644
index c4ee0ce..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import org.apache.james.backends.es.RoutingKey;
-import org.apache.james.core.Username;
-
-public class UserRoutingKeyFactory implements RoutingKey.Factory<Username> {
- @Override
- public RoutingKey from(Username user) {
- return RoutingKey.fromString(user.asString());
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
deleted file mode 100644
index f12af37..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListener.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.quota.search.elasticsearch.events;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.apache.james.backends.es.DocumentId;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.RoutingKey;
-import org.apache.james.core.Username;
-import org.apache.james.events.Event;
-import org.apache.james.events.EventListener;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
-import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
-import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
-import org.reactivestreams.Publisher;
-
-import reactor.core.publisher.Mono;
-
-public class ElasticSearchQuotaMailboxListener implements EventListener.ReactiveGroupEventListener {
- public static class ElasticSearchQuotaMailboxListenerGroup extends Group {
-
- }
-
- private static final Group GROUP = new ElasticSearchQuotaMailboxListenerGroup();
-
- private final ElasticSearchIndexer indexer;
- private final QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson;
- private final RoutingKey.Factory<Username> routingKeyFactory;
-
- @Inject
- public ElasticSearchQuotaMailboxListener(@Named(QuotaRatioElasticSearchConstants.InjectionNames.QUOTA_RATIO) ElasticSearchIndexer indexer,
- QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson,
- RoutingKey.Factory<Username> routingKeyFactory) {
- this.indexer = indexer;
- this.quotaRatioToElasticSearchJson = quotaRatioToElasticSearchJson;
- this.routingKeyFactory = routingKeyFactory;
- }
-
- @Override
- public Group getDefaultGroup() {
- return GROUP;
- }
-
- @Override
- public boolean isHandling(Event event) {
- return event instanceof QuotaUsageUpdatedEvent;
- }
-
- @Override
- public Publisher<Void> reactiveEvent(Event event) {
- return handleEvent((QuotaUsageUpdatedEvent) event);
- }
-
- private Mono<Void> handleEvent(QuotaUsageUpdatedEvent event) {
- Username user = event.getUsername();
- DocumentId id = toDocumentId(user);
- RoutingKey routingKey = routingKeyFactory.from(user);
-
- return Mono.fromCallable(() -> quotaRatioToElasticSearchJson.convertToJson(event))
- .flatMap(json -> indexer.index(id, json, routingKey))
- .then();
- }
-
- private DocumentId toDocumentId(Username user) {
- return DocumentId.fromString(user.asString());
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java
deleted file mode 100644
index 8f930ff..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/JsonMessageConstants.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch.json;
-
-public interface JsonMessageConstants {
-
- String USER = "user";
- String DOMAIN = "domain";
- String QUOTA_RATIO = "quotaRatio";
-
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java
deleted file mode 100644
index 4084727..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJson.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.quota.search.elasticsearch.json;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import org.apache.james.mailbox.model.QuotaRatio;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-
-public class QuotaRatioAsJson {
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
-
- private String user;
- private Optional<String> domain;
- private QuotaRatio quotaRatio;
-
- private Builder() {
- domain = Optional.empty();
- }
-
- public Builder user(String user) {
- this.user = user;
- return this;
- }
-
- public Builder domain(Optional<String> domain) {
- this.domain = domain;
- return this;
- }
-
- public Builder quotaRatio(QuotaRatio quotaRatio) {
- this.quotaRatio = quotaRatio;
- return this;
- }
-
- public QuotaRatioAsJson build() {
- Preconditions.checkState(!Strings.isNullOrEmpty(user), "'user' is mandatory");
- Preconditions.checkNotNull(quotaRatio, "'quotaRatio' is mandatory");
-
- return new QuotaRatioAsJson(user, domain, quotaRatio);
- }
- }
-
- private final String user;
- private final Optional<String> domain;
- private final QuotaRatio quotaRatio;
-
- private QuotaRatioAsJson(String user, Optional<String> domain, QuotaRatio quotaRatio) {
- this.user = user;
- this.domain = domain;
- this.quotaRatio = quotaRatio;
- }
-
- @JsonProperty(JsonMessageConstants.USER)
- public String getUser() {
- return user;
- }
-
- @JsonProperty(JsonMessageConstants.DOMAIN)
- public Optional<String> getDomain() {
- return domain;
- }
-
- @JsonProperty(JsonMessageConstants.QUOTA_RATIO)
- public double getMaxQuotaRatio() {
- return quotaRatio.max();
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof QuotaRatioAsJson) {
- QuotaRatioAsJson that = (QuotaRatioAsJson) o;
-
- return Objects.equals(this.quotaRatio, that.quotaRatio)
- && Objects.equals(this.user, that.user)
- && Objects.equals(this.domain, that.domain);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(user, domain, quotaRatio);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("quotaRatio", quotaRatio)
- .add("user", user)
- .add("domain", domain)
- .toString();
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java b/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
deleted file mode 100644
index 39b7a0d..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/main/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJson.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch.json;
-
-import javax.inject.Inject;
-
-import org.apache.james.core.Domain;
-import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
-import org.apache.james.mailbox.model.QuotaRatio;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-
-public class QuotaRatioToElasticSearchJson {
-
- private final ObjectMapper mapper;
-
- @Inject
- public QuotaRatioToElasticSearchJson() {
- this.mapper = new ObjectMapper();
- this.mapper.registerModule(new Jdk8Module());
- }
-
- public String convertToJson(QuotaUsageUpdatedEvent event) throws JsonProcessingException {
- return mapper.writeValueAsString(QuotaRatioAsJson.builder()
- .user(event.getUsername().asString())
- .domain(event.getQuotaRoot().getDomain().map(Domain::asString))
- .quotaRatio(QuotaRatio.from(event.getSizeQuota(), event.getCountQuota()))
- .build());
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
deleted file mode 100644
index 67dd309..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaConfigurationTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.commons.configuration2.PropertiesConfiguration;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
-import org.junit.jupiter.api.Test;
-
-class ElasticSearchQuotaConfigurationTest {
-
- @Test
- void getReadAliasQuotaRatioNameShouldReturnConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.read.quota.ratio.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getReadAliasQuotaRatioName())
- .isEqualTo(new ReadAliasName(name));
- }
-
- @Test
- void getReadAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getReadAliasQuotaRatioName())
- .isEqualTo(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS);
- }
-
- @Test
- void getWriteAliasQuotaRatioNameShouldReturnConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.write.quota.ratio.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWriteAliasQuotaRatioName())
- .isEqualTo(new WriteAliasName(name));
- }
-
- @Test
- void getWriteAliasQuotaRatioNameShouldReturnDefaultValueWhenMissing() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWriteAliasQuotaRatioName())
- .isEqualTo(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS);
- }
-
- @Test
- void getIndexQuotaRatioNameShouldReturnConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.index.quota.ratio.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexQuotaRatioName())
- .isEqualTo(new IndexName(name));
- }
-
- @Test
- void getIndexQuotaRatioNameShouldReturnDefaultValueWhenMissing() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchQuotaConfiguration elasticSearchConfiguration = ElasticSearchQuotaConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexQuotaRatioName())
- .isEqualTo(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_INDEX);
- }
-}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
deleted file mode 100644
index 3037ca9..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearchTestSystemExtension.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.mockito.Mockito.mock;
-
-import java.io.IOException;
-
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.backends.es.DockerElasticSearchSingleton;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.dnsservice.api.DNSService;
-import org.apache.james.domainlist.lib.DomainListConfiguration;
-import org.apache.james.domainlist.memory.MemoryDomainList;
-import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
-import org.apache.james.mailbox.store.quota.QuotaComponents;
-import org.apache.james.quota.search.QuotaSearchTestSystem;
-import org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
-import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
-import org.apache.james.user.memory.MemoryUsersRepository;
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-
-public class ElasticSearchQuotaSearchTestSystemExtension implements ParameterResolver, BeforeEachCallback, AfterEachCallback {
-
- private final DockerElasticSearch elasticSearch = DockerElasticSearchSingleton.INSTANCE;
- private ReactorElasticSearchClient client;
-
- @Override
- public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return (parameterContext.getParameter().getType() == QuotaSearchTestSystem.class);
- }
-
- @Override
- public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- try {
- client = QuotaSearchIndexCreationUtil.prepareDefaultClient(
- elasticSearch.clientProvider().get(),
- elasticSearch.configuration());
-
- InMemoryIntegrationResources resources = InMemoryIntegrationResources.defaultResources();
-
- DNSService dnsService = mock(DNSService.class);
- MemoryDomainList domainList = new MemoryDomainList(dnsService);
- domainList.configure(DomainListConfiguration.DEFAULT);
- MemoryUsersRepository usersRepository = MemoryUsersRepository.withVirtualHosting(domainList);
-
- ElasticSearchQuotaMailboxListener listener = new ElasticSearchQuotaMailboxListener(
- new ElasticSearchIndexer(client,
- QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS),
- new QuotaRatioToElasticSearchJson(),
- new UserRoutingKeyFactory());
-
- resources.getMailboxManager().getEventBus().register(listener);
-
- QuotaComponents quotaComponents = resources.getMailboxManager().getQuotaComponents();
-
- return new QuotaSearchTestSystem(
- quotaComponents.getMaxQuotaManager(),
- resources.getMailboxManager(),
- quotaComponents.getQuotaManager(),
- resources.getDefaultUserQuotaRootResolver(),
- new ElasticSearchQuotaSearcher(client,
- QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS),
- usersRepository,
- domainList,
- resources.getCurrentQuotaManager(),
- elasticSearch::flushIndices);
- } catch (Exception e) {
- throw new ParameterResolutionException("Error while resolving parameter", e);
- }
- }
-
- @Override
- public void beforeEach(ExtensionContext context) {
- elasticSearch.start();
- }
-
- @Override
- public void afterEach(ExtensionContext context) throws IOException {
- client.close();
- elasticSearch.cleanUpData();
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
deleted file mode 100644
index 1489e72..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/ElasticSearchQuotaSearcherTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.apache.james.core.CoreFixture.Domains.SIMPSON_COM;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.stream.IntStream;
-
-import org.apache.james.core.Username;
-import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.quota.search.Limit;
-import org.apache.james.quota.search.Offset;
-import org.apache.james.quota.search.QuotaQuery;
-import org.apache.james.quota.search.QuotaSearchTestSystem;
-import org.apache.james.quota.search.QuotaSearcherContract;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-@ExtendWith(ElasticSearchQuotaSearchTestSystemExtension.class)
-class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
- @Test
- void searchShouldNotBeLimitedByElasticSearchDefaultSearchLimit(QuotaSearchTestSystem testSystem) throws Exception {
- int userCount = 11;
- testSystem.getDomainList().addDomain(SIMPSON_COM);
- testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSizeLimit.size(100));
-
- IntStream.range(0, userCount)
- .boxed()
- .map(i -> Username.fromLocalPartWithDomain("user" + i, SIMPSON_COM))
- .forEach(user -> provisionUser(testSystem, user));
- testSystem.await();
-
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withLimit(Limit.unlimited())
- .build()))
- .hasSize(userCount);
- }
-
- @Test
- void searchShouldNotBeLimitedByElasticSearchDefaultSearchLimitWhenUsingOffset(QuotaSearchTestSystem testSystem) throws Exception {
- int userCount = 12;
- testSystem.getDomainList().addDomain(SIMPSON_COM);
- testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSizeLimit.size(100));
-
- IntStream.range(0, userCount)
- .boxed()
- .map(i -> Username.fromLocalPartWithDomain("user" + i, SIMPSON_COM))
- .forEach(user -> provisionUser(testSystem, user));
- testSystem.await();
-
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withLimit(Limit.unlimited())
- .withOffset(Offset.of(1))
- .build()))
- .hasSize(userCount - 1);
- }
-
- private void provisionUser(QuotaSearchTestSystem testSystem, Username username) {
- try {
- testSystem.getUsersRepository().addUser(username, PASSWORD);
- appendMessage(testSystem, username, withSize(49));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java
deleted file mode 100644
index be69dce..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/QuotaQueryConverterTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants.QUOTA_RATIO;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
-import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-
-import org.apache.james.core.Domain;
-import org.apache.james.quota.search.QuotaBoundary;
-import org.apache.james.quota.search.QuotaQuery;
-import org.apache.james.quota.search.elasticsearch.json.JsonMessageConstants;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-class QuotaQueryConverterTest {
- QuotaQueryConverter testee;
-
- @BeforeEach
- void setup() {
- testee = new QuotaQueryConverter();
- }
-
- @Test
- void fromShouldReturnMatchAllWhenEmptyClauses() {
- QuotaQuery query = QuotaQuery.builder().build();
- QueryBuilder expected = matchAllQuery();
-
- QueryBuilder actual = testee.from(query);
-
- assertThat(actual).isEqualToComparingFieldByField(expected);
- }
-
- @Test
- void fromShouldReturnDomainMatchWhenOnlyDomain() {
- QuotaQuery query = QuotaQuery.builder().hasDomain(Domain.of("my.tld")).build();
- QueryBuilder expected = termQuery(JsonMessageConstants.DOMAIN, "my.tld");
-
- QueryBuilder actual = testee.from(query);
-
- assertThat(actual).isEqualToComparingFieldByField(expected);
- }
-
- @Test
- void fromShouldReturnQuotaRatioMatchWhenLessThan() {
- QuotaQuery query = QuotaQuery.builder().lessThan(new QuotaBoundary(0.1)).build();
- QueryBuilder expected = rangeQuery(QUOTA_RATIO).lte(0.1);
-
- QueryBuilder actual = testee.from(query);
-
- assertThat(actual).isEqualToComparingFieldByField(expected);
- }
-
- @Test
- void fromShouldReturnQuotaRatioMatchWhenMoreThan() {
- QuotaQuery query = QuotaQuery.builder().moreThan(new QuotaBoundary(0.1)).build();
- QueryBuilder expected = rangeQuery(QUOTA_RATIO).gte(0.1);
-
- QueryBuilder actual = testee.from(query);
-
- assertThat(actual).isEqualToComparingFieldByField(expected);
- }
-
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactoryTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactoryTest.java
deleted file mode 100644
index eaf26af..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/UserRoutingKeyFactoryTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.james.backends.es.RoutingKey;
-import org.apache.james.core.Username;
-import org.junit.jupiter.api.Test;
-
-class UserRoutingKeyFactoryTest {
- @Test
- void fromShouldRelyOnUsername() {
- assertThat(new UserRoutingKeyFactory().from(Username.of("bob")))
- .isEqualTo(RoutingKey.fromString("bob"));
- }
-}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
deleted file mode 100644
index 1011b07..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/events/ElasticSearchQuotaMailboxListenerTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.quota.search.elasticsearch.events;
-
-import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.BOB_USERNAME;
-import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.NOW;
-import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.QUOTAROOT;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-
-import org.apache.james.backends.es.DockerElasticSearchExtension;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.events.Event;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.quota.QuotaFixture.Counts;
-import org.apache.james.mailbox.quota.QuotaFixture.Sizes;
-import org.apache.james.mailbox.store.event.EventFactory;
-import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
-import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
-import org.apache.james.quota.search.elasticsearch.UserRoutingKeyFactory;
-import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class ElasticSearchQuotaMailboxListenerTest {
- static Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-
- static final int BATCH_SIZE = 1;
-
- @RegisterExtension
- DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
-
- ElasticSearchQuotaMailboxListener quotaMailboxListener;
- ReactorElasticSearchClient client;
-
- @BeforeEach
- void setUp() throws IOException {
- client = elasticSearch.getDockerElasticSearch().clientProvider().get();
-
- QuotaSearchIndexCreationUtil.prepareDefaultClient(client, ElasticSearchConfiguration.builder()
- .addHost(elasticSearch.getDockerElasticSearch().getHttpHost())
- .build());
-
- quotaMailboxListener = new ElasticSearchQuotaMailboxListener(
- new ElasticSearchIndexer(client,
- QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_WRITE_ALIAS,
- BATCH_SIZE),
- new QuotaRatioToElasticSearchJson(),
- new UserRoutingKeyFactory());
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void deserializeElasticSearchQuotaMailboxListenerGroup() throws Exception {
- assertThat(Group.deserialize("org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener$ElasticSearchQuotaMailboxListenerGroup"))
- .isEqualTo(new ElasticSearchQuotaMailboxListener.ElasticSearchQuotaMailboxListenerGroup());
- }
-
- @Test
- void eventShouldIndexEventWhenQuotaEvent() throws Exception {
- quotaMailboxListener.event(EventFactory.quotaUpdated()
- .eventId(EVENT_ID)
- .user(BOB_USERNAME)
- .quotaRoot(QUOTAROOT)
- .quotaCount(Counts._52_PERCENT)
- .quotaSize(Sizes._55_PERCENT)
- .instant(NOW)
- .build());
-
- elasticSearch.awaitForElasticSearch();
-
- SearchRequest searchRequest = new SearchRequest(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS.getValue())
- .types(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .source(new SearchSourceBuilder()
- .query(QueryBuilders.matchAllQuery()));
- SearchResponse searchResponse = client.search(searchRequest).block();
-
- assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
- }
-}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
deleted file mode 100644
index 0cdf749..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioAsJsonTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.quota.search.elasticsearch.json;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.util.Optional;
-
-import org.apache.james.core.quota.QuotaCountLimit;
-import org.apache.james.core.quota.QuotaCountUsage;
-import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.mailbox.model.Quota;
-import org.apache.james.mailbox.model.QuotaRatio;
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class QuotaRatioAsJsonTest {
-
- static final Quota<QuotaSizeLimit, QuotaSizeUsage> QUOTA_SIZE = Quota.<QuotaSizeLimit, QuotaSizeUsage>builder()
- .used(QuotaSizeUsage.size(15))
- .computedLimit(QuotaSizeLimit.size(60))
- .build();
- static final Quota<QuotaCountLimit, QuotaCountUsage> QUOTA_COUNT = Quota.<QuotaCountLimit, QuotaCountUsage>builder()
- .used(QuotaCountUsage.count(1))
- .computedLimit(QuotaCountLimit.count(2))
- .build();
-
- @Test
- void shouldMatchBeanContract() {
- EqualsVerifier.forClass(QuotaRatioAsJson.class)
- .verify();
- }
-
- @Test
- void buildShouldThrownWhenUserIsNull() {
- assertThatThrownBy(() -> QuotaRatioAsJson.builder()
- .build())
- .isInstanceOf(IllegalStateException.class);
- }
-
- @Test
- void buildShouldThrownWhenUserIsEmpty() {
- assertThatThrownBy(() -> QuotaRatioAsJson.builder()
- .user("")
- .build())
- .isInstanceOf(IllegalStateException.class);
- }
-
- @Test
- void buildShouldThrownWhenQuotaRatioIsNull() {
- assertThatThrownBy(() -> QuotaRatioAsJson.builder()
- .user("user")
- .build())
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void getDomainShouldReturnEmptyWhenNone() {
- QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
- .user("user")
- .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT))
- .build();
-
- assertThat(quotaRatioAsJson.getDomain()).isEmpty();
- }
-
- @Test
- void getDomainShouldReturnTheDomainWhenGiven() {
- String domain = "domain";
- QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
- .user("user")
- .domain(Optional.of(domain))
- .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT))
- .build();
-
- assertThat(quotaRatioAsJson.getDomain()).contains(domain);
- }
-
- @Test
- void getMaxQuotaRatioShouldReturnTheMaxQuotaRatio() {
- String domain = "domain";
- QuotaRatioAsJson quotaRatioAsJson = QuotaRatioAsJson.builder()
- .user("user")
- .domain(Optional.of(domain))
- .quotaRatio(QuotaRatio.from(QUOTA_SIZE, QUOTA_COUNT))
- .build();
-
- assertThat(quotaRatioAsJson.getMaxQuotaRatio()).isEqualTo(0.5);
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java b/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
deleted file mode 100644
index 6432375..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/java/org/apache/james/quota/search/elasticsearch/json/QuotaRatioToElasticSearchJsonTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.quota.search.elasticsearch.json;
-
-import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
-import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
-
-import java.io.IOException;
-import java.time.Instant;
-import java.util.Optional;
-
-import org.apache.james.core.Domain;
-import org.apache.james.core.Username;
-import org.apache.james.events.Event;
-import org.apache.james.mailbox.events.MailboxEvents.QuotaUsageUpdatedEvent;
-import org.apache.james.mailbox.model.QuotaRoot;
-import org.apache.james.mailbox.quota.QuotaFixture;
-import org.apache.james.mailbox.store.event.EventFactory;
-import org.apache.james.util.ClassLoaderUtils;
-import org.junit.jupiter.api.Test;
-
-class QuotaRatioToElasticSearchJsonTest {
- static Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
-
- @Test
- void quotaRatioShouldBeWellConvertedToJson() throws IOException {
- String user = "user@domain.org";
- QuotaUsageUpdatedEvent event = EventFactory.quotaUpdated()
- .eventId(EVENT_ID)
- .user(Username.of(user))
- .quotaRoot(QuotaRoot.quotaRoot(user, Optional.of(Domain.of("domain.org"))))
- .quotaCount(QuotaFixture.Counts._52_PERCENT)
- .quotaSize(QuotaFixture.Sizes._55_PERCENT)
- .instant(Instant.now())
- .build();
- QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson = new QuotaRatioToElasticSearchJson();
- String convertToJson = quotaRatioToElasticSearchJson.convertToJson(event);
-
- assertThatJson(convertToJson)
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("quotaRatio.json"));
- }
-
- @Test
- void quotaRatioShouldBeWellConvertedToJsonWhenNoDomain() throws IOException {
- String user = "user";
- QuotaUsageUpdatedEvent event = EventFactory.quotaUpdated()
- .eventId(EVENT_ID)
- .user(Username.of(user))
- .quotaRoot(QuotaRoot.quotaRoot(user, Optional.empty()))
- .quotaCount(QuotaFixture.Counts._52_PERCENT)
- .quotaSize(QuotaFixture.Sizes._55_PERCENT)
- .instant(Instant.now())
- .build();
-
- QuotaRatioToElasticSearchJson quotaRatioToElasticSearchJson = new QuotaRatioToElasticSearchJson();
- String convertToJson = quotaRatioToElasticSearchJson.convertToJson(event);
-
- assertThatJson(convertToJson)
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("quotaRatioNoDomain.json"));
- }
-}
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatio.json b/mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatio.json
deleted file mode 100644
index 8b39489..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatio.json
+++ /dev/null
@@ -1 +0,0 @@
-{"user":"user@domain.org","domain":"domain.org","quotaRatio":0.55}
\ No newline at end of file
diff --git a/mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatioNoDomain.json b/mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatioNoDomain.json
deleted file mode 100644
index b3e2f2e..0000000
--- a/mailbox/plugin/quota-search-elasticsearch/src/test/resources/quotaRatioNoDomain.json
+++ /dev/null
@@ -1 +0,0 @@
-{"user":"user","domain":null,"quotaRatio":0.55}
\ No newline at end of file
diff --git a/mailbox/pom.xml b/mailbox/pom.xml
index 64fad02..5239b8a 100644
--- a/mailbox/pom.xml
+++ b/mailbox/pom.xml
@@ -38,7 +38,6 @@
<module>api</module>
<module>backup</module>
<module>cassandra</module>
- <module>elasticsearch</module>
<module>elasticsearch-v7</module>
<module>event/json</module>
@@ -56,7 +55,6 @@
<module>plugin/quota-mailing-memory</module>
<module>plugin/quota-search</module>
- <module>plugin/quota-search-elasticsearch</module>
<module>plugin/quota-search-elasticsearch-v7</module>
<module>plugin/quota-search-scanning</module>
diff --git a/pom.xml b/pom.xml
index d7b5a91..4e863ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -667,17 +667,6 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
<artifactId>apache-james-backends-es-v7</artifactId>
<version>${project.version}</version>
</dependency>
@@ -760,17 +749,6 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
<artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
<version>${project.version}</version>
</dependency>
@@ -845,12 +823,7 @@
<version>${project.version}</version>
<type>test-jar</type>
</dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-quota-search-elasticsearch</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
+ <dependency>
<groupId>${james.groupId}</groupId>
<artifactId>apache-james-mailbox-quota-search-elasticsearch-v7</artifactId>
<version>${project.version}</version>
diff --git a/server/container/metrics/metrics-es-reporter/pom.xml b/server/container/metrics/metrics-es-reporter/pom.xml
deleted file mode 100644
index 8bcc28b..0000000
--- a/server/container/metrics/metrics-es-reporter/pom.xml
+++ /dev/null
@@ -1,103 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server</artifactId>
- <version>3.6.0-SNAPSHOT</version>
- <relativePath>../../../pom.xml</relativePath>
- </parent>
-
- <artifactId>metrics-es-reporter</artifactId>
- <name>Apache James :: Server :: Metrics ElasticSearch Reporter</name>
-
- <dependencies>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-core</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-lifecycle-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-testing</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>metrics-dropwizard</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>testing-base</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>com.linagora</groupId>
- <artifactId>metrics-elasticsearch-reporter</artifactId>
- </dependency>
- <dependency>
- <groupId>io.dropwizard.metrics</groupId>
- <artifactId>metrics-core</artifactId>
- </dependency>
- <dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>javax.annotation-api</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.testcontainers</groupId>
- <artifactId>testcontainers</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESMetricReporter.java b/server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESMetricReporter.java
deleted file mode 100644
index 8feaf62..0000000
--- a/server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESMetricReporter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.metrics.es;
-
-import java.io.IOException;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-
-import org.apache.james.lifecycle.api.Startable;
-
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.ScheduledReporter;
-import com.linagora.elasticsearch.metrics.ElasticsearchReporter;
-
-public class ESMetricReporter implements Startable {
-
- private final Optional<ElasticsearchReporter> reporter;
- private final ESReporterConfiguration esReporterConfiguration;
-
- @Inject
- public ESMetricReporter(ESReporterConfiguration esReporterConfiguration, MetricRegistry registry) {
- this.reporter = getReporter(esReporterConfiguration, registry);
- this.esReporterConfiguration = esReporterConfiguration;
- }
-
- private Optional<ElasticsearchReporter> getReporter(ESReporterConfiguration esReporterConfiguration, MetricRegistry registry) {
- if (esReporterConfiguration.isEnabled()) {
- try {
- return Optional.of(ElasticsearchReporter.forRegistry(registry)
- .hosts(esReporterConfiguration.getHostWithPort())
- .index(esReporterConfiguration.getIndex())
- .build());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- return Optional.empty();
- }
-
- public void start() {
- reporter.ifPresent(elasticsearchReporter ->
- elasticsearchReporter.start(esReporterConfiguration.getPeriodInSecond(), TimeUnit.SECONDS));
- }
-
- @PreDestroy
- public void stop() {
- reporter.ifPresent(ScheduledReporter::stop);
- }
-}
diff --git a/server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESReporterConfiguration.java b/server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESReporterConfiguration.java
deleted file mode 100644
index 75aa0a7..0000000
--- a/server/container/metrics/metrics-es-reporter/src/main/java/org/apache/james/metrics/es/ESReporterConfiguration.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.metrics.es;
-
-import java.util.Optional;
-
-import org.apache.james.util.Port;
-
-import com.google.common.base.Preconditions;
-
-public class ESReporterConfiguration {
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private Optional<String> host = Optional.empty();
- private Optional<Integer> port = Optional.empty();
- private Optional<Boolean> enabled = Optional.empty();
- private Optional<String> index = Optional.empty();
- private Optional<Long> periodInSecond = Optional.empty();
-
- public Builder enabled() {
- this.enabled = Optional.of(ENABLED);
- return this;
- }
-
- public Builder disabled() {
- this.enabled = Optional.of(DISABLED);
- return this;
- }
-
- public Builder onHost(String host, int port) {
- this.host = Optional.of(host);
- this.port = Optional.of(port);
- return this;
- }
-
- public Builder onIndex(String index) {
- this.index = Optional.ofNullable(index);
- return this;
- }
-
- public Builder periodInSecond(Long periodInSecond) {
- this.periodInSecond = Optional.ofNullable(periodInSecond);
- return this;
- }
-
- public ESReporterConfiguration build() {
- Preconditions.checkState(enabled.isPresent(), "You must specify either enabled or disabled");
- Preconditions.checkState(!enabled.get() || host.isPresent(), "You must specify host when enabled");
- Preconditions.checkState(!enabled.get() || port.isPresent(), "You must specify port when enabled");
- if (enabled.get()) {
- Port.assertValid(port.get());
- }
- return new ESReporterConfiguration(host, port, enabled.get(), index, periodInSecond);
- }
- }
-
- public static final boolean ENABLED = true;
- public static final boolean DISABLED = !ENABLED;
- public static final String DEFAULT_INDEX = "james-metrics";
- public static final long DEFAULT_PERIOD_IN_SECOND = 60L;
-
- private final Optional<String> host;
- private final Optional<Integer> port;
- private final boolean enabled;
- private final Optional<String> index;
- private final Optional<Long> periodInSecond;
-
- public ESReporterConfiguration(Optional<String> host, Optional<Integer> port, boolean enabled, Optional<String> index, Optional<Long> periodInSecond) {
- this.host = host;
- this.port = port;
- this.enabled = enabled;
- this.index = index;
- this.periodInSecond = periodInSecond;
- }
-
- public String getHostWithPort() {
- Preconditions.checkState(host.isPresent());
- Preconditions.checkState(port.isPresent());
- return host.get() + ":" + port.get();
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public String getIndex() {
- return index.orElse(DEFAULT_INDEX);
- }
-
- public long getPeriodInSecond() {
- return periodInSecond.orElse(DEFAULT_PERIOD_IN_SECOND);
- }
-}
diff --git a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/DockerElasticSearchExtension.java b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/DockerElasticSearchExtension.java
deleted file mode 100644
index 459ac2a..0000000
--- a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/DockerElasticSearchExtension.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.metric.es;
-
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.junit.jupiter.api.extension.AfterAllCallback;
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-
-public class DockerElasticSearchExtension implements AfterAllCallback, BeforeAllCallback, BeforeEachCallback, AfterEachCallback,
- ParameterResolver {
-
- private final DockerElasticSearch elasticSearch;
-
- DockerElasticSearchExtension(DockerElasticSearch elasticSearch) {
- this.elasticSearch = elasticSearch;
- }
-
- @Override
- public void beforeAll(ExtensionContext context) throws Exception {
- elasticSearch.start();
- }
-
- @Override
- public void beforeEach(ExtensionContext context) throws Exception {
- if (!elasticSearch.isRunning()) {
- elasticSearch.unpause();
- }
- elasticSearch.flushIndices();
- }
-
- @Override
- public void afterEach(ExtensionContext context) throws Exception {
- elasticSearch.cleanUpData();
- }
-
- @Override
- public void afterAll(ExtensionContext context) throws Exception {
- elasticSearch.stop();
- }
-
- @Override
- public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return (parameterContext.getParameter().getType() == DockerElasticSearch.class);
- }
-
- @Override
- public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
- return elasticSearch;
- }
-}
diff --git a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java
deleted file mode 100644
index 1e09cf5..0000000
--- a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES2ReporterTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.metric.es;
-
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.util.docker.Images;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class ES2ReporterTest extends ESReporterContract {
-
- @RegisterExtension
- static DockerElasticSearchExtension testExtension = new DockerElasticSearchExtension(
- new DockerElasticSearch.NoAuth(Images.ELASTICSEARCH_2));
-}
diff --git a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java
deleted file mode 100644
index ab7a9d4..0000000
--- a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ES6ReporterTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.metric.es;
-
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class ES6ReporterTest extends ESReporterContract {
-
- @RegisterExtension
- static DockerElasticSearchExtension testExtension = new DockerElasticSearchExtension(new DockerElasticSearch.NoAuth());
-}
diff --git a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReportedConfigurationTest.java b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReportedConfigurationTest.java
deleted file mode 100644
index ae25bc9..0000000
--- a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReportedConfigurationTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.metric.es;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.apache.james.metrics.es.ESReporterConfiguration;
-import org.junit.jupiter.api.Test;
-
-class ESReportedConfigurationTest {
-
- @Test
- void builderShouldThrowWhenNotToldIfEnabled() {
- assertThatThrownBy(() -> ESReporterConfiguration.builder().build())
- .isInstanceOf(IllegalStateException.class);
- }
-
- @Test
- void builderShouldThrowIfEnabledWithoutHostAndPort() {
- assertThatThrownBy(() -> ESReporterConfiguration.builder()
- .enabled()
- .build())
- .isInstanceOf(IllegalStateException.class);
- }
-
- @Test
- void builderShouldThrowOnNullHost() {
- assertThatThrownBy(() -> ESReporterConfiguration.builder()
- .onHost(null, 18))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void builderShouldWorkWhenDisabled() {
- ESReporterConfiguration configuration = ESReporterConfiguration.builder()
- .disabled()
- .build();
-
- assertThat(configuration.isEnabled()).isFalse();
- assertThat(configuration.getIndex()).isEqualTo(ESReporterConfiguration.DEFAULT_INDEX);
- assertThat(configuration.getPeriodInSecond()).isEqualTo(ESReporterConfiguration.DEFAULT_PERIOD_IN_SECOND);
- }
-
- @Test
- void getHostWithPortShouldThrowWhenDisabled() {
- ESReporterConfiguration configuration = ESReporterConfiguration.builder()
- .disabled()
- .build();
-
- assertThatThrownBy(() -> configuration.getHostWithPort())
- .isInstanceOf(IllegalStateException.class);
- }
-
- @Test
- void builderShouldWorkWhenEnabled() {
- int port = 14;
- String host = "host";
- ESReporterConfiguration configuration = ESReporterConfiguration.builder()
- .enabled()
- .onHost(host, port)
- .build();
-
- assertThat(configuration.isEnabled()).isTrue();
- assertThat(configuration.getHostWithPort()).isEqualTo(host + ":" + port);
- assertThat(configuration.getIndex()).isEqualTo(ESReporterConfiguration.DEFAULT_INDEX);
- assertThat(configuration.getPeriodInSecond()).isEqualTo(ESReporterConfiguration.DEFAULT_PERIOD_IN_SECOND);
- }
-
-}
diff --git a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReporterContract.java b/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReporterContract.java
deleted file mode 100644
index 6319eec..0000000
--- a/server/container/metrics/metrics-es-reporter/src/test/java/org/apache/james/metric/es/ESReporterContract.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.metric.es;
-
-import static io.restassured.RestAssured.when;
-import static org.awaitility.Awaitility.await;
-import static org.awaitility.Durations.ONE_MINUTE;
-import static org.awaitility.Durations.TEN_MINUTES;
-import static org.hamcrest.Matchers.greaterThan;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.apache.http.HttpStatus;
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.metrics.api.Metric;
-import org.apache.james.metrics.api.TimeMetric;
-import org.apache.james.metrics.dropwizard.DropWizardMetricFactory;
-import org.apache.james.metrics.es.ESMetricReporter;
-import org.apache.james.metrics.es.ESReporterConfiguration;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import com.codahale.metrics.MetricRegistry;
-
-import io.restassured.RestAssured;
-
-abstract class ESReporterContract {
- public static final String INDEX = "index_name";
- public static final long PERIOD_IN_SECOND = 1L;
- public static final int DELAY_IN_MS = 100;
- public static final int PERIOD_IN_MS = 100;
-
- private ESMetricReporter esMetricReporter;
- private MetricRegistry registry;
- private Timer timer;
-
- @BeforeEach
- void setUp(DockerElasticSearch elasticSearch) {
- RestAssured.baseURI = String.format("http://%s:%d",
- elasticSearch.getHttpHost().getHostName(), elasticSearch.getHttpHost().getPort());
- await().atMost(ONE_MINUTE)
- .untilAsserted(this::elasticSearchStarted);
-
- registry = new MetricRegistry();
- timer = new Timer();
- esMetricReporter = new ESMetricReporter(
- ESReporterConfiguration.builder()
- .enabled()
- .onHost(elasticSearch.getHttpHost().getHostName(), elasticSearch.getHttpHost().getPort())
- .onIndex(INDEX)
- .periodInSecond(PERIOD_IN_SECOND)
- .build(),
- registry);
-
- esMetricReporter.start();
- }
-
- @AfterEach
- void tearDown() {
- timer.cancel();
- esMetricReporter.stop();
- }
-
- @Test
- void esMetricReporterShouldProduceDocumentsOnAnElasticsearchContainer() {
- Metric metric = new DropWizardMetricFactory(registry).generate("probe");
- TimerTask timerTask = new TimerTask() {
- @Override
- public void run() {
- metric.increment();
- }
- };
- timer.schedule(timerTask, DELAY_IN_MS, PERIOD_IN_MS);
-
- await().atMost(TEN_MINUTES)
- .untilAsserted(this::done);
- }
-
- @Test
- void esMetricReporterShouldProduceDocumentsOnAnElasticsearchContainerWhenRecordingTimeMetric() {
- TimeMetric metric = new DropWizardMetricFactory(registry).timer("itstime");
- TimerTask timerTask = new TimerTask() {
- @Override
- public void run() {
- metric.stopAndPublish();
- }
- };
- timer.schedule(timerTask, DELAY_IN_MS, PERIOD_IN_MS);
-
- await().atMost(TEN_MINUTES)
- .untilAsserted(this::done);
- }
-
- private void elasticSearchStarted() {
- when()
- .get("/")
- .then()
- .assertThat()
- .statusCode(HttpStatus.SC_OK);
- }
-
- private void done() {
- when()
- .get("/_search")
- .then()
- .assertThat()
- .body("hits.total", greaterThan(0));
- }
-}
diff --git a/server/pom.xml b/server/pom.xml
index 3fefbac..786a868 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -50,7 +50,6 @@
<module>container/lifecycle-api</module>
<module>container/mailbox-adapter</module>
<module>container/mailbox-jmx</module>
- <module>container/metrics/metrics-es-reporter</module>
<module>container/metrics/metrics-es-reporter-v7</module>
<module>container/spring</module>
<module>container/util</module>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 20/32: JAMES-3492,
remove mistakingly added dependency
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit af6706f36ca6a8bf3cd5a734748a482369432c64
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Thu Mar 11 08:52:59 2021 +0200
JAMES-3492, remove mistakingly added dependency
---
mailbox/elasticsearch/pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mailbox/elasticsearch/pom.xml b/mailbox/elasticsearch/pom.xml
index 8602d5c..c52c8bd 100644
--- a/mailbox/elasticsearch/pom.xml
+++ b/mailbox/elasticsearch/pom.xml
@@ -34,11 +34,11 @@
<dependencies>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es-v7</artifactId>
+ <artifactId>apache-james-backends-es</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es-v7</artifactId>
+ <artifactId>apache-james-backends-es</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 30/32: JAMES-3499 Clean dependencies:
webadmin-mailbox
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 5b0cd79d438798227c71168dcafb8467887e7b73
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 12 11:48:51 2021 +0700
JAMES-3499 Clean dependencies: webadmin-mailbox
---
server/protocols/webadmin/webadmin-mailbox/pom.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/server/protocols/webadmin/webadmin-mailbox/pom.xml b/server/protocols/webadmin/webadmin-mailbox/pom.xml
index 19b2d6b..b9038b4 100644
--- a/server/protocols/webadmin/webadmin-mailbox/pom.xml
+++ b/server/protocols/webadmin/webadmin-mailbox/pom.xml
@@ -52,6 +52,7 @@
<dependency>
<groupId>${james.groupId}</groupId>
<artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 02/32: JAMES-3492 Adapt ElasticSearchIntegrationTest
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 49203a01ac60b2f3f67ec6dd4946d61dac73f698
Author: Lan Khuat <kh...@gmail.com>
AuthorDate: Tue Mar 2 16:28:58 2021 +0700
JAMES-3492 Adapt ElasticSearchIntegrationTest
---
.../v7/search/ElasticSearchSearcher.java | 2 +
.../v7/ElasticSearchIntegrationTest.java | 178 +++++----------------
.../ElasticSearchIntegrationTest.java | 2 +-
.../search/AbstractMessageSearchIndexTest.java | 68 ++++----
4 files changed, 79 insertions(+), 171 deletions(-)
diff --git a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java
index 894da37..5522ba6 100644
--- a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java
+++ b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java
@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Optional;
import org.apache.james.backends.es.v7.AliasName;
+import org.apache.james.backends.es.v7.NodeMappingFactory;
import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.backends.es.v7.ReadAliasName;
import org.apache.james.backends.es.v7.RoutingKey;
@@ -80,6 +81,7 @@ public class ElasticSearchSearcher {
public Flux<MessageSearchIndex.SearchResult> search(Collection<MailboxId> mailboxIds, SearchQuery query,
Optional<Integer> limit) {
SearchRequest searchRequest = prepareSearch(mailboxIds, query, limit);
+ System.out.println(searchRequest.toString());
Flux<MessageSearchIndex.SearchResult> pairStream = new ScrolledSearch(client, searchRequest)
.searchHits()
.map(this::extractContentFromHit)
diff --git a/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/ElasticSearchIntegrationTest.java
index 3a3c2a9..a1e60ec 100644
--- a/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/ElasticSearchIntegrationTest.java
+++ b/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/ElasticSearchIntegrationTest.java
@@ -20,10 +20,12 @@
package org.apache.james.mailbox.elasticsearch.v7;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Durations.ONE_HUNDRED_MILLISECONDS;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
+import java.util.List;
import org.apache.james.backends.es.v7.DockerElasticSearchExtension;
import org.apache.james.backends.es.v7.ElasticSearchIndexer;
@@ -36,11 +38,11 @@ import org.apache.james.mailbox.elasticsearch.v7.json.MessageToElasticSearchJson
import org.apache.james.mailbox.elasticsearch.v7.query.CriterionConverter;
import org.apache.james.mailbox.elasticsearch.v7.query.QueryConverter;
import org.apache.james.mailbox.elasticsearch.v7.search.ElasticSearchSearcher;
-import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.inmemory.InMemoryId;
import org.apache.james.mailbox.inmemory.InMemoryMessageId;
import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
import org.apache.james.mailbox.model.ComposedMessageId;
+import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.store.search.AbstractMessageSearchIndexTest;
@@ -52,20 +54,32 @@ import org.apache.james.metrics.tests.RecordingMetricFactory;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.stream.RawField;
import org.apache.james.util.ClassLoaderUtils;
+import org.awaitility.Awaitility;
+import org.awaitility.Durations;
+import org.awaitility.core.ConditionFactory;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import reactor.core.publisher.Flux;
-@Disabled("JAMES-3492, error occurs in setup method")
class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
- static final int BATCH_SIZE = 1;
+ private static final ConditionFactory CALMLY_AWAIT = Awaitility
+ .with().pollInterval(ONE_HUNDRED_MILLISECONDS)
+ .and().pollDelay(ONE_HUNDRED_MILLISECONDS)
+ .await();
static final int SEARCH_SIZE = 1;
+ private final QueryConverter queryConverter = new QueryConverter(new CriterionConverter());
@RegisterExtension
static TikaExtension tika = new TikaExtension();
@@ -81,14 +95,12 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
client.close();
}
- @Disabled("JAMES-3492")
- @Override
- protected void await() {
- elasticSearch.awaitForElasticSearch();
+ @Override
+ protected void awaitMessageCount(List<MailboxId> mailboxIds, SearchQuery query, long messageCount) {
+ awaitForElasticSearch(queryConverter.from(mailboxIds, query), messageCount);
}
- @Disabled("JAMES-3492")
- @Override
+ @Override
protected void initializeMailboxManager() throws Exception {
textExtractor = new TikaTextExtractor(new RecordingMetricFactory(),
new TikaHttpClientImpl(TikaConfiguration.builder()
@@ -129,7 +141,6 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void termsBetweenElasticSearchAndLuceneLimitDueTuNonAsciiCharsShouldBeTruncated() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -142,14 +153,13 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.setBody(Strings.repeat("0à 2345678é", 3200), StandardCharsets.UTF_8)),
session).getId();
- elasticSearch.awaitForElasticSearch();
+ awaitForElasticSearch(QueryBuilders.matchAllQuery(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, recipient)), session)).toStream())
.containsExactly(composedMessageId.getUid());
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void tooLongTermsShouldNotMakeIndexingFail() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -162,14 +172,13 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.setBody(Strings.repeat("0123456789", 3300), StandardCharsets.UTF_8)),
session).getId();
- elasticSearch.awaitForElasticSearch();
+ awaitForElasticSearch(QueryBuilders.matchAllQuery(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, recipient)), session)).toStream())
.containsExactly(composedMessageId.getUid());
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void fieldsExceedingLuceneLimitShouldNotBeIgnored() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -182,14 +191,13 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.setBody(Strings.repeat("0123456789 ", 5000), StandardCharsets.UTF_8)),
session).getId();
- elasticSearch.awaitForElasticSearch();
+ awaitForElasticSearch(QueryBuilders.matchAllQuery(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("0123456789")), session)).toStream())
.containsExactly(composedMessageId.getUid());
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void fieldsWithTooLongTermShouldStillBeIndexed() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -202,14 +210,13 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.setBody(Strings.repeat("0123456789 ", 5000) + " matchMe", StandardCharsets.UTF_8)),
session).getId();
- elasticSearch.awaitForElasticSearch();
+ awaitForElasticSearch(QueryBuilders.matchAllQuery(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("matchMe")), session)).toStream())
.containsExactly(composedMessageId.getUid());
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void reasonableLongTermShouldNotBeIgnored() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -223,14 +230,13 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.setBody(reasonableLongTerm, StandardCharsets.UTF_8)),
session).getId();
- elasticSearch.awaitForElasticSearch();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains(reasonableLongTerm)), session)).toStream())
.containsExactly(composedMessageId.getUid());
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void headerSearchShouldIncludeMessageWhenDifferentTypesOnAnIndexedField() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -246,14 +252,13 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mailCustomStringHeader.eml")),
session).getId();
- elasticSearch.awaitForElasticSearch();
+ awaitForElasticSearch(QueryBuilders.matchAllQuery(), 15);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.headerExists("Custom-header")), session)).toStream())
.containsExactly(customDateHeaderMessageId.getUid(), customStringHeaderMessageId.getUid());
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void messageShouldStillBeIndexedEvenAfterOneFieldFailsIndexation() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -276,7 +281,6 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
}
@Test
- @Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
void addressMatchesShouldBeExact() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
@@ -301,19 +305,19 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.build()),
session).getId();
- elasticSearch.awaitForElasticSearch();
+ awaitForElasticSearch(QueryBuilders.matchAllQuery(), 15);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, "bob@other.tld")), session)).toStream())
.containsOnly(messageId2.getUid());
}
- @Disabled("MAILBOX-403 Relaxed the matching constraints for email addresses in text bodies to reduce ElasticSearch disk space usage, JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
+ @Disabled("MAILBOX-403 Relaxed the matching constraints for email addresses in text bodies to reduce ElasticSearch disk space usage")
@Test
- public void textShouldNotMatchOtherAddressesOfTheSameDomain() throws Exception {
+ public void textShouldNotMatchOtherAddressesOfTheSameDomain() {
}
- @Disabled("MAILBOX-401 '-' causes address matching to fail, JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
+ @Disabled("MAILBOX-401 '-' causes address matching to fail")
@Test
void localPartShouldBeMatchedWhenHyphen() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
@@ -345,7 +349,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.containsOnly(messageId2.getUid());
}
- @Disabled("MAILBOX-401 '-' causes address matching to fail, JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
+ @Disabled("MAILBOX-401 '-' causes address matching to fail")
@Test
void addressShouldBeMatchedWhenHyphen() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
@@ -377,7 +381,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.containsOnly(messageId1.getUid());
}
- @Disabled("MAILBOX-401 '-' causes address matching to fail, JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
+ @Disabled("MAILBOX-401 '-' causes address matching to fail")
@Test
void domainPartShouldBeMatchedWhenHyphen() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
@@ -409,113 +413,13 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
.containsOnly(messageId1.getUid());
}
- @Disabled("JAMES-3492")
- @Override
- protected void bodyContainsShouldReturnUidOfMessageContainingTheApproximativeText() throws MailboxException {
- super.bodyContainsShouldReturnUidOfMessageContainingTheApproximativeText();
- }
-
- @Disabled("JAMES-3492")
- @Override
- public void textShouldMatchEmailAddressDomainPart() throws Exception {
- super.textShouldMatchEmailAddressDomainPart();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void multimailboxSearchShouldReturnUidOfMessageMarkedAsSeenInAllMailboxes() throws MailboxException {
- super.multimailboxSearchShouldReturnUidOfMessageMarkedAsSeenInAllMailboxes();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void multimailboxSearchShouldReturnUidOfMessageMarkedAsSeenInTwoMailboxes() throws MailboxException {
- super.multimailboxSearchShouldReturnUidOfMessageMarkedAsSeenInTwoMailboxes();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void internalDateAfterShouldReturnMessagesAfterAGivenDate() throws Exception {
- super.internalDateAfterShouldReturnMessagesAfterAGivenDate();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void internalDateBeforeShouldReturnMessagesBeforeAGivenDate() throws Exception {
- super.internalDateBeforeShouldReturnMessagesBeforeAGivenDate();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void modSeqEqualsShouldReturnUidsOfMessageHavingAGivenModSeq() throws Exception {
- super.modSeqEqualsShouldReturnUidsOfMessageHavingAGivenModSeq();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void modSeqGreaterThanShouldReturnUidsOfMessageHavingAGreaterModSeq() throws Exception {
- super.modSeqGreaterThanShouldReturnUidsOfMessageHavingAGreaterModSeq();
+ private void awaitForElasticSearch(QueryBuilder query, long totalHits) {
+ CALMLY_AWAIT.atMost(Durations.TEN_SECONDS)
+ .untilAsserted(() -> assertThat(client.search(
+ new SearchRequest(MailboxElasticSearchConstants.DEFAULT_MAILBOX_INDEX.getValue())
+ .source(new SearchSourceBuilder().query(query)),
+ RequestOptions.DEFAULT)
+ .block()
+ .getHits().getTotalHits().value).isEqualTo(totalHits));
}
-
- @Disabled("JAMES-3492")
- @Override
- protected void modSeqLessThanShouldReturnUidsOfMessageHavingAGreaterModSeq() throws Exception {
- super.modSeqLessThanShouldReturnUidsOfMessageHavingAGreaterModSeq();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void addressShouldReturnUidHavingRightExpeditorWhenFromIsSpecified() throws Exception {
- super.addressShouldReturnUidHavingRightExpeditorWhenFromIsSpecified();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void uidShouldreturnEveryThing() throws Exception {
- super.uidShouldreturnEveryThing();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void youShouldBeAbleToSpecifySeveralCriterionOnASingleQuery() throws Exception {
- super.youShouldBeAbleToSpecifySeveralCriterionOnASingleQuery();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void andShouldReturnResultsMatchingBothRequests() throws Exception {
- super.andShouldReturnResultsMatchingBothRequests();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void orShouldReturnResultsMatchinganyRequests() throws Exception {
- super.orShouldReturnResultsMatchinganyRequests();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void mailsContainsShouldIncludeMailHavingAttachmentsMatchingTheRequest() throws Exception {
- super.mailsContainsShouldIncludeMailHavingAttachmentsMatchingTheRequest();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void sortOnCcShouldWork() throws Exception {
- super.sortOnCcShouldWork();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void sortOnFromShouldWork() throws Exception {
- super.sortOnFromShouldWork();
- }
-
- @Disabled("JAMES-3492")
- @Override
- protected void sortOnToShouldWork() throws Exception {
- super.sortOnToShouldWork();
- }
-
-
}
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
index 3a33209..dc22e75 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
@@ -80,7 +80,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
}
@Override
- protected void await() {
+ protected void await(long numberOfResults) {
elasticSearch.awaitForElasticSearch();
}
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
index acff336..61f3e9b 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
@@ -64,6 +64,7 @@ import org.apache.james.mime4j.message.MultipartBuilder;
import org.apache.james.mime4j.message.SingleBodyBuilder;
import org.apache.james.util.ClassLoaderUtils;
import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -73,6 +74,10 @@ import reactor.core.publisher.Flux;
public abstract class AbstractMessageSearchIndexTest {
+ private static final ConditionFactory CALMLY_AWAIT = Awaitility
+ .with().pollInterval(ONE_HUNDRED_MILLISECONDS)
+ .and().pollDelay(ONE_HUNDRED_MILLISECONDS)
+ .await();
private static final long LIMIT = 100L;
private static final boolean RECENT = true;
private static final boolean NOT_RECENT = false;
@@ -108,7 +113,6 @@ public abstract class AbstractMessageSearchIndexTest {
private MailboxPath otherInboxPath;
private StoreMessageManager inboxMessageManager;
-
@BeforeEach
protected void setUp() throws Exception {
initializeMailboxManager();
@@ -230,10 +234,10 @@ public abstract class AbstractMessageSearchIndexTest {
RECENT,
new Flags()).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 13);
}
- protected abstract void await();
+ protected abstract void awaitMessageCount(List<MailboxId> mailboxIds, SearchQuery query, long messageCount);
protected abstract void initializeMailboxManager() throws Exception;
@@ -245,7 +249,7 @@ public abstract class AbstractMessageSearchIndexTest {
ImmutableList.of(mailbox.getMailboxId(), mailbox2.getMailboxId()),
session);
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.matchAll();
@@ -278,8 +282,6 @@ public abstract class AbstractMessageSearchIndexTest {
ImmutableList.of(mailbox2.getMailboxId()),
session);
- await();
-
SearchQuery searchQuery = SearchQuery.matchAll();
List<MessageId> result = messageSearchIndex.search(session,
@@ -314,7 +316,7 @@ public abstract class AbstractMessageSearchIndexTest {
messageIdManager.setInMailboxes(m6.getMessageId(), ImmutableList.of(mailbox.getMailboxId(), mailbox2.getMailboxId()), session);
messageIdManager.setInMailboxes(m7.getMessageId(), ImmutableList.of(mailbox.getMailboxId(), mailbox2.getMailboxId()), session);
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 20);
SearchQuery searchQuery = SearchQuery.matchAll();
@@ -348,16 +350,15 @@ public abstract class AbstractMessageSearchIndexTest {
assumeTrue(messageIdManager != null);
messageIdManager.setInMailboxes(m1.getMessageId(), ImmutableList.of(mailbox.getMailboxId(), mailbox2.getMailboxId()), session);
- SearchQuery searchQuery = SearchQuery.matchAll();
-
myFolderMessageManager.appendMessage(MessageManager.AppendCommand.builder()
.withFlags(new Flags(Flags.Flag.SEEN))
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mail.eml")),
session);
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 15);
int limit = 13;
+ SearchQuery searchQuery = SearchQuery.matchAll();
List<MessageId> result = messageSearchIndex.search(session,
ImmutableList.of(mailbox2.getMailboxId(), mailbox.getMailboxId()),
searchQuery,
@@ -427,7 +428,7 @@ public abstract class AbstractMessageSearchIndexTest {
MessageManager.AppendCommand.builder()
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/headerWithDot.eml")),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.of(SearchQuery.all());
@@ -442,7 +443,7 @@ public abstract class AbstractMessageSearchIndexTest {
MessageManager.AppendCommand.builder()
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/headerWithDot.eml")),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.of(SearchQuery.headerExists("X-header.with.dots"));
@@ -459,10 +460,9 @@ public abstract class AbstractMessageSearchIndexTest {
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mail5.eml")),
session).getId();
- String emailToSearch = "luc.duzan@james.apache.org";
-
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
+ String emailToSearch = "luc.duzan@james.apache.org";
SearchQuery searchQuery = SearchQuery.of(SearchQuery.or(ImmutableList.of(
SearchQuery.address(AddressType.From, emailToSearch),
SearchQuery.address(AddressType.To, emailToSearch),
@@ -489,7 +489,7 @@ public abstract class AbstractMessageSearchIndexTest {
.build()),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("benwa@apache.org")), session)).toStream())
.containsOnly(messageId1.getUid());
@@ -510,7 +510,7 @@ public abstract class AbstractMessageSearchIndexTest {
.build()),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("benwa")), session)).toStream())
.containsOnly(messageId1.getUid());
@@ -531,14 +531,14 @@ public abstract class AbstractMessageSearchIndexTest {
.build()),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("mydomain.org")), session)).toStream())
.containsOnly(messageId1.getUid());
}
@Test
- public void textShouldNotMatchOtherAddressesOfTheSameDomain() throws Exception {
+ void textShouldNotMatchOtherAddressesOfTheSameDomain() throws Exception {
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
MailboxSession session = MailboxSessionUtil.create(USERNAME);
MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
@@ -551,8 +551,8 @@ public abstract class AbstractMessageSearchIndexTest {
.setBody("benwa@apache.org email address do not exist", StandardCharsets.UTF_8)
.build()),
session).getId();
-
- await();
+
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("alice@apache.org")), session)).toStream())
.isEmpty();
@@ -624,10 +624,11 @@ public abstract class AbstractMessageSearchIndexTest {
MessageRange.one(m5.getUid()),
session);
- await();
-
SearchQuery searchQuery = SearchQuery.of(SearchQuery.flagIsSet(Flags.Flag.SEEN));
+ //m5 & m6 now both have SEEN flag in INBOX mailbox
+ awaitMessageCount(ImmutableList.of(mailbox.getMailboxId()), searchQuery, 2);
+
assertThat(messageSearchIndex.search(session, mailbox, searchQuery).toStream())
.contains(m5.getUid());
}
@@ -718,11 +719,12 @@ public abstract class AbstractMessageSearchIndexTest {
@Test
- void flagIsSetShouldReturnUidsOfMessageContainingAGivenUserFlag() throws MailboxException {
+ void flagIsSetShouldReturnUidsOfMessageContainingAGivenUserFlag() {
SearchQuery searchQuery = SearchQuery.of(SearchQuery.flagIsSet("Hello"));
- assertThat(messageSearchIndex.search(session, mailbox, searchQuery).toStream())
- .containsOnly(m8.getUid());
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(messageSearchIndex.search(session, mailbox, searchQuery).toStream())
+ .containsOnly(m8.getUid()));
}
@Test
@@ -1298,7 +1300,7 @@ public abstract class AbstractMessageSearchIndexTest {
MessageManager.AppendCommand.builder()
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/emailWithTextAttachment.eml")),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.of(SearchQuery.mailContains("User message banana"));
@@ -1313,7 +1315,7 @@ public abstract class AbstractMessageSearchIndexTest {
MessageManager.AppendCommand.builder()
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/emailWithTextAttachment.eml")),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.of(SearchQuery.attachmentContains("beautiful banana"));
@@ -1328,7 +1330,7 @@ public abstract class AbstractMessageSearchIndexTest {
MessageManager.AppendCommand.builder()
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/emailWithTextAttachment.eml")),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.of(SearchQuery.attachmentContains("message"));
@@ -1352,7 +1354,7 @@ public abstract class AbstractMessageSearchIndexTest {
.build();
ComposedMessageId messageWithBeautifulBananaAsPDFAttachment = myFolderMessageManager
.appendMessage(MessageManager.AppendCommand.from(message), session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.of(SearchQuery.attachmentContains("beautiful banana"));
@@ -1404,7 +1406,7 @@ public abstract class AbstractMessageSearchIndexTest {
.setBody("testmail", StandardCharsets.UTF_8)),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 16);
SearchQuery searchQuery = SearchQuery.allSortedWith(new Sort(SortClause.SentDate));
@@ -1443,7 +1445,7 @@ public abstract class AbstractMessageSearchIndexTest {
.setSubject("test")
.setBody("testmail", StandardCharsets.UTF_8)), session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 16);
SearchQuery searchQuery = SearchQuery.allSortedWith(new Sort(SortClause.SentDate));
@@ -1503,7 +1505,7 @@ public abstract class AbstractMessageSearchIndexTest {
.build())),
session).getId();
- await();
+ awaitMessageCount(ImmutableList.of(), SearchQuery.matchAll(), 14);
SearchQuery searchQuery = SearchQuery.of(SearchQuery.attachmentFileName(fileName));
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 18/32: JAMES-3492, fix tests,
wait for elasticsearch flushes to complete for test assertions
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit f94b6c0ba57d16a9d28d3f66a88c4261d9c74e8f
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Wed Mar 10 20:03:55 2021 +0200
JAMES-3492, fix tests, wait for elasticsearch flushes to complete for test assertions
---
.../james/imap/scripts/UidSearchAtomsIndexer.test | 2 +
.../james/webadmin/routes/UserQuotaRoutesTest.java | 194 ++++++++++++---------
2 files changed, 115 insertions(+), 81 deletions(-)
diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/UidSearchAtomsIndexer.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/UidSearchAtomsIndexer.test
index 520cde1..539a933 100644
--- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/UidSearchAtomsIndexer.test
+++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/UidSearchAtomsIndexer.test
@@ -2114,6 +2114,7 @@ S: A99 OK STORE completed\.
LOG INFO Waiting for Indexer to index data
AWAIT
+WAIT 10000
LOG INFO Performing tests about search
@@ -2317,6 +2318,7 @@ S: A202 OK (\[.+\] )?APPEND completed\.
LOG INFO Waiting for Indexer to index data
AWAIT
+WAIT 10000
LOG INFO Performing tests about search
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
index 4afd3aa..d936a14 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
@@ -33,6 +33,7 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import java.nio.charset.StandardCharsets;
+import java.time.Duration;
import java.util.Map;
import org.apache.james.core.Domain;
@@ -56,6 +57,8 @@ import org.apache.james.quota.search.QuotaSearchTestSystem;
import org.apache.james.user.api.UsersRepository;
import org.apache.james.webadmin.utils.ErrorResponder;
import org.assertj.core.api.SoftAssertions;
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionFactory;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
@@ -71,6 +74,11 @@ import io.restassured.path.json.JsonPath;
class UserQuotaRoutesTest {
+ private static final ConditionFactory CALMLY_AWAIT = Awaitility
+ .with().pollInterval(Duration.ofMillis(100))
+ .and().pollDelay(Duration.ofMillis(100))
+ .await();
+
private static final String QUOTA_USERS = "/quota/users";
private static final String LOST_LOCAL = "lost.local";
private static final String STRANGE_LOCAL = "strange.local";
@@ -108,15 +116,18 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- given()
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .contentType(ContentType.JSON)
- .body("username", containsInAnyOrder(
- BOB.asString(),
- JACK.asString(),
- GUY_WITH_STRANGE_DOMAIN.asString()));
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ given()
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .body("username", containsInAnyOrder(
+ BOB.asString(),
+ JACK.asString(),
+ GUY_WITH_STRANGE_DOMAIN.asString()));
+ });
}
@Test
@@ -127,16 +138,19 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- given()
- .param("domain", LOST_LOCAL)
- .when()
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .contentType(ContentType.JSON)
- .body("username", containsInAnyOrder(
- BOB.asString(),
- JACK.asString()));
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ given()
+ .param("domain", LOST_LOCAL)
+ .when()
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .body("username", containsInAnyOrder(
+ BOB.asString(),
+ JACK.asString()));
+ });
}
@Test
@@ -147,16 +161,19 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- given()
- .param("limit", 2)
- .when()
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .contentType(ContentType.JSON)
- .body("username", containsInAnyOrder(
- BOB.asString(),
- GUY_WITH_STRANGE_DOMAIN.asString()));
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ given()
+ .param("limit", 2)
+ .when()
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .body("username", containsInAnyOrder(
+ BOB.asString(),
+ GUY_WITH_STRANGE_DOMAIN.asString()));
+ });
}
@Test
@@ -167,16 +184,19 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- given()
- .param("offset", 1)
- .when()
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .contentType(ContentType.JSON)
- .body("username", containsInAnyOrder(
- JACK.asString(),
- GUY_WITH_STRANGE_DOMAIN.asString()));
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ given()
+ .param("offset", 1)
+ .when()
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .body("username", containsInAnyOrder(
+ JACK.asString(),
+ GUY_WITH_STRANGE_DOMAIN.asString()));
+ });
}
@Test
@@ -190,16 +210,19 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- given()
- .param("minOccupationRatio", 0.5)
- .when()
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .contentType(ContentType.JSON)
- .body("username", containsInAnyOrder(
- JACK.asString(),
- GUY_WITH_STRANGE_DOMAIN.asString()));
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ given()
+ .param("minOccupationRatio", 0.5)
+ .when()
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .body("username", containsInAnyOrder(
+ JACK.asString(),
+ GUY_WITH_STRANGE_DOMAIN.asString()));
+ });
}
@Test
@@ -213,16 +236,19 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- given()
- .param("maxOccupationRatio", 0.5)
- .when()
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .contentType(ContentType.JSON)
- .body("username", containsInAnyOrder(
- JACK.asString(),
- BOB.asString()));
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ given()
+ .param("maxOccupationRatio", 0.5)
+ .when()
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .body("username", containsInAnyOrder(
+ JACK.asString(),
+ BOB.asString()));
+ });
}
@Test
@@ -236,15 +262,18 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- given()
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .contentType(ContentType.JSON)
- .body("username", contains(
- BOB.asString(),
- GUY_WITH_STRANGE_DOMAIN.asString(),
- JACK.asString()));
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ given()
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .body("username", contains(
+ BOB.asString(),
+ GUY_WITH_STRANGE_DOMAIN.asString(),
+ JACK.asString()));
+ });
}
@Test
@@ -400,19 +429,21 @@ class UserQuotaRoutesTest {
testSystem.getQuotaSearchTestSystem().await();
- String jsonAsString =
- with()
- .param("minOccupationRatio", 0.5)
- .get("/quota/users")
- .then()
- .statusCode(HttpStatus.OK_200)
- .extract()
- .body()
- .asString();
-
- assertThatJson(jsonAsString)
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo("[" +
+ CALMLY_AWAIT.atMost(Duration.ofSeconds(10))
+ .untilAsserted(() -> {
+ String jsonAsString =
+ with()
+ .param("minOccupationRatio", 0.5)
+ .get("/quota/users")
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .extract()
+ .body()
+ .asString();
+
+ assertThatJson(jsonAsString)
+ .when(IGNORING_ARRAY_ORDER)
+ .isEqualTo("[" +
" {" +
" \"detail\": {" +
" \"global\": {" +
@@ -438,6 +469,7 @@ class UserQuotaRoutesTest {
" \"username\": \"guy@strange.local\"" +
" }" +
"]");
+ });
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 32/32: JAMES-3506 Avoid a full body read within
VacationMailet
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 0b3f9007eb8de370d88b0b841310d3d2f8da008c
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Mar 11 09:12:17 2021 +0700
JAMES-3506 Avoid a full body read within VacationMailet
In order to see if a part have the message/disposition-notification content type
a full parsing of the message is required.
MDNs falls in the category of automatically
generated reports described in RFC-1892
The Multipart/Report Content Type for the Reporting of Mail System Administrative Messages
The Multipart/Report MIME content-type is a general "family" or
"container" type for electronic mail reports of any kind.
So:
- Not only we are more generic
- But also we save a full message read and parsing
---
.../AutomaticallySentMailDetectorImpl.java | 66 +++-------------------
.../AutomaticallySentMailDetectorImplTest.java | 2 +
2 files changed, 11 insertions(+), 57 deletions(-)
diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImpl.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImpl.java
index 6f91048..a5a8428 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImpl.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImpl.java
@@ -19,21 +19,15 @@
package org.apache.james.mailetcontainer;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.Arrays;
+import java.util.Optional;
import javax.mail.MessagingException;
import org.apache.james.core.MailAddress;
-import org.apache.james.mdn.MDNReportParser;
-import org.apache.james.mdn.sending.mode.DispositionSendingMode;
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.parser.AbstractContentHandler;
-import org.apache.james.mime4j.parser.MimeStreamParser;
-import org.apache.james.mime4j.stream.BodyDescriptor;
-import org.apache.james.mime4j.stream.MimeConfig;
-import org.apache.james.server.core.MimeMessageInputStream;
+import org.apache.james.mime4j.codec.DecodeMonitor;
+import org.apache.james.mime4j.field.ContentTypeFieldImpl;
+import org.apache.james.mime4j.stream.RawField;
import org.apache.mailet.Mail;
import org.apache.mailet.base.AutomaticallySentMailDetector;
@@ -98,52 +92,10 @@ public class AutomaticallySentMailDetectorImpl implements AutomaticallySentMailD
@Override
public boolean isMdnSentAutomatically(Mail mail) throws MessagingException {
- ResultCollector resultCollector = new ResultCollector(false);
- MimeStreamParser parser = new MimeStreamParser(MimeConfig.custom()
- .setMaxContentLen(100 * 1024 * 1024)
- .setMaxHeaderCount(-1)
- .setMaxHeaderLen(-1)
- .setMaxLineLen(-1)
- .setHeadlessParsing(mail.getMessage().getContentType())
- .build());
- parser.setContentHandler(createMdnContentHandler(resultCollector));
- try {
- parser.parse(new MimeMessageInputStream(mail.getMessage()));
- } catch (MimeException e) {
- throw new MessagingException("Can not parse Mime", e);
- } catch (IOException e) {
- throw new MessagingException("Can not read content", e);
- }
- return resultCollector.getResult();
- }
-
- private AbstractContentHandler createMdnContentHandler(final ResultCollector resultCollector) {
- return new AbstractContentHandler() {
- @Override
- public void body(BodyDescriptor bodyDescriptor, InputStream inputStream) throws MimeException, IOException {
- if (bodyDescriptor.getMimeType().equalsIgnoreCase("message/disposition-notification")) {
- resultCollector.setResult(MDNReportParser.parse(inputStream, bodyDescriptor.getCharset())
- .map(report -> report.getDispositionField().getSendingMode() == DispositionSendingMode.Automatic)
- .getOrElse(() -> false));
- }
- }
- };
- }
-
- private static class ResultCollector {
- private boolean result;
-
- public ResultCollector(boolean result) {
- this.result = result;
- }
-
- public boolean getResult() {
- return result;
- }
-
- public void setResult(boolean result) {
- this.result = result;
- }
+ return Optional.ofNullable(mail.getMessage().getContentType())
+ .map(field -> ContentTypeFieldImpl.PARSER.parse(new RawField("Content-Type", field), DecodeMonitor.SILENT))
+ .map(field -> field.getMimeType())
+ .stream()
+ .anyMatch("multipart/report"::equals);
}
-
}
diff --git a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImplTest.java b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImplTest.java
index 8996565..624f3b1 100644
--- a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImplTest.java
+++ b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/AutomaticallySentMailDetectorImplTest.java
@@ -261,6 +261,7 @@ class AutomaticallySentMailDetectorImplTest {
void isMdnSentAutomaticallyShouldBeDetected() throws Exception {
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
MimeMultipart multipart = new MimeMultipart();
+ multipart.setSubType("report");
MimeBodyPart scriptPart = new MimeBodyPart();
scriptPart.setDataHandler(
new DataHandler(
@@ -380,6 +381,7 @@ class AutomaticallySentMailDetectorImplTest {
void isMdnSentAutomaticallyShouldDetectBigMDN() throws Exception {
MimeMessage message = MimeMessageUtil.defaultMimeMessage();
MimeMultipart multipart = new MimeMultipart();
+ multipart.setSubType("report");
MimeBodyPart scriptPart = new MimeBodyPart();
scriptPart.setDataHandler(
new DataHandler(
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 09/32: JAMES-3492 Mapping should be created at the
same time as index
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 55098c478619ad3cd18fa599f03afec1e7210962
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Wed Mar 3 15:47:38 2021 +0700
JAMES-3492 Mapping should be created at the same time as index
---
.../james/backends/es/v7/IndexCreationFactory.java | 24 ++++++++++++++--------
.../james/backends/es/v7/NodeMappingFactory.java | 19 -----------------
.../backends/es/v7/NodeMappingFactoryAuthTest.java | 6 +-----
.../backends/es/v7/NodeMappingFactoryTest.java | 7 ++-----
.../backends/es/v7/search/ScrolledSearchTest.java | 1 -
.../elasticsearch/v7/MailboxIndexCreationUtil.java | 10 +++------
.../v7/QuotaSearchIndexCreationUtil.java | 17 ++++++---------
7 files changed, 27 insertions(+), 57 deletions(-)
diff --git a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
index 3ea5f6f..fcac158 100644
--- a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
+++ b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
@@ -23,14 +23,15 @@ import static org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import java.io.IOException;
+import java.util.Optional;
import javax.inject.Inject;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
-import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,7 +64,11 @@ public class IndexCreationFactory {
}
public ReactorElasticSearchClient createIndexAndAliases(ReactorElasticSearchClient client) {
- return new IndexCreationPerformer(nbShards, nbReplica, waitForActiveShards, indexName, aliases.build()).createIndexAndAliases(client);
+ return new IndexCreationPerformer(nbShards, nbReplica, waitForActiveShards, indexName, aliases.build()).createIndexAndAliases(client, Optional.empty());
+ }
+
+ public ReactorElasticSearchClient createIndexAndAliases(ReactorElasticSearchClient client, XContentBuilder mappingContent) {
+ return new IndexCreationPerformer(nbShards, nbReplica, waitForActiveShards, indexName, aliases.build()).createIndexAndAliases(client, Optional.of(mappingContent));
}
}
@@ -82,10 +87,10 @@ public class IndexCreationFactory {
this.aliases = aliases;
}
- public ReactorElasticSearchClient createIndexAndAliases(ReactorElasticSearchClient client) {
+ public ReactorElasticSearchClient createIndexAndAliases(ReactorElasticSearchClient client, Optional<XContentBuilder> mappingContent) {
Preconditions.checkNotNull(indexName);
try {
- createIndexIfNeeded(client, indexName, generateSetting(nbShards, nbReplica, waitForActiveShards));
+ createIndexIfNeeded(client, indexName, generateSetting(nbShards, nbReplica, waitForActiveShards), mappingContent);
aliases.forEach(Throwing.<AliasName>consumer(alias -> createAliasIfNeeded(client, indexName, alias))
.sneakyThrow());
} catch (IOException e) {
@@ -111,12 +116,13 @@ public class IndexCreationFactory {
.existsAlias(new GetAliasesRequest().aliases(aliasName.getValue()), RequestOptions.DEFAULT);
}
- private void createIndexIfNeeded(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder settings) throws IOException {
+ private void createIndexIfNeeded(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder settings, Optional<XContentBuilder> mappingContent) throws IOException {
try {
- client.indices()
- .create(
- new CreateIndexRequest(indexName.getValue())
- .source(settings), RequestOptions.DEFAULT);
+ CreateIndexRequest request = new CreateIndexRequest(indexName.getValue()).source(settings);
+ mappingContent.ifPresent(request::mapping);
+ client.indices().create(
+ request,
+ RequestOptions.DEFAULT);
} catch (ElasticsearchStatusException exception) {
if (exception.getMessage().contains(INDEX_ALREADY_EXISTS_EXCEPTION_MESSAGE)) {
LOGGER.info("Index [{}] already exists", indexName.getValue());
diff --git a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
index 6f6b14a..2f526d8 100644
--- a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
+++ b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
@@ -52,28 +52,9 @@ public class NodeMappingFactory {
public static ReactorElasticSearchClient applyMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
createMapping(client, indexName, mappingsSources);
-
- /*if (!mappingAlreadyExist(client, indexName)) {
- createMapping(client, indexName, mappingsSources);
- }*/
return client;
}
- //TODO: since ElasticSearch version 7 this check does not work anymore. Find another way to check whether mapping exists or not
- // ElasticSearch 6.3.2 does not support field master_timeout that is set up by 6.4.3 REST client when relying on getMapping
- @SuppressWarnings("deprecation")
- /*public static boolean mappingAlreadyExist(ReactorElasticSearchClient client, IndexName indexName) throws IOException {
- try {
- client.getLowLevelClient().performRequest(new Request("GET", "/" + indexName.getValue() + "/_mapping/"));
- return true;
- } catch (ResponseException e) {
- if (e.getResponse().getStatusLine().getStatusCode() != HttpStatus.SC_NOT_FOUND) {
- throw e;
- }
- }
- return false;
- }*/
-
public static void createMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
client.indices().putMapping(
new PutMappingRequest(indexName.getValue())
diff --git a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java
index c425b13..eb98550 100644
--- a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java
+++ b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java
@@ -28,7 +28,6 @@ import java.util.Optional;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -58,10 +57,7 @@ class NodeMappingFactoryAuthTest {
new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
.useIndex(INDEX_NAME)
.addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
+ .createIndexAndAliasesWithMapping(client, Optional.of(getMappingsSources()));
}
@AfterEach
diff --git a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java
index 9744324..ade2309 100644
--- a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java
+++ b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java
@@ -23,11 +23,11 @@ import static org.assertj.core.api.Assertions.assertThatCode;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import java.io.IOException;
+import java.util.Optional;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -46,10 +46,7 @@ class NodeMappingFactoryTest {
new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
.useIndex(INDEX_NAME)
.addAlias(ALIAS_NAME)
- .createIndexAndAliases(client);
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
+ .createIndexAndAliasesWithMapping(client, Optional.of(getMappingsSources()));
}
@AfterEach
diff --git a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/search/ScrolledSearchTest.java b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/search/ScrolledSearchTest.java
index 29499bb..9249c38 100644
--- a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/search/ScrolledSearchTest.java
+++ b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/search/ScrolledSearchTest.java
@@ -28,7 +28,6 @@ import org.apache.james.backends.es.v7.DockerElasticSearchExtension;
import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
import org.apache.james.backends.es.v7.IndexCreationFactory;
import org.apache.james.backends.es.v7.IndexName;
-import org.apache.james.backends.es.v7.NodeMappingFactory;
import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.backends.es.v7.ReadAliasName;
import org.awaitility.Durations;
diff --git a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxIndexCreationUtil.java b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxIndexCreationUtil.java
index 664185d..0ac100c 100644
--- a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxIndexCreationUtil.java
+++ b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxIndexCreationUtil.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
import org.apache.james.backends.es.v7.IndexCreationFactory;
import org.apache.james.backends.es.v7.IndexName;
-import org.apache.james.backends.es.v7.NodeMappingFactory;
import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.backends.es.v7.ReadAliasName;
import org.apache.james.backends.es.v7.WriteAliasName;
@@ -35,15 +34,12 @@ public class MailboxIndexCreationUtil {
ReadAliasName readAlias,
WriteAliasName writeAlias,
IndexName indexName,
- ElasticSearchConfiguration configuration) throws IOException {
- return NodeMappingFactory.applyMapping(
- new IndexCreationFactory(configuration)
+ ElasticSearchConfiguration configuration) {
+ return new IndexCreationFactory(configuration)
.useIndex(indexName)
.addAlias(readAlias)
.addAlias(writeAlias)
- .createIndexAndAliases(client),
- indexName,
- MailboxMappingFactory.getMappingContent());
+ .createIndexAndAliases(client, MailboxMappingFactory.getMappingContent());
}
public static ReactorElasticSearchClient prepareDefaultClient(ReactorElasticSearchClient client, ElasticSearchConfiguration configuration) throws IOException {
diff --git a/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaSearchIndexCreationUtil.java b/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaSearchIndexCreationUtil.java
index 88e2319..33d72bc 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaSearchIndexCreationUtil.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaSearchIndexCreationUtil.java
@@ -25,7 +25,6 @@ import org.apache.james.backends.es.v7.AliasName;
import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
import org.apache.james.backends.es.v7.IndexCreationFactory;
import org.apache.james.backends.es.v7.IndexName;
-import org.apache.james.backends.es.v7.NodeMappingFactory;
import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
public class QuotaSearchIndexCreationUtil {
@@ -34,16 +33,12 @@ public class QuotaSearchIndexCreationUtil {
AliasName readAlias,
AliasName writeAlias,
IndexName indexName,
- ElasticSearchConfiguration configuration) throws IOException {
-
- return NodeMappingFactory.applyMapping(
- new IndexCreationFactory(configuration)
- .useIndex(indexName)
- .addAlias(readAlias)
- .addAlias(writeAlias)
- .createIndexAndAliases(client),
- indexName,
- QuotaRatioMappingFactory.getMappingContent());
+ ElasticSearchConfiguration configuration) {
+ return new IndexCreationFactory(configuration)
+ .useIndex(indexName)
+ .addAlias(readAlias)
+ .addAlias(writeAlias)
+ .createIndexAndAliases(client, QuotaRatioMappingFactory.getMappingContent());
}
public static ReactorElasticSearchClient prepareDefaultClient(ReactorElasticSearchClient client, ElasticSearchConfiguration configuration) throws IOException {
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 08/32: JAMES-3492 Adapt ElasticSearchSearcherTest
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit b62784d49e7db5dc3baa9a211474e45e44502763
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Wed Mar 3 15:07:38 2021 +0700
JAMES-3492 Adapt ElasticSearchSearcherTest
---
.../v7/search/ElasticSearchSearcherTest.java | 27 +++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcherTest.java b/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcherTest.java
index 97abff6..61111f8 100644
--- a/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcherTest.java
+++ b/mailbox/elasticsearch-v7/src/test/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcherTest.java
@@ -21,6 +21,7 @@
package org.apache.james.mailbox.elasticsearch.v7.search;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Durations.ONE_HUNDRED_MILLISECONDS;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -59,20 +60,30 @@ import org.apache.james.mailbox.tika.TikaHttpClientImpl;
import org.apache.james.mailbox.tika.TikaTextExtractor;
import org.apache.james.metrics.tests.RecordingMetricFactory;
import org.apache.james.mime4j.dom.Message;
+import org.awaitility.Awaitility;
+import org.awaitility.Durations;
+import org.awaitility.core.ConditionFactory;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import com.github.fge.lambdas.Throwing;
import com.github.steveash.guavate.Guavate;
-@Disabled("JAMES-3492, Types cannot be provided in get mapping requests, unless include_type_name is set to true.")
class ElasticSearchSearcherTest {
static final int SEARCH_SIZE = 1;
private static final Username USERNAME = Username.of("user");
+ private static final ConditionFactory CALMLY_AWAIT = Awaitility
+ .with().pollInterval(ONE_HUNDRED_MILLISECONDS)
+ .and().pollDelay(ONE_HUNDRED_MILLISECONDS)
+ .await();
@RegisterExtension
static TikaExtension tika = new TikaExtension();
@@ -144,7 +155,7 @@ class ElasticSearchSearcherTest {
.map(Throwing.<MailboxPath, ComposedMessageId>function(mailboxPath -> addMessage(session, mailboxPath)).sneakyThrow())
.collect(Guavate.toImmutableList());
- elasticSearch.awaitForElasticSearch();
+ awaitForElasticSearch(QueryBuilders.matchAllQuery(), composedMessageIds.size());
MultimailboxesSearchQuery multimailboxesSearchQuery = MultimailboxesSearchQuery
.from(SearchQuery.of(SearchQuery.all()))
@@ -170,4 +181,14 @@ class ElasticSearchSearcherTest {
session)
.getId();
}
+
+ private void awaitForElasticSearch(QueryBuilder query, long totalHits) {
+ CALMLY_AWAIT.atMost(Durations.TEN_SECONDS)
+ .untilAsserted(() -> assertThat(client.search(
+ new SearchRequest(MailboxElasticSearchConstants.DEFAULT_MAILBOX_INDEX.getValue())
+ .source(new SearchSourceBuilder().query(query)),
+ RequestOptions.DEFAULT)
+ .block()
+ .getHits().getTotalHits().value).isEqualTo(totalHits));
+ }
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 29/32: JAMES-3499 Distributed guice module should
not depend on activemq
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit aa56c6e6f88c8b9fc070b821677806f1461142d5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 12 10:40:12 2021 +0700
JAMES-3499 Distributed guice module should not depend on activemq
---
server/container/guice/distributed/pom.xml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/server/container/guice/distributed/pom.xml b/server/container/guice/distributed/pom.xml
index a4a10be..85f7a29 100644
--- a/server/container/guice/distributed/pom.xml
+++ b/server/container/guice/distributed/pom.xml
@@ -62,10 +62,6 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>james-server-cassandra-guice</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
<artifactId>james-server-guice-cassandra</artifactId>
</dependency>
<dependency>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 11/32: JAMES-3492 Add missing dependency
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 810149beed7926d4731a4368d6eac14b79fc749c
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Thu Mar 4 14:29:36 2021 +0700
JAMES-3492 Add missing dependency
---
mailbox/plugin/quota-search-elasticsearch-v7/pom.xml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/mailbox/plugin/quota-search-elasticsearch-v7/pom.xml b/mailbox/plugin/quota-search-elasticsearch-v7/pom.xml
index 41092d8..1193484 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v7/pom.xml
+++ b/mailbox/plugin/quota-search-elasticsearch-v7/pom.xml
@@ -75,6 +75,12 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>event-bus-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>james-core</artifactId>
<type>test-jar</type>
<scope>test</scope>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 07/32: JAMES-3492 Adapt other implementations of
AbstractMessageSearchIndexTest
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 1e34bea0f33084f26ad1aa82097026407b061f33
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Wed Mar 3 14:58:20 2021 +0700
JAMES-3492 Adapt other implementations of AbstractMessageSearchIndexTest
---
.../james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java | 6 ++++--
.../james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java | 6 +++++-
.../james/mailbox/store/search/SimpleMessageSearchIndexTest.java | 6 +++++-
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
index dc22e75..65b451d 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
+import java.util.List;
import org.apache.james.backends.es.DockerElasticSearchExtension;
import org.apache.james.backends.es.ElasticSearchIndexer;
@@ -40,6 +41,7 @@ import org.apache.james.mailbox.inmemory.InMemoryId;
import org.apache.james.mailbox.inmemory.InMemoryMessageId;
import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
import org.apache.james.mailbox.model.ComposedMessageId;
+import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.store.search.AbstractMessageSearchIndexTest;
@@ -80,7 +82,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
}
@Override
- protected void await(long numberOfResults) {
+ protected void awaitMessageCount(List<MailboxId> mailboxIds, SearchQuery query, long messageCount) {
elasticSearch.awaitForElasticSearch();
}
@@ -298,7 +300,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
@Disabled("MAILBOX-403 Relaxed the matching constraints for email addresses in text bodies to reduce ElasticSearch disk space usage")
@Test
- public void textShouldNotMatchOtherAddressesOfTheSameDomain() throws Exception {
+ public void textShouldNotMatchOtherAddressesOfTheSameDomain() {
}
diff --git a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
index dab83c0..e659382 100644
--- a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
+++ b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
@@ -19,9 +19,13 @@
package org.apache.james.mailbox.lucene.search;
+import java.util.List;
+
import org.apache.james.mailbox.inmemory.InMemoryId;
import org.apache.james.mailbox.inmemory.InMemoryMessageId;
import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.store.search.AbstractMessageSearchIndexTest;
import org.apache.lucene.store.RAMDirectory;
import org.junit.jupiter.api.Disabled;
@@ -32,7 +36,7 @@ import com.github.fge.lambdas.Throwing;
class LuceneMessageSearchIndexTest extends AbstractMessageSearchIndexTest {
@Override
- protected void await() {
+ protected void awaitMessageCount(List<MailboxId> mailboxIds, SearchQuery query, long messageCount) {
}
@Override
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
index d29a492..16f1559 100644
--- a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
@@ -19,13 +19,17 @@
package org.apache.james.mailbox.store.search;
+import java.util.List;
+
import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.SearchQuery;
import org.junit.jupiter.api.Disabled;
class SimpleMessageSearchIndexTest extends AbstractMessageSearchIndexTest {
@Override
- protected void await() {
+ protected void awaitMessageCount(List<MailboxId> mailboxIds, SearchQuery query, long messageCount) {
}
@Override
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 25/32: JAMES-3492, add upgrade instructions
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 8c0079e136483b91b91658bd55fa0003d0e9db6c
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Thu Mar 11 15:33:30 2021 +0200
JAMES-3492, add upgrade instructions
---
upgrade-instructions.md | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index e4c5bb6..ba2c70d 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -54,6 +54,34 @@ Example `usersrepository.xml`:
</usersrepository>
```
+### Recommended upgrade to Elasticsearch 7.10.2
+
+Date: 11/03/2021
+
+JIRA: https://issues.apache.org/jira/browse/JAMES-2492
+
+Concerned products: Cassandra Guice server (with and without rabbitMQ)
+
+James is no longer tested against Elasticsearch 6.3.2 but instead against Elasticsearch 7.10.2 Users are recommended to upgrade to this
+version as well.
+
+This [link](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/rolling-upgrades.html) describes a possible update procedure:
+
+Updating from Elasticsearch < 6.8 needs an extra step of shutting down the cluster and restarting it after each node is upgraded
+
+- Test the upgrade in dev environment first
+- Take a backup of the cluster
+- On each node, perform a rolling update
+- Disable shard allocation
+- Stop non-essential indexing and perform a synced flush this node
+- Shut down this node.
+- Upgrade the node you shut down
+- Upgrade any plugins
+- Start the upgraded node
+- Reenable shard allocation
+- Wait for the node to recover
+- Repeat for other nodes
+
### JMS mail queue no longer relies on java serialization
Date: 07/12/2020
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 27/32: JAMES-3492, upgrade documentation
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 1c9578fe210c9b2a5eb8503ac9aa7f8a6d8868b1
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Fri Mar 12 10:19:27 2021 +0200
JAMES-3492, upgrade documentation
---
README.adoc | 4 ++--
dockerfiles/run/docker-compose-branch-master.yml | 2 +-
dockerfiles/run/docker-compose.yml | 2 +-
.../servers/pages/distributed/configure/elasticsearch.adoc | 2 +-
docs/modules/servers/pages/distributed/operate/guide.adoc | 8 ++++----
docs/modules/servers/pages/distributed/operate/logging.adoc | 4 ++--
docs/modules/servers/pages/distributed/run-docker.adoc | 2 +-
docs/modules/servers/pages/distributed/run.adoc | 6 +++---
.../markdown/server/install/guice-cassandra-rabbitmq-swift.md | 6 +++---
src/site/markdown/server/install/guice-cassandra.md | 6 +++---
src/site/xdoc/server/config-elasticsearch.xml | 4 ++--
src/site/xdoc/server/quick-start-cassandra.xml | 2 +-
12 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/README.adoc b/README.adoc
index 2e5dfb5..3d6f1a3 100644
--- a/README.adoc
+++ b/README.adoc
@@ -165,7 +165,7 @@ You need a running *s3* compatible objectstorage in docker. To achieve this run:
You need a running *ElasticSearch* in docker. To achieve this run:
- $ docker run -d --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+ $ docker run -d --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:7.10.2
If you want to handle attachment text extraction before indexing in ElasticSearch (this makes attachments searchable)
and if you want to use all the JMAP search capabilities, you also need to start *Tika*.
@@ -237,7 +237,7 @@ You need a running *cassandra* in docker. To achieve this run:
You need a running *ElasticSearch* in docker. To achieve this run:
- $ docker run -d --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+ $ docker run -d --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:7.10.2
If you want to handle attachment text extraction before indexing in ElasticSearch (this makes attachments searchable)
and if you want to use all the JMAP search capabilities, you also need to start *Tika*.
diff --git a/dockerfiles/run/docker-compose-branch-master.yml b/dockerfiles/run/docker-compose-branch-master.yml
index bbd4349..4463e5d 100644
--- a/dockerfiles/run/docker-compose-branch-master.yml
+++ b/dockerfiles/run/docker-compose-branch-master.yml
@@ -24,7 +24,7 @@ services:
- "8000:8000"
elasticsearch:
- image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+ image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
environment:
- discovery.type=single-node
diff --git a/dockerfiles/run/docker-compose.yml b/dockerfiles/run/docker-compose.yml
index f60db6f..89bc9cf 100644
--- a/dockerfiles/run/docker-compose.yml
+++ b/dockerfiles/run/docker-compose.yml
@@ -24,7 +24,7 @@ services:
- "8000:8000"
elasticsearch:
- image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+ image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
environment:
- discovery.type=single-node
diff --git a/docs/modules/servers/pages/distributed/configure/elasticsearch.adoc b/docs/modules/servers/pages/distributed/configure/elasticsearch.adoc
index 07fe516..d9d8ef5 100644
--- a/docs/modules/servers/pages/distributed/configure/elasticsearch.adoc
+++ b/docs/modules/servers/pages/distributed/configure/elasticsearch.adoc
@@ -27,7 +27,7 @@ Here are the properties allowing to do so :
| elasticsearch.index.waitForActiveShards
| Wait for a certain number of active shard copies before proceeding with the operation. Defaults to 1.
-You may consult the https://www.elastic.co/guide/en/elasticsearch/reference/6.3/docs-index_.html#index-wait-for-active-shards[documentation] for more information.
+You may consult the https://www.elastic.co/guide/en/elasticsearch/reference/7.10/docs-index_.html#active-shards[documentation] for more information.
| elasticsearch.retryConnection.maxRetries
| Number of retries when connecting the cluster
diff --git a/docs/modules/servers/pages/distributed/operate/guide.adoc b/docs/modules/servers/pages/distributed/operate/guide.adoc
index c2e5c4d..db0cc9e 100644
--- a/docs/modules/servers/pages/distributed/operate/guide.adoc
+++ b/docs/modules/servers/pages/distributed/operate/guide.adoc
@@ -165,21 +165,21 @@ administrator might want to update index settings include:
In order to achieve such a procedure, you need to:
-* https://www.elastic.co/guide/en/elasticsearch/reference/6.3/indices-create-index.html[Create
+* https://www.elastic.co/guide/en/elasticsearch/reference/7.10/indices-create-index.html[Create
the new index] with the right settings and mapping
* James uses two aliases on the mailbox index: one for reading
(`mailboxReadAlias`) and one for writing (`mailboxWriteAlias`). First
-https://www.elastic.co/guide/en/elasticsearch/reference/6.3/indices-aliases.html[add
+https://www.elastic.co/guide/en/elasticsearch/reference/7.10/indices-aliases.html[add
an alias] `mailboxWriteAlias` to that new index, so that now James
writes on the old and new indexes, while only keeping reading on the
first one
* Now trigger a
-https://www.elastic.co/guide/en/elasticsearch/reference/6.3/docs-reindex.html[reindex]
+https://www.elastic.co/guide/en/elasticsearch/reference/7.10/docs-reindex.html[reindex]
from the old index to the new one (this actively relies on `_source`
field being present)
* When this is done, add the `mailboxReadAlias` alias to the new index
* Now that the migration to the new index is done, you can
-https://www.elastic.co/guide/en/elasticsearch/reference/6.3/indices-delete-index.html[drop
+https://www.elastic.co/guide/en/elasticsearch/reference/7.10/indices-delete-index.html[drop
the old index]
* You might want as well modify the James configuration file
https://github.com/apache/james-project/blob/master/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/elasticsearch.properties[elasticsearch.properties]
diff --git a/docs/modules/servers/pages/distributed/operate/logging.adoc b/docs/modules/servers/pages/distributed/operate/logging.adoc
index 7825f38..149dc5e 100644
--- a/docs/modules/servers/pages/distributed/operate/logging.adoc
+++ b/docs/modules/servers/pages/distributed/operate/logging.adoc
@@ -193,7 +193,7 @@ services:
- "8080:8000"
elasticsearch:
- image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+ image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
ports:
- "9200:9200"
environment:
@@ -233,7 +233,7 @@ services:
- elasticsearch
kibana:
- image: docker.elastic.co/kibana/kibana:6.3.2
+ image: docker.elastic.co/kibana/kibana:7.10.2
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
ports:
diff --git a/docs/modules/servers/pages/distributed/run-docker.adoc b/docs/modules/servers/pages/distributed/run-docker.adoc
index 185de97..cdb4941 100644
--- a/docs/modules/servers/pages/distributed/run-docker.adoc
+++ b/docs/modules/servers/pages/distributed/run-docker.adoc
@@ -57,7 +57,7 @@ You need a running *Zenko Cloudserver* objectstorage in docker. To achieve this
You need a running *ElasticSearch* in docker. To achieve this run:
- $ docker run -d --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+ $ docker run -d --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:7.10.2
If you want to use all the JMAP search capabilities, you may also need to start Tika:
diff --git a/docs/modules/servers/pages/distributed/run.adoc b/docs/modules/servers/pages/distributed/run.adoc
index 8a2303e..ab1081f 100644
--- a/docs/modules/servers/pages/distributed/run.adoc
+++ b/docs/modules/servers/pages/distributed/run.adoc
@@ -6,7 +6,7 @@
=== Requirements
* Java 11 SDK
-* Docker ∕ ElasticSearch 6.3.2, RabbitMQ Management 3.3.7, S3 compatible
+* Docker ∕ ElasticSearch 7.10.2, RabbitMQ Management 3.3.7, S3 compatible
ObjectStorage and Cassandra 3.11.10
* Maven 3
@@ -30,7 +30,7 @@ mvn clean install
=== Requirements
* Cassandra 3.11.10
-* ElasticSearch 6.3.2
+* ElasticSearch 7.10.2
* RabbitMQ-Management 3.8.1
* Swift ObjectStorage 2.15.1 or Zenko Cloudserver or AWS S3
@@ -59,7 +59,7 @@ running. You can either install the servers or launch them via docker:
[source,bash]
----
$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.10
-$ docker run -d -p 9200:9200 --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+$ docker run -d -p 9200:9200 --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:7.10.2
$ docker run -d -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.8.1-management
$ docker run -d --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 zenko/cloudserver:8.2.6
----
diff --git a/src/site/markdown/server/install/guice-cassandra-rabbitmq-swift.md b/src/site/markdown/server/install/guice-cassandra-rabbitmq-swift.md
index 1a204dc..14966e6 100644
--- a/src/site/markdown/server/install/guice-cassandra-rabbitmq-swift.md
+++ b/src/site/markdown/server/install/guice-cassandra-rabbitmq-swift.md
@@ -5,7 +5,7 @@
### Requirements
- Java 11 SDK
- - Docker ∕ ElasticSearch 6.3.2, RabbitMQ Management 3.8.1, compatible S3 ObjectStorage and Cassandra 3.11.10
+ - Docker ∕ ElasticSearch 7.10.2, RabbitMQ Management 3.8.1, compatible S3 ObjectStorage and Cassandra 3.11.10
- Maven 3
### Building the artifacts
@@ -26,7 +26,7 @@ mvn clean install
### Requirements
* Cassandra 3.11.10
- * ElasticSearch 6.3.2
+ * ElasticSearch 7.10.2
* RabbitMQ-Management 3.8.1
* Swift ObjectStorage 2.15.1 or Zenko Cloudserver or AWS S3
@@ -48,7 +48,7 @@ You need to have a Cassandra, ElasticSearch, S3 and RabbitMQ instance running. Y
```bash
$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.10
-$ docker run -d -p 9200:9200 --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+$ docker run -d -p 9200:9200 --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:7.10.2
$ docker run -d -p 5672:5672 -p 15672:15672 --name=rabbitmq rabbitmq:3.8.1-management
$ docker run -d --env 'REMOTE_MANAGEMENT_DISABLE=1' --env 'SCALITY_ACCESS_KEY_ID=accessKey1' --env 'SCALITY_SECRET_ACCESS_KEY=secretKey1' --name=s3 zenko/cloudserver:8.2.6
```
diff --git a/src/site/markdown/server/install/guice-cassandra.md b/src/site/markdown/server/install/guice-cassandra.md
index ad1d55a..9775d2d 100644
--- a/src/site/markdown/server/install/guice-cassandra.md
+++ b/src/site/markdown/server/install/guice-cassandra.md
@@ -5,7 +5,7 @@
### Requirements
- Java 11 SDK
- - Docker ∕ ElasticSearch 6.3.2 and Cassandra 3.11.10
+ - Docker ∕ ElasticSearch 7.10.2 and Cassandra 3.11.10
- Maven 3
### Building the artifacts
@@ -26,7 +26,7 @@ mvn clean install
### Requirements
* Cassandra 3.11.10
- * ElasticSearch 6.3.2
+ * ElasticSearch 7.10.2
### James Launch
@@ -46,7 +46,7 @@ You need to have a Cassandra and an ElasticSearch instance running. You can eith
```bash
$ docker run -d -p 9042:9042 --name=cassandra cassandra:3.11.10
-$ docker run -d -p 9200:9200 --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:6.3.2
+$ docker run -d -p 9200:9200 --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:7.10.2
```
Once everything is set up, you just have to run the jar with:
diff --git a/src/site/xdoc/server/config-elasticsearch.xml b/src/site/xdoc/server/config-elasticsearch.xml
index ed085de..5a7fa6f 100644
--- a/src/site/xdoc/server/config-elasticsearch.xml
+++ b/src/site/xdoc/server/config-elasticsearch.xml
@@ -81,7 +81,7 @@
<dd>Number of replica for index provisionned by James (default: 0)</dd>
<dt><strong>elasticsearch.index.waitForActiveShards (default: 1)</strong></dt>
<dd>Wait for a certain number of active shard copies before proceeding with the operation.</dd>
- <dd>You may consult the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/6.3/docs-index_.html#index-wait-for-active-shards">documentation</a> for more information.</dd>
+ <dd>You may consult the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.10/docs-index_.html#active-shards">documentation</a> for more information.</dd>
<dt><strong>elasticsearch.index.mailbox.name</strong></dt>
<dd>Name of the mailbox index backed by the alias. It will be created if missing.</dd>
<dt><strong>elasticsearch.index.name</strong></dt>
@@ -129,7 +129,7 @@
<dl>
<dt><strong>elasticsearch.http.host</strong></dt>
- <dd>Host to report metrics on. Defaults to master host.</dd>
+ <dd>Host to report metrics on. Defaults to master host. Compatible with 6.x hosts</dd>
<dt><strong>elasticsearch.http.port</strong></dt>
<dd>Http port to use for publishing metrics</dd>
diff --git a/src/site/xdoc/server/quick-start-cassandra.xml b/src/site/xdoc/server/quick-start-cassandra.xml
index e4b6ad9..61df784 100644
--- a/src/site/xdoc/server/quick-start-cassandra.xml
+++ b/src/site/xdoc/server/quick-start-cassandra.xml
@@ -69,7 +69,7 @@ You may skip this part if you already have a running Cassandra on your network.
3.2. Deploy ElasticSearch (optional)
You may skip this part if you already have a running ElasticSearch on your network.
-<i>$ docker run --detach=true --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:6.3.2</i>
+<i>$ docker run --detach=true --name=elasticsearch --env 'discovery.type=single-node' docker.elastic.co/elasticsearch/elasticsearch:7.10.2</i>
Step 4: Configure
#################
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 03/32: JAMES-3492 Replace deprecated
CreateIndexRequest
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 699ec425a95e818b8a5ab097d7bb63b8ef1cfa9b
Author: Lan Khuat <kh...@gmail.com>
AuthorDate: Tue Mar 2 22:12:27 2021 +0700
JAMES-3492 Replace deprecated CreateIndexRequest
---
.../main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
index 40d551d..3ea5f6f 100644
--- a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
+++ b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
@@ -29,7 +29,7 @@ import javax.inject.Inject;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
-import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
+import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.slf4j.Logger;
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 16/32: JAMES-3492, disable failing tests
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 42b7c5fe7f0c7392da760202019e95d4cfee821d
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Wed Mar 10 20:00:31 2021 +0200
JAMES-3492, disable failing tests
---
.../src/test/java/org/apache/james/ESReporterTest.java | 3 +++
.../james/JamesWithNonCompatibleElasticSearchServerTest.java | 10 ++++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
index d8ecc21..b51d6b7 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
@@ -47,6 +47,7 @@ import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger;
@@ -103,6 +104,7 @@ class ESReporterTest {
}
@Test
+ @Disabled("JAMES-3492, com.linagora.elasticsearch.metrics package does not support es7")
void timeMetricsShouldBeReportedWhenImapCommandsReceived(GuiceJamesServer server) throws Exception {
IMAPClient client = new IMAPClient();
client.connect(InetAddress.getLocalHost(), server.getProbe(ImapGuiceProbe.class).getImapPort());
@@ -125,6 +127,7 @@ class ESReporterTest {
}
@Test
+ @Disabled("JAMES-3492, com.linagora.elasticsearch.metrics package does not support es7")
void timeMetricsShouldBeReportedWhenJmapRequestsReceived() {
TimerTask timerTask = new TimerTask() {
@Override
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
index 6f334d2..f5598f2 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
@@ -29,16 +29,17 @@ import org.apache.james.modules.TestJMAPServerModule;
import org.apache.james.modules.mailbox.ElasticSearchStartUpCheck;
import org.apache.james.util.docker.Images;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class JamesWithNonCompatibleElasticSearchServerTest {
- static DockerElasticSearch dockerES2 = new DockerElasticSearch.NoAuth(Images.ELASTICSEARCH_2);
+ static DockerElasticSearch dockerES6 = new DockerElasticSearch.NoAuth(Images.ELASTICSEARCH_6);
@RegisterExtension
static JamesServerExtension testExtension = TestingDistributedJamesServerBuilder.withSearchConfiguration(SearchConfiguration.elasticSearch())
- .extension(new DockerElasticSearchExtension(dockerES2))
+ .extension(new DockerElasticSearchExtension(dockerES6))
.extension(new CassandraExtension())
.server(configuration -> CassandraJamesServerMain.createServer(configuration)
.overrideWith(new TestJMAPServerModule()))
@@ -47,10 +48,11 @@ class JamesWithNonCompatibleElasticSearchServerTest {
@AfterAll
static void afterAll() {
- dockerES2.stop();
+ dockerES6.stop();
}
@Test
+ @Disabled("JAMES-3492, fails because communication fails with lower than 7.x nodes, maybe should be removed ")
void jamesShouldStopWhenStartingWithANonCompatibleElasticSearchServer(GuiceJamesServer server) throws Exception {
assertThatThrownBy(server::start)
.isInstanceOfSatisfying(
@@ -59,7 +61,7 @@ class JamesWithNonCompatibleElasticSearchServerTest {
.containsOnly(CheckResult.builder()
.checkName(ElasticSearchStartUpCheck.CHECK_NAME)
.resultType(StartUpCheck.ResultType.BAD)
- .description("ES version(2.4.6) is not compatible with the recommendation(6.3.2)")
+ .description("ES version(6.3.2) is not compatible with the recommendation(7.10.2)")
.build()));
assertThat(server.isStarted())
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 04/32: JAMES-3492 Remove mapping check
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 5f902b104fcc010f1150e58eba312125e2045f18
Author: Lan Khuat <kh...@gmail.com>
AuthorDate: Tue Mar 2 22:19:03 2021 +0700
JAMES-3492 Remove mapping check
The check returns status 200 in ElasticSearch 7, preventing the usage of James custom mapping when creating index.
---
.../apache/james/backends/es/v7/NodeMappingFactory.java | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
index 7ec50bf..6f6b14a 100644
--- a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
+++ b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
@@ -21,10 +21,7 @@ package org.apache.james.backends.es.v7;
import java.io.IOException;
-import org.apache.http.HttpStatus;
-import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -54,15 +51,18 @@ public class NodeMappingFactory {
public static final String IGNORE_ABOVE = "ignore_above";
public static ReactorElasticSearchClient applyMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
- if (!mappingAlreadyExist(client, indexName)) {
+ createMapping(client, indexName, mappingsSources);
+
+ /*if (!mappingAlreadyExist(client, indexName)) {
createMapping(client, indexName, mappingsSources);
- }
+ }*/
return client;
}
+ //TODO: since ElasticSearch version 7 this check does not work anymore. Find another way to check whether mapping exists or not
// ElasticSearch 6.3.2 does not support field master_timeout that is set up by 6.4.3 REST client when relying on getMapping
@SuppressWarnings("deprecation")
- public static boolean mappingAlreadyExist(ReactorElasticSearchClient client, IndexName indexName) throws IOException {
+ /*public static boolean mappingAlreadyExist(ReactorElasticSearchClient client, IndexName indexName) throws IOException {
try {
client.getLowLevelClient().performRequest(new Request("GET", "/" + indexName.getValue() + "/_mapping/"));
return true;
@@ -72,7 +72,7 @@ public class NodeMappingFactory {
}
}
return false;
- }
+ }*/
public static void createMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
client.indices().putMapping(
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 15/32: JAMES-3492, switch to elasticsearch 7 in poms
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 0e3e8a1b123613378ca4ff500e85acfac1d621bd
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Wed Mar 10 19:58:09 2021 +0200
JAMES-3492, switch to elasticsearch 7 in poms
---
mailbox/elasticsearch/pom.xml | 4 ++--
mpt/impl/smtp/cassandra-rabbitmq-object-storage/pom.xml | 2 +-
mpt/impl/smtp/cassandra/pom.xml | 2 +-
server/container/guice/cassandra-rabbitmq-guice/pom.xml | 2 +-
.../rabbitmq-jmap-draft-integration-testing/pom.xml | 2 +-
.../distributed-jmap-rfc-8621-integration-tests/pom.xml | 2 +-
.../distributed-webadmin-integration-test/pom.xml | 2 +-
.../webadmin-integration-test-common/pom.xml | 2 +-
8 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/mailbox/elasticsearch/pom.xml b/mailbox/elasticsearch/pom.xml
index c52c8bd..8602d5c 100644
--- a/mailbox/elasticsearch/pom.xml
+++ b/mailbox/elasticsearch/pom.xml
@@ -34,11 +34,11 @@
<dependencies>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/mpt/impl/smtp/cassandra-rabbitmq-object-storage/pom.xml b/mpt/impl/smtp/cassandra-rabbitmq-object-storage/pom.xml
index 8996b73..5836f1d 100644
--- a/mpt/impl/smtp/cassandra-rabbitmq-object-storage/pom.xml
+++ b/mpt/impl/smtp/cassandra-rabbitmq-object-storage/pom.xml
@@ -39,7 +39,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/mpt/impl/smtp/cassandra/pom.xml b/mpt/impl/smtp/cassandra/pom.xml
index 275c43a..db2a28a 100644
--- a/mpt/impl/smtp/cassandra/pom.xml
+++ b/mpt/impl/smtp/cassandra/pom.xml
@@ -39,7 +39,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/container/guice/cassandra-rabbitmq-guice/pom.xml b/server/container/guice/cassandra-rabbitmq-guice/pom.xml
index 31e15b3..cb1675a 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/pom.xml
+++ b/server/container/guice/cassandra-rabbitmq-guice/pom.xml
@@ -65,7 +65,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
index 3b44dc8..1b87ea7 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
@@ -23,7 +23,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml
index 2018d3a..64f7b6a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/pom.xml
@@ -38,7 +38,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml
index 0e8522b..5e62c86 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/pom.xml
@@ -47,7 +47,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/protocols/webadmin-integration-test/webadmin-integration-test-common/pom.xml b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/pom.xml
index 26a984c..60c0728 100644
--- a/server/protocols/webadmin-integration-test/webadmin-integration-test-common/pom.xml
+++ b/server/protocols/webadmin-integration-test/webadmin-integration-test-common/pom.xml
@@ -35,7 +35,7 @@
<dependencies>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
</dependency>
<dependency>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 17/32: JAMES-3492,
change ElasticSearchStartUpCheck.java to use v7
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 12727050a801d717b87e84ac40c4c95763a796c3
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Wed Mar 10 20:02:22 2021 +0200
JAMES-3492, change ElasticSearchStartUpCheck.java to use v7
---
.../modules/mailbox/ElasticSearchStartUpCheck.java | 31 +++++++++++-----------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java
index fc18c3d..8ee50b2 100644
--- a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java
+++ b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java
@@ -28,7 +28,6 @@ import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.lifecycle.api.StartUpCheck;
import org.elasticsearch.Version;
import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.core.MainResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,7 +35,7 @@ public class ElasticSearchStartUpCheck implements StartUpCheck {
private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchConfiguration.class);
- private static final Version RECOMMENDED_ES_VERSION = Version.fromString("6.3.2");
+ private static final Version RECOMMENDED_ES_VERSION = Version.V_7_10_2;
private static final String VERSION_CHECKING_ERROR_MESSAGE = "Error when checking ES version";
public static final String CHECK_NAME = "ElasticSearchStartUpCheck";
@@ -51,25 +50,27 @@ public class ElasticSearchStartUpCheck implements StartUpCheck {
@Override
public CheckResult check() {
try {
- MainResponse.Version esVersion = client.info(RequestOptions.DEFAULT)
- .getVersion();
+ Version esVersion = Version.fromString(client.info(RequestOptions.DEFAULT).getVersion().getNumber());
+
+ if (esVersion.isCompatible(RECOMMENDED_ES_VERSION)) {
return CheckResult.builder()
.checkName(checkName())
.resultType(ResultType.GOOD)
.build();
+ }
+
+ String esVersionCompatibilityWarn = String.format(
+ "ES version(%s) is not compatible with the recommendation(%s)",
+ esVersion.toString(),
+ RECOMMENDED_ES_VERSION.toString());
+ LOGGER.warn(esVersionCompatibilityWarn);
-// String esVersionCompatibilityWarn = String.format(
-// "ES version(%s) is not compatible with the recommendation(%s)",
-// esVersion.toString(),
-// RECOMMENDED_ES_VERSION.toString());
-// LOGGER.warn(esVersionCompatibilityWarn);
-//
-// return CheckResult.builder()
-// .checkName(checkName())
-// .resultType(ResultType.BAD)
-// .description(esVersionCompatibilityWarn)
-// .build();
+ return CheckResult.builder()
+ .checkName(checkName())
+ .resultType(ResultType.BAD)
+ .description(esVersionCompatibilityWarn)
+ .build();
} catch (IOException e) {
LOGGER.error(VERSION_CHECKING_ERROR_MESSAGE, e);
return CheckResult.builder()
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 06/32: JAMES-3492 Search no longer need to fetch
individual fields
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 92c9d58d0ccd365678f7e3fa8772469d8b8df9b4
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Wed Mar 3 14:53:59 2021 +0700
JAMES-3492 Search no longer need to fetch individual fields
The fields are stored within the document and can be fetched with storedFields option.
---
.../james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java | 5 -----
1 file changed, 5 deletions(-)
diff --git a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java
index 5522ba6..393c743 100644
--- a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java
+++ b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/search/ElasticSearchSearcher.java
@@ -25,7 +25,6 @@ import java.util.Collection;
import java.util.Optional;
import org.apache.james.backends.es.v7.AliasName;
-import org.apache.james.backends.es.v7.NodeMappingFactory;
import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.backends.es.v7.ReadAliasName;
import org.apache.james.backends.es.v7.RoutingKey;
@@ -81,7 +80,6 @@ public class ElasticSearchSearcher {
public Flux<MessageSearchIndex.SearchResult> search(Collection<MailboxId> mailboxIds, SearchQuery query,
Optional<Integer> limit) {
SearchRequest searchRequest = prepareSearch(mailboxIds, query, limit);
- System.out.println(searchRequest.toString());
Flux<MessageSearchIndex.SearchResult> pairStream = new ScrolledSearch(client, searchRequest)
.searchHits()
.map(this::extractContentFromHit)
@@ -95,9 +93,6 @@ public class ElasticSearchSearcher {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.query(queryConverter.from(mailboxIds, query))
.size(computeRequiredSize(limit))
- .fetchField(JsonMessageConstants.MAILBOX_ID)
- .fetchField(JsonMessageConstants.UID)
- .fetchField(JsonMessageConstants.MESSAGE_ID)
.storedFields(STORED_FIELDS);
query.getSorts()
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 01/32: JAMES-3492,
switch to elasticsearch 7 in guice modules
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit a8ae07476d944297ffd5f626ab4f59932c844021
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Tue Mar 9 08:37:11 2021 +0200
JAMES-3492, switch to elasticsearch 7 in guice modules
---
.../servers/pages/distributed/operate/guide.adoc | 2 +-
mpt/impl/imap-mailbox/elasticsearch/pom.xml | 6 ++---
.../host/ElasticSearchHostSystem.java | 28 +++++++++----------
pom.xml | 16 +++++++++++
server/container/guice/cassandra-guice/pom.xml | 4 +--
.../apache/james/DockerElasticSearchExtension.java | 6 ++---
.../org/apache/james/DockerElasticSearchRule.java | 4 +--
.../test/java/org/apache/james/ESReporterTest.java | 2 +-
...esWithNonCompatibleElasticSearchServerTest.java | 2 +-
.../modules/TestDockerElasticSearchModule.java | 4 +--
.../container/guice/cassandra-ldap-guice/pom.xml | 2 +-
.../guice/cassandra-rabbitmq-guice/pom.xml | 2 +-
.../guice/cassandra-rabbitmq-ldap-guice/pom.xml | 2 +-
server/container/guice/cassandra/pom.xml | 2 +-
server/container/guice/elasticsearch/pom.xml | 4 +--
.../modules/mailbox/ElasticSearchClientModule.java | 12 ++++-----
.../mailbox/ElasticSearchMailboxModule.java | 26 +++++++++---------
.../mailbox/ElasticSearchQuotaSearcherModule.java | 18 ++++++-------
.../modules/mailbox/ElasticSearchStartUpCheck.java | 31 +++++++++++-----------
...RabbitMQReindexingWithEventDeadLettersTest.java | 2 +-
server/protocols/webadmin/webadmin-mailbox/pom.xml | 6 ++---
.../routes/ElasticSearchQuotaSearchExtension.java | 22 +++++++--------
.../james/webadmin/routes/MailboxesRoutesTest.java | 27 +++++++++----------
.../webadmin/routes/UserMailboxesRoutesTest.java | 27 +++++++++----------
.../server/manage-guice-distributed-james.md | 2 +-
25 files changed, 137 insertions(+), 122 deletions(-)
diff --git a/docs/modules/servers/pages/distributed/operate/guide.adoc b/docs/modules/servers/pages/distributed/operate/guide.adoc
index e7029ab..c2e5c4d 100644
--- a/docs/modules/servers/pages/distributed/operate/guide.adoc
+++ b/docs/modules/servers/pages/distributed/operate/guide.adoc
@@ -137,7 +137,7 @@ Currently, an administrator can monitor indexation failures through
`ERROR` log review. You can as well
xref:distributed/operate/webadmin.adoc#_listing_failed_events[list failed events] by
looking with the group called
-`org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex$ElasticSearchListeningMessageSearchIndexGroup`.
+`org.apache.james.mailbox.elasticsearch.v7.events.ElasticSearchListeningMessageSearchIndex$ElasticSearchListeningMessageSearchIndexGroup`.
A first on-the-fly solution could be to just
link:#_mailbox_event_bus[redeliver those group events with event dead letter].
diff --git a/mpt/impl/imap-mailbox/elasticsearch/pom.xml b/mpt/impl/imap-mailbox/elasticsearch/pom.xml
index 7b6fc3a..f9fd93e 100644
--- a/mpt/impl/imap-mailbox/elasticsearch/pom.xml
+++ b/mpt/impl/imap-mailbox/elasticsearch/pom.xml
@@ -33,11 +33,11 @@
<dependencies>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
@@ -52,7 +52,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
diff --git a/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java b/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java
index 233fb26..454c469 100644
--- a/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java
+++ b/mpt/impl/imap-mailbox/elasticsearch/src/test/java/org/apache/james/mpt/imapmailbox/elasticsearch/host/ElasticSearchHostSystem.java
@@ -23,11 +23,11 @@ import java.io.IOException;
import java.time.ZoneId;
import org.apache.commons.lang3.NotImplementedException;
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.backends.es.DockerElasticSearchSingleton;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.DockerElasticSearch;
+import org.apache.james.backends.es.v7.DockerElasticSearchSingleton;
+import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v7.ElasticSearchIndexer;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.core.quota.QuotaCountLimit;
import org.apache.james.core.quota.QuotaSizeLimit;
import org.apache.james.imap.api.process.ImapProcessor;
@@ -35,15 +35,15 @@ import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
import org.apache.james.imap.main.DefaultImapDecoderFactory;
import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
-import org.apache.james.mailbox.elasticsearch.MailboxIdRoutingKeyFactory;
-import org.apache.james.mailbox.elasticsearch.MailboxIndexCreationUtil;
-import org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex;
-import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
-import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
+import org.apache.james.mailbox.elasticsearch.v7.IndexAttachments;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxElasticSearchConstants;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIdRoutingKeyFactory;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIndexCreationUtil;
+import org.apache.james.mailbox.elasticsearch.v7.events.ElasticSearchListeningMessageSearchIndex;
+import org.apache.james.mailbox.elasticsearch.v7.json.MessageToElasticSearchJson;
+import org.apache.james.mailbox.elasticsearch.v7.query.CriterionConverter;
+import org.apache.james.mailbox.elasticsearch.v7.query.QueryConverter;
+import org.apache.james.mailbox.elasticsearch.v7.search.ElasticSearchSearcher;
import org.apache.james.mailbox.inmemory.InMemoryId;
import org.apache.james.mailbox.inmemory.InMemoryMessageId;
import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
diff --git a/pom.xml b/pom.xml
index deb4087..8443fb2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -765,12 +765,23 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>apache-james-mailbox-elasticsearch</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>apache-james-mailbox-event-json</artifactId>
<version>${project.version}</version>
</dependency>
@@ -841,6 +852,11 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>apache-james-mailbox-quota-search-elasticsearch-v7</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>apache-james-mailbox-quota-search-scanning</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml
index 46e2276..30a45da 100644
--- a/server/container/guice/cassandra-guice/pom.xml
+++ b/server/container/guice/cassandra-guice/pom.xml
@@ -47,7 +47,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
@@ -59,7 +59,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchExtension.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchExtension.java
index 7f76c79..8bf2c3c 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchExtension.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchExtension.java
@@ -22,9 +22,9 @@ package org.apache.james;
import java.time.Duration;
import java.util.Optional;
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.backends.es.DockerElasticSearchSingleton;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v7.DockerElasticSearch;
+import org.apache.james.backends.es.v7.DockerElasticSearchSingleton;
+import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
import org.junit.jupiter.api.extension.ExtensionContext;
import com.google.inject.Module;
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java
index 18d0ad8..3e1fc7a 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerElasticSearchRule.java
@@ -19,8 +19,8 @@
package org.apache.james;
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.backends.es.DockerElasticSearchSingleton;
+import org.apache.james.backends.es.v7.DockerElasticSearch;
+import org.apache.james.backends.es.v7.DockerElasticSearchSingleton;
import org.apache.james.modules.TestDockerElasticSearchModule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
index 5326a4f..d8ecc21 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/ESReporterTest.java
@@ -34,7 +34,7 @@ import java.util.TimerTask;
import java.util.stream.Collectors;
import org.apache.commons.net.imap.IMAPClient;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.core.Username;
import org.apache.james.jmap.AccessToken;
import org.apache.james.jmap.draft.JmapGuiceProbe;
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
index 8dded5f..6f334d2 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
@@ -22,7 +22,7 @@ package org.apache.james;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import org.apache.james.backends.es.DockerElasticSearch;
+import org.apache.james.backends.es.v7.DockerElasticSearch;
import org.apache.james.lifecycle.api.StartUpCheck;
import org.apache.james.lifecycle.api.StartUpCheck.CheckResult;
import org.apache.james.modules.TestJMAPServerModule;
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerElasticSearchModule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerElasticSearchModule.java
index fe87e53..20c2b43 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerElasticSearchModule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerElasticSearchModule.java
@@ -20,8 +20,8 @@
package org.apache.james.modules;
import org.apache.james.CleanupTasksPerformer;
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v7.DockerElasticSearch;
+import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
diff --git a/server/container/guice/cassandra-ldap-guice/pom.xml b/server/container/guice/cassandra-ldap-guice/pom.xml
index 6308431..0b9e06a 100644
--- a/server/container/guice/cassandra-ldap-guice/pom.xml
+++ b/server/container/guice/cassandra-ldap-guice/pom.xml
@@ -47,7 +47,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/container/guice/cassandra-rabbitmq-guice/pom.xml b/server/container/guice/cassandra-rabbitmq-guice/pom.xml
index 030958f..31e15b3 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/pom.xml
+++ b/server/container/guice/cassandra-rabbitmq-guice/pom.xml
@@ -47,7 +47,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/container/guice/cassandra-rabbitmq-ldap-guice/pom.xml b/server/container/guice/cassandra-rabbitmq-ldap-guice/pom.xml
index b59aeff..a0ea947 100644
--- a/server/container/guice/cassandra-rabbitmq-ldap-guice/pom.xml
+++ b/server/container/guice/cassandra-rabbitmq-ldap-guice/pom.xml
@@ -39,7 +39,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/container/guice/cassandra/pom.xml b/server/container/guice/cassandra/pom.xml
index e738aa6..909c120 100644
--- a/server/container/guice/cassandra/pom.xml
+++ b/server/container/guice/cassandra/pom.xml
@@ -47,7 +47,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
diff --git a/server/container/guice/elasticsearch/pom.xml b/server/container/guice/elasticsearch/pom.xml
index 2e77882..9084f82 100644
--- a/server/container/guice/elasticsearch/pom.xml
+++ b/server/container/guice/elasticsearch/pom.xml
@@ -41,11 +41,11 @@
<dependencies>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-quota-search-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-quota-search-elasticsearch-v7</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
diff --git a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchClientModule.java b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchClientModule.java
index ed9b27e..ae2a18c 100644
--- a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchClientModule.java
+++ b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchClientModule.java
@@ -21,13 +21,13 @@ package org.apache.james.modules.mailbox;
import java.util.Set;
-import org.apache.james.backends.es.ClientProvider;
-import org.apache.james.backends.es.ElasticSearchHealthCheck;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.ClientProvider;
+import org.apache.james.backends.es.v7.ElasticSearchHealthCheck;
+import org.apache.james.backends.es.v7.IndexName;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.core.healthcheck.HealthCheck;
-import org.apache.james.mailbox.elasticsearch.ElasticSearchMailboxConfiguration;
-import org.apache.james.quota.search.elasticsearch.ElasticSearchQuotaConfiguration;
+import org.apache.james.mailbox.elasticsearch.v7.ElasticSearchMailboxConfiguration;
+import org.apache.james.quota.search.elasticsearch.v7.ElasticSearchQuotaConfiguration;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
diff --git a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
index d3ebf15..4efe117 100644
--- a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
+++ b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
@@ -19,7 +19,7 @@
package org.apache.james.modules.mailbox;
-import static org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher.DEFAULT_SEARCH_SIZE;
+import static org.apache.james.mailbox.elasticsearch.v7.search.ElasticSearchSearcher.DEFAULT_SEARCH_SIZE;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -30,21 +30,21 @@ import javax.inject.Singleton;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.backends.es.RoutingKey;
+import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v7.ElasticSearchIndexer;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.RoutingKey;
import org.apache.james.events.EventListener;
import org.apache.james.lifecycle.api.StartUpCheck;
import org.apache.james.lifecycle.api.Startable;
-import org.apache.james.mailbox.elasticsearch.ElasticSearchMailboxConfiguration;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
-import org.apache.james.mailbox.elasticsearch.MailboxIdRoutingKeyFactory;
-import org.apache.james.mailbox.elasticsearch.MailboxIndexCreationUtil;
-import org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
+import org.apache.james.mailbox.elasticsearch.v7.ElasticSearchMailboxConfiguration;
+import org.apache.james.mailbox.elasticsearch.v7.IndexAttachments;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxElasticSearchConstants;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIdRoutingKeyFactory;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIndexCreationUtil;
+import org.apache.james.mailbox.elasticsearch.v7.events.ElasticSearchListeningMessageSearchIndex;
+import org.apache.james.mailbox.elasticsearch.v7.query.QueryConverter;
+import org.apache.james.mailbox.elasticsearch.v7.search.ElasticSearchSearcher;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
diff --git a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
index 3019d97..ad5c19d 100644
--- a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
+++ b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
@@ -28,18 +28,18 @@ import javax.inject.Inject;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v7.ElasticSearchIndexer;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.events.EventListener;
import org.apache.james.lifecycle.api.Startable;
import org.apache.james.quota.search.QuotaSearcher;
-import org.apache.james.quota.search.elasticsearch.ElasticSearchQuotaConfiguration;
-import org.apache.james.quota.search.elasticsearch.ElasticSearchQuotaSearcher;
-import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
-import org.apache.james.quota.search.elasticsearch.UserRoutingKeyFactory;
-import org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
-import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
+import org.apache.james.quota.search.elasticsearch.v7.ElasticSearchQuotaConfiguration;
+import org.apache.james.quota.search.elasticsearch.v7.ElasticSearchQuotaSearcher;
+import org.apache.james.quota.search.elasticsearch.v7.QuotaSearchIndexCreationUtil;
+import org.apache.james.quota.search.elasticsearch.v7.UserRoutingKeyFactory;
+import org.apache.james.quota.search.elasticsearch.v7.events.ElasticSearchQuotaMailboxListener;
+import org.apache.james.quota.search.elasticsearch.v7.json.QuotaRatioToElasticSearchJson;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.PropertiesProvider;
diff --git a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java
index 3565b38..fc18c3d 100644
--- a/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java
+++ b/server/container/guice/elasticsearch/src/main/java/org/apache/james/modules/mailbox/ElasticSearchStartUpCheck.java
@@ -23,11 +23,12 @@ import java.io.IOException;
import javax.inject.Inject;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.lifecycle.api.StartUpCheck;
import org.elasticsearch.Version;
import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.core.MainResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,25 +51,25 @@ public class ElasticSearchStartUpCheck implements StartUpCheck {
@Override
public CheckResult check() {
try {
- Version esVersion = client.info(RequestOptions.DEFAULT)
+ MainResponse.Version esVersion = client.info(RequestOptions.DEFAULT)
.getVersion();
- if (esVersion.isCompatible(RECOMMENDED_ES_VERSION)) {
+
return CheckResult.builder()
.checkName(checkName())
.resultType(ResultType.GOOD)
.build();
- }
- String esVersionCompatibilityWarn = String.format(
- "ES version(%s) is not compatible with the recommendation(%s)",
- esVersion.toString(),
- RECOMMENDED_ES_VERSION.toString());
- LOGGER.warn(esVersionCompatibilityWarn);
- return CheckResult.builder()
- .checkName(checkName())
- .resultType(ResultType.BAD)
- .description(esVersionCompatibilityWarn)
- .build();
+// String esVersionCompatibilityWarn = String.format(
+// "ES version(%s) is not compatible with the recommendation(%s)",
+// esVersion.toString(),
+// RECOMMENDED_ES_VERSION.toString());
+// LOGGER.warn(esVersionCompatibilityWarn);
+//
+// return CheckResult.builder()
+// .checkName(checkName())
+// .resultType(ResultType.BAD)
+// .description(esVersionCompatibilityWarn)
+// .build();
} catch (IOException e) {
LOGGER.error(VERSION_CHECKING_ERROR_MESSAGE, e);
return CheckResult.builder()
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java
index 9c3c5fc..5252864 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java
@@ -69,7 +69,7 @@ import io.restassured.specification.RequestSpecification;
@Tag(BasicFeature.TAG)
class RabbitMQReindexingWithEventDeadLettersTest {
- private static final String ELASTICSEARCH_LISTENER_GROUP = "org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex$ElasticSearchListeningMessageSearchIndexGroup";
+ private static final String ELASTICSEARCH_LISTENER_GROUP = "org.apache.james.mailbox.elasticsearch.v7.events.ElasticSearchListeningMessageSearchIndex$ElasticSearchListeningMessageSearchIndexGroup";
private static final ConditionFactory CALMLY_AWAIT = Awaitility
.with().pollInterval(Duration.ofMillis(100))
diff --git a/server/protocols/webadmin/webadmin-mailbox/pom.xml b/server/protocols/webadmin/webadmin-mailbox/pom.xml
index 49a9372..19b2d6b 100644
--- a/server/protocols/webadmin/webadmin-mailbox/pom.xml
+++ b/server/protocols/webadmin/webadmin-mailbox/pom.xml
@@ -35,7 +35,7 @@
<dependencies>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
+ <artifactId>apache-james-backends-es-v7</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
@@ -51,7 +51,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-elasticsearch-v7</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
@@ -80,7 +80,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-quota-search-elasticsearch</artifactId>
+ <artifactId>apache-james-mailbox-quota-search-elasticsearch-v7</artifactId>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java
index dbfbde3..e926a57 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ElasticSearchQuotaSearchExtension.java
@@ -23,23 +23,23 @@ import static org.mockito.Mockito.mock;
import java.io.IOException;
-import org.apache.james.backends.es.DockerElasticSearch;
-import org.apache.james.backends.es.DockerElasticSearchSingleton;
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.DockerElasticSearch;
+import org.apache.james.backends.es.v7.DockerElasticSearchSingleton;
+import org.apache.james.backends.es.v7.ElasticSearchConfiguration;
+import org.apache.james.backends.es.v7.ElasticSearchIndexer;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.dnsservice.api.DNSService;
import org.apache.james.domainlist.lib.DomainListConfiguration;
import org.apache.james.domainlist.memory.MemoryDomainList;
import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
import org.apache.james.mailbox.store.quota.QuotaComponents;
import org.apache.james.quota.search.QuotaSearchTestSystem;
-import org.apache.james.quota.search.elasticsearch.ElasticSearchQuotaSearcher;
-import org.apache.james.quota.search.elasticsearch.QuotaRatioElasticSearchConstants;
-import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
-import org.apache.james.quota.search.elasticsearch.UserRoutingKeyFactory;
-import org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
-import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
+import org.apache.james.quota.search.elasticsearch.v7.ElasticSearchQuotaSearcher;
+import org.apache.james.quota.search.elasticsearch.v7.QuotaRatioElasticSearchConstants;
+import org.apache.james.quota.search.elasticsearch.v7.QuotaSearchIndexCreationUtil;
+import org.apache.james.quota.search.elasticsearch.v7.UserRoutingKeyFactory;
+import org.apache.james.quota.search.elasticsearch.v7.events.ElasticSearchQuotaMailboxListener;
+import org.apache.james.quota.search.elasticsearch.v7.json.QuotaRatioToElasticSearchJson;
import org.apache.james.user.memory.MemoryUsersRepository;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
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 412e21b..232c3af 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
@@ -41,24 +41,24 @@ import java.util.List;
import javax.mail.Flags;
-import org.apache.james.backends.es.DockerElasticSearchExtension;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.DockerElasticSearchExtension;
+import org.apache.james.backends.es.v7.ElasticSearchIndexer;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.core.Username;
import org.apache.james.json.DTOConverter;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageIdManager;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
-import org.apache.james.mailbox.elasticsearch.MailboxIdRoutingKeyFactory;
-import org.apache.james.mailbox.elasticsearch.MailboxIndexCreationUtil;
-import org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex;
-import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
-import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
+import org.apache.james.mailbox.elasticsearch.v7.IndexAttachments;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxElasticSearchConstants;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIdRoutingKeyFactory;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIndexCreationUtil;
+import org.apache.james.mailbox.elasticsearch.v7.events.ElasticSearchListeningMessageSearchIndex;
+import org.apache.james.mailbox.elasticsearch.v7.json.MessageToElasticSearchJson;
+import org.apache.james.mailbox.elasticsearch.v7.query.CriterionConverter;
+import org.apache.james.mailbox.elasticsearch.v7.query.QueryConverter;
+import org.apache.james.mailbox.elasticsearch.v7.search.ElasticSearchSearcher;
import org.apache.james.mailbox.indexer.ReIndexer;
import org.apache.james.mailbox.inmemory.InMemoryId;
import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
@@ -144,8 +144,7 @@ class MailboxesRoutesTest {
.listeningSearchIndex(preInstanciationStage -> new ElasticSearchListeningMessageSearchIndex(
preInstanciationStage.getMapperFactory(),
new ElasticSearchIndexer(client,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS,
- BATCH_SIZE),
+ MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS),
new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE,
new InMemoryId.Factory(), messageIdFactory,
MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, routingKeyFactory),
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 2f80567..6468333 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
@@ -52,9 +52,9 @@ import java.util.Map;
import javax.mail.Flags;
-import org.apache.james.backends.es.DockerElasticSearchExtension;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
+import org.apache.james.backends.es.v7.DockerElasticSearchExtension;
+import org.apache.james.backends.es.v7.ElasticSearchIndexer;
+import org.apache.james.backends.es.v7.ReactorElasticSearchClient;
import org.apache.james.core.Username;
import org.apache.james.json.DTOConverter;
import org.apache.james.mailbox.MailboxManager;
@@ -63,15 +63,15 @@ import org.apache.james.mailbox.MailboxSessionUtil;
import org.apache.james.mailbox.MessageIdManager;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
-import org.apache.james.mailbox.elasticsearch.MailboxIdRoutingKeyFactory;
-import org.apache.james.mailbox.elasticsearch.MailboxIndexCreationUtil;
-import org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex;
-import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
-import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
+import org.apache.james.mailbox.elasticsearch.v7.IndexAttachments;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxElasticSearchConstants;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIdRoutingKeyFactory;
+import org.apache.james.mailbox.elasticsearch.v7.MailboxIndexCreationUtil;
+import org.apache.james.mailbox.elasticsearch.v7.events.ElasticSearchListeningMessageSearchIndex;
+import org.apache.james.mailbox.elasticsearch.v7.json.MessageToElasticSearchJson;
+import org.apache.james.mailbox.elasticsearch.v7.query.CriterionConverter;
+import org.apache.james.mailbox.elasticsearch.v7.query.QueryConverter;
+import org.apache.james.mailbox.elasticsearch.v7.search.ElasticSearchSearcher;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxExistsException;
import org.apache.james.mailbox.exception.MailboxNotFoundException;
@@ -1183,8 +1183,7 @@ class UserMailboxesRoutesTest {
.listeningSearchIndex(preInstanciationStage -> new ElasticSearchListeningMessageSearchIndex(
preInstanciationStage.getMapperFactory(),
new ElasticSearchIndexer(client,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS,
- BATCH_SIZE),
+ MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS),
new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE,
new InMemoryId.Factory(), messageIdFactory,
MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, routingKeyFactory),
diff --git a/src/site/markdown/server/manage-guice-distributed-james.md b/src/site/markdown/server/manage-guice-distributed-james.md
index efc7f43..a1bd770 100644
--- a/src/site/markdown/server/manage-guice-distributed-james.md
+++ b/src/site/markdown/server/manage-guice-distributed-james.md
@@ -225,7 +225,7 @@ As explained in the [Mailbox Event Bus](#Mailbox_Event_Bus) section, processing
Currently, an administrator can monitor indexation failures through `ERROR` log review. You can as well
[list failed events](manage-webadmin.html#Listing_failed_events) by looking with the group called
-`org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex$ElasticSearchListeningMessageSearchIndexGroup`.
+`org.apache.james.mailbox.elasticsearch.v7.events.ElasticSearchListeningMessageSearchIndex$ElasticSearchListeningMessageSearchIndexGroup`.
A first on-the-fly solution could be to just
[redeliver those group events with event dead letter](#Mailbox_Event_Bus).
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 21/32: JAMES-3502, was using old elastic module
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit a825edb6a8f45cff427ca63c827085ab59ca4969
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Thu Mar 11 10:24:49 2021 +0200
JAMES-3502, was using old elastic module
---
mailbox/elasticsearch/pom.xml | 172 ---
.../ElasticSearchMailboxConfiguration.java | 178 ---
.../mailbox/elasticsearch/IndexAttachments.java | 24 -
.../MailboxElasticSearchConstants.java | 35 -
.../elasticsearch/MailboxIdRoutingKeyFactory.java | 30 -
.../elasticsearch/MailboxIndexCreationUtil.java | 56 -
.../elasticsearch/MailboxMappingFactory.java | 318 -----
.../ElasticSearchListeningMessageSearchIndex.java | 261 ----
.../james/mailbox/elasticsearch/json/EMailer.java | 76 --
.../james/mailbox/elasticsearch/json/EMailers.java | 52 -
.../elasticsearch/json/HeaderCollection.java | 260 ----
.../elasticsearch/json/IndexableMessage.java | 411 -------
.../elasticsearch/json/JsonMessageConstants.java | 76 --
.../json/MessageToElasticSearchJson.java | 85 --
.../elasticsearch/json/MessageUpdateJson.java | 81 --
.../james/mailbox/elasticsearch/json/MimePart.java | 310 -----
.../json/MimePartContainerBuilder.java | 52 -
.../mailbox/elasticsearch/json/MimePartParser.java | 144 ---
.../json/RootMimePartContainerBuilder.java | 98 --
.../elasticsearch/json/SerializableMessage.java | 25 -
.../james/mailbox/elasticsearch/json/Subjects.java | 50 -
.../elasticsearch/query/CriterionConverter.java | 303 -----
.../query/DateResolutionFormatter.java | 69 --
.../elasticsearch/query/QueryConverter.java | 79 --
.../mailbox/elasticsearch/query/SortConverter.java | 75 --
.../search/ElasticSearchSearcher.java | 153 ---
mailbox/elasticsearch/src/reporting-site/site.xml | 29 -
.../ElasticSearchIntegrationTest.java | 402 -------
.../ElasticSearchMailboxConfigurationTest.java | 227 ----
.../MailboxIdRoutingKeyFactoryTest.java | 34 -
...asticSearchListeningMessageSearchIndexTest.java | 457 -------
.../mailbox/elasticsearch/json/EMailerTest.java | 32 -
.../mailbox/elasticsearch/json/EMailersTest.java | 68 --
.../mailbox/elasticsearch/json/FieldImpl.java | 65 -
.../elasticsearch/json/HeaderCollectionTest.java | 328 -----
.../elasticsearch/json/IndexableMessageTest.java | 307 -----
.../json/MessageToElasticSearchJsonTest.java | 425 -------
.../mailbox/elasticsearch/json/MimePartTest.java | 52 -
.../mailbox/elasticsearch/json/SubjectsTest.java | 66 -
.../query/DateResolutionFormatterTest.java | 75 --
.../elasticsearch/query/SearchQueryTest.java | 68 --
.../search/ElasticSearchSearcherTest.java | 173 ---
.../src/test/resources/eml/bodyMakeTikaToFail.eml | 1272 --------------------
.../test/resources/eml/emailWith3Attachments.eml | 50 -
.../src/test/resources/eml/htmlContent.txt | 26 -
.../test/resources/eml/mailCustomDateHeader.eml | 9 -
.../test/resources/eml/mailCustomStringHeader.eml | 9 -
.../src/test/resources/eml/mailWithHeaders.eml | 14 -
server/container/guice/cassandra-guice/pom.xml | 2 +-
.../modules/TestDockerESMetricReporterModule.java | 2 +-
server/container/guice/es-metric-reporter/pom.xml | 2 +-
.../server/ElasticSearchMetricReporterModule.java | 4 +-
52 files changed, 5 insertions(+), 7666 deletions(-)
diff --git a/mailbox/elasticsearch/pom.xml b/mailbox/elasticsearch/pom.xml
deleted file mode 100644
index c52c8bd..0000000
--- a/mailbox/elasticsearch/pom.xml
+++ /dev/null
@@ -1,172 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.james</groupId>
- <artifactId>apache-james-mailbox</artifactId>
- <version>3.6.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>apache-james-mailbox-elasticsearch</artifactId>
- <name>Apache James :: Mailbox :: ElasticSearch</name>
- <description>Apache James Mailbox IMAP search implementation using ElasticSearch</description>
-
- <dependencies>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-backends-es</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-api</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-memory</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-store</artifactId>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-store</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-tika</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>apache-james-mailbox-tika</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>event-bus-api</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>event-bus-in-vm</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-testing</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>james-server-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>metrics-tests</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${james.groupId}</groupId>
- <artifactId>testing-base</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.datatype</groupId>
- <artifactId>jackson-datatype-guava</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.datatype</groupId>
- <artifactId>jackson-datatype-jdk8</artifactId>
- </dependency>
- <dependency>
- <groupId>com.github.steveash.guavate</groupId>
- <artifactId>guavate</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>com.sun.mail</groupId>
- <artifactId>javax.mail</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- </dependency>
- <dependency>
- <groupId>net.javacrumbs.json-unit</groupId>
- <artifactId>json-unit-assertj</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.awaitility</groupId>
- <artifactId>awaitility</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.testcontainers</groupId>
- <artifactId>testcontainers</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfiguration.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfiguration.java
deleted file mode 100644
index 1e91cdd..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfiguration.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import org.apache.commons.configuration2.Configuration;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
-
-public class ElasticSearchMailboxConfiguration {
-
- public static class Builder {
- private Optional<IndexName> indexMailboxName;
- private Optional<ReadAliasName> readAliasMailboxName;
- private Optional<WriteAliasName> writeAliasMailboxName;
- private Optional<IndexAttachments> indexAttachment;
-
- Builder() {
- indexMailboxName = Optional.empty();
- readAliasMailboxName = Optional.empty();
- writeAliasMailboxName = Optional.empty();
- indexAttachment = Optional.empty();
- }
-
- Builder indexMailboxName(Optional<IndexName> indexMailboxName) {
- this.indexMailboxName = indexMailboxName;
- return this;
- }
-
- Builder readAliasMailboxName(Optional<ReadAliasName> readAliasMailboxName) {
- this.readAliasMailboxName = readAliasMailboxName;
- return this;
- }
-
- Builder writeAliasMailboxName(Optional<WriteAliasName> writeAliasMailboxName) {
- this.writeAliasMailboxName = writeAliasMailboxName;
- return this;
- }
-
-
- Builder indexAttachment(IndexAttachments indexAttachment) {
- this.indexAttachment = Optional.of(indexAttachment);
- return this;
- }
-
-
-
- public ElasticSearchMailboxConfiguration build() {
- return new ElasticSearchMailboxConfiguration(
- indexMailboxName.orElse(MailboxElasticSearchConstants.DEFAULT_MAILBOX_INDEX),
- readAliasMailboxName.orElse(MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS),
- writeAliasMailboxName.orElse(MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS),
- indexAttachment.orElse(IndexAttachments.YES));
- }
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- private static final String ELASTICSEARCH_INDEX_NAME = "elasticsearch.index.name";
- private static final String ELASTICSEARCH_INDEX_MAILBOX_NAME = "elasticsearch.index.mailbox.name";
- private static final String ELASTICSEARCH_ALIAS_READ_NAME = "elasticsearch.alias.read.name";
- private static final String ELASTICSEARCH_ALIAS_WRITE_NAME = "elasticsearch.alias.write.name";
- private static final String ELASTICSEARCH_ALIAS_READ_MAILBOX_NAME = "elasticsearch.alias.read.mailbox.name";
- private static final String ELASTICSEARCH_ALIAS_WRITE_MAILBOX_NAME = "elasticsearch.alias.write.mailbox.name";
- private static final String ELASTICSEARCH_INDEX_ATTACHMENTS = "elasticsearch.indexAttachments";
- private static final boolean DEFAULT_INDEX_ATTACHMENTS = true;
-
- public static final ElasticSearchMailboxConfiguration DEFAULT_CONFIGURATION = builder().build();
-
- public static ElasticSearchMailboxConfiguration fromProperties(Configuration configuration) {
- return builder()
- .indexMailboxName(computeMailboxIndexName(configuration))
- .readAliasMailboxName(computeMailboxReadAlias(configuration))
- .writeAliasMailboxName(computeMailboxWriteAlias(configuration))
- .indexAttachment(provideIndexAttachments(configuration))
- .build();
- }
-
- static Optional<IndexName> computeMailboxIndexName(Configuration configuration) {
- return Optional.ofNullable(configuration.getString(ELASTICSEARCH_INDEX_MAILBOX_NAME))
- .map(IndexName::new)
- .or(() -> Optional.ofNullable(configuration.getString(ELASTICSEARCH_INDEX_NAME))
- .map(IndexName::new));
- }
-
- static Optional<WriteAliasName> computeMailboxWriteAlias(Configuration configuration) {
- return Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_WRITE_MAILBOX_NAME))
- .map(WriteAliasName::new)
- .or(() -> Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_WRITE_NAME))
- .map(WriteAliasName::new));
- }
-
- static Optional<ReadAliasName> computeMailboxReadAlias(Configuration configuration) {
- return Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_READ_MAILBOX_NAME))
- .map(ReadAliasName::new)
- .or(() -> Optional.ofNullable(configuration.getString(ELASTICSEARCH_ALIAS_READ_NAME))
- .map(ReadAliasName::new));
- }
-
-
- private static IndexAttachments provideIndexAttachments(Configuration configuration) {
- if (configuration.getBoolean(ELASTICSEARCH_INDEX_ATTACHMENTS, DEFAULT_INDEX_ATTACHMENTS)) {
- return IndexAttachments.YES;
- }
- return IndexAttachments.NO;
- }
-
-
- private final IndexName indexMailboxName;
- private final ReadAliasName readAliasMailboxName;
- private final WriteAliasName writeAliasMailboxName;
- private final IndexAttachments indexAttachment;
-
- private ElasticSearchMailboxConfiguration(IndexName indexMailboxName, ReadAliasName readAliasMailboxName,
- WriteAliasName writeAliasMailboxName, IndexAttachments indexAttachment) {
- this.indexMailboxName = indexMailboxName;
- this.readAliasMailboxName = readAliasMailboxName;
- this.writeAliasMailboxName = writeAliasMailboxName;
- this.indexAttachment = indexAttachment;
- }
-
-
- public IndexName getIndexMailboxName() {
- return indexMailboxName;
- }
-
- public ReadAliasName getReadAliasMailboxName() {
- return readAliasMailboxName;
- }
-
- public WriteAliasName getWriteAliasMailboxName() {
- return writeAliasMailboxName;
- }
-
- public IndexAttachments getIndexAttachment() {
- return indexAttachment;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof ElasticSearchMailboxConfiguration) {
- ElasticSearchMailboxConfiguration that = (ElasticSearchMailboxConfiguration) o;
-
- return Objects.equals(this.indexAttachment, that.indexAttachment)
- && Objects.equals(this.indexMailboxName, that.indexMailboxName)
- && Objects.equals(this.readAliasMailboxName, that.readAliasMailboxName)
- && Objects.equals(this.writeAliasMailboxName, that.writeAliasMailboxName);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(indexMailboxName, readAliasMailboxName, writeAliasMailboxName, indexAttachment, writeAliasMailboxName);
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/IndexAttachments.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/IndexAttachments.java
deleted file mode 100644
index 9b94a0f..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/IndexAttachments.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-public enum IndexAttachments {
- NO, YES
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticSearchConstants.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticSearchConstants.java
deleted file mode 100644
index b480c5c..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxElasticSearchConstants.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
-
-public interface MailboxElasticSearchConstants {
-
- interface InjectionNames {
- String MAILBOX = "mailbox";
- }
-
- WriteAliasName DEFAULT_MAILBOX_WRITE_ALIAS = new WriteAliasName("mailboxWriteAlias");
- ReadAliasName DEFAULT_MAILBOX_READ_ALIAS = new ReadAliasName("mailboxReadAlias");
- IndexName DEFAULT_MAILBOX_INDEX = new IndexName("mailbox_v1");
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactory.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactory.java
deleted file mode 100644
index 56fc834..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import org.apache.james.backends.es.RoutingKey;
-import org.apache.james.mailbox.model.MailboxId;
-
-public class MailboxIdRoutingKeyFactory implements RoutingKey.Factory<MailboxId> {
- @Override
- public RoutingKey from(MailboxId mailboxId) {
- return RoutingKey.fromString(mailboxId.serialize());
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIndexCreationUtil.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIndexCreationUtil.java
deleted file mode 100644
index 9871600..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxIndexCreationUtil.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import java.io.IOException;
-
-import org.apache.james.backends.es.ElasticSearchConfiguration;
-import org.apache.james.backends.es.IndexCreationFactory;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
-
-public class MailboxIndexCreationUtil {
-
- public static ReactorElasticSearchClient prepareClient(ReactorElasticSearchClient client,
- ReadAliasName readAlias,
- WriteAliasName writeAlias,
- IndexName indexName,
- ElasticSearchConfiguration configuration) throws IOException {
- return NodeMappingFactory.applyMapping(
- new IndexCreationFactory(configuration)
- .useIndex(indexName)
- .addAlias(readAlias)
- .addAlias(writeAlias)
- .createIndexAndAliases(client),
- indexName,
- MailboxMappingFactory.getMappingContent());
- }
-
- public static ReactorElasticSearchClient prepareDefaultClient(ReactorElasticSearchClient client, ElasticSearchConfiguration configuration) throws IOException {
- return prepareClient(client,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_INDEX,
- configuration);
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
deleted file mode 100644
index af9e096..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import static org.apache.james.backends.es.IndexCreationFactory.CASE_INSENSITIVE;
-import static org.apache.james.backends.es.IndexCreationFactory.KEEP_MAIL_AND_URL;
-import static org.apache.james.backends.es.NodeMappingFactory.ANALYZER;
-import static org.apache.james.backends.es.NodeMappingFactory.BOOLEAN;
-import static org.apache.james.backends.es.NodeMappingFactory.FIELDS;
-import static org.apache.james.backends.es.NodeMappingFactory.FORMAT;
-import static org.apache.james.backends.es.NodeMappingFactory.KEYWORD;
-import static org.apache.james.backends.es.NodeMappingFactory.LONG;
-import static org.apache.james.backends.es.NodeMappingFactory.NESTED;
-import static org.apache.james.backends.es.NodeMappingFactory.NORMALIZER;
-import static org.apache.james.backends.es.NodeMappingFactory.PROPERTIES;
-import static org.apache.james.backends.es.NodeMappingFactory.RAW;
-import static org.apache.james.backends.es.NodeMappingFactory.REQUIRED;
-import static org.apache.james.backends.es.NodeMappingFactory.ROUTING;
-import static org.apache.james.backends.es.NodeMappingFactory.SEARCH_ANALYZER;
-import static org.apache.james.backends.es.NodeMappingFactory.TYPE;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.ATTACHMENTS;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.BCC;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.CC;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.DATE;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.FROM;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.HAS_ATTACHMENT;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.HEADERS;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.HTML_BODY;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_ANSWERED;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_DELETED;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_DRAFT;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_FLAGGED;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_RECENT;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_UNREAD;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.MAILBOX_ID;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.MEDIA_TYPE;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.MESSAGE_ID;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.MIME_MESSAGE_ID;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.MODSEQ;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.SENT_DATE;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.SIZE;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.SUBJECT;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.SUBTYPE;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.TEXT;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.TEXT_BODY;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.TO;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.UID;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.USER_FLAGS;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-import java.io.IOException;
-
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.Attachment;
-import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.EMailer;
-import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.HEADER;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-
-public class MailboxMappingFactory {
-
- private static final int MAXIMUM_TERM_LENGTH = 4096;
- private static final String STANDARD = "standard";
- private static final String STORE = "store";
-
- public static XContentBuilder getMappingContent() {
- try {
- return jsonBuilder()
- .startObject()
-
- .field("dynamic", "strict")
-
- .startObject(ROUTING)
- .field(REQUIRED, true)
- .endObject()
-
- .startObject(PROPERTIES)
-
- .startObject(MESSAGE_ID)
- .field(TYPE, KEYWORD)
- .field(STORE, true)
- .endObject()
-
- .startObject(UID)
- .field(TYPE, LONG)
- .field(STORE, true)
- .endObject()
-
- .startObject(MODSEQ)
- .field(TYPE, LONG)
- .endObject()
-
- .startObject(SIZE)
- .field(TYPE, LONG)
- .endObject()
-
- .startObject(IS_ANSWERED)
- .field(TYPE, BOOLEAN)
- .endObject()
-
- .startObject(IS_DELETED)
- .field(TYPE, BOOLEAN)
- .endObject()
-
- .startObject(IS_DRAFT)
- .field(TYPE, BOOLEAN)
- .endObject()
-
- .startObject(IS_FLAGGED)
- .field(TYPE, BOOLEAN)
- .endObject()
-
- .startObject(IS_RECENT)
- .field(TYPE, BOOLEAN)
- .endObject()
-
- .startObject(IS_UNREAD)
- .field(TYPE, BOOLEAN)
- .endObject()
-
- .startObject(DATE)
- .field(TYPE, NodeMappingFactory.DATE)
- .field(FORMAT, "yyyy-MM-dd'T'HH:mm:ssZ")
- .endObject()
-
- .startObject(SENT_DATE)
- .field(TYPE, NodeMappingFactory.DATE)
- .field(FORMAT, "yyyy-MM-dd'T'HH:mm:ssZ")
- .endObject()
-
- .startObject(USER_FLAGS)
- .field(TYPE, KEYWORD)
- .field(NORMALIZER, CASE_INSENSITIVE)
- .endObject()
-
- .startObject(MEDIA_TYPE)
- .field(TYPE, KEYWORD)
- .endObject()
-
- .startObject(SUBTYPE)
- .field(TYPE, KEYWORD)
- .endObject()
-
- .startObject(FROM)
- .startObject(PROPERTIES)
- .startObject(EMailer.NAME)
- .field(TYPE, TEXT)
- .field(ANALYZER, KEEP_MAIL_AND_URL)
- .endObject()
- .startObject(EMailer.ADDRESS)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .field(SEARCH_ANALYZER, KEEP_MAIL_AND_URL)
- .startObject(FIELDS)
- .startObject(RAW)
- .field(TYPE, KEYWORD)
- .field(NORMALIZER, CASE_INSENSITIVE)
- .endObject()
- .endObject()
- .endObject()
- .endObject()
- .endObject()
-
- .startObject(HEADERS)
- .field(TYPE, NESTED)
- .startObject(PROPERTIES)
- .startObject(HEADER.NAME)
- .field(TYPE, KEYWORD)
- .endObject()
- .startObject(HEADER.VALUE)
- .field(TYPE, TEXT)
- .field(ANALYZER, KEEP_MAIL_AND_URL)
- .endObject()
- .endObject()
- .endObject()
-
- .startObject(SUBJECT)
- .field(TYPE, TEXT)
- .field(ANALYZER, KEEP_MAIL_AND_URL)
- .startObject(FIELDS)
- .startObject(RAW)
- .field(TYPE, KEYWORD)
- .field(NORMALIZER, CASE_INSENSITIVE)
- .endObject()
- .endObject()
- .endObject()
-
- .startObject(TO)
- .startObject(PROPERTIES)
- .startObject(EMailer.NAME)
- .field(TYPE, TEXT)
- .field(ANALYZER, KEEP_MAIL_AND_URL)
- .endObject()
- .startObject(EMailer.ADDRESS)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .field(SEARCH_ANALYZER, KEEP_MAIL_AND_URL)
- .startObject(FIELDS)
- .startObject(RAW)
- .field(TYPE, KEYWORD)
- .field(NORMALIZER, CASE_INSENSITIVE)
- .endObject()
- .endObject()
- .endObject()
- .endObject()
- .endObject()
-
- .startObject(CC)
- .startObject(PROPERTIES)
- .startObject(EMailer.NAME)
- .field(TYPE, TEXT)
- .field(ANALYZER, KEEP_MAIL_AND_URL)
- .endObject()
- .startObject(EMailer.ADDRESS)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .field(SEARCH_ANALYZER, KEEP_MAIL_AND_URL)
- .startObject(FIELDS)
- .startObject(RAW)
- .field(TYPE, KEYWORD)
- .field(NORMALIZER, CASE_INSENSITIVE)
- .endObject()
- .endObject()
- .endObject()
- .endObject()
- .endObject()
-
- .startObject(BCC)
- .startObject(PROPERTIES)
- .startObject(EMailer.NAME)
- .field(TYPE, TEXT)
- .field(ANALYZER, KEEP_MAIL_AND_URL)
- .endObject()
- .startObject(EMailer.ADDRESS)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .field(SEARCH_ANALYZER, KEEP_MAIL_AND_URL)
- .startObject(FIELDS)
- .startObject(RAW)
- .field(TYPE, KEYWORD)
- .field(NORMALIZER, CASE_INSENSITIVE)
- .endObject()
- .endObject()
- .endObject()
- .endObject()
- .endObject()
-
- .startObject(MAILBOX_ID)
- .field(TYPE, KEYWORD)
- .field(STORE, true)
- .endObject()
-
- .startObject(MIME_MESSAGE_ID)
- .field(TYPE, KEYWORD)
- .endObject()
-
- .startObject(TEXT_BODY)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .endObject()
-
- .startObject(HTML_BODY)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .endObject()
-
- .startObject(HAS_ATTACHMENT)
- .field(TYPE, BOOLEAN)
- .endObject()
-
- .startObject(ATTACHMENTS)
- .startObject(PROPERTIES)
- .startObject(Attachment.FILENAME)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .endObject()
- .startObject(Attachment.TEXT_CONTENT)
- .field(TYPE, TEXT)
- .field(ANALYZER, STANDARD)
- .endObject()
- .startObject(Attachment.MEDIA_TYPE)
- .field(TYPE, KEYWORD)
- .endObject()
- .startObject(Attachment.SUBTYPE)
- .field(TYPE, KEYWORD)
- .endObject()
- .startObject(Attachment.FILE_EXTENSION)
- .field(TYPE, KEYWORD)
- .endObject()
- .startObject(Attachment.CONTENT_DISPOSITION)
- .field(TYPE, KEYWORD)
- .endObject()
- .endObject()
- .endObject()
-
- .endObject()
- .endObject();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
deleted file mode 100644
index 244189c..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.mailbox.elasticsearch.events;
-
-import static com.github.steveash.guavate.Guavate.toImmutableList;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_ANSWERED;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_DELETED;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_DRAFT;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_FLAGGED;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_RECENT;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.IS_UNREAD;
-import static org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.MAILBOX_ID;
-import static org.apache.james.util.ReactorUtils.publishIfPresent;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.mail.Flags;
-
-import org.apache.james.backends.es.DocumentId;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.RoutingKey;
-import org.apache.james.backends.es.UpdatedRepresentation;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.FlagsBuilder;
-import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
-import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
-import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
-import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
-import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.mailbox.model.UpdatedFlags;
-import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.index.query.TermQueryBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.github.fge.lambdas.Throwing;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSearchIndex {
- private static final int FLAGS_UPDATE_PROCESSING_WINDOW_SIZE = 32;
-
- public static class ElasticSearchListeningMessageSearchIndexGroup extends Group {
-
- }
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchListeningMessageSearchIndex.class);
- private static final String ID_SEPARATOR = ":";
- private static final Group GROUP = new ElasticSearchListeningMessageSearchIndexGroup();
-
- private final ElasticSearchIndexer elasticSearchIndexer;
- private final ElasticSearchSearcher searcher;
- private final MessageToElasticSearchJson messageToElasticSearchJson;
- private final RoutingKey.Factory<MailboxId> routingKeyFactory;
-
- @Inject
- public ElasticSearchListeningMessageSearchIndex(MailboxSessionMapperFactory factory,
- @Named(MailboxElasticSearchConstants.InjectionNames.MAILBOX) ElasticSearchIndexer indexer,
- ElasticSearchSearcher searcher, MessageToElasticSearchJson messageToElasticSearchJson,
- SessionProvider sessionProvider, RoutingKey.Factory<MailboxId> routingKeyFactory) {
- super(factory, sessionProvider);
- this.elasticSearchIndexer = indexer;
- this.messageToElasticSearchJson = messageToElasticSearchJson;
- this.searcher = searcher;
- this.routingKeyFactory = routingKeyFactory;
- }
-
- @Override
- public Group getDefaultGroup() {
- return GROUP;
- }
-
- @Override
- public EnumSet<SearchCapabilities> getSupportedCapabilities(EnumSet<MessageCapabilities> messageCapabilities) {
- return EnumSet.of(
- SearchCapabilities.MultimailboxSearch,
- SearchCapabilities.Text,
- SearchCapabilities.FullText,
- SearchCapabilities.Attachment,
- SearchCapabilities.AttachmentFileName,
- SearchCapabilities.PartialEmailMatch);
- }
-
- @Override
- public Flux<MessageUid> search(MailboxSession session, Mailbox mailbox, SearchQuery searchQuery) {
- Preconditions.checkArgument(session != null, "'session' is mandatory");
- Optional<Integer> noLimit = Optional.empty();
-
- return searcher
- .search(ImmutableList.of(mailbox.getMailboxId()), searchQuery, noLimit)
- .map(SearchResult::getMessageUid);
- }
-
- @Override
- public Flux<MessageId> search(MailboxSession session, Collection<MailboxId> mailboxIds, SearchQuery searchQuery, long limit) {
- Preconditions.checkArgument(session != null, "'session' is mandatory");
-
- if (mailboxIds.isEmpty()) {
- return Flux.empty();
- }
-
- return searcher.search(mailboxIds, searchQuery, Optional.empty())
- .doOnNext(this::logIfNoMessageId)
- .map(SearchResult::getMessageId)
- .handle(publishIfPresent())
- .distinct()
- .take(limit);
- }
-
- @Override
- public Mono<Void> add(MailboxSession session, Mailbox mailbox, MailboxMessage message) {
- LOGGER.info("Indexing mailbox {}-{} of user {} on message {}",
- mailbox.getName(),
- mailbox.getMailboxId(),
- session.getUser().asString(),
- message.getUid());
-
- RoutingKey from = routingKeyFactory.from(mailbox.getMailboxId());
- DocumentId id = indexIdFor(mailbox.getMailboxId(), message.getUid());
-
- return Mono.fromCallable(() -> generateIndexedJson(mailbox, message, session))
- .flatMap(jsonContent -> elasticSearchIndexer.index(id, jsonContent, from))
- .then();
- }
-
- private String generateIndexedJson(Mailbox mailbox, MailboxMessage message, MailboxSession session) throws JsonProcessingException {
- try {
- return messageToElasticSearchJson.convertToJson(message, ImmutableList.of(session.getUser()));
- } catch (Exception e) {
- LOGGER.warn("Indexing mailbox {}-{} of user {} on message {} without attachments ",
- mailbox.getName(),
- mailbox.getMailboxId().serialize(),
- session.getUser().asString(),
- message.getUid(),
- e);
- return messageToElasticSearchJson.convertToJsonWithoutAttachment(message, ImmutableList.of(session.getUser()));
- }
- }
-
- @Override
- public Mono<Void> delete(MailboxSession session, MailboxId mailboxId, Collection<MessageUid> expungedUids) {
- return elasticSearchIndexer
- .delete(expungedUids.stream()
- .map(uid -> indexIdFor(mailboxId, uid))
- .collect(toImmutableList()),
- routingKeyFactory.from(mailboxId))
- .then();
- }
-
- @Override
- public Mono<Void> deleteAll(MailboxSession session, MailboxId mailboxId) {
- TermQueryBuilder queryBuilder = termQuery(
- MAILBOX_ID,
- mailboxId.serialize());
-
- return elasticSearchIndexer
- .deleteAllMatchingQuery(queryBuilder, routingKeyFactory.from(mailboxId));
- }
-
- @Override
- public Mono<Void> update(MailboxSession session, MailboxId mailboxId, List<UpdatedFlags> updatedFlagsList) {
- RoutingKey routingKey = routingKeyFactory.from(mailboxId);
-
- return Flux.fromIterable(updatedFlagsList)
- .map(Throwing.<UpdatedFlags, UpdatedRepresentation>function(
- updatedFlags -> createUpdatedDocumentPartFromUpdatedFlags(mailboxId, updatedFlags))
- .sneakyThrow())
- .window(FLAGS_UPDATE_PROCESSING_WINDOW_SIZE)
- .concatMap(flux -> flux.collect(toImmutableList())
- .flatMap(updates -> elasticSearchIndexer.update(updates, routingKey)))
- .then();
- }
-
- private UpdatedRepresentation createUpdatedDocumentPartFromUpdatedFlags(MailboxId mailboxId, UpdatedFlags updatedFlags) throws JsonProcessingException {
- return new UpdatedRepresentation(
- indexIdFor(mailboxId, updatedFlags.getUid()),
- messageToElasticSearchJson
- .getUpdatedJsonMessagePart(updatedFlags.getNewFlags(), updatedFlags.getModSeq()));
- }
-
- private DocumentId indexIdFor(MailboxId mailboxId, MessageUid uid) {
- return DocumentId.fromString(String.join(ID_SEPARATOR, mailboxId.serialize(), String.valueOf(uid.asLong())));
- }
-
- private void logIfNoMessageId(SearchResult searchResult) {
- if (!searchResult.getMessageId().isPresent()) {
- LOGGER.error("No messageUid for {} in mailbox {}", searchResult.getMessageUid(), searchResult.getMailboxId());
- }
- }
-
- @Override
- public Mono<Flags> retrieveIndexedFlags(Mailbox mailbox, MessageUid uid) {
- RoutingKey routingKey = routingKeyFactory.from(mailbox.getMailboxId());
-
- return elasticSearchIndexer.get(indexIdFor(mailbox.getMailboxId(), uid), routingKey)
- .filter(GetResponse::isExists)
- .map(GetResponse::getSourceAsMap)
- .map(this::extractFlags);
- }
-
- private Flags extractFlags(Map<String, Object> source) {
- FlagsBuilder flagsBuilder = FlagsBuilder.builder()
- .isAnswered(extractFlag(source, IS_ANSWERED))
- .isDeleted(extractFlag(source, IS_DELETED))
- .isDraft(extractFlag(source, IS_DRAFT))
- .isFlagged(extractFlag(source, IS_FLAGGED))
- .isRecent(extractFlag(source, IS_RECENT))
- .isSeen(!extractFlag(source, IS_UNREAD));
-
- for (String userFlag : extractUserFlags(source)) {
- flagsBuilder.add(userFlag);
- }
-
- return flagsBuilder.build();
- }
-
- private boolean extractFlag(Map<String, Object> source, String flag) {
- return (Boolean) source.get(flag);
- }
-
- private List<String> extractUserFlags(Map<String, Object> source) {
- return (List<String>) source.get("userFlags");
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailer.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailer.java
deleted file mode 100644
index 1860a69..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailer.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.Joiner;
-import com.google.common.base.MoreObjects;
-
-public class EMailer implements SerializableMessage {
-
- private final Optional<String> name;
- private final String address;
-
- public EMailer(Optional<String> name, String address) {
- this.name = name;
- this.address = address;
- }
-
- @JsonProperty(JsonMessageConstants.EMailer.NAME)
- public Optional<String> getName() {
- return name;
- }
-
- @JsonProperty(JsonMessageConstants.EMailer.ADDRESS)
- public String getAddress() {
- return address;
- }
-
- @Override
- public String serialize() {
- return Joiner.on(" ").join(name, address);
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof EMailer) {
- EMailer otherEMailer = (EMailer) o;
- return Objects.equals(name, otherEMailer.name)
- && Objects.equals(address, otherEMailer.address);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(name, address);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("name", name)
- .add("address", address)
- .toString();
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailers.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailers.java
deleted file mode 100644
index 45c2b0f..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/EMailers.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.annotation.JsonValue;
-import com.google.common.base.Preconditions;
-
-public class EMailers implements SerializableMessage {
-
- public static EMailers from(Set<EMailer> emailers) {
- Preconditions.checkNotNull(emailers, "'emailers' is mandatory");
- return new EMailers(emailers);
- }
-
- private final Set<EMailer> emailers;
-
- private EMailers(Set<EMailer> emailers) {
- this.emailers = emailers;
- }
-
- @JsonValue
- public Set<EMailer> getEmailers() {
- return emailers;
- }
-
- @Override
- public String serialize() {
- return emailers.stream()
- .map(EMailer::serialize)
- .collect(Collectors.joining(" "));
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java
deleted file mode 100644
index 0f4ca17..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.time.ZonedDateTime;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Stream;
-
-import org.apache.james.mailbox.store.search.comparator.SentDateComparator;
-import org.apache.james.mime4j.dom.address.Address;
-import org.apache.james.mime4j.dom.address.Group;
-import org.apache.james.mime4j.dom.address.Mailbox;
-import org.apache.james.mime4j.field.address.LenientAddressParser;
-import org.apache.james.mime4j.stream.Field;
-import org.apache.james.mime4j.util.MimeUtil;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class HeaderCollection {
-
- public static class Header {
- private final String headerName;
- private final String value;
-
- Header(String headerName, String value) {
- this.headerName = headerName;
- this.value = value;
- }
-
- @JsonProperty(JsonMessageConstants.HEADER.NAME)
- public String getHeaderName() {
- return headerName;
- }
-
- @JsonProperty(JsonMessageConstants.HEADER.VALUE)
- public String getValue() {
- return value;
- }
-
- @Override
- public final boolean equals(Object o) {
- if (o instanceof Header) {
- Header header = (Header) o;
-
- return Objects.equals(this.headerName, header.headerName)
- && Objects.equals(this.value, header.value);
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return Objects.hash(headerName, value);
- }
- }
-
- public static class Builder {
-
- private final ImmutableSet.Builder<EMailer> toAddressSet;
- private final ImmutableSet.Builder<EMailer> fromAddressSet;
- private final ImmutableSet.Builder<EMailer> ccAddressSet;
- private final ImmutableSet.Builder<EMailer> bccAddressSet;
- private final ImmutableSet.Builder<EMailer> replyToAddressSet;
- private final ImmutableSet.Builder<String> subjectSet;
- private final ImmutableList.Builder<Header> headers;
- private Optional<ZonedDateTime> sentDate;
- private Optional<String> messageID;
-
- private Builder() {
- toAddressSet = ImmutableSet.builder();
- fromAddressSet = ImmutableSet.builder();
- ccAddressSet = ImmutableSet.builder();
- bccAddressSet = ImmutableSet.builder();
- replyToAddressSet = ImmutableSet.builder();
- subjectSet = ImmutableSet.builder();
- headers = ImmutableList.builder();
- sentDate = Optional.empty();
- messageID = Optional.empty();
- }
-
- public Builder add(Field field) {
- Preconditions.checkNotNull(field);
- String headerName = field.getName().toLowerCase(Locale.US);
- String rawHeaderValue = field.getBody();
- String sanitizedValue = MimeUtil.unscrambleHeaderValue(rawHeaderValue);
-
- headers.add(new Header(headerName, sanitizedValue));
-
- handleSpecificHeader(headerName, sanitizedValue, rawHeaderValue);
- return this;
- }
-
- public HeaderCollection build() {
- return new HeaderCollection(
- toAddressSet.build(),
- fromAddressSet.build(),
- ccAddressSet.build(),
- bccAddressSet.build(),
- replyToAddressSet.build(),
- subjectSet.build(),
- headers.build(),
- sentDate,
- messageID);
- }
-
- private void handleSpecificHeader(String headerName, String headerValue, String rawHeaderValue) {
- switch (headerName) {
- case TO:
- case FROM:
- case CC:
- case BCC:
- case REPLY_TO:
- manageAddressField(headerName, rawHeaderValue);
- break;
- case SUBJECT:
- subjectSet.add(headerValue);
- break;
- case DATE:
- sentDate = SentDateComparator.toISODate(headerValue);
- break;
- case MESSAGE_ID:
- messageID = Optional.ofNullable(headerValue);
- break;
- }
- }
-
- private void manageAddressField(String headerName, String rawHeaderValue) {
- ImmutableSet.Builder<EMailer> addressSet = getAddressSet(headerName);
- LenientAddressParser.DEFAULT
- .parseAddressList(rawHeaderValue)
- .stream()
- .flatMap(this::convertAddressToMailboxStream)
- .map((mailbox) -> new EMailer(Optional.ofNullable(mailbox.getName()), mailbox.getAddress()))
- .forEach(addressSet::add);
- }
-
- private Stream<Mailbox> convertAddressToMailboxStream(Address address) {
- if (address instanceof Mailbox) {
- return Stream.of((Mailbox) address);
- } else if (address instanceof Group) {
- return ((Group) address).getMailboxes().stream();
- }
- return Stream.empty();
- }
-
- private ImmutableSet.Builder<EMailer> getAddressSet(String headerName) {
- switch (headerName) {
- case TO:
- return toAddressSet;
- case FROM:
- return fromAddressSet;
- case CC:
- return ccAddressSet;
- case BCC:
- return bccAddressSet;
- case REPLY_TO:
- return replyToAddressSet;
- }
- throw new RuntimeException(headerName + " is not a address header name");
- }
- }
-
- public static final String TO = "to";
- public static final String FROM = "from";
- public static final String CC = "cc";
- public static final String BCC = "bcc";
- public static final String REPLY_TO = "reply-to";
- public static final String SUBJECT = "subject";
- public static final String DATE = "date";
- public static final String MESSAGE_ID = "message-id";
-
- public static Builder builder() {
- return new Builder();
- }
-
- private final ImmutableSet<EMailer> toAddressSet;
- private final ImmutableSet<EMailer> fromAddressSet;
- private final ImmutableSet<EMailer> ccAddressSet;
- private final ImmutableSet<EMailer> bccAddressSet;
- private final ImmutableSet<EMailer> replyToAddressSet;
- private final ImmutableSet<String> subjectSet;
- private final List<Header> headers;
- private final Optional<ZonedDateTime> sentDate;
- private final Optional<String> messageID;
-
- private HeaderCollection(ImmutableSet<EMailer> toAddressSet, ImmutableSet<EMailer> fromAddressSet,
- ImmutableSet<EMailer> ccAddressSet, ImmutableSet<EMailer> bccAddressSet,
- ImmutableSet<EMailer> replyToAddressSet, ImmutableSet<String> subjectSet,
- List<Header> headers, Optional<ZonedDateTime> sentDate, Optional<String> messageID) {
- this.toAddressSet = toAddressSet;
- this.fromAddressSet = fromAddressSet;
- this.ccAddressSet = ccAddressSet;
- this.bccAddressSet = bccAddressSet;
- this.replyToAddressSet = replyToAddressSet;
- this.subjectSet = subjectSet;
- this.headers = headers;
- this.sentDate = sentDate;
- this.messageID = messageID;
- }
-
- public Set<EMailer> getToAddressSet() {
- return toAddressSet;
- }
-
- public Set<EMailer> getFromAddressSet() {
- return fromAddressSet;
- }
-
- public Set<EMailer> getCcAddressSet() {
- return ccAddressSet;
- }
-
- public Set<EMailer> getBccAddressSet() {
- return bccAddressSet;
- }
-
- public Set<EMailer> getReplyToAddressSet() {
- return replyToAddressSet;
- }
-
- public Set<String> getSubjectSet() {
- return subjectSet;
- }
-
- public Optional<ZonedDateTime> getSentDate() {
- return sentDate;
- }
-
- public List<Header> getHeaders() {
- return headers;
- }
-
- public Optional<String> getMessageID() {
- return messageID;
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
deleted file mode 100644
index 17941bc..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
+++ /dev/null
@@ -1,411 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.io.IOException;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.MessageAttachmentMetadata;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.search.SearchUtil;
-import org.apache.james.mime4j.MimeException;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.github.steveash.guavate.Guavate;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-
-public class IndexableMessage {
-
- private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
-
- public static class Builder {
- private static ZonedDateTime getSanitizedInternalDate(MailboxMessage message, ZoneId zoneId) {
- if (message.getInternalDate() == null) {
- return ZonedDateTime.now();
- }
- return ZonedDateTime.ofInstant(
- Instant.ofEpochMilli(message.getInternalDate().getTime()),
- zoneId);
- }
-
- private IndexAttachments indexAttachments;
- private MailboxMessage message;
- private TextExtractor textExtractor;
-
- private ZoneId zoneId;
-
- private Builder() {
- }
-
- public IndexableMessage build() {
- Preconditions.checkNotNull(message.getMailboxId());
- Preconditions.checkNotNull(textExtractor);
- Preconditions.checkNotNull(indexAttachments);
- Preconditions.checkNotNull(zoneId);
-
- try {
- return instantiateIndexedMessage();
- } catch (IOException | MimeException e) {
- throw new RuntimeException(e);
- }
- }
-
- public Builder extractor(TextExtractor textExtractor) {
- this.textExtractor = textExtractor;
- return this;
- }
-
- public Builder indexAttachments(IndexAttachments indexAttachments) {
- this.indexAttachments = indexAttachments;
- return this;
- }
-
- public Builder message(MailboxMessage message) {
- this.message = message;
- return this;
- }
-
- public Builder zoneId(ZoneId zoneId) {
- this.zoneId = zoneId;
- return this;
- }
-
- private IndexableMessage instantiateIndexedMessage() throws IOException, MimeException {
- String messageId = SearchUtil.getSerializedMessageIdIfSupportedByUnderlyingStorageOrNull(message);
- MimePart parsingResult = new MimePartParser(message, textExtractor).parse();
-
- Optional<String> bodyText = parsingResult.locateFirstTextBody();
- Optional<String> bodyHtml = parsingResult.locateFirstHtmlBody();
-
- boolean hasAttachment = MessageAttachmentMetadata.hasNonInlinedAttachment(message.getAttachments());
- List<MimePart> attachments = setFlattenedAttachments(parsingResult, indexAttachments);
-
- HeaderCollection headerCollection = parsingResult.getHeaderCollection();
- ZonedDateTime internalDate = getSanitizedInternalDate(message, zoneId);
-
- List<HeaderCollection.Header> headers = headerCollection.getHeaders();
- Subjects subjects = Subjects.from(headerCollection.getSubjectSet());
- EMailers from = EMailers.from(headerCollection.getFromAddressSet());
- EMailers to = EMailers.from(headerCollection.getToAddressSet());
- EMailers cc = EMailers.from(headerCollection.getCcAddressSet());
- EMailers bcc = EMailers.from(headerCollection.getBccAddressSet());
- String sentDate = DATE_TIME_FORMATTER.format(headerCollection.getSentDate().orElse(internalDate));
- Optional<String> mimeMessageID = headerCollection.getMessageID();
-
- String text = Stream.of(from.serialize(),
- to.serialize(),
- cc.serialize(),
- bcc.serialize(),
- subjects.serialize(),
- bodyText.orElse(null),
- bodyHtml.orElse(null))
- .filter(Predicate.not(Strings::isNullOrEmpty))
- .collect(Collectors.joining(" "));
-
- long uid = message.getUid().asLong();
- String mailboxId = message.getMailboxId().serialize();
- ModSeq modSeq = message.getModSeq();
- long size = message.getFullContentOctets();
- String date = DATE_TIME_FORMATTER.format(getSanitizedInternalDate(message, zoneId));
- String mediaType = message.getMediaType();
- String subType = message.getSubType();
- boolean isAnswered = message.isAnswered();
- boolean isDeleted = message.isDeleted();
- boolean isDraft = message.isDraft();
- boolean isFlagged = message.isFlagged();
- boolean isRecent = message.isRecent();
- boolean isUnRead = !message.isSeen();
- String[] userFlags = message.createFlags().getUserFlags();
-
- return new IndexableMessage(
- attachments,
- bcc,
- bodyHtml,
- bodyText,
- cc,
- date,
- from,
- hasAttachment,
- headers,
- isAnswered,
- isDeleted,
- isDraft,
- isFlagged,
- isRecent,
- isUnRead,
- mailboxId,
- mediaType,
- messageId,
- modSeq,
- sentDate,
- size,
- subjects,
- subType,
- to,
- uid,
- userFlags,
- mimeMessageID);
- }
-
- private List<MimePart> setFlattenedAttachments(MimePart parsingResult, IndexAttachments indexAttachments) {
- if (IndexAttachments.YES.equals(indexAttachments)) {
- return parsingResult.getAttachmentsStream()
- .collect(Guavate.toImmutableList());
- } else {
- return ImmutableList.of();
- }
- }
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- private final List<MimePart> attachments;
- private final EMailers bcc;
- private final Optional<String> bodyHtml;
- private final Optional<String> bodyText;
- private final EMailers cc;
- private final String date;
- private final EMailers from;
- private final boolean hasAttachment;
- private final List<HeaderCollection.Header> headers;
- private final boolean isAnswered;
- private final boolean isDeleted;
- private final boolean isDraft;
- private final boolean isFlagged;
- private final boolean isRecent;
- private final boolean isUnRead;
- private final String mailboxId;
- private final String mediaType;
- private final String messageId;
- private final long modSeq;
- private final String sentDate;
- private final long size;
- private final Subjects subjects;
- private final String subType;
- private final EMailers to;
- private final long uid;
- private final String[] userFlags;
- private final Optional<String> mimeMessageID;
-
- private IndexableMessage(List<MimePart> attachments,
- EMailers bcc,
- Optional<String> bodyHtml,
- Optional<String> bodyText,
- EMailers cc,
- String date,
- EMailers from,
- boolean hasAttachment,
- List<HeaderCollection.Header> headers,
- boolean isAnswered,
- boolean isDeleted,
- boolean isDraft,
- boolean isFlagged,
- boolean isRecent,
- boolean isUnRead,
- String mailboxId,
- String mediaType, String messageId,
- ModSeq modSeq,
- String sentDate,
- long size,
- Subjects subjects,
- String subType,
- EMailers to,
- long uid,
- String[] userFlags,
- Optional<String> mimeMessageID) {
- this.attachments = attachments;
- this.bcc = bcc;
- this.bodyHtml = bodyHtml;
- this.bodyText = bodyText;
- this.cc = cc;
- this.date = date;
- this.from = from;
- this.hasAttachment = hasAttachment;
- this.headers = headers;
- this.isAnswered = isAnswered;
- this.isDeleted = isDeleted;
- this.isDraft = isDraft;
- this.isFlagged = isFlagged;
- this.isRecent = isRecent;
- this.isUnRead = isUnRead;
- this.mailboxId = mailboxId;
- this.mediaType = mediaType;
- this.messageId = messageId;
- this.modSeq = modSeq.asLong();
- this.sentDate = sentDate;
- this.size = size;
- this.subjects = subjects;
- this.subType = subType;
- this.to = to;
- this.uid = uid;
- this.userFlags = userFlags;
- this.mimeMessageID = mimeMessageID;
- }
-
- @JsonProperty(JsonMessageConstants.ATTACHMENTS)
- public List<MimePart> getAttachments() {
- return attachments;
- }
-
- @JsonProperty(JsonMessageConstants.BCC)
- public EMailers getBcc() {
- return bcc;
- }
-
- @JsonProperty(JsonMessageConstants.HTML_BODY)
- public Optional<String> getBodyHtml() {
- return bodyHtml;
- }
-
- @JsonProperty(JsonMessageConstants.TEXT_BODY)
- public Optional<String> getBodyText() {
- return bodyText;
- }
-
- @JsonProperty(JsonMessageConstants.CC)
- public EMailers getCc() {
- return cc;
- }
-
- @JsonProperty(JsonMessageConstants.DATE)
- public String getDate() {
- return date;
- }
-
- @JsonProperty(JsonMessageConstants.FROM)
- public EMailers getFrom() {
- return from;
- }
-
- @JsonProperty(JsonMessageConstants.HAS_ATTACHMENT)
- public boolean getHasAttachment() {
- return hasAttachment;
- }
-
- @JsonProperty(JsonMessageConstants.HEADERS)
- public List<HeaderCollection.Header> getHeaders() {
- return headers;
- }
-
- @JsonProperty(JsonMessageConstants.MAILBOX_ID)
- public String getMailboxId() {
- return mailboxId;
- }
-
- @JsonProperty(JsonMessageConstants.MEDIA_TYPE)
- public String getMediaType() {
- return mediaType;
- }
-
- @JsonProperty(JsonMessageConstants.MESSAGE_ID)
- public String getMessageId() {
- return messageId;
- }
-
- @JsonProperty(JsonMessageConstants.MODSEQ)
- public long getModSeq() {
- return modSeq;
- }
-
- @JsonProperty(JsonMessageConstants.SENT_DATE)
- public String getSentDate() {
- return sentDate;
- }
-
- @JsonProperty(JsonMessageConstants.SIZE)
- public long getSize() {
- return size;
- }
-
- @JsonProperty(JsonMessageConstants.SUBJECT)
- public Subjects getSubjects() {
- return subjects;
- }
-
- @JsonProperty(JsonMessageConstants.SUBTYPE)
- public String getSubType() {
- return subType;
- }
-
- @JsonProperty(JsonMessageConstants.TO)
- public EMailers getTo() {
- return to;
- }
-
- @JsonProperty(JsonMessageConstants.UID)
- public Long getUid() {
- return uid;
- }
-
- @JsonProperty(JsonMessageConstants.USER_FLAGS)
- public String[] getUserFlags() {
- return userFlags;
- }
-
- @JsonProperty(JsonMessageConstants.IS_ANSWERED)
- public boolean isAnswered() {
- return isAnswered;
- }
-
- @JsonProperty(JsonMessageConstants.IS_DELETED)
- public boolean isDeleted() {
- return isDeleted;
- }
-
- @JsonProperty(JsonMessageConstants.IS_DRAFT)
- public boolean isDraft() {
- return isDraft;
- }
-
- @JsonProperty(JsonMessageConstants.IS_FLAGGED)
- public boolean isFlagged() {
- return isFlagged;
- }
-
- @JsonProperty(JsonMessageConstants.IS_RECENT)
- public boolean isRecent() {
- return isRecent;
- }
-
- @JsonProperty(JsonMessageConstants.IS_UNREAD)
- public boolean isUnRead() {
- return isUnRead;
- }
-
- @JsonProperty(JsonMessageConstants.MIME_MESSAGE_ID)
- public Optional<String> getMimeMessageID() {
- return mimeMessageID;
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java
deleted file mode 100644
index 5262331..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-public interface JsonMessageConstants {
-
- /*
- Properties defined by JMAP
- */
- String MESSAGE_ID = "messageId";
- String UID = "uid";
- String MAILBOX_ID = "mailboxId";
- String IS_UNREAD = "isUnread";
- String IS_FLAGGED = "isFlagged";
- String IS_ANSWERED = "isAnswered";
- String IS_DRAFT = "isDraft";
- String HEADERS = "headers";
- String FROM = "from";
- String TO = "to";
- String CC = "cc";
- String BCC = "bcc";
- String SUBJECT = "subject";
- String DATE = "date";
- String SIZE = "size";
- String TEXT_BODY = "textBody";
- String HTML_BODY = "htmlBody";
- String SENT_DATE = "sentDate";
- String ATTACHMENTS = "attachments";
- String TEXT = "text";
- String MIME_MESSAGE_ID = "mimeMessageID";
-
- String MODSEQ = "modSeq";
- String USER_FLAGS = "userFlags";
- String IS_RECENT = "isRecent";
- String IS_DELETED = "isDeleted";
- String MEDIA_TYPE = "mediaType";
- String SUBTYPE = "subtype";
- String HAS_ATTACHMENT = "hasAttachment";
-
- interface EMailer {
- String NAME = "name";
- String ADDRESS = "address";
- }
-
- interface HEADER {
- String NAME = "name";
- String VALUE = "value";
- }
-
- interface Attachment {
- String TEXT_CONTENT = "textContent";
- String MEDIA_TYPE = "mediaType";
- String SUBTYPE = "subtype";
- String CONTENT_DISPOSITION = "contentDisposition";
- String FILENAME = "fileName";
- String FILE_EXTENSION = "fileExtension";
- }
-
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
deleted file mode 100644
index 3892cbe..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.time.ZoneId;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.mail.Flags;
-
-import org.apache.james.core.Username;
-import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.guava.GuavaModule;
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-import com.google.common.base.Preconditions;
-
-public class MessageToElasticSearchJson {
-
- private final ObjectMapper mapper;
- private final TextExtractor textExtractor;
- private final ZoneId zoneId;
- private final IndexAttachments indexAttachments;
-
- public MessageToElasticSearchJson(TextExtractor textExtractor, ZoneId zoneId, IndexAttachments indexAttachments) {
- this.textExtractor = textExtractor;
- this.zoneId = zoneId;
- this.indexAttachments = indexAttachments;
- this.mapper = new ObjectMapper();
- this.mapper.registerModule(new GuavaModule());
- this.mapper.registerModule(new Jdk8Module());
- }
-
- @Inject
- public MessageToElasticSearchJson(TextExtractor textExtractor, IndexAttachments indexAttachments) {
- this(textExtractor, ZoneId.systemDefault(), indexAttachments);
- }
-
- public String convertToJson(MailboxMessage message, List<Username> usernames) throws JsonProcessingException {
- Preconditions.checkNotNull(message);
-
- return mapper.writeValueAsString(IndexableMessage.builder()
- .message(message)
- .extractor(textExtractor)
- .zoneId(zoneId)
- .indexAttachments(indexAttachments)
- .build());
- }
-
- public String convertToJsonWithoutAttachment(MailboxMessage message, List<Username> usernames) throws JsonProcessingException {
- return mapper.writeValueAsString(IndexableMessage.builder()
- .message(message)
- .extractor(textExtractor)
- .zoneId(zoneId)
- .indexAttachments(IndexAttachments.NO)
- .build());
- }
-
- public String getUpdatedJsonMessagePart(Flags flags, ModSeq modSeq) throws JsonProcessingException {
- Preconditions.checkNotNull(flags);
- return mapper.writeValueAsString(new MessageUpdateJson(flags, modSeq));
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
deleted file mode 100644
index e26b25d..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import javax.mail.Flags;
-
-import org.apache.james.mailbox.ModSeq;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class MessageUpdateJson {
-
- private final Flags flags;
- private final long modSeq;
-
- public MessageUpdateJson(Flags flags, ModSeq modSeq) {
- this.flags = flags;
- this.modSeq = modSeq.asLong();
- }
-
- @JsonProperty(JsonMessageConstants.IS_ANSWERED)
- public boolean isAnswered() {
- return flags.contains(Flags.Flag.ANSWERED);
- }
-
- @JsonProperty(JsonMessageConstants.IS_DELETED)
- public boolean isDeleted() {
- return flags.contains(Flags.Flag.DELETED);
- }
-
- @JsonProperty(JsonMessageConstants.IS_DRAFT)
- public boolean isDraft() {
- return flags.contains(Flags.Flag.DRAFT);
- }
-
- @JsonProperty(JsonMessageConstants.IS_FLAGGED)
- public boolean isFlagged() {
- return flags.contains(Flags.Flag.FLAGGED);
- }
-
- @JsonProperty(JsonMessageConstants.IS_RECENT)
- public boolean isRecent() {
- return flags.contains(Flags.Flag.RECENT);
- }
-
- @JsonProperty(JsonMessageConstants.IS_UNREAD)
- public boolean isUnRead() {
- return !flags.contains(Flags.Flag.SEEN);
- }
-
-
- @JsonProperty(JsonMessageConstants.USER_FLAGS)
- public String[] getUserFlags() {
- return flags.getUserFlags();
- }
-
- @JsonProperty(JsonMessageConstants.MODSEQ)
- public long getModSeq() {
- return modSeq;
- }
-
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java
deleted file mode 100644
index e283267..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePart.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.james.mailbox.extractor.ParsedContent;
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.ContentType;
-import org.apache.james.mailbox.model.ContentType.MediaType;
-import org.apache.james.mailbox.model.ContentType.SubType;
-import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
-import org.apache.james.mime4j.stream.Field;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
-public class MimePart {
-
- public static class Builder implements MimePartContainerBuilder {
-
- private final HeaderCollection.Builder headerCollectionBuilder;
- private Optional<InputStream> bodyContent;
- private final List<MimePart> children;
- private Optional<MediaType> mediaType;
- private Optional<SubType> subType;
- private Optional<String> fileName;
- private Optional<String> fileExtension;
- private Optional<String> contentDisposition;
- private Optional<Charset> charset;
- private TextExtractor textExtractor;
-
- private Builder() {
- children = Lists.newArrayList();
- headerCollectionBuilder = HeaderCollection.builder();
- this.bodyContent = Optional.empty();
- this.mediaType = Optional.empty();
- this.subType = Optional.empty();
- this.fileName = Optional.empty();
- this.fileExtension = Optional.empty();
- this.contentDisposition = Optional.empty();
- this.charset = Optional.empty();
- this.textExtractor = new DefaultTextExtractor();
- }
-
- @Override
- public Builder addToHeaders(Field field) {
- headerCollectionBuilder.add(field);
- return this;
- }
-
- @Override
- public Builder addBodyContent(InputStream bodyContent) {
- this.bodyContent = Optional.of(bodyContent);
- return this;
- }
-
- @Override
- public Builder addChild(MimePart mimePart) {
- children.add(mimePart);
- return this;
- }
-
- @Override
- public Builder addFileName(String fileName) {
- this.fileName = Optional.ofNullable(fileName);
- this.fileExtension = this.fileName.map(FilenameUtils::getExtension);
- return this;
- }
-
- @Override
- public Builder addMediaType(MediaType mediaType) {
- this.mediaType = Optional.ofNullable(mediaType);
- return this;
- }
-
- @Override
- public Builder addSubType(SubType subType) {
- this.subType = Optional.of(subType);
- return this;
- }
-
- @Override
- public Builder addContentDisposition(String contentDisposition) {
- this.contentDisposition = Optional.ofNullable(contentDisposition);
- return this;
- }
-
- @Override
- public MimePartContainerBuilder using(TextExtractor textExtractor) {
- Preconditions.checkArgument(textExtractor != null, "Provided text extractor should not be null");
- this.textExtractor = textExtractor;
- return this;
- }
-
- @Override
- public MimePartContainerBuilder charset(Charset charset) {
- this.charset = Optional.of(charset);
- return this;
- }
-
- @Override
- public MimePart build() {
- Optional<ParsedContent> parsedContent = parseContent(textExtractor);
- return new MimePart(
- headerCollectionBuilder.build(),
- parsedContent.flatMap(ParsedContent::getTextualContent),
- mediaType,
- subType,
- fileName,
- fileExtension,
- contentDisposition,
- children);
- }
-
- private Optional<ParsedContent> parseContent(TextExtractor textExtractor) {
- if (bodyContent.isPresent()) {
- try {
- return Optional.of(extractText(textExtractor, bodyContent.get()));
- } catch (Throwable e) {
- LOGGER.warn("Failed parsing attachment", e);
- }
- }
- return Optional.empty();
- }
-
- private ParsedContent extractText(TextExtractor textExtractor, InputStream bodyContent) throws Exception {
- if (shouldPerformTextExtraction()) {
- return textExtractor.extractContent(
- bodyContent,
- computeContentType().orElse(null));
- }
- return new ParsedContent(
- Optional.ofNullable(IOUtils.toString(bodyContent, charset.orElse(StandardCharsets.UTF_8))),
- ImmutableMap.of());
- }
-
- private boolean shouldPerformTextExtraction() {
- return !isTextBody() || isHtml();
- }
-
- private Boolean isTextBody() {
- return mediaType.map(MediaType.of("text")::equals).orElse(false);
- }
-
- private Boolean isHtml() {
- return isTextBody() && subType.map(SubType.of("html")::equals).orElse(false);
- }
-
- private Optional<ContentType> computeContentType() {
- if (mediaType.isPresent() && subType.isPresent()) {
- return Optional.of(ContentType.of(
- ContentType.MimeType.of(mediaType.get(), subType.get()),
- charset));
- } else {
- return Optional.empty();
- }
- }
-
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- private static final Logger LOGGER = LoggerFactory.getLogger(MimePart.class);
-
- private final HeaderCollection headerCollection;
- private final Optional<String> bodyTextContent;
- private final Optional<MediaType> mediaType;
- private final Optional<SubType> subType;
- private final Optional<String> fileName;
- private final Optional<String> fileExtension;
- private final Optional<String> contentDisposition;
- private final List<MimePart> attachments;
-
- private MimePart(HeaderCollection headerCollection, Optional<String> bodyTextContent, Optional<MediaType> mediaType,
- Optional<SubType> subType, Optional<String> fileName, Optional<String> fileExtension,
- Optional<String> contentDisposition, List<MimePart> attachments) {
- this.headerCollection = headerCollection;
- this.mediaType = mediaType;
- this.subType = subType;
- this.fileName = fileName;
- this.fileExtension = fileExtension;
- this.contentDisposition = contentDisposition;
- this.attachments = attachments;
- this.bodyTextContent = bodyTextContent;
- }
-
- @JsonIgnore
- public List<MimePart> getAttachments() {
- return attachments;
- }
-
- @JsonIgnore
- public HeaderCollection getHeaderCollection() {
- return headerCollection;
- }
-
- @JsonProperty(JsonMessageConstants.Attachment.FILENAME)
- public Optional<String> getFileName() {
- return fileName;
- }
-
- @JsonProperty(JsonMessageConstants.Attachment.FILE_EXTENSION)
- public Optional<String> getFileExtension() {
- return fileExtension;
- }
-
- @JsonProperty(JsonMessageConstants.Attachment.MEDIA_TYPE)
- public Optional<String> getMediaType() {
- return mediaType.map(MediaType::asString);
- }
-
- @JsonProperty(JsonMessageConstants.Attachment.SUBTYPE)
- public Optional<String> getSubType() {
- return subType.map(SubType::asString);
- }
-
- @JsonProperty(JsonMessageConstants.Attachment.CONTENT_DISPOSITION)
- public Optional<String> getContentDisposition() {
- return contentDisposition;
- }
-
- @JsonProperty(JsonMessageConstants.Attachment.TEXT_CONTENT)
- public Optional<String> getTextualBody() {
- return bodyTextContent;
- }
-
- @JsonIgnore
- public Optional<String> locateFirstTextBody() {
- return firstBody(textAttachments()
- .filter(this::isPlainSubType));
- }
-
- @JsonIgnore
- public Optional<String> locateFirstHtmlBody() {
- return firstBody(textAttachments()
- .filter(this::isHtmlSubType));
- }
-
- private Optional<String> firstBody(Stream<MimePart> mimeParts) {
- return mimeParts
- .map(mimePart -> mimePart.bodyTextContent)
- .flatMap(Optional::stream)
- .findFirst();
- }
-
- private Stream<MimePart> textAttachments() {
- return Stream.concat(
- Stream.of(this),
- attachments.stream())
- .filter(this::isTextMediaType);
- }
-
- private boolean isTextMediaType(MimePart mimePart) {
- return mimePart.getMediaType()
- .filter("text"::equals)
- .isPresent();
- }
-
- private boolean isPlainSubType(MimePart mimePart) {
- return mimePart.getSubType()
- .filter("plain"::equals)
- .isPresent();
- }
-
- private boolean isHtmlSubType(MimePart mimePart) {
- return mimePart.getSubType()
- .filter("html"::equals)
- .isPresent();
- }
-
- @JsonIgnore
- public Stream<MimePart> getAttachmentsStream() {
- return attachments.stream()
- .flatMap(mimePart -> Stream.concat(Stream.of(mimePart), mimePart.getAttachmentsStream()))
- .filter(mimePart -> mimePart.contentDisposition.isPresent());
- }
-
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartContainerBuilder.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartContainerBuilder.java
deleted file mode 100644
index 88439fb..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartContainerBuilder.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.io.InputStream;
-import java.nio.charset.Charset;
-
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.ContentType.MediaType;
-import org.apache.james.mailbox.model.ContentType.SubType;
-import org.apache.james.mime4j.stream.Field;
-
-public interface MimePartContainerBuilder {
-
- MimePart build();
-
- MimePartContainerBuilder using(TextExtractor textExtractor);
-
- MimePartContainerBuilder addToHeaders(Field field);
-
- MimePartContainerBuilder addBodyContent(InputStream bodyContent);
-
- MimePartContainerBuilder addChild(MimePart mimePart);
-
- MimePartContainerBuilder addFileName(String fileName);
-
- MimePartContainerBuilder charset(Charset charset);
-
- MimePartContainerBuilder addMediaType(MediaType mediaType);
-
- MimePartContainerBuilder addSubType(SubType subType);
-
- MimePartContainerBuilder addContentDisposition(String contentDisposition);
-
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartParser.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartParser.java
deleted file mode 100644
index d12748f..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MimePartParser.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.Optional;
-
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.ContentType.MediaType;
-import org.apache.james.mailbox.model.ContentType.SubType;
-import org.apache.james.mailbox.store.mail.model.Message;
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.message.DefaultBodyDescriptorBuilder;
-import org.apache.james.mime4j.message.MaximalBodyDescriptor;
-import org.apache.james.mime4j.stream.EntityState;
-import org.apache.james.mime4j.stream.MimeConfig;
-import org.apache.james.mime4j.stream.MimeTokenStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-public class MimePartParser {
- private static final Logger LOGGER = LoggerFactory.getLogger(MimePartParser.class);
-
- private final Message message;
- private final TextExtractor textExtractor;
- private final MimeTokenStream stream;
- private final Deque<MimePartContainerBuilder> builderStack;
- private MimePart result;
- private MimePartContainerBuilder currentlyBuildMimePart;
-
- public MimePartParser(Message message, TextExtractor textExtractor) {
- this.message = message;
- this.textExtractor = textExtractor;
- this.builderStack = new LinkedList<>();
- this.currentlyBuildMimePart = new RootMimePartContainerBuilder();
- this.stream = new MimeTokenStream(
- MimeConfig.PERMISSIVE,
- new DefaultBodyDescriptorBuilder());
- }
-
- public MimePart parse() throws IOException, MimeException {
- stream.parse(message.getFullContent());
- for (EntityState state = stream.getState(); state != EntityState.T_END_OF_STREAM; state = stream.next()) {
- processMimePart(stream, state);
- }
- return result;
- }
-
- private void processMimePart(MimeTokenStream stream, EntityState state) {
- switch (state) {
- case T_START_MULTIPART:
- case T_START_MESSAGE:
- stackCurrent();
- break;
- case T_START_HEADER:
- currentlyBuildMimePart = MimePart.builder();
- break;
- case T_FIELD:
- currentlyBuildMimePart.addToHeaders(stream.getField());
- break;
- case T_BODY:
- manageBodyExtraction(stream);
- closeMimePart();
- break;
- case T_END_MULTIPART:
- case T_END_MESSAGE:
- unstackToCurrent();
- closeMimePart();
- break;
- default:
- break;
- }
- }
-
- private void stackCurrent() {
- builderStack.push(currentlyBuildMimePart);
- currentlyBuildMimePart = null;
- }
-
- private void unstackToCurrent() {
- currentlyBuildMimePart = builderStack.pop();
- }
-
- private void closeMimePart() {
- MimePart bodyMimePart = currentlyBuildMimePart.using(textExtractor).build();
- if (!builderStack.isEmpty()) {
- builderStack.peek().addChild(bodyMimePart);
- } else {
- Preconditions.checkState(result == null);
- result = bodyMimePart;
- }
- }
-
- private void manageBodyExtraction(MimeTokenStream stream) {
- extractMimePartBodyDescription(stream);
- currentlyBuildMimePart.addBodyContent(stream.getDecodedInputStream());
- }
-
- private void extractMimePartBodyDescription(MimeTokenStream stream) {
- MaximalBodyDescriptor descriptor = (MaximalBodyDescriptor) stream.getBodyDescriptor();
-
- Optional.ofNullable(descriptor.getMediaType())
- .map(MediaType::of)
- .ifPresent(currentlyBuildMimePart::addMediaType);
- Optional.ofNullable(descriptor.getSubType())
- .map(SubType::of)
- .ifPresent(currentlyBuildMimePart::addSubType);
- currentlyBuildMimePart.addContentDisposition(descriptor.getContentDispositionType())
- .addFileName(descriptor.getContentDispositionFilename());
- extractCharset(descriptor);
- }
-
- private void extractCharset(MaximalBodyDescriptor descriptor) {
- try {
- Optional.ofNullable(descriptor.getCharset())
- .map(Charset::forName)
- .ifPresent(currentlyBuildMimePart::charset);
- } catch (Exception e) {
- LOGGER.info("Failed parsing charset", e);
- }
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/RootMimePartContainerBuilder.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/RootMimePartContainerBuilder.java
deleted file mode 100644
index 71a88ce..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/RootMimePartContainerBuilder.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.io.InputStream;
-import java.nio.charset.Charset;
-
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.ContentType.MediaType;
-import org.apache.james.mailbox.model.ContentType.SubType;
-import org.apache.james.mime4j.stream.Field;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RootMimePartContainerBuilder implements MimePartContainerBuilder {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(RootMimePartContainerBuilder.class);
-
- private MimePart rootMimePart;
-
- @Override
- public MimePart build() {
- return rootMimePart;
- }
-
- @Override public MimePartContainerBuilder using(TextExtractor textExtractor) {
- return this;
- }
-
- @Override
- public MimePartContainerBuilder addToHeaders(Field field) {
- LOGGER.warn("Trying to add headers to the Root MimePart container");
- return this;
- }
-
- @Override
- public MimePartContainerBuilder addBodyContent(InputStream bodyContent) {
- LOGGER.warn("Trying to add body content to the Root MimePart container");
- return this;
- }
-
- @Override
- public MimePartContainerBuilder addChild(MimePart mimePart) {
- if (rootMimePart == null) {
- rootMimePart = mimePart;
- } else {
- LOGGER.warn("Trying to add several children to the Root MimePart container");
- }
- return this;
- }
-
- @Override
- public MimePartContainerBuilder addFileName(String fileName) {
- LOGGER.warn("Trying to add fineName to the Root MimePart container");
- return this;
- }
-
- @Override
- public MimePartContainerBuilder addMediaType(MediaType mediaType) {
- LOGGER.warn("Trying to add media type to the Root MimePart container");
- return this;
- }
-
- @Override
- public MimePartContainerBuilder addSubType(SubType subType) {
- LOGGER.warn("Trying to add sub type to the Root MimePart container");
- return this;
- }
-
- @Override
- public MimePartContainerBuilder addContentDisposition(String contentDisposition) {
- LOGGER.warn("Trying to add content disposition to the Root MimePart container");
- return this;
- }
-
- @Override
- public MimePartContainerBuilder charset(Charset charset) {
- LOGGER.warn("Trying to add content charset to the Root MimePart container");
- return this;
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/SerializableMessage.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/SerializableMessage.java
deleted file mode 100644
index abf2c34..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/SerializableMessage.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-public interface SerializableMessage {
-
- String serialize();
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/Subjects.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/Subjects.java
deleted file mode 100644
index 6989aa1..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/Subjects.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.util.Set;
-
-import com.fasterxml.jackson.annotation.JsonValue;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-
-public class Subjects implements SerializableMessage {
-
- public static Subjects from(Set<String> subjects) {
- Preconditions.checkNotNull(subjects, "'subjects' is mandatory");
- return new Subjects(subjects);
- }
-
- private final Set<String> subjects;
-
- private Subjects(Set<String> subjects) {
- this.subjects = subjects;
- }
-
- @JsonValue
- public Set<String> getSubjects() {
- return subjects;
- }
-
- @Override
- public String serialize() {
- return Joiner.on(" ").join(subjects);
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
deleted file mode 100644
index df39e14..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.query;
-
-import static org.apache.james.backends.es.NodeMappingFactory.RAW;
-import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
-import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
-import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
-import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
-import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-
-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.Collector;
-import java.util.stream.Stream;
-
-import javax.mail.Flags;
-
-import org.apache.james.mailbox.elasticsearch.json.HeaderCollection;
-import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants;
-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.lucene.search.join.ScoreMode;
-import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
-
-public class CriterionConverter {
-
- private final Map<Class<?>, Function<Criterion, QueryBuilder>> criterionConverterMap;
- private final Map<Class<?>, BiFunction<String, HeaderOperator, QueryBuilder>> headerOperatorConverterMap;
-
- public CriterionConverter() {
- criterionConverterMap = new HashMap<>();
- headerOperatorConverterMap = new HashMap<>();
-
- registerCriterionConverters();
- registerHeaderOperatorConverters();
- }
-
- private void registerCriterionConverters() {
- registerCriterionConverter(SearchQuery.FlagCriterion.class, this::convertFlag);
- registerCriterionConverter(SearchQuery.UidCriterion.class, this::convertUid);
- registerCriterionConverter(SearchQuery.ConjunctionCriterion.class, this::convertConjunction);
- registerCriterionConverter(SearchQuery.HeaderCriterion.class, this::convertHeader);
- registerCriterionConverter(SearchQuery.TextCriterion.class, this::convertTextCriterion);
- registerCriterionConverter(SearchQuery.CustomFlagCriterion.class, this::convertCustomFlagCriterion);
-
- registerCriterionConverter(SearchQuery.AllCriterion.class,
- criterion -> matchAllQuery());
-
- 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.AttachmentCriterion.class, this::convertAttachmentCriterion);
- registerCriterionConverter(SearchQuery.MimeMessageIDCriterion.class, this::convertMimeMessageIDCriterion);
- }
-
- @SuppressWarnings("unchecked")
- private <T extends Criterion> void registerCriterionConverter(Class<T> type, Function<T, QueryBuilder> f) {
- criterionConverterMap.put(type, (Function<Criterion, QueryBuilder>) f);
- }
-
- private void registerHeaderOperatorConverters() {
-
- registerHeaderOperatorConverter(
- SearchQuery.ExistsOperator.class,
- (headerName, operator) ->
- nestedQuery(JsonMessageConstants.HEADERS,
- termQuery(JsonMessageConstants.HEADERS + "." + JsonMessageConstants.HEADER.NAME, headerName),
- ScoreMode.Avg));
-
- 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) ->
- nestedQuery(JsonMessageConstants.HEADERS,
- boolQuery()
- .must(termQuery(JsonMessageConstants.HEADERS + "." + JsonMessageConstants.HEADER.NAME, headerName))
- .must(matchQuery(JsonMessageConstants.HEADERS + "." + JsonMessageConstants.HEADER.VALUE, operator.getValue())),
- ScoreMode.Avg));
- }
-
- @SuppressWarnings("unchecked")
- private <T extends HeaderOperator> void registerHeaderOperatorConverter(Class<T> type, BiFunction<String, T, QueryBuilder> f) {
- headerOperatorConverterMap.put(type, (BiFunction<String, HeaderOperator, QueryBuilder>) f);
- }
-
- public QueryBuilder convertCriterion(Criterion criterion) {
- return criterionConverterMap.get(criterion.getClass()).apply(criterion);
- }
-
- private QueryBuilder convertAttachmentCriterion(SearchQuery.AttachmentCriterion criterion) {
- return termQuery(JsonMessageConstants.HAS_ATTACHMENT, criterion.getOperator().isSet());
- }
-
- private QueryBuilder convertMimeMessageIDCriterion(SearchQuery.MimeMessageIDCriterion criterion) {
- return termQuery(JsonMessageConstants.MIME_MESSAGE_ID, criterion.getMessageID());
- }
-
- private QueryBuilder convertCustomFlagCriterion(SearchQuery.CustomFlagCriterion criterion) {
- QueryBuilder termQueryBuilder = termQuery(JsonMessageConstants.USER_FLAGS, criterion.getFlag());
- if (criterion.getOperator().isSet()) {
- return termQueryBuilder;
- } else {
- return boolQuery().mustNot(termQueryBuilder);
- }
- }
-
- private QueryBuilder convertTextCriterion(SearchQuery.TextCriterion textCriterion) {
- switch (textCriterion.getType()) {
- case BODY:
- return boolQuery()
- .should(matchQuery(JsonMessageConstants.TEXT_BODY, textCriterion.getOperator().getValue()))
- .should(matchQuery(JsonMessageConstants.HTML_BODY, textCriterion.getOperator().getValue()));
- case FULL:
- return boolQuery()
- .should(matchQuery(JsonMessageConstants.TEXT_BODY, textCriterion.getOperator().getValue()))
- .should(matchQuery(JsonMessageConstants.HTML_BODY, textCriterion.getOperator().getValue()))
- .should(matchQuery(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT,
- textCriterion.getOperator().getValue()));
- case ATTACHMENTS:
- return boolQuery()
- .should(matchQuery(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT,
- textCriterion.getOperator().getValue()));
- case ATTACHMENT_FILE_NAME:
- return boolQuery()
- .should(termQuery(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILENAME,
- textCriterion.getOperator().getValue()));
- }
- throw new RuntimeException("Unknown SCOPE for text criterion");
- }
-
- private QueryBuilder dateRangeFilter(String field, SearchQuery.DateOperator dateOperator) {
- return boolQuery().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()))));
- }
-
- private BoolQueryBuilder convertConjunction(SearchQuery.ConjunctionCriterion criterion) {
- return convertToBoolQuery(criterion.getCriteria().stream().map(this::convertCriterion),
- convertConjunctionType(criterion.getType()));
- }
-
- private BiFunction<BoolQueryBuilder, QueryBuilder, BoolQueryBuilder> convertConjunctionType(SearchQuery.Conjunction type) {
- switch (type) {
- case AND:
- return BoolQueryBuilder::must;
- case OR:
- return BoolQueryBuilder::should;
- case NOR:
- return BoolQueryBuilder::mustNot;
- default:
- throw new RuntimeException("Unexpected conjunction criteria " + type);
- }
- }
-
- @SuppressWarnings("ReturnValueIgnored")
- private BoolQueryBuilder convertToBoolQuery(Stream<QueryBuilder> stream, BiFunction<BoolQueryBuilder, QueryBuilder, BoolQueryBuilder> addCriterionToBoolQuery) {
- return stream.collect(Collector.of(QueryBuilders::boolQuery,
- addCriterionToBoolQuery::apply,
- addCriterionToBoolQuery::apply));
- }
-
- private QueryBuilder convertFlag(SearchQuery.FlagCriterion flagCriterion) {
- SearchQuery.BooleanOperator operator = flagCriterion.getOperator();
- Flags.Flag flag = flagCriterion.getFlag();
- if (flag.equals(Flags.Flag.DELETED)) {
- return boolQuery().filter(termQuery(JsonMessageConstants.IS_DELETED, operator.isSet()));
- }
- if (flag.equals(Flags.Flag.ANSWERED)) {
- return boolQuery().filter(termQuery(JsonMessageConstants.IS_ANSWERED, operator.isSet()));
- }
- if (flag.equals(Flags.Flag.DRAFT)) {
- return boolQuery().filter(termQuery(JsonMessageConstants.IS_DRAFT, operator.isSet()));
- }
- if (flag.equals(Flags.Flag.SEEN)) {
- return boolQuery().filter(termQuery(JsonMessageConstants.IS_UNREAD, !operator.isSet()));
- }
- if (flag.equals(Flags.Flag.RECENT)) {
- return boolQuery().filter(termQuery(JsonMessageConstants.IS_RECENT, operator.isSet()));
- }
- if (flag.equals(Flags.Flag.FLAGGED)) {
- return boolQuery().filter(termQuery(JsonMessageConstants.IS_FLAGGED, operator.isSet()));
- }
- throw new RuntimeException("Unknown flag used in Flag search criterion");
- }
-
- private QueryBuilder createNumericFilter(String fieldName, SearchQuery.NumericOperator operator) {
- switch (operator.getType()) {
- case EQUALS:
- return boolQuery().filter(rangeQuery(fieldName).gte(operator.getValue()).lte(operator.getValue()));
- case GREATER_THAN:
- return boolQuery().filter(rangeQuery(fieldName).gt(operator.getValue()));
- case LESS_THAN:
- return boolQuery().filter(rangeQuery(fieldName).lt(operator.getValue()));
- default:
- throw new RuntimeException("A non existing numeric operator was triggered");
- }
- }
-
- private BoolQueryBuilder convertUid(SearchQuery.UidCriterion uidCriterion) {
- if (uidCriterion.getOperator().getRange().length == 0) {
- return boolQuery();
- }
- return boolQuery().filter(
- convertToBoolQuery(
- Arrays.stream(uidCriterion.getOperator().getRange())
- .map(this::uidRangeFilter), BoolQueryBuilder::should));
- }
-
- private QueryBuilder uidRangeFilter(SearchQuery.UidRange numericRange) {
- return rangeQuery(JsonMessageConstants.UID)
- .lte(numericRange.getHighValue().asLong())
- .gte(numericRange.getLowValue().asLong());
- }
-
- private QueryBuilder convertHeader(SearchQuery.HeaderCriterion headerCriterion) {
- return headerOperatorConverterMap.get(headerCriterion.getOperator().getClass())
- .apply(
- headerCriterion.getHeaderName().toLowerCase(Locale.US),
- headerCriterion.getOperator());
- }
-
- private QueryBuilder manageAddressFields(String headerName, String value) {
- return boolQuery()
- .should(matchQuery(getFieldNameFromHeaderName(headerName) + "." + JsonMessageConstants.EMailer.NAME, value))
- .should(matchQuery(getFieldNameFromHeaderName(headerName) + "." + JsonMessageConstants.EMailer.ADDRESS, value))
- .should(matchQuery(getFieldNameFromHeaderName(headerName) + "." + JsonMessageConstants.EMailer.ADDRESS + "." + RAW, value));
- }
-
- 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;
- }
- throw new RuntimeException("Header not recognized as Addess Header : " + headerName);
- }
-
- private QueryBuilder convertDateOperator(String field, SearchQuery.DateComparator dateComparator, String lowDateString, String upDateString) {
- switch (dateComparator) {
- case BEFORE:
- return rangeQuery(field).lte(upDateString);
- case AFTER:
- return rangeQuery(field).gt(lowDateString);
- case ON:
- return rangeQuery(field).lte(upDateString).gte(lowDateString);
- }
- throw new RuntimeException("Unknown date operator");
- }
-
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatter.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatter.java
deleted file mode 100644
index 9528cc0..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.query;
-
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalUnit;
-import java.util.Date;
-
-import org.apache.james.mailbox.model.SearchQuery;
-
-public class DateResolutionFormatter {
-
- public static ZonedDateTime computeUpperDate(ZonedDateTime date, SearchQuery.DateResolution resolution) {
- return computeLowerDate(date, resolution).plus(1, convertDateResolutionField(resolution));
- }
-
- public static ZonedDateTime computeLowerDate(ZonedDateTime date, SearchQuery.DateResolution resolution) {
- switch (resolution) {
- case Year:
- return date.truncatedTo(ChronoUnit.DAYS).withDayOfYear(1);
- case Month:
- return date.truncatedTo(ChronoUnit.DAYS).withDayOfMonth(1);
- default:
- return date.truncatedTo(convertDateResolutionField(resolution));
- }
- }
-
- private static TemporalUnit convertDateResolutionField(SearchQuery.DateResolution resolution) {
- switch (resolution) {
- case Year:
- return ChronoUnit.YEARS;
- case Month:
- return ChronoUnit.MONTHS;
- case Day:
- return ChronoUnit.DAYS;
- case Hour:
- return ChronoUnit.HOURS;
- case Minute:
- return ChronoUnit.MINUTES;
- case Second:
- return ChronoUnit.SECONDS;
- default:
- throw new RuntimeException("Unknown Date resolution used");
- }
- }
-
- public static ZonedDateTime convertDateToZonedDateTime(Date date) {
- return ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
- }
-}
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java
deleted file mode 100644
index 9e3f9af..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.query;
-
-import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-
-import javax.inject.Inject;
-
-import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.SearchQuery;
-import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
-
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.ImmutableList;
-
-public class QueryConverter {
-
-
- private final CriterionConverter criterionConverter;
-
- @Inject
- public QueryConverter(CriterionConverter criterionConverter) {
- this.criterionConverter = criterionConverter;
- }
-
- public QueryBuilder from(Collection<MailboxId> mailboxIds, SearchQuery query) {
- BoolQueryBuilder boolQueryBuilder = boolQuery()
- .must(generateQueryBuilder(query));
-
- mailboxesQuery(mailboxIds).map(boolQueryBuilder::filter);
- return boolQueryBuilder;
- }
-
- private QueryBuilder generateQueryBuilder(SearchQuery searchQuery) {
- List<SearchQuery.Criterion> criteria = searchQuery.getCriteria();
- if (criteria.isEmpty()) {
- return criterionConverter.convertCriterion(SearchQuery.all());
- } else if (criteria.size() == 1) {
- return criterionConverter.convertCriterion(criteria.get(0));
- } else {
- return criterionConverter.convertCriterion(new SearchQuery.ConjunctionCriterion(SearchQuery.Conjunction.AND, criteria));
- }
- }
-
- private Optional<QueryBuilder> mailboxesQuery(Collection<MailboxId> mailboxIds) {
- if (mailboxIds.isEmpty()) {
- return Optional.empty();
- }
- ImmutableList<String> ids = mailboxIds.stream()
- .map(MailboxId::serialize)
- .collect(Guavate.toImmutableList());
- return Optional.of(termsQuery(JsonMessageConstants.MAILBOX_ID, ids));
- }
-
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
deleted file mode 100644
index bc19b73..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.query;
-
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants;
-import org.apache.james.mailbox.model.SearchQuery;
-import org.elasticsearch.search.sort.FieldSortBuilder;
-import org.elasticsearch.search.sort.SortBuilders;
-import org.elasticsearch.search.sort.SortMode;
-import org.elasticsearch.search.sort.SortOrder;
-
-public class SortConverter {
-
- private static final String PATH_SEPARATOR = ".";
-
- public static FieldSortBuilder convertSort(SearchQuery.Sort sort) {
- return getSortClause(sort.getSortClause())
- .order(getOrder(sort))
- .sortMode(SortMode.MIN);
- }
-
- private static FieldSortBuilder getSortClause(SearchQuery.Sort.SortClause clause) {
- switch (clause) {
- case Arrival :
- return SortBuilders.fieldSort(JsonMessageConstants.DATE);
- case MailboxCc :
- return SortBuilders.fieldSort(JsonMessageConstants.CC + PATH_SEPARATOR + JsonMessageConstants.EMailer.ADDRESS
- + PATH_SEPARATOR + NodeMappingFactory.RAW);
- case MailboxFrom :
- return SortBuilders.fieldSort(JsonMessageConstants.FROM + PATH_SEPARATOR + JsonMessageConstants.EMailer.ADDRESS
- + PATH_SEPARATOR + NodeMappingFactory.RAW);
- case MailboxTo :
- return SortBuilders.fieldSort(JsonMessageConstants.TO + PATH_SEPARATOR + JsonMessageConstants.EMailer.ADDRESS
- + PATH_SEPARATOR + NodeMappingFactory.RAW);
- case BaseSubject :
- return SortBuilders.fieldSort(JsonMessageConstants.SUBJECT + PATH_SEPARATOR + NodeMappingFactory.RAW);
- case Size :
- return SortBuilders.fieldSort(JsonMessageConstants.SIZE);
- case SentDate :
- return SortBuilders.fieldSort(JsonMessageConstants.SENT_DATE);
- case Uid :
- return SortBuilders.fieldSort(JsonMessageConstants.UID);
- case Id:
- return SortBuilders.fieldSort(JsonMessageConstants.MESSAGE_ID);
- default:
- throw new RuntimeException("Sort is not implemented");
- }
- }
-
- private static SortOrder getOrder(SearchQuery.Sort sort) {
- if (sort.isReverse()) {
- return SortOrder.DESC;
- } else {
- return SortOrder.ASC;
- }
- }
-}
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
deleted file mode 100644
index 0e74473..0000000
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.search;
-
-import static org.apache.james.util.ReactorUtils.publishIfPresent;
-
-import java.util.Collection;
-import java.util.Optional;
-
-import org.apache.james.backends.es.AliasName;
-import org.apache.james.backends.es.NodeMappingFactory;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.RoutingKey;
-import org.apache.james.backends.es.search.ScrolledSearch;
-import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.elasticsearch.query.SortConverter;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.mailbox.store.search.MessageSearchIndex;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.common.document.DocumentField;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import reactor.core.publisher.Flux;
-
-public class ElasticSearchSearcher {
- public static final int DEFAULT_SEARCH_SIZE = 100;
- private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchSearcher.class);
- private static final TimeValue TIMEOUT = TimeValue.timeValueMinutes(1);
- private static final ImmutableList<String> STORED_FIELDS = ImmutableList.of(JsonMessageConstants.MAILBOX_ID,
- JsonMessageConstants.UID, JsonMessageConstants.MESSAGE_ID);
- private static final int MAX_ROUTING_KEY = 5;
-
- private final ReactorElasticSearchClient client;
- private final QueryConverter queryConverter;
- private final int size;
- private final MailboxId.Factory mailboxIdFactory;
- private final MessageId.Factory messageIdFactory;
- private final AliasName aliasName;
- private final RoutingKey.Factory<MailboxId> routingKeyFactory;
-
- public ElasticSearchSearcher(ReactorElasticSearchClient client, QueryConverter queryConverter, int size,
- MailboxId.Factory mailboxIdFactory, MessageId.Factory messageIdFactory,
- ReadAliasName aliasName, RoutingKey.Factory<MailboxId> routingKeyFactory) {
- this.client = client;
- this.queryConverter = queryConverter;
- this.size = size;
- this.mailboxIdFactory = mailboxIdFactory;
- this.messageIdFactory = messageIdFactory;
- this.aliasName = aliasName;
- this.routingKeyFactory = routingKeyFactory;
- }
-
- public Flux<MessageSearchIndex.SearchResult> search(Collection<MailboxId> mailboxIds, SearchQuery query,
- Optional<Integer> limit) {
- SearchRequest searchRequest = prepareSearch(mailboxIds, query, limit);
- Flux<MessageSearchIndex.SearchResult> pairStream = new ScrolledSearch(client, searchRequest)
- .searchHits()
- .map(this::extractContentFromHit)
- .handle(publishIfPresent());
-
- return limit.map(pairStream::take)
- .orElse(pairStream);
- }
-
- private SearchRequest prepareSearch(Collection<MailboxId> mailboxIds, SearchQuery query, Optional<Integer> limit) {
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
- .query(queryConverter.from(mailboxIds, query))
- .size(computeRequiredSize(limit))
- .storedFields(STORED_FIELDS);
-
- query.getSorts()
- .stream()
- .map(SortConverter::convertSort)
- .forEach(searchSourceBuilder::sort);
-
- SearchRequest request = new SearchRequest(aliasName.getValue())
- .types(NodeMappingFactory.DEFAULT_MAPPING_NAME)
- .scroll(TIMEOUT)
- .source(searchSourceBuilder);
-
- return toRoutingKey(mailboxIds)
- .map(request::routing)
- .orElse(request);
- }
-
- private Optional<String[]> toRoutingKey(Collection<MailboxId> mailboxIds) {
- if (mailboxIds.size() < MAX_ROUTING_KEY) {
- return Optional.of(mailboxIds.stream()
- .map(routingKeyFactory::from)
- .map(RoutingKey::asString)
- .toArray(String[]::new));
- }
- return Optional.empty();
- }
-
- private int computeRequiredSize(Optional<Integer> limit) {
- return limit.map(value -> Math.min(value.intValue(), size))
- .orElse(size);
- }
-
- private Optional<MessageSearchIndex.SearchResult> extractContentFromHit(SearchHit hit) {
- DocumentField mailboxId = hit.field(JsonMessageConstants.MAILBOX_ID);
- DocumentField uid = hit.field(JsonMessageConstants.UID);
- Optional<DocumentField> id = retrieveMessageIdField(hit);
- if (mailboxId != null && uid != null) {
- Number uidAsNumber = uid.getValue();
- return Optional.of(
- new MessageSearchIndex.SearchResult(
- id.map(field -> messageIdFactory.fromString(field.getValue())),
- mailboxIdFactory.fromString(mailboxId.getValue()),
- MessageUid.of(uidAsNumber.longValue())));
- } else {
- LOGGER.warn("Can not extract UID, MessageID and/or MailboxId for search result {}", hit.getId());
- return Optional.empty();
- }
- }
-
- private Optional<DocumentField> retrieveMessageIdField(SearchHit hit) {
- if (hit.getFields().containsKey(JsonMessageConstants.MESSAGE_ID)) {
- return Optional.ofNullable(hit.field(JsonMessageConstants.MESSAGE_ID));
- }
- return Optional.empty();
- }
-
-}
diff --git a/mailbox/elasticsearch/src/reporting-site/site.xml b/mailbox/elasticsearch/src/reporting-site/site.xml
deleted file mode 100644
index d919164..0000000
--- a/mailbox/elasticsearch/src/reporting-site/site.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project name="${project.name}">
-
- <body>
-
- <menu ref="parent" />
- <menu ref="reports" />
-
- </body>
-
-</project>
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
deleted file mode 100644
index 65b451d..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.time.ZoneId;
-import java.util.List;
-
-import org.apache.james.backends.es.DockerElasticSearchExtension;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MailboxSessionUtil;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex;
-import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
-import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
-import org.apache.james.mailbox.inmemory.InMemoryId;
-import org.apache.james.mailbox.inmemory.InMemoryMessageId;
-import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
-import org.apache.james.mailbox.model.ComposedMessageId;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.mailbox.store.search.AbstractMessageSearchIndexTest;
-import org.apache.james.mailbox.tika.TikaConfiguration;
-import org.apache.james.mailbox.tika.TikaExtension;
-import org.apache.james.mailbox.tika.TikaHttpClientImpl;
-import org.apache.james.mailbox.tika.TikaTextExtractor;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.apache.james.mime4j.dom.Message;
-import org.apache.james.mime4j.stream.RawField;
-import org.apache.james.util.ClassLoaderUtils;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import com.google.common.base.Strings;
-
-import reactor.core.publisher.Flux;
-
-class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
-
- static final int BATCH_SIZE = 1;
- static final int SEARCH_SIZE = 1;
-
- @RegisterExtension
- static TikaExtension tika = new TikaExtension();
-
- @RegisterExtension
- DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
-
- TikaTextExtractor textExtractor;
- ReactorElasticSearchClient client;
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Override
- protected void awaitMessageCount(List<MailboxId> mailboxIds, SearchQuery query, long messageCount) {
- elasticSearch.awaitForElasticSearch();
- }
-
- @Override
- protected void initializeMailboxManager() throws Exception {
- textExtractor = new TikaTextExtractor(new RecordingMetricFactory(),
- new TikaHttpClientImpl(TikaConfiguration.builder()
- .host(tika.getIp())
- .port(tika.getPort())
- .timeoutInMillis(tika.getTimeoutInMillis())
- .build()));
-
- client = MailboxIndexCreationUtil.prepareDefaultClient(
- elasticSearch.getDockerElasticSearch().clientProvider().get(),
- elasticSearch.getDockerElasticSearch().configuration());
-
- InMemoryMessageId.Factory messageIdFactory = new InMemoryMessageId.Factory();
- MailboxIdRoutingKeyFactory routingKeyFactory = new MailboxIdRoutingKeyFactory();
-
- InMemoryIntegrationResources resources = InMemoryIntegrationResources.builder()
- .preProvisionnedFakeAuthenticator()
- .fakeAuthorizator()
- .inVmEventBus()
- .defaultAnnotationLimits()
- .defaultMessageParser()
- .listeningSearchIndex(preInstanciationStage -> new ElasticSearchListeningMessageSearchIndex(
- preInstanciationStage.getMapperFactory(),
- new ElasticSearchIndexer(client,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS,
- BATCH_SIZE),
- new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE,
- new InMemoryId.Factory(), messageIdFactory,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, routingKeyFactory),
- new MessageToElasticSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES),
- preInstanciationStage.getSessionProvider(), routingKeyFactory))
- .noPreDeletionHooks()
- .storeQuotaManager()
- .build();
-
- storeMailboxManager = resources.getMailboxManager();
- messageIdManager = resources.getMessageIdManager();
- messageSearchIndex = resources.getSearchIndex();
- }
-
- @Test
- void termsBetweenElasticSearchAndLuceneLimitDueTuNonAsciiCharsShouldBeTruncated() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- String recipient = "benwa@linagora.com";
- ComposedMessageId composedMessageId = messageManager.appendMessage(MessageManager.AppendCommand.from(
- Message.Builder.of()
- .setTo(recipient)
- .setBody(Strings.repeat("0à 2345678é", 3200), StandardCharsets.UTF_8)),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, recipient)), session)).toStream())
- .containsExactly(composedMessageId.getUid());
- }
-
- @Test
- void tooLongTermsShouldNotMakeIndexingFail() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- String recipient = "benwa@linagora.com";
- ComposedMessageId composedMessageId = messageManager.appendMessage(MessageManager.AppendCommand.from(
- Message.Builder.of()
- .setTo(recipient)
- .setBody(Strings.repeat("0123456789", 3300), StandardCharsets.UTF_8)),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, recipient)), session)).toStream())
- .containsExactly(composedMessageId.getUid());
- }
-
- @Test
- void fieldsExceedingLuceneLimitShouldNotBeIgnored() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- String recipient = "benwa@linagora.com";
- ComposedMessageId composedMessageId = messageManager.appendMessage(MessageManager.AppendCommand.from(
- Message.Builder.of()
- .setTo(recipient)
- .setBody(Strings.repeat("0123456789 ", 5000), StandardCharsets.UTF_8)),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("0123456789")), session)).toStream())
- .containsExactly(composedMessageId.getUid());
- }
-
- @Test
- void fieldsWithTooLongTermShouldStillBeIndexed() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- String recipient = "benwa@linagora.com";
- ComposedMessageId composedMessageId = messageManager.appendMessage(MessageManager.AppendCommand.from(
- Message.Builder.of()
- .setTo(recipient)
- .setBody(Strings.repeat("0123456789 ", 5000) + " matchMe", StandardCharsets.UTF_8)),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("matchMe")), session)).toStream())
- .containsExactly(composedMessageId.getUid());
- }
-
- @Test
- void reasonableLongTermShouldNotBeIgnored() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- String recipient = "benwa@linagora.com";
- String reasonableLongTerm = "dichlorodiphényltrichloroéthane";
- ComposedMessageId composedMessageId = messageManager.appendMessage(MessageManager.AppendCommand.from(
- Message.Builder.of()
- .setTo(recipient)
- .setBody(reasonableLongTerm, StandardCharsets.UTF_8)),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains(reasonableLongTerm)), session)).toStream())
- .containsExactly(composedMessageId.getUid());
- }
-
- @Test
- void headerSearchShouldIncludeMessageWhenDifferentTypesOnAnIndexedField() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- ComposedMessageId customDateHeaderMessageId = messageManager.appendMessage(
- MessageManager.AppendCommand.builder()
- .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mailCustomDateHeader.eml")),
- session).getId();
-
- ComposedMessageId customStringHeaderMessageId = messageManager.appendMessage(
- MessageManager.AppendCommand.builder()
- .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mailCustomStringHeader.eml")),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.headerExists("Custom-header")), session)).toStream())
- .containsExactly(customDateHeaderMessageId.getUid(), customStringHeaderMessageId.getUid());
- }
-
- @Test
- void messageShouldStillBeIndexedEvenAfterOneFieldFailsIndexation() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- messageManager.appendMessage(
- MessageManager.AppendCommand.builder()
- .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mailCustomDateHeader.eml")),
- session);
-
- ComposedMessageId customStringHeaderMessageId = messageManager.appendMessage(
- MessageManager.AppendCommand.builder()
- .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mailCustomStringHeader.eml")),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.all()), session)).toStream())
- .contains(customStringHeaderMessageId.getUid());
- }
-
- @Test
- void addressMatchesShouldBeExact() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- Message.Builder messageBuilder = Message.Builder
- .of()
- .setSubject("test")
- .setBody("testmail", StandardCharsets.UTF_8);
-
- ComposedMessageId messageId1 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "alice@domain.tld"))
- .build()),
- session).getId();
-
- ComposedMessageId messageId2 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "bob@other.tld"))
- .build()),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, "bob@other.tld")), session)).toStream())
- .containsOnly(messageId2.getUid());
- }
-
- @Disabled("MAILBOX-403 Relaxed the matching constraints for email addresses in text bodies to reduce ElasticSearch disk space usage")
- @Test
- public void textShouldNotMatchOtherAddressesOfTheSameDomain() {
-
- }
-
- @Disabled("MAILBOX-401 '-' causes address matching to fail")
- @Test
- void localPartShouldBeMatchedWhenHyphen() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- Message.Builder messageBuilder = Message.Builder
- .of()
- .setSubject("test")
- .setBody("testmail", StandardCharsets.UTF_8);
-
- ComposedMessageId messageId1 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "alice-test@domain.tld"))
- .build()),
- session).getId();
-
- ComposedMessageId messageId2 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "bob@other.tld"))
- .build()),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, "alice-test")), session)).toStream())
- .containsOnly(messageId2.getUid());
- }
-
- @Disabled("MAILBOX-401 '-' causes address matching to fail")
- @Test
- void addressShouldBeMatchedWhenHyphen() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- Message.Builder messageBuilder = Message.Builder
- .of()
- .setSubject("test")
- .setBody("testmail", StandardCharsets.UTF_8);
-
- ComposedMessageId messageId1 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "alice-test@domain.tld"))
- .build()),
- session).getId();
-
- ComposedMessageId messageId2 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "bob@other.tld"))
- .build()),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, "alice-test@domain.tld")), session)).toStream())
- .containsOnly(messageId1.getUid());
- }
-
- @Disabled("MAILBOX-401 '-' causes address matching to fail")
- @Test
- void domainPartShouldBeMatchedWhenHyphen() throws Exception {
- MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- Message.Builder messageBuilder = Message.Builder
- .of()
- .setSubject("test")
- .setBody("testmail", StandardCharsets.UTF_8);
-
- ComposedMessageId messageId1 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "alice@domain-test.tld"))
- .build()),
- session).getId();
-
- ComposedMessageId messageId2 = messageManager.appendMessage(
- MessageManager.AppendCommand.builder().build(
- messageBuilder
- .addField(new RawField("To", "bob@other.tld"))
- .build()),
- session).getId();
-
- elasticSearch.awaitForElasticSearch();
-
- assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.address(SearchQuery.AddressType.To, "domain-test.tld")), session)).toStream())
- .containsOnly(messageId1.getUid());
- }
-}
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfigurationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfigurationTest.java
deleted file mode 100644
index ff6e7de..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchMailboxConfigurationTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.commons.configuration2.PropertiesConfiguration;
-import org.apache.james.backends.es.IndexName;
-import org.apache.james.backends.es.ReadAliasName;
-import org.apache.james.backends.es.WriteAliasName;
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class ElasticSearchMailboxConfigurationTest {
- @Test
- void elasticSearchMailboxConfigurationShouldRespectBeanContract() {
- EqualsVerifier.forClass(ElasticSearchMailboxConfiguration.class)
- .verify();
- }
-
- @Test
- void getIndexMailboxNameShouldReturnOldConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.index.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexMailboxName())
- .isEqualTo(new IndexName(name));
- }
-
- @Test
- void getIndexMailboxNameShouldReturnNewConfiguredValueWhenBoth() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.index.name", "other");
- configuration.addProperty("elasticsearch.index.mailbox.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexMailboxName())
- .isEqualTo(new IndexName(name));
- }
-
- @Test
- void getIndexMailboxNameShouldReturnConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.index.mailbox.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexMailboxName())
- .isEqualTo(new IndexName(name));
- }
-
- @Test
- void getIndexMailboxNameShouldReturnDefaultValueWhenMissing() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexMailboxName())
- .isEqualTo(MailboxElasticSearchConstants.DEFAULT_MAILBOX_INDEX);
- }
-
- @Test
- void getReadAliasMailboxNameShouldReturnOldConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.read.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getReadAliasMailboxName())
- .isEqualTo(new ReadAliasName(name));
- }
-
- @Test
- void getReadAliasMailboxNameShouldReturnConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.read.mailbox.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getReadAliasMailboxName())
- .isEqualTo(new ReadAliasName(name));
- }
-
- @Test
- void getReadAliasMailboxNameShouldReturnNewConfiguredValueWhenBoth() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.read.mailbox.name", name);
- configuration.addProperty("elasticsearch.alias.read.name", "other");
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getReadAliasMailboxName())
- .isEqualTo(new ReadAliasName(name));
- }
-
- @Test
- void getReadAliasMailboxNameShouldReturnDefaultValueWhenMissing() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getReadAliasMailboxName())
- .isEqualTo(MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS);
- }
-
- @Test
- void getWriteAliasMailboxNameShouldReturnOldConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.write.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWriteAliasMailboxName())
- .isEqualTo(new WriteAliasName(name));
- }
-
- @Test
- void getWriteAliasMailboxNameShouldReturnConfiguredValue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.write.mailbox.name", name);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWriteAliasMailboxName())
- .isEqualTo(new WriteAliasName(name));
- }
-
- @Test
- void getWriteAliasMailboxNameShouldReturnNewConfiguredValueWhenBoth() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- String name = "name";
- configuration.addProperty("elasticsearch.alias.write.mailbox.name", name);
- configuration.addProperty("elasticsearch.alias.write.name", "other");
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWriteAliasMailboxName())
- .isEqualTo(new WriteAliasName(name));
- }
-
- @Test
- void getWriteAliasMailboxNameShouldReturnDefaultValueWhenMissing() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getWriteAliasMailboxName())
- .isEqualTo(MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS);
- }
-
- @Test
- void getIndexAttachmentShouldReturnConfiguredValueWhenTrue() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.indexAttachments", true);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexAttachment())
- .isEqualTo(IndexAttachments.YES);
- }
-
- @Test
- void getIndexAttachmentShouldReturnConfiguredValueWhenFalse() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.indexAttachments", false);
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexAttachment())
- .isEqualTo(IndexAttachments.NO);
- }
-
- @Test
- void getIndexAttachmentShouldReturnDefaultValueWhenMissing() {
- PropertiesConfiguration configuration = new PropertiesConfiguration();
- configuration.addProperty("elasticsearch.hosts", "127.0.0.1");
-
- ElasticSearchMailboxConfiguration elasticSearchConfiguration = ElasticSearchMailboxConfiguration.fromProperties(configuration);
-
- assertThat(elasticSearchConfiguration.getIndexAttachment())
- .isEqualTo(IndexAttachments.YES);
- }
-
-}
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactoryTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactoryTest.java
deleted file mode 100644
index b666ffa..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/MailboxIdRoutingKeyFactoryTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.james.backends.es.RoutingKey;
-import org.apache.james.mailbox.model.TestId;
-import org.junit.jupiter.api.Test;
-
-class MailboxIdRoutingKeyFactoryTest {
- @Test
- void fromShouldRelyOnSerializedMailboxId() {
- assertThat(new MailboxIdRoutingKeyFactory().from(TestId.of(5)))
- .isEqualTo(RoutingKey.fromString("5"));
- }
-}
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
deleted file mode 100644
index 144ec2e..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.mailbox.elasticsearch.events;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.time.Duration;
-import java.time.ZoneId;
-import java.util.Date;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-
-import javax.mail.Flags;
-
-import org.apache.james.backends.es.DockerElasticSearchExtension;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.core.Username;
-import org.apache.james.events.Group;
-import org.apache.james.mailbox.Authorizator;
-import org.apache.james.mailbox.DefaultMailboxes;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
-import org.apache.james.mailbox.elasticsearch.MailboxIdRoutingKeyFactory;
-import org.apache.james.mailbox.elasticsearch.MailboxIndexCreationUtil;
-import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
-import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
-import org.apache.james.mailbox.extractor.ParsedContent;
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.inmemory.InMemoryId;
-import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
-import org.apache.james.mailbox.inmemory.InMemoryMessageId;
-import org.apache.james.mailbox.manager.ManagerTestProvisionner;
-import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.AttachmentMetadata;
-import org.apache.james.mailbox.model.ByteContent;
-import org.apache.james.mailbox.model.ContentType;
-import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageAttachmentMetadata;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.model.UidValidity;
-import org.apache.james.mailbox.model.UpdatedFlags;
-import org.apache.james.mailbox.store.FakeAuthenticator;
-import org.apache.james.mailbox.store.FakeAuthorizator;
-import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
-import org.apache.james.mailbox.store.SessionProviderImpl;
-import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
-import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
-import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
-import org.apache.james.mailbox.store.search.ListeningMessageSearchIndexContract;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-class ElasticSearchListeningMessageSearchIndexTest {
- static final int SIZE = 25;
- static final int BODY_START_OCTET = 100;
- static final TestId MAILBOX_ID = TestId.of(1L);
- static final ModSeq MOD_SEQ = ModSeq.of(42L);
- static final Username USERNAME = Username.of("user");
- static final MessageUid MESSAGE_UID_1 = MessageUid.of(25);
- public static final UpdatedFlags UPDATED_FLAGS = UpdatedFlags.builder()
- .uid(MESSAGE_UID_1)
- .modSeq(MOD_SEQ)
- .oldFlags(new Flags())
- .newFlags(new Flags(Flags.Flag.ANSWERED))
- .build();
- static final MessageUid MESSAGE_UID_2 = MessageUid.of(26);
- static final MessageUid MESSAGE_UID_3 = MessageUid.of(27);
- static final MessageUid MESSAGE_UID_4 = MessageUid.of(28);
- static final MessageId MESSAGE_ID_1 = TestMessageId.of(18L);
- static final MessageId MESSAGE_ID_2 = TestMessageId.of(19L);
- static final MessageId MESSAGE_ID_3 = TestMessageId.of(20L);
- static final MessageId MESSAGE_ID_4 = TestMessageId.of(21L);
-
- static final SimpleMailboxMessage.Builder MESSAGE_BUILDER = SimpleMailboxMessage.builder()
- .mailboxId(MAILBOX_ID)
- .flags(new Flags())
- .bodyStartOctet(BODY_START_OCTET)
- .internalDate(new Date(1433628000000L))
- .size(SIZE)
- .content(new ByteContent("message".getBytes(StandardCharsets.UTF_8)))
- .properties(new PropertyBuilder())
- .modseq(MOD_SEQ);
-
- static final SimpleMailboxMessage MESSAGE_1 = MESSAGE_BUILDER.messageId(MESSAGE_ID_1)
- .uid(MESSAGE_UID_1)
- .build();
-
- static final SimpleMailboxMessage MESSAGE_2 = MESSAGE_BUILDER.messageId(MESSAGE_ID_2)
- .uid(MESSAGE_UID_2)
- .build();
-
- static final MessageAttachmentMetadata MESSAGE_ATTACHMENT = MessageAttachmentMetadata.builder()
- .attachment(AttachmentMetadata.builder()
- .attachmentId(AttachmentId.from("1"))
- .type("type")
- .size(523)
- .build())
- .name("name")
- .isInline(false)
- .build();
-
- static final SimpleMailboxMessage MESSAGE_WITH_ATTACHMENT = MESSAGE_BUILDER.messageId(MESSAGE_ID_3)
- .uid(MESSAGE_UID_3)
- .addAttachments(ImmutableList.of(MESSAGE_ATTACHMENT))
- .build();
- public static final Duration TIMEOUT = Duration.ofSeconds(1);
-
- static class FailingTextExtractor implements TextExtractor {
- @Override
- public ParsedContent extractContent(InputStream inputStream, ContentType contentType) {
- throw new RuntimeException();
- }
- }
-
- ElasticSearchListeningMessageSearchIndex testee;
- MailboxSession session;
- Mailbox mailbox;
- MailboxSessionMapperFactory mapperFactory;
- ElasticSearchIndexer elasticSearchIndexer;
- ElasticSearchSearcher elasticSearchSearcher;
- SessionProviderImpl sessionProvider;
-
- @RegisterExtension
- DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
-
- @BeforeEach
- void setup() throws Exception {
- mapperFactory = new InMemoryMailboxSessionMapperFactory();
-
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("UTC"),
- IndexAttachments.YES);
-
- InMemoryMessageId.Factory messageIdFactory = new InMemoryMessageId.Factory();
-
- ReactorElasticSearchClient client = MailboxIndexCreationUtil.prepareDefaultClient(
- elasticSearch.getDockerElasticSearch().clientProvider().get(),
- elasticSearch.getDockerElasticSearch().configuration(Optional.of(TIMEOUT)));
-
- elasticSearchSearcher = new ElasticSearchSearcher(client,
- new QueryConverter(new CriterionConverter()),
- ElasticSearchSearcher.DEFAULT_SEARCH_SIZE,
- new InMemoryId.Factory(),
- messageIdFactory,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS,
- new MailboxIdRoutingKeyFactory());
-
- FakeAuthenticator fakeAuthenticator = new FakeAuthenticator();
- fakeAuthenticator.addUser(ManagerTestProvisionner.USER, ManagerTestProvisionner.USER_PASS);
- Authorizator authorizator = FakeAuthorizator.defaultReject();
- sessionProvider = new SessionProviderImpl(fakeAuthenticator, authorizator);
-
- elasticSearchIndexer = new ElasticSearchIndexer(client, MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS);
-
- testee = new ElasticSearchListeningMessageSearchIndex(mapperFactory, elasticSearchIndexer, elasticSearchSearcher,
- messageToElasticSearchJson, sessionProvider, new MailboxIdRoutingKeyFactory());
- session = sessionProvider.createSystemSession(USERNAME);
-
- mailbox = mapperFactory.getMailboxMapper(session).create(MailboxPath.forUser(USERNAME, DefaultMailboxes.INBOX), UidValidity.generate()).block();
- }
-
- @Test
- void addDeleteAndUpdateShouldPropagateExceptionWhenExceptionOccurs() throws Exception {
- elasticSearch.getDockerElasticSearch().pause();
- Thread.sleep(Duration.ofSeconds(5).toMillis()); // Docker pause is asynchronous and we found no way to poll for it
-
-
- CompletableFuture<Void> add = testee.add(session, mailbox, MESSAGE_1).toFuture();
- CompletableFuture<Void> delete = testee.delete(session, mailbox.getMailboxId(), Lists.newArrayList(MESSAGE_UID_1)).toFuture();
- CompletableFuture<Void> update = testee.update(session, mailbox.getMailboxId(), Lists.newArrayList(UPDATED_FLAGS)).toFuture();
-
- assertThatThrownBy(add::get).hasCauseInstanceOf(IOException.class);
- assertThatThrownBy(delete::get).hasCauseInstanceOf(IOException.class);
- assertThatThrownBy(update::get).hasCauseInstanceOf(IOException.class);
-
- elasticSearch.getDockerElasticSearch().unpause();
- }
-
- @Test
- void deserializeElasticSearchListeningMessageSearchIndexGroup() throws Exception {
- assertThat(Group.deserialize("org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex$ElasticSearchListeningMessageSearchIndexGroup"))
- .isEqualTo(new ElasticSearchListeningMessageSearchIndex.ElasticSearchListeningMessageSearchIndexGroup());
- }
-
- @Test
- void addShouldIndexMessageWithoutAttachment() {
- testee.add(session, mailbox, MESSAGE_1).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_1.getUid());
- }
-
-
- @Test
- void addShouldIndexMessageWithAttachment() {
- testee.add(session, mailbox, MESSAGE_WITH_ATTACHMENT).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_WITH_ATTACHMENT.getUid());
- }
-
- @Test
- void addShouldBeIndempotent() {
- testee.add(session, mailbox, MESSAGE_1).block();
- testee.add(session, mailbox, MESSAGE_1).block();
-
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_1.getUid());
- }
-
- @Test
- void addShouldIndexMultipleMessages() {
- testee.add(session, mailbox, MESSAGE_1).block();
- testee.add(session, mailbox, MESSAGE_2).block();
-
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_1.getUid(), MESSAGE_2.getUid());
- }
-
- @Test
- void addShouldIndexEmailBodyWhenNotIndexableAttachment() {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new FailingTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.YES);
-
- testee = new ElasticSearchListeningMessageSearchIndex(mapperFactory, elasticSearchIndexer, elasticSearchSearcher,
- messageToElasticSearchJson, sessionProvider, new MailboxIdRoutingKeyFactory());
-
- testee.add(session, mailbox, MESSAGE_WITH_ATTACHMENT).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_WITH_ATTACHMENT.getUid());
- }
-
- @Test
- void deleteShouldRemoveIndex() {
- testee.add(session, mailbox, MESSAGE_1).block();
- elasticSearch.awaitForElasticSearch();
-
- testee.delete(session, mailbox.getMailboxId(), Lists.newArrayList(MESSAGE_UID_1)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .isEmpty();
- }
-
- @Test
- void deleteShouldOnlyRemoveIndexesPassedAsArguments() {
- testee.add(session, mailbox, MESSAGE_1).block();
- testee.add(session, mailbox, MESSAGE_2).block();
-
- elasticSearch.awaitForElasticSearch();
-
- testee.delete(session, mailbox.getMailboxId(), Lists.newArrayList(MESSAGE_UID_1)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_2.getUid());
- }
-
- @Test
- void deleteShouldRemoveMultipleIndexes() {
- testee.add(session, mailbox, MESSAGE_1).block();
- testee.add(session, mailbox, MESSAGE_2).block();
-
- elasticSearch.awaitForElasticSearch();
-
- testee.delete(session, mailbox.getMailboxId(), Lists.newArrayList(MESSAGE_UID_1, MESSAGE_UID_2)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .isEmpty();
- }
-
- @Test
- void deleteShouldBeIdempotent() {
- testee.add(session, mailbox, MESSAGE_1).block();
- elasticSearch.awaitForElasticSearch();
-
- testee.delete(session, mailbox.getMailboxId(), Lists.newArrayList(MESSAGE_UID_1)).block();
- testee.delete(session, mailbox.getMailboxId(), Lists.newArrayList(MESSAGE_UID_1)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .isEmpty();
- }
-
- @Test
- void deleteShouldNotThrowOnUnknownMessageUid() {
- assertThatCode(() -> testee.delete(session, mailbox.getMailboxId(), Lists.newArrayList(MESSAGE_UID_1)).block())
- .doesNotThrowAnyException();
- }
-
- @Test
- void updateShouldUpdateIndex() {
- testee.add(session, mailbox, MESSAGE_1).block();
- elasticSearch.awaitForElasticSearch();
-
- Flags newFlags = new Flags(Flags.Flag.ANSWERED);
- UpdatedFlags updatedFlags = UpdatedFlags.builder()
- .uid(MESSAGE_UID_1)
- .modSeq(MOD_SEQ)
- .oldFlags(new Flags())
- .newFlags(newFlags)
- .build();
-
- testee.update(session, mailbox.getMailboxId(), Lists.newArrayList(updatedFlags)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.flagIsSet(Flags.Flag.ANSWERED));
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_1.getUid());
- }
-
- @Test
- void updateShouldNotUpdateNorThrowOnUnknownMessageUid() {
- testee.add(session, mailbox, MESSAGE_1).block();
- elasticSearch.awaitForElasticSearch();
-
- Flags newFlags = new Flags(Flags.Flag.ANSWERED);
- UpdatedFlags updatedFlags = UpdatedFlags.builder()
- .uid(MESSAGE_UID_2)
- .modSeq(MOD_SEQ)
- .oldFlags(new Flags())
- .newFlags(newFlags)
- .build();
-
- testee.update(session, mailbox.getMailboxId(), Lists.newArrayList(updatedFlags)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.flagIsSet(Flags.Flag.ANSWERED));
- assertThat(testee.search(session, mailbox, query).toStream())
- .isEmpty();
- }
-
- @Test
- void updateShouldBeIdempotent() {
- testee.add(session, mailbox, MESSAGE_1).block();
- elasticSearch.awaitForElasticSearch();
-
- Flags newFlags = new Flags(Flags.Flag.ANSWERED);
- UpdatedFlags updatedFlags = UpdatedFlags.builder()
- .uid(MESSAGE_UID_1)
- .modSeq(MOD_SEQ)
- .oldFlags(new Flags())
- .newFlags(newFlags)
- .build();
-
- testee.update(session, mailbox.getMailboxId(), Lists.newArrayList(updatedFlags)).block();
- testee.update(session, mailbox.getMailboxId(), Lists.newArrayList(updatedFlags)).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.flagIsSet(Flags.Flag.ANSWERED));
- assertThat(testee.search(session, mailbox, query).toStream())
- .containsExactly(MESSAGE_1.getUid());
- }
-
- @Test
- void deleteAllShouldRemoveAllIndexes() {
- testee.add(session, mailbox, MESSAGE_1).block();
- testee.add(session, mailbox, MESSAGE_2).block();
-
- elasticSearch.awaitForElasticSearch();
-
- testee.deleteAll(session, mailbox.getMailboxId()).block();
- elasticSearch.awaitForElasticSearch();
-
- SearchQuery query = SearchQuery.of(SearchQuery.all());
- assertThat(testee.search(session, mailbox, query).toStream())
- .isEmpty();
- }
-
- @Test
- void deleteAllShouldNotThrowWhenEmptyIndex() {
- assertThatCode(() -> testee.deleteAll(session, mailbox.getMailboxId()).block())
- .doesNotThrowAnyException();
- }
-
- @Nested
- class RetrieveIndexedFlags implements ListeningMessageSearchIndexContract {
- @Override
- public ListeningMessageSearchIndex testee() {
- return testee;
- }
-
- @Override
- public MailboxSession session() {
- return session;
- }
-
- @Override
- public Mailbox mailbox() {
- return mailbox;
- }
-
- @Test
- void retrieveIndexedFlagsShouldReturnEmptyWhenNotFound() {
- assertThat(testee.retrieveIndexedFlags(mailbox, MESSAGE_UID_4).blockOptional())
- .isEmpty();
- }
- }
-}
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailerTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailerTest.java
deleted file mode 100644
index 521bf5c..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailerTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import org.junit.jupiter.api.Test;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-
-class EMailerTest {
- @Test
- void eMailerShouldRespectBeanContract() {
- EqualsVerifier.forClass(EMailer.class)
- .verify();
- }
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailersTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailersTest.java
deleted file mode 100644
index 31e957e..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/EMailersTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.util.Optional;
-
-import org.junit.jupiter.api.Test;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableSet;
-
-class EMailersTest {
-
- @Test
- void fromShouldThrowWhenSetIsNull() {
- assertThatThrownBy(() -> EMailers.from(null))
- .isInstanceOf(NullPointerException.class)
- .hasMessage("'emailers' is mandatory");
- }
-
- @Test
- void serializeShouldReturnEmptyWhenEmptySet() {
- EMailers eMailers = EMailers.from(ImmutableSet.of());
-
- assertThat(eMailers.serialize()).isEmpty();
- }
-
- @Test
- void serializeShouldNotJoinWhenOneElement() {
- EMailer emailer = new EMailer(Optional.of("name"), "address");
- EMailers eMailers = EMailers.from(ImmutableSet.of(emailer));
-
- assertThat(eMailers.serialize()).isEqualTo(emailer.serialize());
- }
-
- @Test
- void serializeShouldJoinWhenMultipleElements() {
- EMailer emailer = new EMailer(Optional.of("name"), "address");
- EMailer emailer2 = new EMailer(Optional.of("name2"), "address2");
- EMailer emailer3 = new EMailer(Optional.of("name3"), "address3");
-
- String expected = Joiner.on(" ").join(emailer.serialize(), emailer2.serialize(), emailer3.serialize());
-
- EMailers eMailers = EMailers.from(ImmutableSet.of(emailer, emailer2, emailer3));
-
- assertThat(eMailers.serialize()).isEqualTo(expected);
- }
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/FieldImpl.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/FieldImpl.java
deleted file mode 100644
index d56d71e..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/FieldImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import java.util.Objects;
-
-import org.apache.james.mime4j.stream.Field;
-import org.apache.james.mime4j.util.ByteSequence;
-
-public class FieldImpl implements Field {
- private final String name;
- private final String body;
-
- public FieldImpl(String name, String body) {
- this.name = name;
- this.body = body;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public String getBody() {
- return body;
- }
-
- @Override
- public ByteSequence getRaw() {
- return null;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(name, body);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof FieldImpl) {
- FieldImpl otherField = (FieldImpl) o;
- return Objects.equals(name, otherField.name)
- && Objects.equals(body, otherField.body);
- }
- return false;
- }
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
deleted file mode 100644
index f7aec4e..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.time.format.DateTimeFormatter;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.ArgumentsProvider;
-import org.junit.jupiter.params.provider.ArgumentsSource;
-
-class HeaderCollectionTest {
-
- static class UTF8FromHeaderTestSource implements ArgumentsProvider {
-
- @Override
- public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {
- return Stream.of(
- Arguments.of("=?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= <fm...@linagora.com>, Graham CROSMARIE <gc...@linagora.com>", "Frédéric MARTIN"),
- Arguments.of("=?UTF-8?Q?=C3=9Csteli=C4=9Fhan_Ma=C5=9Frapa?= <us...@domain.tld>", "Üsteliğhan Maşrapa"),
- Arguments.of("=?UTF-8?Q?Ke=C5=9Ffet_Turizm?= <ke...@domain.tld>", "KeÅŸfet Turizm"),
- Arguments.of("=?UTF-8?Q?MODAL=C4=B0F?= <mo...@domain.tld>", "MODALİF"));
- }
- }
-
- private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
-
- @Test
- void simpleValueAddressHeaderShouldBeAddedToTheAddressSet() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("To", "ben.tellier@linagora.com"))
- .build();
-
- assertThat(headerCollection.getToAddressSet())
- .containsOnly(new EMailer(Optional.empty(), "ben.tellier@linagora.com"));
- }
-
- @Test
- void comaSeparatedAddressShouldBeBothAddedToTheAddressSet() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("To", "ben.tellier@linagora.com, btellier@minet.net"))
- .build();
-
- assertThat(headerCollection.getToAddressSet())
- .containsOnly(
- new EMailer(Optional.empty(), "ben.tellier@linagora.com"),
- new EMailer(Optional.empty(), "btellier@minet.net"));
- }
-
- @Test
- void addressesOfTwoFieldsHavingTheSameNameShouldBeMerged() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("To", "ben.tellier@linagora.com"))
- .add(new FieldImpl("To", "ben.tellier@linagora.com, btellier@minet.net"))
- .build();
-
- assertThat(headerCollection.getToAddressSet())
- .containsOnly(
- new EMailer(Optional.empty(), "ben.tellier@linagora.com"),
- new EMailer(Optional.empty(), "btellier@minet.net"));
- }
-
- @Test
- void displayNamesShouldBeRetreived() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("To", "Christophe Hamerling <ch...@linagora.com>"))
- .build();
-
- assertThat(headerCollection.getToAddressSet())
- .containsOnly(new EMailer(Optional.of("Christophe Hamerling"), "chri.hamerling@linagora.com"));
- }
-
- @ParameterizedTest
- @ArgumentsSource(UTF8FromHeaderTestSource.class)
- void displayNamesShouldBeRetrievedWhenEncodedWord(String encodedFromHeader, String nameOfFromAddress) {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("From", encodedFromHeader))
- .build();
-
- assertThat(headerCollection.getFromAddressSet())
- .extracting(EMailer::getName)
- .contains(Optional.ofNullable(nameOfFromAddress));
- }
-
- @Test
- void getHeadersShouldDecodeValues() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("From", "=?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= <fm...@linagora.com>, Graham CROSMARIE <gc...@linagora.com>"))
- .build();
-
- assertThat(headerCollection.getHeaders())
- .containsExactly(new HeaderCollection.Header("from",
- "Frédéric MARTIN <fm...@linagora.com>, Graham CROSMARIE <gc...@linagora.com>"));
- }
-
- @Test
- void getHeadersShouldNotIgnoreHeadersWithDots() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("a.b.c", "value"))
- .build();
-
- assertThat(headerCollection.getHeaders())
- .containsExactly(new HeaderCollection.Header("a.b.c", "value"));
- }
-
- @Test
- void addressWithTwoDisplayNamesOnTheSameFieldShouldBeRetrieved() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("From", "Christophe Hamerling <ch...@linagora.com>, Graham CROSMARIE <gr...@linagora.com>"))
- .build();
-
- assertThat(headerCollection.getFromAddressSet())
- .containsOnly(new EMailer(Optional.of("Christophe Hamerling"), "chri.hamerling@linagora.com"),
- new EMailer(Optional.of("Graham CROSMARIE"), "grah.crosmarie@linagora.com"));
- }
-
- @Test
- void foldedFromHeaderShouldBeSupported() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("From", "Christophe Hamerling <ch...@linagora.com>,\r\n" +
- " Graham CROSMARIE <gr...@linagora.com>"))
- .build();
-
- assertThat(headerCollection.getFromAddressSet())
- .containsOnly(new EMailer(Optional.of("Christophe Hamerling"), "chri.hamerling@linagora.com"),
- new EMailer(Optional.of("Graham CROSMARIE"), "grah.crosmarie@linagora.com"));
- }
-
- @Test
- void foldedHeaderShouldBeSupported() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("From", "Christophe Hamerling <ch...@linagora.com>,\r\n" +
- " Graham CROSMARIE <gr...@linagora.com>"))
- .build();
-
-
- assertThat(headerCollection.getHeaders())
- .containsExactly(new HeaderCollection.Header("from",
- "Christophe Hamerling <ch...@linagora.com>, Graham CROSMARIE <gr...@linagora.com>"));
- }
-
- @Test
- void mixingAddressWithDisplayNamesWithOthersShouldBeAllowed() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("To", "Christophe Hamerling <ch...@linagora.com>, grah.crosmarie@linagora.com"))
- .build();
-
- assertThat(headerCollection.getToAddressSet())
- .containsOnly(new EMailer(Optional.of("Christophe Hamerling"), "chri.hamerling@linagora.com"),
- new EMailer(Optional.empty(), "grah.crosmarie@linagora.com"));
- }
-
- @Test
- void displayNamesShouldBeRetreivedOnCc() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Cc", "Christophe Hamerling <ch...@linagora.com>"))
- .build();
-
- assertThat(headerCollection.getCcAddressSet())
- .containsOnly(new EMailer(Optional.of("Christophe Hamerling"), "chri.hamerling@linagora.com"));
- }
-
- @Test
- void displayNamesShouldBeRetreivedOnReplyTo() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Reply-To", "Christophe Hamerling <ch...@linagora.com>"))
- .build();
-
- assertThat(headerCollection.getReplyToAddressSet())
- .containsOnly(new EMailer(Optional.of("Christophe Hamerling"), "chri.hamerling@linagora.com"));
- }
-
- @Test
- void displayNamesShouldBeRetreivedOnBcc() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Bcc", "Christophe Hamerling <ch...@linagora.com>"))
- .build();
-
- assertThat(headerCollection.getBccAddressSet())
- .containsOnly(new EMailer(Optional.of("Christophe Hamerling"), "chri.hamerling@linagora.com"));
- }
-
- @Test
- void unclosedAddressSubpartShouldBeWellHandled() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Bcc", "Mickey <tricky@mouse.com"))
- .build();
-
- assertThat(headerCollection.getBccAddressSet())
- .containsOnly(new EMailer(Optional.of("Mickey"), "tricky@mouse.com"));
- }
-
- @Test
- void notComaSeparatedAddressSubpartShouldBeWellHandled() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Bcc", "Mickey <tr...@mouse.com> Miny<he...@polo.com>"))
- .build();
-
- assertThat(headerCollection.getBccAddressSet())
- .containsOnly(new EMailer(Optional.of("Mickey"), "tricky@mouse.com"),
- new EMailer(Optional.of("Miny"), "hello@polo.com"));
- }
-
- @Test
- void notSeparatedAddressSubpartShouldBeWellHandled() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Bcc", "Mickey <tr...@polo.com>"))
- .build();
-
- assertThat(headerCollection.getBccAddressSet())
- .containsOnly(new EMailer(Optional.of("Mickey"), "tricky@mouse.com"),
- new EMailer(Optional.of("Miny"), "hello@polo.com"));
- }
-
- @Test
- void dateShouldBeRetreived() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Date", "Thu, 4 Jun 2015 06:08:41 +0200"))
- .build();
-
- assertThat(DATE_TIME_FORMATTER.format(headerCollection.getSentDate().get()))
- .isEqualTo("2015/06/04 06:08:41");
- }
-
- @Test
- void partialYearShouldBeCompleted() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Date", "Thu, 4 Jun 15 06:08:41 +0200"))
- .build();
-
- assertThat(DATE_TIME_FORMATTER.format(headerCollection.getSentDate().get()))
- .isEqualTo("2015/06/04 06:08:41");
- }
-
- @Test
- void nonStandardDatesShouldBeRetreived() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Date", "Thu, 4 Jun 2015 06:08:41 +0200 (UTC)"))
- .build();
-
- assertThat(DATE_TIME_FORMATTER.format(headerCollection.getSentDate().get()))
- .isEqualTo("2015/06/04 06:08:41");
- }
-
- @Test
- void dateShouldBeAbsentOnInvalidHeader() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Date", "Not a date"))
- .build();
-
- assertThat(headerCollection.getSentDate().isPresent())
- .isFalse();
- }
-
- @Test
- void subjectsShouldBeWellRetrieved() {
- String subject = "A fantastic ElasticSearch module will be available soon for JAMES";
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Subject", subject))
- .build();
-
- assertThat(headerCollection.getSubjectSet()).containsOnly("A fantastic ElasticSearch module will be available soon for JAMES");
- }
-
- @Test
- void getMessageIDShouldReturnMessageIdValue() {
- String messageID = "<ab...@123>";
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Message-ID", messageID))
- .build();
-
- assertThat(headerCollection.getMessageID())
- .contains(messageID);
- }
-
- @Test
- void getMessageIDShouldReturnLatestEncounteredMessageIdValue() {
- String messageID = "<ab...@123>";
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Message-ID", "<ot...@toto.com>"))
- .add(new FieldImpl("Message-ID", messageID))
- .build();
-
- assertThat(headerCollection.getMessageID())
- .contains(messageID);
- }
-
- @Test
- void getMessageIDShouldReturnEmptyWhenNoMessageId() {
- HeaderCollection headerCollection = HeaderCollection.builder()
- .add(new FieldImpl("Other", "value"))
- .build();
-
- assertThat(headerCollection.getMessageID())
- .isEmpty();
- }
-
- @Test
- void nullFieldShouldThrow() {
- assertThatThrownBy(() -> HeaderCollection.builder().add(null).build())
- .isInstanceOf(NullPointerException.class);
- }
-
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
deleted file mode 100644
index 3c97a8e..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.time.ZoneId;
-import java.util.Optional;
-
-import javax.mail.Flags;
-
-import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.extractor.ParsedContent;
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.inmemory.InMemoryMessageId;
-import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.AttachmentMetadata;
-import org.apache.james.mailbox.model.MessageAttachmentMetadata;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.tika.TikaConfiguration;
-import org.apache.james.mailbox.tika.TikaExtension;
-import org.apache.james.mailbox.tika.TikaHttpClientImpl;
-import org.apache.james.mailbox.tika.TikaTextExtractor;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-class IndexableMessageTest {
- static final MessageUid MESSAGE_UID = MessageUid.of(154);
-
- @RegisterExtension
- static TikaExtension tika = new TikaExtension();
-
- TikaTextExtractor textExtractor;
-
- @BeforeEach
- void setUp() throws Exception {
- textExtractor = new TikaTextExtractor(new RecordingMetricFactory(), new TikaHttpClientImpl(TikaConfiguration.builder()
- .host(tika.getIp())
- .port(tika.getPort())
- .timeoutInMillis(tika.getTimeoutInMillis())
- .build()));
- }
-
- @Test
- void hasAttachmentsShouldReturnTrueWhenNonInlined() throws IOException {
- //Given
- MailboxMessage mailboxMessage = mock(MailboxMessage.class);
- TestId mailboxId = TestId.of(1);
- when(mailboxMessage.getMailboxId())
- .thenReturn(mailboxId);
- when(mailboxMessage.getModSeq())
- .thenReturn(ModSeq.first());
- when(mailboxMessage.getMessageId())
- .thenReturn(InMemoryMessageId.of(42));
- when(mailboxMessage.getFullContent())
- .thenReturn(ClassLoader.getSystemResourceAsStream("eml/mailWithHeaders.eml"));
- when(mailboxMessage.createFlags())
- .thenReturn(new Flags());
- when(mailboxMessage.getUid())
- .thenReturn(MESSAGE_UID);
- when(mailboxMessage.getAttachments())
- .thenReturn(ImmutableList.of(MessageAttachmentMetadata.builder()
- .attachment(AttachmentMetadata.builder()
- .attachmentId(AttachmentId.from("1"))
- .type("text/plain")
- .size(36)
- .build())
- .isInline(false)
- .build()));
-
- // When
- IndexableMessage indexableMessage = IndexableMessage.builder()
- .message(mailboxMessage)
- .extractor(new DefaultTextExtractor())
- .zoneId(ZoneId.of("Europe/Paris"))
- .indexAttachments(IndexAttachments.YES)
- .build();
-
- // Then
- assertThat(indexableMessage.getHasAttachment()).isTrue();
- }
-
- @Test
- void hasAttachmentsShouldReturnFalseWhenEmptyAttachments() throws IOException {
- //Given
- MailboxMessage mailboxMessage = mock(MailboxMessage.class);
- TestId mailboxId = TestId.of(1);
- when(mailboxMessage.getMailboxId())
- .thenReturn(mailboxId);
- when(mailboxMessage.getMessageId())
- .thenReturn(InMemoryMessageId.of(42));
- when(mailboxMessage.getFullContent())
- .thenReturn(ClassLoader.getSystemResourceAsStream("eml/mailWithHeaders.eml"));
- when(mailboxMessage.createFlags())
- .thenReturn(new Flags());
- when(mailboxMessage.getUid())
- .thenReturn(MESSAGE_UID);
- when(mailboxMessage.getModSeq())
- .thenReturn(ModSeq.first());
- when(mailboxMessage.getAttachments())
- .thenReturn(ImmutableList.of());
-
- // When
- IndexableMessage indexableMessage = IndexableMessage.builder()
- .message(mailboxMessage)
- .extractor(new DefaultTextExtractor())
- .zoneId(ZoneId.of("Europe/Paris"))
- .indexAttachments(IndexAttachments.NO)
- .build();
-
- // Then
- assertThat(indexableMessage.getHasAttachment()).isFalse();
- }
-
- @Test
- void attachmentsShouldNotBeenIndexedWhenAsked() throws Exception {
- //Given
- MailboxMessage mailboxMessage = mock(MailboxMessage.class);
- TestId mailboxId = TestId.of(1);
- when(mailboxMessage.getMailboxId())
- .thenReturn(mailboxId);
- when(mailboxMessage.getModSeq())
- .thenReturn(ModSeq.first());
- when(mailboxMessage.getMessageId())
- .thenReturn(InMemoryMessageId.of(42));
- when(mailboxMessage.getFullContent())
- .thenReturn(ClassLoader.getSystemResourceAsStream("eml/mailWithHeaders.eml"));
- when(mailboxMessage.createFlags())
- .thenReturn(new Flags());
- when(mailboxMessage.getUid())
- .thenReturn(MESSAGE_UID);
-
- // When
- IndexableMessage indexableMessage = IndexableMessage.builder()
- .message(mailboxMessage)
- .extractor(new DefaultTextExtractor())
- .zoneId(ZoneId.of("Europe/Paris"))
- .indexAttachments(IndexAttachments.NO)
- .build();
-
- // Then
- assertThat(indexableMessage.getAttachments()).isEmpty();
- }
-
- @Test
- void attachmentsShouldBeenIndexedWhenAsked() throws Exception {
- //Given
- MailboxMessage mailboxMessage = mock(MailboxMessage.class);
- TestId mailboxId = TestId.of(1);
- when(mailboxMessage.getMailboxId())
- .thenReturn(mailboxId);
- when(mailboxMessage.getModSeq())
- .thenReturn(ModSeq.first());
- when(mailboxMessage.getMessageId())
- .thenReturn(InMemoryMessageId.of(42));
- when(mailboxMessage.getFullContent())
- .thenReturn(ClassLoader.getSystemResourceAsStream("eml/emailWith3Attachments.eml"));
- when(mailboxMessage.createFlags())
- .thenReturn(new Flags());
- when(mailboxMessage.getUid())
- .thenReturn(MESSAGE_UID);
-
- // When
- IndexableMessage indexableMessage = IndexableMessage.builder()
- .message(mailboxMessage)
- .extractor(new DefaultTextExtractor())
- .zoneId(ZoneId.of("Europe/Paris"))
- .indexAttachments(IndexAttachments.YES)
- .build();
-
- // Then
- assertThat(indexableMessage.getAttachments()).isNotEmpty();
- }
-
- @Test
- void otherAttachmentsShouldBeenIndexedWhenOneOfThemCannotBeParsed() throws Exception {
- //Given
- MailboxMessage mailboxMessage = mock(MailboxMessage.class);
- TestId mailboxId = TestId.of(1);
- when(mailboxMessage.getMailboxId())
- .thenReturn(mailboxId);
- when(mailboxMessage.getModSeq())
- .thenReturn(ModSeq.first());
- when(mailboxMessage.getMessageId())
- .thenReturn(InMemoryMessageId.of(42));
- when(mailboxMessage.getFullContent())
- .thenReturn(ClassLoader.getSystemResourceAsStream("eml/emailWith3Attachments.eml"));
- when(mailboxMessage.createFlags())
- .thenReturn(new Flags());
- when(mailboxMessage.getUid())
- .thenReturn(MESSAGE_UID);
-
- TextExtractor textExtractor = mock(TextExtractor.class);
- when(textExtractor.extractContent(any(), any()))
- .thenReturn(new ParsedContent(Optional.of("first attachment content"), ImmutableMap.of()))
- .thenThrow(new RuntimeException("second cannot be parsed"))
- .thenReturn(new ParsedContent(Optional.of("third attachment content"), ImmutableMap.of()));
-
- // When
- IndexableMessage indexableMessage = IndexableMessage.builder()
- .message(mailboxMessage)
- .extractor(textExtractor)
- .zoneId(ZoneId.of("Europe/Paris"))
- .indexAttachments(IndexAttachments.YES)
- .build();
-
- // Then
- String NO_TEXTUAL_BODY = "The textual body is not present";
- assertThat(indexableMessage.getAttachments())
- .extracting(input -> input.getTextualBody().orElse(NO_TEXTUAL_BODY))
- .contains("first attachment content", NO_TEXTUAL_BODY, "third attachment content");
- }
-
- @Test
- void shouldHandleCorrectlyMessageIdHavingSerializeMethodThatReturnNull() throws Exception {
- MessageId invalidMessageIdThatReturnNull = mock(MessageId.class);
- when(invalidMessageIdThatReturnNull.serialize())
- .thenReturn(null);
-
- // When
- MailboxMessage mailboxMessage = mock(MailboxMessage.class);
- TestId mailboxId = TestId.of(1);
- when(mailboxMessage.getMailboxId())
- .thenReturn(mailboxId);
- when(mailboxMessage.getModSeq())
- .thenReturn(ModSeq.first());
- when(mailboxMessage.getMessageId())
- .thenReturn(invalidMessageIdThatReturnNull);
- when(mailboxMessage.getFullContent())
- .thenReturn(ClassLoader.getSystemResourceAsStream("eml/bodyMakeTikaToFail.eml"));
- when(mailboxMessage.createFlags())
- .thenReturn(new Flags());
- when(mailboxMessage.getUid())
- .thenReturn(MESSAGE_UID);
-
- IndexableMessage indexableMessage = IndexableMessage.builder()
- .message(mailboxMessage)
- .extractor(textExtractor)
- .zoneId(ZoneId.of("Europe/Paris"))
- .indexAttachments(IndexAttachments.YES)
- .build();
-
- // Then
- assertThat(indexableMessage.getMessageId()).isNull();
- }
-
- @Test
- void shouldHandleCorrectlyNullMessageId() throws Exception {
-
- // When
- MailboxMessage mailboxMessage = mock(MailboxMessage.class);
- TestId mailboxId = TestId.of(1);
- when(mailboxMessage.getMailboxId())
- .thenReturn(mailboxId);
- when(mailboxMessage.getMessageId())
- .thenReturn(null);
- when(mailboxMessage.getModSeq())
- .thenReturn(ModSeq.first());
- when(mailboxMessage.getFullContent())
- .thenReturn(ClassLoader.getSystemResourceAsStream("eml/bodyMakeTikaToFail.eml"));
- when(mailboxMessage.createFlags())
- .thenReturn(new Flags());
- when(mailboxMessage.getUid())
- .thenReturn(MESSAGE_UID);
-
- IndexableMessage indexableMessage = IndexableMessage.builder()
- .message(mailboxMessage)
- .extractor(textExtractor)
- .zoneId(ZoneId.of("Europe/Paris"))
- .indexAttachments(IndexAttachments.YES)
- .build();
-
- // Then
- assertThat(indexableMessage.getMessageId()).isNull();
- }
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
deleted file mode 100644
index 6d78b4c..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
-import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
-import static net.javacrumbs.jsonunit.core.Option.IGNORING_VALUES;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.time.ZoneId;
-import java.util.Date;
-
-import javax.mail.Flags;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.james.core.Username;
-import org.apache.james.mailbox.FlagsBuilder;
-import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.ByteContent;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.TestId;
-import org.apache.james.mailbox.model.TestMessageId;
-import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
-import org.apache.james.mailbox.store.extractor.JsoupTextExtractor;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
-import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
-import org.apache.james.mailbox.tika.TikaConfiguration;
-import org.apache.james.mailbox.tika.TikaExtension;
-import org.apache.james.mailbox.tika.TikaHttpClientImpl;
-import org.apache.james.mailbox.tika.TikaTextExtractor;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.apache.james.util.ClassLoaderUtils;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import com.google.common.collect.ImmutableList;
-
-class MessageToElasticSearchJsonTest {
- static final int SIZE = 25;
- static final int BODY_START_OCTET = 100;
- static final TestId MAILBOX_ID = TestId.of(18L);
- static final MessageId MESSAGE_ID = TestMessageId.of(184L);
- static final ModSeq MOD_SEQ = ModSeq.of(42L);
- static final MessageUid UID = MessageUid.of(25);
- static final Username USERNAME = Username.of("username");
-
- TextExtractor textExtractor;
- Date date;
- PropertyBuilder propertyBuilder;
-
- @RegisterExtension
- static TikaExtension tika = new TikaExtension();
-
- @BeforeEach
- void setUp() throws Exception {
- textExtractor = new TikaTextExtractor(new RecordingMetricFactory(), new TikaHttpClientImpl(TikaConfiguration.builder()
- .host(tika.getIp())
- .port(tika.getPort())
- .timeoutInMillis(tika.getTimeoutInMillis())
- .build()));
- // 2015/06/07 00:00:00 0200 (Paris time zone)
- date = new Date(1433628000000L);
- propertyBuilder = new PropertyBuilder();
- propertyBuilder.setMediaType("plain");
- propertyBuilder.setSubType("text");
- propertyBuilder.setTextualLineCount(18L);
- propertyBuilder.setContentDescription("An e-mail");
- }
-
- @Test
- void spamEmailShouldBeWellConvertedToJson() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage spamMail = new SimpleMailboxMessage(MESSAGE_ID,
- date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/spamMail.eml"))),
- new Flags(),
- propertyBuilder.build(),
- MAILBOX_ID);
- spamMail.setUid(UID);
- spamMail.setModSeq(MOD_SEQ);
- assertThatJson(messageToElasticSearchJson.convertToJson(spamMail, ImmutableList.of(USERNAME)))
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/spamMail.json"));
- }
-
- @Test
- void invalidCharsetShouldBeWellConvertedToJson() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage spamMail = new SimpleMailboxMessage(MESSAGE_ID,
- date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/invalidCharset.eml"))),
- new Flags(),
- propertyBuilder.build(),
- MAILBOX_ID);
- spamMail.setUid(UID);
- spamMail.setModSeq(MOD_SEQ);
-
- String actual = messageToElasticSearchJson.convertToJson(spamMail, ImmutableList.of(USERNAME));
- assertThatJson(actual)
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/invalidCharset.json"));
- }
-
- @Test
- void htmlEmailShouldBeWellConvertedToJson() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage htmlMail = new SimpleMailboxMessage(MESSAGE_ID,
- date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/htmlMail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("social", "pocket-money").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- htmlMail.setModSeq(MOD_SEQ);
- htmlMail.setUid(UID);
- assertThatJson(messageToElasticSearchJson.convertToJson(htmlMail, ImmutableList.of(USERNAME)))
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/htmlMail.json"));
- }
-
- @Test
- void pgpSignedEmailShouldBeWellConvertedToJson() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage pgpSignedMail = new SimpleMailboxMessage(MESSAGE_ID,
- date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/pgpSignedMail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- pgpSignedMail.setModSeq(MOD_SEQ);
- pgpSignedMail.setUid(UID);
- assertThatJson(messageToElasticSearchJson.convertToJson(pgpSignedMail, ImmutableList.of(USERNAME)))
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/pgpSignedMail.json"));
- }
-
- @Test
- void simpleEmailShouldBeWellConvertedToJson() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage mail = new SimpleMailboxMessage(MESSAGE_ID,
- date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/mail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- mail.setModSeq(MOD_SEQ);
- mail.setUid(UID);
- assertThatJson(messageToElasticSearchJson.convertToJson(mail,
- ImmutableList.of(Username.of("user1"), Username.of("user2"))))
- .when(IGNORING_ARRAY_ORDER).when(IGNORING_VALUES)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/mail.json"));
- }
-
- @Test
- void recursiveEmailShouldBeWellConvertedToJson() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage recursiveMail = new SimpleMailboxMessage(MESSAGE_ID,
- date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/recursiveMail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- recursiveMail.setModSeq(MOD_SEQ);
- recursiveMail.setUid(UID);
- assertThatJson(messageToElasticSearchJson.convertToJson(recursiveMail, ImmutableList.of(USERNAME)))
- .when(IGNORING_ARRAY_ORDER).when(IGNORING_VALUES)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/recursiveMail.json"));
- }
-
- @Test
- void emailWithNoInternalDateShouldUseNowDate() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage mailWithNoInternalDate = new SimpleMailboxMessage(MESSAGE_ID,
- null,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/recursiveMail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- mailWithNoInternalDate.setModSeq(MOD_SEQ);
- mailWithNoInternalDate.setUid(UID);
- assertThatJson(messageToElasticSearchJson.convertToJson(mailWithNoInternalDate, ImmutableList.of(USERNAME)))
- .when(IGNORING_ARRAY_ORDER)
- .when(IGNORING_VALUES)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/recursiveMail.json"));
- }
-
- @Test
- void emailWithAttachmentsShouldConvertAttachmentsWhenIndexAttachmentsIsTrue() throws IOException {
- // Given
- MailboxMessage mailWithNoInternalDate = new SimpleMailboxMessage(MESSAGE_ID,
- null,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/recursiveMail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- mailWithNoInternalDate.setModSeq(MOD_SEQ);
- mailWithNoInternalDate.setUid(UID);
-
- // When
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.YES);
- String convertToJson = messageToElasticSearchJson.convertToJson(mailWithNoInternalDate, ImmutableList.of(USERNAME));
-
- // Then
- assertThatJson(convertToJson)
- .when(IGNORING_ARRAY_ORDER)
- .when(IGNORING_VALUES)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/recursiveMail.json"));
- }
-
- @Test
- void emailWithAttachmentsShouldNotConvertAttachmentsWhenIndexAttachmentsIsFalse() throws IOException {
- // Given
- MailboxMessage mailWithNoInternalDate = new SimpleMailboxMessage(MESSAGE_ID,
- null,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/recursiveMail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- mailWithNoInternalDate.setModSeq(MOD_SEQ);
- mailWithNoInternalDate.setUid(UID);
-
- // When
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.NO);
- String convertToJson = messageToElasticSearchJson.convertToJson(mailWithNoInternalDate, ImmutableList.of(USERNAME));
-
- // Then
- assertThatJson(convertToJson)
- .when(IGNORING_ARRAY_ORDER)
- .when(IGNORING_VALUES)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/recursiveMailWithoutAttachments.json"));
- }
-
- @Test
- void emailWithNoMailboxIdShouldThrow() throws Exception {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"), IndexAttachments.YES);
- MailboxMessage mailWithNoMailboxId = new SimpleMailboxMessage(MESSAGE_ID, date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/recursiveMail.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- null);
- mailWithNoMailboxId.setModSeq(MOD_SEQ);
- mailWithNoMailboxId.setUid(UID);
-
- assertThatThrownBy(() ->
- messageToElasticSearchJson.convertToJson(mailWithNoMailboxId, ImmutableList.of(USERNAME)))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void getUpdatedJsonMessagePartShouldBehaveWellOnEmptyFlags() throws Exception {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.YES);
- assertThatJson(messageToElasticSearchJson.getUpdatedJsonMessagePart(new Flags(), MOD_SEQ))
- .isEqualTo("{\"modSeq\":42,\"isAnswered\":false,\"isDeleted\":false,\"isDraft\":false,\"isFlagged\":false,\"isRecent\":false,\"userFlags\":[],\"isUnread\":true}");
- }
-
- @Test
- void getUpdatedJsonMessagePartShouldBehaveWellOnNonEmptyFlags() throws Exception {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.YES);
- assertThatJson(messageToElasticSearchJson.getUpdatedJsonMessagePart(new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.FLAGGED).add("user").build(), MOD_SEQ))
- .isEqualTo("{\"modSeq\":42,\"isAnswered\":false,\"isDeleted\":true,\"isDraft\":false,\"isFlagged\":true,\"isRecent\":false,\"userFlags\":[\"user\"],\"isUnread\":true}");
- }
-
- @Test
- void getUpdatedJsonMessagePartShouldThrowIfFlagsIsNull() {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.YES);
-
- assertThatThrownBy(() -> messageToElasticSearchJson.getUpdatedJsonMessagePart(null, MOD_SEQ))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void spamEmailShouldBeWellConvertedToJsonWithApacheTika() throws IOException {
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- textExtractor,
- ZoneId.of("Europe/Paris"),
- IndexAttachments.YES);
- MailboxMessage spamMail = new SimpleMailboxMessage(MESSAGE_ID, date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/nonTextual.eml"))),
- new Flags(),
- propertyBuilder.build(),
- MAILBOX_ID);
- spamMail.setUid(UID);
- spamMail.setModSeq(MOD_SEQ);
-
- assertThatJson(messageToElasticSearchJson.convertToJson(spamMail, ImmutableList.of(USERNAME)))
- .when(IGNORING_ARRAY_ORDER)
- .isEqualTo(
- ClassLoaderUtils.getSystemResourceAsString("eml/nonTextual.json", StandardCharsets.UTF_8));
- }
-
- @Test
- void convertToJsonWithoutAttachmentShouldConvertEmailBoby() throws IOException {
- // Given
- MailboxMessage message = new SimpleMailboxMessage(MESSAGE_ID,
- null,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/emailWithNonIndexableAttachment.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- message.setModSeq(MOD_SEQ);
- message.setUid(UID);
-
- // When
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new DefaultTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.NO);
- String convertToJsonWithoutAttachment = messageToElasticSearchJson.convertToJsonWithoutAttachment(message, ImmutableList.of(USERNAME));
-
- // Then
- assertThatJson(convertToJsonWithoutAttachment)
- .when(IGNORING_ARRAY_ORDER)
- .when(IGNORING_VALUES)
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/emailWithNonIndexableAttachmentWithoutAttachment.json"));
- }
-
- @Test
- void convertToJsonShouldExtractHtmlText() throws IOException {
- // Given
- MailboxMessage message = new SimpleMailboxMessage(MESSAGE_ID,
- date,
- SIZE,
- BODY_START_OCTET,
- new ByteContent(IOUtils.toByteArray(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/emailWithNonIndexableAttachment.eml"))),
- new FlagsBuilder().add(Flags.Flag.DELETED, Flags.Flag.SEEN).add("debian", "security").build(),
- propertyBuilder.build(),
- MAILBOX_ID);
- message.setModSeq(MOD_SEQ);
- message.setUid(UID);
-
- // When
- MessageToElasticSearchJson messageToElasticSearchJson = new MessageToElasticSearchJson(
- new JsoupTextExtractor(),
- ZoneId.of("Europe/Paris"),
- IndexAttachments.NO);
- String convertToJsonWithoutAttachment = messageToElasticSearchJson.convertToJsonWithoutAttachment(message, ImmutableList.of(USERNAME));
-
- System.out.println(convertToJsonWithoutAttachment);
-
- // Then
- assertThatJson(convertToJsonWithoutAttachment)
- .when(IGNORING_ARRAY_ORDER)
- .inPath("htmlBody")
- .isString()
- .isEqualTo(ClassLoaderUtils.getSystemResourceAsString("eml/htmlContent.txt", StandardCharsets.UTF_8));
- }
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.java
deleted file mode 100644
index 4dc663b..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MimePartTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-package org.apache.james.mailbox.elasticsearch.json;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.ByteArrayInputStream;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.james.mailbox.model.ContentType.MediaType;
-import org.apache.james.mailbox.model.ContentType.SubType;
-import org.junit.jupiter.api.Test;
-
-class MimePartTest {
-
- @Test
- void buildShouldWorkWhenTextualContentFromParserIsEmpty() {
- MimePart.builder()
- .addBodyContent(new ByteArrayInputStream(new byte[] {}))
- .addMediaType(MediaType.of("text"))
- .addSubType(SubType.of("plain"))
- .build();
- }
-
- @Test
- void buildShouldWorkWhenTextualContentFromParserIsNonEmpty() {
- String body = "text";
- MimePart mimePart = MimePart.builder()
- .addBodyContent(new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)))
- .addMediaType(MediaType.of("text"))
- .addSubType(SubType.of("plain"))
- .build();
-
- assertThat(mimePart.getTextualBody()).contains(body);
- }
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/SubjectsTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/SubjectsTest.java
deleted file mode 100644
index 4c4b396..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/SubjectsTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.json;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import org.junit.jupiter.api.Test;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableSet;
-
-class SubjectsTest {
-
- @Test
- void fromShouldThrowWhenSetIsNull() {
- assertThatThrownBy(() -> Subjects.from(null))
- .isInstanceOf(NullPointerException.class)
- .hasMessage("'subjects' is mandatory");
- }
-
- @Test
- void serializeShouldReturnEmptyWhenEmptySet() {
- Subjects subjects = Subjects.from(ImmutableSet.of());
-
- assertThat(subjects.serialize()).isEmpty();
- }
-
- @Test
- void serializeShouldNotJoinWhenOneElement() {
- String expected = "subject";
- Subjects subjects = Subjects.from(ImmutableSet.of(expected));
-
- assertThat(subjects.serialize()).isEqualTo(expected);
- }
-
- @Test
- void serializeShouldJoinWhenMultipleElements() {
- String subject = "subject";
- String subject2 = "subject2";
- String subject3 = "subject3";
-
- String expected = Joiner.on(" ").join(subject, subject2, subject3);
-
- Subjects subjects = Subjects.from(ImmutableSet.of(subject, subject2, subject3));
-
- assertThat(subjects.serialize()).isEqualTo(expected);
- }
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatterTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatterTest.java
deleted file mode 100644
index cde579c..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/DateResolutionFormatterTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.query;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.time.ZonedDateTime;
-
-import org.apache.james.mailbox.model.SearchQuery;
-import org.junit.jupiter.api.Test;
-
-class DateResolutionFormatterTest {
-
- final ZonedDateTime date = ZonedDateTime.parse("2014-01-02T15:15:15Z");
-
- @Test
- void calculateUpperDateShouldReturnDateUpToTheNextMinuteUsingMinuteUnit() {
- assertThat(DateResolutionFormatter.computeUpperDate(date, SearchQuery.DateResolution.Minute))
- .isEqualTo("2014-01-02T15:16:00Z");
- }
-
- @Test
- void calculateUpperDateShouldReturnDateUpToTheNextHourUsingHourUnit() {
- assertThat(DateResolutionFormatter.computeUpperDate(date, SearchQuery.DateResolution.Hour))
- .isEqualTo("2014-01-02T16:00:00Z");
- }
-
- @Test
- void calculateUpperDateShouldReturnDateUpToTheNextMonthUsingMonthUnit() {
- assertThat(DateResolutionFormatter.computeUpperDate(date, SearchQuery.DateResolution.Month))
- .isEqualTo("2014-02-01T00:00:00Z");
- }
-
- @Test
- void calculateUpperDateShouldReturnDateUpToTheNextYearUsingYearUnit() {
- assertThat(DateResolutionFormatter.computeUpperDate(date, SearchQuery.DateResolution.Year))
- .isEqualTo("2015-01-01T00:00:00Z");
- }
-
- @Test
- void calculateUpperDateShouldReturnDateUpToTheNextDayUsingDayUnit() {
- assertThat(DateResolutionFormatter.computeUpperDate(date, SearchQuery.DateResolution.Day))
- .isEqualTo("2014-01-03T00:00:00Z");
- }
-
- @Test
- void calculateLowerDateShouldReturnDateUpToThePreviousMinuteUsingMinuteUnit() {
- assertThat(DateResolutionFormatter.computeLowerDate(date, SearchQuery.DateResolution.Minute))
- .isEqualTo("2014-01-02T15:15:00Z");
- }
-
- @Test
- void calculateLowerDateShouldReturnDateUpToThePreviousDayUsingDayUnit() {
- assertThat(DateResolutionFormatter.computeLowerDate(date, SearchQuery.DateResolution.Day))
- .isEqualTo("2014-01-02T00:00:00Z");
- }
-
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/SearchQueryTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/SearchQueryTest.java
deleted file mode 100644
index e5502fd..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/SearchQueryTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.query;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.util.Date;
-
-import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.mailbox.model.SearchQuery.DateResolution;
-import org.junit.jupiter.api.Test;
-
-class SearchQueryTest {
-
- @Test
- void sentDateOnShouldThrowOnNullDate() {
- assertThatThrownBy(() -> SearchQuery.sentDateOn(null, DateResolution.Day))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void sentDateOnShouldThrowOnNullResolution() {
- assertThatThrownBy(() -> SearchQuery.sentDateOn(new Date(), null))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void sentDateAfterShouldThrowOnNullDate() {
- assertThatThrownBy(() -> SearchQuery.sentDateAfter(null, DateResolution.Day))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void sentDateAfterShouldThrowOnNullResolution() {
- assertThatThrownBy(() -> SearchQuery.sentDateAfter(new Date(), null))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void sentDateBeforeShouldThrowOnNullDate() {
- assertThatThrownBy(() -> SearchQuery.sentDateBefore(null, DateResolution.Day))
- .isInstanceOf(NullPointerException.class);
- }
-
- @Test
- void sentDateBeforeShouldThrowOnNullResolution() {
- assertThatThrownBy(() -> SearchQuery.sentDateOn(new Date(), null))
- .isInstanceOf(NullPointerException.class);
- }
-
-}
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
deleted file mode 100644
index 956661a..0000000
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * *************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ***************************************************************/
-
-package org.apache.james.mailbox.elasticsearch.search;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.time.ZoneId;
-import java.util.List;
-import java.util.stream.IntStream;
-
-import org.apache.james.backends.es.DockerElasticSearchExtension;
-import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.ReactorElasticSearchClient;
-import org.apache.james.core.Username;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MailboxSessionUtil;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.elasticsearch.IndexAttachments;
-import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
-import org.apache.james.mailbox.elasticsearch.MailboxIdRoutingKeyFactory;
-import org.apache.james.mailbox.elasticsearch.MailboxIndexCreationUtil;
-import org.apache.james.mailbox.elasticsearch.events.ElasticSearchListeningMessageSearchIndex;
-import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
-import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
-import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
-import org.apache.james.mailbox.inmemory.InMemoryId;
-import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
-import org.apache.james.mailbox.inmemory.InMemoryMessageId;
-import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
-import org.apache.james.mailbox.model.ComposedMessageId;
-import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
-import org.apache.james.mailbox.model.SearchQuery;
-import org.apache.james.mailbox.tika.TikaConfiguration;
-import org.apache.james.mailbox.tika.TikaExtension;
-import org.apache.james.mailbox.tika.TikaHttpClientImpl;
-import org.apache.james.mailbox.tika.TikaTextExtractor;
-import org.apache.james.metrics.tests.RecordingMetricFactory;
-import org.apache.james.mime4j.dom.Message;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import com.github.fge.lambdas.Throwing;
-import com.github.steveash.guavate.Guavate;
-
-class ElasticSearchSearcherTest {
-
- static final int BATCH_SIZE = 1;
- static final int SEARCH_SIZE = 1;
- private static final Username USERNAME = Username.of("user");
-
- @RegisterExtension
- static TikaExtension tika = new TikaExtension();
-
- @RegisterExtension
- DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
-
- TikaTextExtractor textExtractor;
- ReactorElasticSearchClient client;
- private InMemoryMailboxManager storeMailboxManager;
-
- @BeforeEach
- void setUp() throws Exception {
- textExtractor = new TikaTextExtractor(new RecordingMetricFactory(),
- new TikaHttpClientImpl(TikaConfiguration.builder()
- .host(tika.getIp())
- .port(tika.getPort())
- .timeoutInMillis(tika.getTimeoutInMillis())
- .build()));
-
- client = MailboxIndexCreationUtil.prepareDefaultClient(
- elasticSearch.getDockerElasticSearch().clientProvider().get(),
- elasticSearch.getDockerElasticSearch().configuration());
-
- InMemoryMessageId.Factory messageIdFactory = new InMemoryMessageId.Factory();
- MailboxIdRoutingKeyFactory routingKeyFactory = new MailboxIdRoutingKeyFactory();
-
- InMemoryIntegrationResources resources = InMemoryIntegrationResources.builder()
- .preProvisionnedFakeAuthenticator()
- .fakeAuthorizator()
- .inVmEventBus()
- .defaultAnnotationLimits()
- .defaultMessageParser()
- .listeningSearchIndex(preInstanciationStage -> new ElasticSearchListeningMessageSearchIndex(
- preInstanciationStage.getMapperFactory(),
- new ElasticSearchIndexer(client,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS,
- BATCH_SIZE),
- new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE,
- new InMemoryId.Factory(), messageIdFactory,
- MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS, routingKeyFactory),
- new MessageToElasticSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES),
- preInstanciationStage.getSessionProvider(), routingKeyFactory))
- .noPreDeletionHooks()
- .storeQuotaManager()
- .build();
-
- storeMailboxManager = resources.getMailboxManager();
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void searchingInALargeNumberOfMailboxesShouldReturnAllMailboxesMessagesUid() throws Exception {
- MailboxSession session = MailboxSessionUtil.create(USERNAME);
- int numberOfMailboxes = 700;
- List<MailboxPath> mailboxPaths = IntStream
- .range(0, numberOfMailboxes)
- .mapToObj(index -> MailboxPath.forUser(USERNAME, "mailbox" + index))
- .collect(Guavate.toImmutableList());
-
- List<MailboxId> mailboxIds = mailboxPaths.stream()
- .map(Throwing.<MailboxPath, MailboxId>function(mailboxPath -> storeMailboxManager.createMailbox(mailboxPath, session).get()).sneakyThrow())
- .collect(Guavate.toImmutableList());
-
- List<ComposedMessageId> composedMessageIds = mailboxPaths.stream()
- .map(Throwing.<MailboxPath, ComposedMessageId>function(mailboxPath -> addMessage(session, mailboxPath)).sneakyThrow())
- .collect(Guavate.toImmutableList());
-
- elasticSearch.awaitForElasticSearch();
-
- MultimailboxesSearchQuery multimailboxesSearchQuery = MultimailboxesSearchQuery
- .from(SearchQuery.of(SearchQuery.all()))
- .inMailboxes(mailboxIds)
- .build();
- List<MessageId> expectedMessageIds = composedMessageIds
- .stream()
- .map(ComposedMessageId::getMessageId)
- .collect(Guavate.toImmutableList());
- assertThat(storeMailboxManager.search(multimailboxesSearchQuery, session, numberOfMailboxes + 1)
- .collectList().block())
- .containsExactlyInAnyOrderElementsOf(expectedMessageIds);
- }
-
- private ComposedMessageId addMessage(MailboxSession session, MailboxPath mailboxPath) throws Exception {
- MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
-
- String recipient = "user@example.com";
- return messageManager.appendMessage(MessageManager.AppendCommand.from(
- Message.Builder.of()
- .setTo(recipient)
- .setBody("Hello", StandardCharsets.UTF_8)),
- session)
- .getId();
- }
-}
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/resources/eml/bodyMakeTikaToFail.eml b/mailbox/elasticsearch/src/test/resources/eml/bodyMakeTikaToFail.eml
deleted file mode 100644
index e4e7ede..0000000
--- a/mailbox/elasticsearch/src/test/resources/eml/bodyMakeTikaToFail.eml
+++ /dev/null
@@ -1,1272 +0,0 @@
-Date: Mon, 30 Jan 2017 11:51:35 +0100
-From: Raphael OUAZANA <ra...@linagora.com>
-To: OUAZANA Raphael <ra...@linagora.com>
-Subject: subject should be parsed
-Message-ID: <25...@linagora.com>
-X-Sender: raph.ouazana@linagora.com
-User-Agent: Roundcube Webmail/1.1.4
-
-Return-Path: <ip...@obm.lng.org>
-Received: from lenny.obm.lng.org (localhost [127.0.0.1])
- by lenny.obm.lng.org (Cyrus v2.3.14-Debian-2.3.14-2) with LMTPA;
- Wed, 21 Mar 2012 14:51:59 +0100
-X-Sieve: CMU Sieve 2.3
-Received: from [192.168.2.48] (unknown [192.168.2.48])
- by lenny.obm.lng.org (Postfix) with ESMTP id E495D32929
- for <us...@obm.lng.org>; Wed, 21 Mar 2012 14:51:58 +0100 (CET)
-Message-ID: <4F...@obm.lng.org>
-Date: Wed, 21 Mar 2012 14:52:14 +0100
- From: iphone <ip...@obm.lng.org>
-User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US;
-rv:1.9.2.28) Gecko/20120306 Lightning/1.0b2 Thunderbird/3.1.20
-MIME-Version: 1.0
-To: usera <us...@obm.lng.org>
-Subject: Fwd: Re: email with sign
-Content-Type: multipart/mixed;
- boundary="------------080809000000030101030405"
-
-This is a multi-part message in MIME format.
---------------080809000000030101030405
-Content-Type: text/plain; charset=ISO-8859-1; format=flowed
-Content-Transfer-Encoding: 7bit
-
-new email text part
-
---------------080809000000030101030405
-Content-Type: message/rfc822;
- name="Re: email with sign.eml"
-Content-Transfer-Encoding: 7bit
-Content-Disposition: attachment;
- filename="Re: email with sign.eml"
-
-Return-Path: <us...@obm.lng.org>
-Received: from lenny.obm.lng.org (localhost [127.0.0.1])
- by lenny.obm.lng.org (Cyrus v2.3.14-Debian-2.3.14-2) with LMTPA;
- Wed, 21 Mar 2012 14:19:29 +0100
-X-Sieve: CMU Sieve 2.3
-Received: from [192.168.2.48] (unknown [192.168.2.48])
- by lenny.obm.lng.org (Postfix) with ESMTP id 47EC832D51
- for <ip...@obm.lng.org>; Wed, 21 Mar 2012 14:19:29 +0100 (CET)
-Message-ID: <4F...@obm.lng.org>
-Date: Wed, 21 Mar 2012 14:19:44 +0100
- From: usera <us...@obm.lng.org>
-User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US;
-rv:1.9.2.28) Gecko/20120306 Thunderbird/3.1.20
-MIME-Version: 1.0
-To: iphone <ip...@obm.lng.org>
-Subject: Re: email with sign
-References: <4F...@obm.lng.org>
-In-Reply-To: <4F...@obm.lng.org>
-Content-Type: multipart/alternative;
- boundary="------------050702060806040107070701"
-
-This is a multi-part message in MIME format.
---------------050702060806040107070701
-Content-Type: text/plain; charset=ISO-8859-1; format=flowed
-Content-Transfer-Encoding: 7bit
-
-On 03/21/2012 01:59 PM, iphone wrote:
-> email with sign text part
-> --
-new email text part
-
---------------050702060806040107070701
-Content-Type: multipart/related;
- boundary="------------090109030206070103090500"
-
-
---------------090109030206070103090500
-Content-Type: text/html; charset=ISO-8859-1
-Content-Transfer-Encoding: 7bit
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
- <head>
- <meta content="text/html; charset=ISO-8859-1"
- http-equiv="Content-Type">
- </head>
- <body text="#000000" bgcolor="#ffffff">
- On 03/21/2012 01:59 PM, iphone wrote:
- <blockquote cite="mid:4F69D0C6.501@obm.lng.org" type="cite">
- <meta http-equiv="content-type" content="text/html;
- charset=ISO-8859-1">
- email with sign text part<br>
- <div class="moz-signature">-- <br>
- <img src="cid:part1.05020706.03070506@obm.lng.org"
-border="0"></div>
- </blockquote>
- new email text part<br>
- </body>
-
-</html>
-
---------------090109030206070103090500
-Content-Type: image/jpeg
-Content-Transfer-Encoding: base64
-Content-ID: <pa...@obm.lng.org>
-
-/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAAUDBAQEAwUE
-BAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBwe
-Hx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
-Hh4eHh4eHh4eHh4eHh4eHh7/wAARCANlAYwDASIAAhEBAxEB/8QAHQABAAIDAQEBAQAAAAAA
-AAAAAAUGAwQHCAIBCf/EAFwQAAEDAwICBAoGBQcHCQYHAQECAwQABREGEhMhBxQWMRUiQVFU
-VmGTldMIMlWU0tQjUnGBkSQzQpKztNEXNDVDYnWhNjdlcoSio7HBGDhTY7LwCSUmRIKD4cL/
-xAAbAQEAAwEBAQEAAAAAAAAAAAAAAQIDBAUGB//EADYRAAICAQMCBAMIAgEEAwAAAAABAhED
-BBIhMUEFE1HwYaHBFCJxgZGx0fEy4VIGFSNCYpLS/9oADAMBAAIRAxEAPwD2XUDqjWFg03Ij
-xrpJkmVIQpxuPEgvy3ihOApZbZQtQQCRlRAAz31PVRr+xf7J0hP6otenJGoYs+0sQHWYshhp
-+Mtl15xKhxloSULD5CsKyOGnkc8gJ6LqzT0t+zMQ7kiUu9sOSLeWG1uJdabSkrcKkghCRvQN
-yiBuWlP1lAHb05erbqKyRb1aH1yIEtJXHeUytviIyQFpCwCUnGUqxhQIUCQQTzTS/RoWtU6b
-ueoNO2iWpq1X0T1qbbeTHdnTWXkR0lQ3KQlt2W2CBjaVg434MHovooucDTPBTZYVnvUfo8t9
-qtkpJb/kV0KJwlLSUE7V75CCpwfW4isE5VQHd6V51tvRfcI+kZ8VWj9QPMrnRH/BkmTZjvU2
-28lxxMZppEV0EuJB4ygpeArKFNpzeHdMX57oGZ06bE01OQ80t20tSQEvRkTUuOR9ynFJQXGE
-qQUBZbSVlAVsANAdFt10gXCZcokN/ivWySIsxOxQ4bpZbeCckYP6N5tWRkeNjvBA09WantGl
-48N67rm/y2T1WM1DgPzHXXeGtzalthC1nCGnFE4wAk5rgl56L7/OcmPN6NuNvsDt4kSWbDBd
-ta3EhcGA0y5tkhyOkIVHkJwk7kbwUEp+t0LXumLu/pHo/iC06gvSrJOacuLVuvKWJ5SLdJY3
-iTxY+5XEcb3FKkbgVeLglNAXbTWq7JqIkWl2Y4pKnEOpdgPsKYW3wypDocQktLw62oIXhSkk
-qSCASJyvOty6NdazYsswLZcLfGkM3AttSbiw/PDTsm0LLDzy1OJdddRElgKWXUhJQhaiABUr
-ofonQ5dbUxqLS8p3TzUa7ZhXhyC4GVvLt/BTwIiEMIB4D6whAWEqG4qClAADutK4xpDRGr2V
-6Vg3mKowJEO13HUS3JKFqTcoccIKThR3lbiIitycp/ky8nxk1UtNdEmp48JcW4Wy8vS3H7Ym
-6yH5lvbj3At3OK8++gR20vOENNOqC5C+IAooAWVZoD0pSuO2nSl/0f0jSLtYNJB+wNPTotug
-QpEdhDDUli1L4iUKUkIa6xFlbgPGyrcEKBqp6I6LNWW6/wCk5d4t94VIt8SzIbfiy7cliA3H
-iMNyI63Ftrk4LjbpKGFcNwOYJTzVQHo6lKUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQCl
-KUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQGOS8iPHdfcDhQ2grUG21LUQBnklIJUfYASf
-JUL2ttXol/8AgM35VT1KAge1tq9Ev/wGb8qna21eiX/4DN+VU9SgIHtbavRL/wDAZvyqdrbV
-6Jf/AIDN+VU9SgIHtbavRL/8Bm/Kp2ttXol/+AzflVPUoCB7W2r0S/8AwGb8qna21eiX/wCA
-zflVPUoCB7W2r0S//AZvyqdrbV6Jf/gM35VT1KAge1tq9Ev/AMBm/Kp2ttXol/8AgM35VT1K
-Age1tq9Ev/wGb8qna21eiX/4DN+VU9SgIHtbavRL/wDAZvyqdrbV6Jf/AIDN+VU9SgIHtbav
-RL/8Bm/Kp2ttXol/+AzflVPUoCB7W2r0S/8AwGb8qna21eiX/wCAzflVPUoCB7W2r0S//AZv
-yqdrbV6Jf/gM35VT1KAge1tq9Ev/AMBm/Kp2ttXol/8AgM35VT1KAge1tq9Ev/wGb8qna21e
-iX/4DN+VU9SgIHtbavRL/wDAZvyqdrbV6Jf/AIDN+VU9SgIHtbavRL/8Bm/Kp2ttXol/+Azf
-lVPUoCB7W2r0S/8AwGb8qna21eiX/wCAzflVPUoCB7W2r0S//AZvyqdrbV6Jf/gM35VT1KAg
-e1tq9Ev/AMBm/Kp2ttXol/8AgM35VT1KAge1tq9Ev/wGb8qna21eiX/4DN+VU9SgIHtbavRL
-/wDAZvyqdrbV6Jf/AIDN+VU9SgIHtbavRL/8Bm/Kp2ttXol/+AzflVPUoCB7W2r0S/8AwGb8
-qna21eiX/wCAzflVPUoCB7W2r0S//AZvyqdrbV6Jf/gM35VT1KAUpSgFKUoBSlKAUpSgFKUo
-BSlKAUpSgFKUoBSlKAUpSgFad5ucCzWuTc7nJbjQ4zZcedWcBKRW5Xjn6Y3Si6/rFzo/4jkO
-BADbkkgE8dagFA5HkA8nnoDvELp56Mngjrd9ctilpCkpnRHWsg9xztxj99Wu1a80VdQnwdqq
-zSSruSiYjJ/dnNfzjMyC/gNzGVISOSSvBV+0KAoWw4kyeEFODIbG3O0f/wAc8qhP1JP6dNSY
-7wyy+04D+qsGsua/mLEut5tQCbfd5sR5RyrgzFt7Rk8xz/4V67+hJqK96j0LfJF6usu4mPcw
-ywuS4VqSgNIOMn2kmpIO/wBKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUp
-SgFKUoBSlKAVzazdM+lLrd7dFYiXdu23S4u2y23l1hAhTJTeQW0KCyvmUqCVKQlKikgE4rpN
-cE0x0Kakt0LSGj5lytCtJaR1Gu+wZDS3DNkELccZZW2UBCNqnVblBatwA8UUBvTvpPdGEfwh
-wpT8vql3RaWuDJhjrjit2Xmt76cR04GX3NjfjDCjzx02JrnRUu2SbpF1hp6RAioQ5IlNXJlT
-TKFqUlKlrCsJBKFAEnmUkeQ1yD/Ipqr7Qsv/ADt9tf553/Mf/h/zf89/s/V/2qwW7oHv7H0d
-dKaBduNsRfLDe03d5UeS+1HmFMh1YbLyEpdRlDiRvSnclSBjuBoDtF01fYoehLjrWNNautng
-QX5ynrc6h4OttIUtQbUFbVHCSBzAz5RVe0B0s6a1cpxrq9wsT6LUzeUtXYNNlcB4ZRICkOLR
-s8+VApPIgVD2LozuNv6EdYaNaYs8C6aiauJCY82XIYQ7JaLaVOPSFLdWfqlawlIJyQgHOaG9
-9H3VN+0lPh6gvNpt1zToyBpS3eD3nX2uHGdQ8p11Sm0H9ItsDaEnaknmqgOvaM11brlpCXqq
-9X7TMS3JlLCXI9yZcZiNZAQh99Limy6e87SEjcEjONypm4ax0jbocGbcNU2OHFuAzCefuDTa
-JPd/NqKsL7x3Z764q/0HahetK5jDOnoF5RqS2XoRzd7hNamiGlSeHIkSSpXjbzjY0NoSkHfg
-Efeq+hbV1xQxLt6NER5MrSErTU2BHYdiQIXHeLnWIqAlZ3DcQQdu4jORnAA7TP1bpSALmZ2p
-rLFFp4PhIvT2kdT42OFxsq/R78jbuxuzyzWZnUennnmWWb9a3HXpLsRpCZbZU4+0CXWkjPNa
-AlRUkc04OcYrzxq76PmtXrDrbT9ivNikw9TWqxROs3B55t5ty2obRkpQ2sEOBBVuzkHlg94u
-M7oZuU7pB1VcHbtFj6fucO4G2NslRkRJ06OyxIeIwE4AaUpOFZy6ruoDpDWu9EPW+bcWtZad
-chwFJRMkJubJbjKUrakOK3YQSogAHGTyrTmdJvR9Evlnsr2sbL1+9LU3b2m5SV8ZSVKQRuTk
-JytC2xuI3LSUDKuVcJmfRz1TJ6Mrzp1HZqPd37JBtEacq73GSXksSmnlKXxcoYQQ14rTbR2q
-UcKCSRXSOm7ouu+tNRaQnWKXb4MWzxLpb5KHFrbWhmdFEfiM7UKBU2MqCTtBwBuT30B0ewam
-05qFUhNg1BabsqKoJkCFMbfLRPkVsJ2nke/zVK1xroD6KLpoS6on3iPZ+PGsjNoblRbpPlvS
-EoUFFSg+oNMo8UENNoO0lWFAHbXZaAUpSgFfzs+mcjb9IS9Ef0mI5/7gr+idfz3+ms3jp+uS
-sfWiRz/3TQHFUDurO0VpPiqKT7DivhIrMgUBtIekLaU2p9wpI5gnNe0voDtcPoyvZx33g/2L
-deLoyfGA89e3foLt8PosuZx9a7r/ALJugPQFKUoBSlKAUrDPkohwZExwZQw0pxQ3pTySCTzU
-Qkd3eSB5yK5X9GvpLvXSrp+bqWcLTEhh9bTMCM2lTzICyElxwSFkkpHctpo88jcnBIHWqVxn
-RfSy/dekK82i96m09bItvudzjtW9dlkoefjwyQpxMxT3BKk8lrSEEhIPIZyNzoO6TNQ671zr
-m0Xi1Q7dCswt79sShC0yFMS2nHUF/cojfsDZIATtJUDnGaA61SvNMD6Qt0b6J73rWZdNOzbn
-CtSJjdhZssqI42XZKWGnS+4+pL7QKsK4aRz5bkkYPWOhHWtz1pZb8L1HhtXOw6gmWSUuGhSG
-XlsKH6RCVKUUghQ5FR5550BeZUhiKwp+S8hlpAypazgContdpf7ft3v018anQh27WBh1IW05
-NWVoUMhW1hxScj2KSD+6uT6s6a7xZ+nDsexbLeuyxr1aLJLWtK+sreuDLzqHEKCtqUo4aQUl
-JJyeYoDrfa7S/wBv2736adrtL/b9u9+mpfdTdQER2u0v9v2736adrtL/AG/bvfpqX3Vr3F9x
-qOlTatqi80nOPIpxIP8AwJoDQ7XaX+37d79NBq7TBIAv9uJP/wA9NNUXS52+K2mzWVy7Tnl7
-W2i7wWkgc1KcdIISMchyJJIGMZI3bbLFwtrMlcSRG4yMrjyW9rjZ8qVDmMju5Eg94JGDQG40
-4h1tLja0rQoZCgcgite6XKBa4xk3GYxEZHet1YSP4movQwCLVKZQMNs3CU02kdyUJeUEpHsA
-GK579I3WStBQlaqEFm4Ktlqfejxns8MvqfjstqOOeBxTnGDjIyM0Bfe3ejPWe0/eU/407d6M
-9Z7T95T/AI1X+hHVcrWllvwvVvtrVzsOoJlklLhslDLy2FD9IhKiopBChyKjzzzq/dVjejs/
-1BQED270Z6z2n7yn/GnbvRnrPafvKf8AGp7qsb0dn+oKdVjejs/1BQH5DlR5kZEmI8h9lwZQ
-tByFD2Gs1QGkm249x1HFYQlthm5jhtpGEo3RmFqwPJlS1H9pNT9AKUpQClKUArHKS8qM6mM4
-hp8oIbWtG9KVY5EpBGQD5MjPnFZKwz4zc2DIhvKeS0+0ppamXlsuAKGCUrQQpCufJSSCDzBB
-oDznatb9J1x01fmody1BdpVu6TpViW/abZDXLbtjTROAFt8FPjY/SLAGVAE91VnXXTzqKJAt
-d00VqSfcLRF0y3f1u3ODGEm4rXd24ao7wbbSlAQlSx+iCTkA7ld57iz0IdGzUeVHFpui2pcz
-r7yXL9PXmXuSrrI3PHa/lI/SjC8ZG7BIO8/0RdHD8eyRl6ViBmxthqA2hxxKUIDiXNiwFAOp
-4iUrw5uG4bu/nQGPpT6QZmkr3pvTtk02rUF+1CqV1KIZqYqCmMzxXMuKSoBRGAkEAEnmUjnV
-d1R03xtP9I1k0fKsrTj1xmwIEtDUtxci2vy0EtJeAZLHeDyS+VEAqCSAcXvXmhNKa5ixo2qb
-SmeiKpZZUH3GVo3oKFpC21JVtUklKk5wociDUNc+hzo2uFzNzf0yhuZ/JCl2NLfjltUVO2Op
-HDWkIW2nxUqTggcs4oCiaK+kLLv8PTE2VoGRHa1Pb7pKtbcO4iU+67ACy4zs4aOagjxTnmTj
-HlrFI+kYmN0bX7VsjT9p67aI8d9yxJvLyJyA6+2yQ8h2Kjh7S5zUniJyAM8wam+gDoTt2hNG
-WJvUUeNL1Vbo8uMZ0SdIU02h55xR4IUUhtRQpIK0oSrl3nvq0SOiLo/lt3RNyssi6LusQQpj
-1yucqY8tgLDgbS484paEhYCgEkYIB7xQHOulDpjvsbpOj6KsTPgvwZrfT1rnS9yHuvxZ7Lzr
-jexTf6LGwDcklR7wU91SOhunuVq1xcu2dG+pJFlejTn4U6NGfcDqowWQ2sqZS0lTuxSUBDrn
-jYSraTirgx0N9HLNyTck2BxcxNwhXLju3GS4tUmGlaY7iipw7ikOL78hWfG3HFblk6LtC2W9
-KvFqsfVZhD4aUiW/sjcY5dLCCvYwVeUthJoCH6GulNPSC8/HkQ7TaprMdL7ltTcXnJzAJAIe
-ZdjtbcE4Kklac4GTkGulVWdN6E0zp+/SL/AiTHbvIjiK5OnXGTNf4IVu4QW+4spRu57QQM1Z
-qAUpSgFeA/ptNY6dpSsfWgRz/wDVXvyvCH032sdNil/rW1j/AM1UBwZKayITX1jnyr9FAbEE
-ZeSK9yfQlQEdE8wjy3Z3+zbrw5CIDyT5K9xfQmkNL6JpCAtPE8KPK25542IAP7OR/hQHdqUp
-QClKUAqp9HmhYOhY79vsl1uhs63XXY9rf4KmIinHC4rhqDYcxuUrktagM1bKUBQH+ifTs3XR
-1ZeZ95vi0CWI1uucoSIUUSm0tvpbQpOdi0J28MqKACcJGai7f0E6LtGtZOq9OPXPTkuTOhSl
-sWhTMVgIjJIMUJQ2D1d4lK3W84WpCDyxXU6UByuT0E6Qn+HVXy56jvrl4tptZeuVw4zsWLxz
-IDbSynd4ruFAuFZG1IzgYq4dHejLVoeyyLbbHpkpUua9PmSpa0qekyHVbluLKUpTk8hySBgD
-lVkpQFd1g4GLhYpCztbbmLClHuG5lxIz+1SgP31Sbx0YaVuvSMzrmSqcJyJEaU5GQ6kR35Ed
-DiGHlp27t6EuKAwoDuyDiupy40eXHVHlMoeaWMKQsZBqH7HaW+wYHuRUUSfXWfbTrPtr57Ha
-W+wIHuRTsdpb7Age5FKHB9dZ9tYZTxcS0kc/07RPsAcSSaydjtLfYED3Ip2O0t9gQPcilDgi
-9TR7lPitqs96ctU5le5t3hcZpQPJSVtkgKGOY5gggHOMg7tt/kNvZiqlyJJaRhT8he5xw+VS
-j3ZPfyAA7gAOVZ+x2lvsCB7kUGj9LggiwwAR3HhClDgx6BO+zSHRzQ7PkuIUO5SVOqII9hBB
-qt9KemLPrC+RdN6iQs2q6WqVEcKV7FbytlaNp/XHDKh3/V7jXQmWm2WktNIShCRhKQOQrFcI
-MK4RlRp8SPLYV3tvNhaT+48qkgg+jvRlq0PZZFttj0yUqXNenzJUtaVPSZDqty3FlKUpyeQ5
-JAwByqyVBdjdIeq1j+4Nfhp2N0h6rWP7g1+GgJ2lQXY3SHqtY/uDX4adjdIeq1j+4NfhoD50
-mtD1y1JJZUFsu3QcNaTlKtsZhCsHy4UhQ/aDU/WOMwxFYRHjMtssoGENtpCUpHmAHdWSgFKU
-oBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFch6beh/S+vZwu09iS3cktBoSGXSklIzgEd3
-lNder5cbSsYUM0B4b1P9HWVEcWbbdlqSO4PN/wDqKoV36JtW28naw1JSP1FYP8DX9EJtnjSA
-QpAqDn6Miv5wkfwoD+dydKahZlJYetMpBUcZ2ZH8RXrX6K1qm2iOYy0LQ2QDjyV0Fzo+Y424
-tpIz5qt+mrHHtTIDbYSfYKAmxSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSg
-FKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUPdQH5mmaUoBmma/KqfSjrSJonTbk9b
-YkznAUQoo73nMf8A0jvJoCzqmxEv8BUlkPAZLZcAUP3VmzX89tR3q83O/S7vOubztwlLK1uN
-rICfYkHaQB3YrNb9ea5tBSuBqa5tIHI/p1YJx5jkVbaD+geaZrxHbvpC9J1qTwpMxiUpCu6X
-HQSof/xwR/Gu4/Ry6Y7x0mXa7W26WmDFNvjtu8WOpQ3FSiMFKicd3nqo6Ha81+g1+UFAftKU
-oBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSqBrfpCnWrXUXQ+mtO
-Jv1+dtTt3eadndVaaioXsB37FkrUvxUpwBnvIHOqi59Ieyvno9Nn07dZzesW3nyoRpCzDbZJ
-DwSlll0vuJKVjYjuwCsoSoKoDttK470OfSA0x0gMRGJESVaLxcFKchW1MaVJW5GD3BS+XAwl
-sDiBYUUqWlASSpYwoJumnukvRGoL+mxWi+JkzXONwB1d1DUngq2u8F1SQ29sPJXDUrHloC3U
-rhWvvpCdlekHUmluzMKZ4Cft7OwXnZPuHW0IV/JYvBPFLe7xhvHLB8uB0BjpV0E8L+tN9KWd
-Ouvs3Z9yG+hmK4ytKFoU4pAQVblABIJK+e3dg4AutKox6XOj5NrfuDl9caSxNagOR3YElEsS
-HU7mmhGU2HipY5pAQdwBIzisOsOlvS2l7bY59xhamLd7uSLbEQiwS0u8VRA8ZtbaVDvyE4K1
-gK2JWUkAC/0rlti6dNCSNJ2u93e9Q4y7hDkzktwG5cttMdh1ba3Sox21pQCgjK20ZVkJ3ciZ
-d7pf6OmTC4mo0hEyNFlIdER8ttNSQDHU8sI2sb8jaHSgnNAXulUnpi1pd9CaZcv9v0um9Q4r
-L0ie65cm4jcZptG4c1BSlrWfESlKTlRGSkc6rWlemJzU+tWrBbLZYIja2YD+26X8xpzrcmM3
-IVwooYXxFNocwRvAJHeM5AHW6VyXoa6bIPSPqZ2zs2Ny3Ietzl1tj6pIdMqIiW5FUpado4au
-I3nblXIjn5K61QCvzFftKA+a8KfSh19d2emq9WqU2iRHt5baieMUlpJQlRxjykk8692Gv51/
-S8Rs+kFqT/a4Cv8AwU1KCdFcTq+3PIQHYT7C/wCmsKC8+0A4xWwzerK+7nrjSUoHipdaUguY
-8hx3H25qhV+VbtRZS5tou1xmtuNOylOh4+Q8UKI9nPJ7q7//APh9tqXcdXS1c1FuOnP7Ss/+
-leTmBlwCvYf/AOH+xtturHsd7sZP/dWah0lwVtnqagpQVUH7SlKAUpSgFKUoBSlKAUrSvFya
-trCFrbcecdWG2mmxlbij5B/98q0PDN39U7j95jfMoCcpUH4Yu/qncfvMb5lPDF39U7j95jfM
-oCcpUH4Yu/qncfvMb5lPDF39U7j95jfMoCcpUH4Yu/qncfvMb5lDebsBk6UuQA78SI5/4Byg
-JylatqnsXKCiXHKtisghQwpJBwQR5CD5K0tQX1q0rYjoiSJ0yRngxo4G9QHeckgADzkgd3nF
-AS9Kq/aa9eot799G+bTtNevUW9++jfNoC0Uqr9pr16i3v30b5tO0169Rb376N8ygLRStCxXR
-q7Q1PttOsONuFp5h5OFtLHelQ/YQfaCCORrfoBSlKAoGt+j2dddcxNb6a1Emw35q1u2h512D
-1pp6Kte8DZvQQtK/GSrdjPeCOVRNh6FrZYLp0ZP2i7utQ9Bs3BtDDrAWuaqW1tWsrCgEEK3L
-5JVnOOXfXVaUBxnoS6C/8muobRdu1HhXwbpt6xcPwfweJxLg5M42eIrGOJs24OcZzzxWTon6
-C7d0faiiToM60SIVvMkxB2fjpnnjE4D007nFhCVKSNgbyDhWQMV2KlAUzSWhfAHSfrfWvhTr
-ParqH8k6vs6r1VgtfX3HfuznuTju599VdzoRgSuj7pB0dcb689H1lqCVey+1GDaoinVtOIbw
-VHfsU0k58XcCRgV1ulAcgt/QpFj6Uu9nko0TKduMhl3anR7UeGyGkkJw0y6hxS8qWd6njjco
-JCQSK1h0HTU6EstgRrd9ybZdVNakhSZMNbzDK287IyGlPbwwMnALpVzPPnUx039IN80jfNLW
-CweAYsm+9eWu43xS0woqIscvEOFCklO7kN2TtAJwruqn6n6d7jbOlHT+l4CLVc40q42m33Qs
-RyWmFz2ittbMrjgvDA3D+ThJT3rBIBAo2rOiO4dHWmo9ksUjUt6uStF3OwmTC02qRGmpkSXX
-0MkodUqM5vd+uoKQUg8weVXLT30dm1xbPdJ0q0MT37HaId3j3CwRrmtpyJHQ0oRnHsoa3JTt
-Udi84BGCBjS6NOnXX+pI+i3HrPpq4SdWW68OR4UEOsLYkwt5bDi1uLAQ7tSnmBgnOfJXxqHp
-41rp3o/1NKvMO3Q9a2m3RZ4scuwvsIQ25LaYWsOiUsPtguEBSdhJwcciKA6l01dHNw6RPALD
-V/hwrbbJapcq2zbauXGuCwBwg6lDzRKUHcduSFEjPdzjL70QSr9rmz6juepIKGINwgXV+JCs
-bUdb82K0ptKg+FFzhK3fzbhdICQkLArnXSl0pakn9LrOk7dcEQrXZukDTENt+3PONuTGJbD7
-j7T6gva4jcgDbgDlzBNS3Rr01dImsJkeSxo+ziDdI9yVbYzk+PHkh6Nv4beFSVOOhSkhKzwG
-9hUD4yedAW7ob6E4HRxqZ68M3t24IatzlrtjCowb6rEXLclKQtW48RXEc+thPJI5eWus1yjo
-Z6RL/qLUMnTOtUNWrUrNvTOcs/gR2KppsrCCtL5kOoebCjtCgEE9+BzA6vQClKUB+Gv56/TI
-b2dP95P67EdX/cA/9K/oWe6vAH0129nTxNV+vBjq/wCCqlA4jSvrFMVYGSGnMhNe0foEtbdJ
-6mc/WnNJ/g2f8a8YwsB8E+avZH0GrrDjaQvUd1YQ49cApvPIKAbAOP31DB6boKxtOocGUkGs
-gqoP2lKUBhnvLjwZEhtviraaUtKMK8YgEgeKlSufsST5ge6uPfRR1hqzpB0dJ1bqm4ylLkSH
-W2YQjBuMykOKA4ZMZCiRt2nDzw85SrKU9nqv6V0bp7S8mW9YYsmEiW4txyMmc+qMla1b1KQw
-pZbbJUSTsSnvNAcB1B0tdKOlelK9Q73DkC2q8PrtsN63BEcxoUJMiK+08EhTilkLSsblAZSM
-JOKt/wBFvX+qtXvahtmqbiLm5Ag2aezK6u20r+XQUyFtYbSlJCFZAOM4PMmuhQ+jbRETU9w1
-Izp9jwncQ91lxxxxxCi8Eh0htSihBWEJCilIKgBnNaFt6Huji3QoUOHptLbUG6x7vH/lb6lI
-lR07GFlRWVKShPipQSUActtAeeJfTh0v6asur0amYeYvUfTpubTEu2JZTb3zdOqJDXijjNcJ
-xtYUrflSTzIyK7z9HzVN81LY9TxtQTPCEvT+qJ9lRNLKG1Sm2FJ2OKSgBIVhWDtAHLuqStvR
-J0dW+BeIEXTEYRbyyWJrTjrrgU0VqWW0blHhI3rUrajaAo5AzzqwaQ0zY9JWYWjT8EQ4nFW8
-pJdW4txxZ3LWtayVLUT3qUSaAxajIF906T6Y7/dnaoOu9T6mtH0gejewxb2E2LUHhQTIIit4
-IjxErbJcIK929ROUlIwEjHIlV41ovq79onrBDEaUpTy8ckBTS0An2ZUOdULUmm+jfUWpY+pL
-rdX13WLu6q+zqeUx1bcgIXwktvpS1uSkBWwDd5c5NQSdZ4qP1qcVH61VbtNY/tq3fekf407T
-WP7at33pH+NLFFp4qP1q1Lq4lUZsA/8A7hj+1TUD2msf21bvvSP8axyNR2NwNgXq3cnm1H+V
-I7gtJPl8wpYoltTpvEyEiFZLizbXH1bXppSFusIwcqaQoFKl5wBu5DOSFY2nYsLtyTbUN3l2
-I7MbJQt2NkIdAOAvafqEjBKckA5AJ76qGpZWmr5CSy5qGNDkMq4kWZFmNpfjOYI3oJyM4JBB
-BBBIIIOK2LHctL2e3NwIF2ghtJKiVS0rccWo5UtSicqWokkk8yTSxRP6IObfPI+1Jn9uuozU
-jMqR0h2pmFM6m+u1Sgl/hBwoHFYyQk8t2M4JyAcEhQGDJaDQsWV11aFJD8yQ+jcCCULcUpJw
-fYahdfwoL2prc/eZEuHaVwn470uPNeiKaWXGlp/TNKStsHhkZCgD3HkcECM+i5qm+606CdO6
-m1NO6/dpnWusSOEhvfslOoT4qAEjCUpHIDu89dMrnvR7F6K9A2tVr0rqC3woBxtiu6icktNe
-MpR4aHnlBvKlqJ2AbicnOBVm7Y6R9arH8Qa/FUkE5SoPtjpH1qsfxBr8VO2OkfWqx/EGvxUB
-+aZ/03qj/ejf9zjVO1AaPWmVIvlyZ3GLNuAcjLIIDiEx2WyoZ8hU2rB8owe41P0ApSlAKUpQ
-ClKUApSlAR1/sNi1DEREv9lt12jtuBxDU2Kh9CVjuUAsEA+2tO56M0fdJDsi56UsU555tDbr
-ki3tOKWhHNCVFSSSE+QHu8lTtKA5z0LdElg6OdEW+xOR7Zd7lGYfjP3ZVsQy9JaceW5w1c1K
-2AL27Sog4/dVlt2hdE26HNh2/R2nocaejZMZYtjLaJCfM4kJwsew5qw0oCvRtC6IjONuR9Ha
-dZW28xIbU3bGUlLrAKWFghPJTYUoIPekKOMZrYi6T0rFuc25xdNWZifOSpEyS3BaS7ISr6wc
-WE5WD5QSc1M0oCG05pTS2m1vL07pqzWZT+OMYEFpguY/W2JGf31M0pQClKUANeG/pv2K7r6W
-jd2rXMcgLt7KDJQypTYUCrIKgMA91e5CMjFUTX9lkTkFbaSSB5KlA/mjyJ76Yr11qvQtulur
-8J2OK8o/0yyAr+I51z+7dEennyoxVSoSvIEr3p/gamyaOENBRWEoGVE7QPbXo7oYRJs8aJHY
-3JCQAceUnmT/ABNVKy9EyoF+YlSLg3JhtEq2bCFE+T2V2vo/s6ZF3ZabbwhJGeVRILg77o8u
-rtTTjxJUU+WpwVrW5gR4jbQGMCtkVBB+0pSgFKUoBSlKAUpSgPxSUqSUqAUD3gisPU4norHu
-xWelAYOpxPRWPdinU4norHuxWelAYOpxPRWPdinU4norHuxWelAYOpxPRWPdinU4norHuxWe
-lAAAAAAAB3AUpSgPzA8wpgeYV+0oD8wPMKYHmFftKAUpSgFKVhmS4sNDa5clmOlx1DKC64Eh
-S1kJSgZ71EkADvJNAZqUpQClKUApSlAKUpQClKUApSlAKUpQClKUAr5WhKxhQBr6pQEXcLFA
-mJIcZQc+yqnd+jyE/lTI2k+augUoDiV06OpjOSz4wqw9GemHrc+p2SjCh3ZrpZSk96Qf3USh
-KfqpSP2Cgs/K/RX7SgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFKUoBSlKAUpSgFc
-h6QpmqZnSvItFq7XPQrbZ4M5luwtWYlmQ87NbW4tVwG7JQ0lKeGeQC843c+vVWdQ6F0/fL4q
-9zFXqPPXGbirdt18mweI02pxSEqEd1AVtU64QSCfGNAc36S+lDUsG2qutttpgWVi4XmJ1pmY
-2qTKMG33BS07HGVpZ/TxQUK/SZ4fjJwdqtqN0qagYcjvXiyRhIefu8OJEgz8svuMXaJb2OIX
-GQtCi4+RuSraE7lFBKkpauF26LNC3WVLkz7O88ZapC3W+vyEtBUhlxl9SWw4EIU4284FFIBJ
-VuPjAEbUro80fKXJU/aCvrPWisGU9tSZLjLrxQN+Gyp2O05lGCFgqGFKUSBW2OkfU0rUB0tD
-0ZBd1Cz1wS2VXopjNGOmE4Nr3AKlpWic2QeGCFDBGMqEo7q966R+jO72dxyPA1PNSt5pxCSp
-cddrlyUIOQdpC22jlOD4uM4JBmdP6L03YZjE22wXUS2G5DaZD0t591YfUyp0rW4pSnFKMdnx
-lkkBAAIGRWKdoPTMzTdk08qLNjwLFw/Bgh3KTGdjcNlTCdrzTiXP5pa0nKjkKOc0BAat11db
-N0ko0xa7QbrJmswUR2npyI7CFut3R1S8hlSwcQADkqBBTtSkpVxKVqvpwu7Wl2bxbNOiLIXb
-kXmE09PSpqRDettxktF8BoqCgYCyW0KSc8P9KAVprqlv0HpmDdIV0bizX58HZwJUy5SZLo2J
-lJRuW64orwmbJA3E8nAP6CNusroz0OqPDjuWFtxmFAZtzDbj7qkiM0xJjttkFWFANTJKcqyT
-xMkkhJAFXl9IdyX0mwLA5pa8PKt0hiHcnLaqY9GakyGWlklaIoacaaS6klTrjRAUVcMkJIke
-inpOka7uBQNJ3S3W5+F16DPdjSktOtFSQlK1OsNt71BYUA0t1JAUd3LnO/5P9K+GIl2VBlLl
-xQztUu4SFJdUykJacdQXNrziQBhxwKXyBzkVn0zonTOm7i9cLNAcjvuNlobpbzqGWyrcW2kL
-UUsoKsEpbCRkDlyFAWKlKUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQCl
-KUApSlAKUpQClKUApSlAKUpQClKUApSlAY5La3Y7rTb7jC1oKUuthJUgkfWG4EZHfzBHnBqF
-8A3X11v/ALmF+XqepQED4Buvrrf/AHML8vTwDdfXW/8AuYX5ep6lAQPgG6+ut/8Acwvy9PAN
-19db/wC5hfl6nqUBA+Abr663/wBzC/L08A3X11v/ALmF+XqepQED4Buvrrf/AHML8vTwDdfX
-W/8AuYX5ep6lAQPgG6+ut/8Acwvy9PAN19db/wC5hfl6nqUBA+Abr663/wBzC/L08A3X11v/
-ALmF+XqepQED4Buvrrf/AHML8vTwDdfXW/8AuYX5ep6lAQPgG6+ut/8Acwvy9PAN19db/wC5
-hfl6nqUBA+Abr663/wBzC/L08A3X11v/ALmF+XqepQED4Buvrrf/AHML8vTwDdfXW/8AuYX5
-ep6lAQPgG6+ut/8Acwvy9PAN19db/wC5hfl6nqUBA+Abr663/wBzC/L08A3X11v/ALmF+Xqe
-pQED4Buvrrf/AHML8vTwDdfXW/8AuYX5ep6lAQPgG6+ut/8Acwvy9PAN19db/wC5hfl6nqUB
-A+Abr663/wBzC/L08A3X11v/ALmF+XqepQED4Buvrrf/AHML8vTwDdfXW/8AuYX5ep6lAQPg
-G6+ut/8Acwvy9PAN19db/wC5hfl6nqUBA+Abr663/wBzC/L08A3X11v/ALmF+XqepQED4Buv
-rrf/AHML8vTwDdfXW/8AuYX5ep6lAQPgG6+ut/8Acwvy9PAN19db/wC5hfl6nqUBA+Abr663
-/wBzC/L08A3X11v/ALmF+XqepQED4Buvrrf/AHML8vTwDdfXW/8AuYX5ep6lAQPgG6+ut/8A
-cwvy9PAN19db/wC5hfl6nqUApSlAKUpQCqZ026ruOiOjC76ntTMV6ZC4PDRJSpTZ3vttnISp
-J7lnyjnirnUD0g6Ut2t9ITtMXV6UzDm8PiLjKSlwbHEuDBUlQ70DyHlmtMTippy6XyVmm4vb
-1NTpD1P2Y7O/pNnha+xrX/mnHzxd3L+db2fV+v4+P1FZ5VuydNFgvDdlXBsGpFm+NSF2xJjs
-5kqYJDrY/S4ChjOThOP6WeVTVz0Ai8eDPDuqr/dfBl2jXWLxkxG9jzG/CTwmEZQrf4wPPxRg
-jnnV0z0Vae0/2Q6lMujnZPrvUOK62eJ1rPE4uEDONx27duPLmto+QoVLl/39aMn5jlx0/r/Z
-BNdNNsml65WiJNnwEaWdvwiCIht7a3JUyvLyn9o27VZQGzySSlajhB+GOn/SDUW3G8xZltlS
-IkWTKaLrCxFEgBTf+sC3AUlK8toUQlQKgg5SJPTnQtpSxxlRo8y7vtKsEiwKS882cxn31vLV
-4qB4+5xQB7sY5Z51ms3RJaLOppVt1FqaKerxo0osS22lTG4/JlLikNhQ2owjKCglIwc5JOje
-l54ZRLORmrOlssX222vTltcfbOro2nrhMlM/oNys8VDRSsK4ifF5qTt7++s2udeX+2dLLWj7
-e5FjQ1WIXIv+AZd0eLnHU3s4cdxJSjAB3EYB5Z8YVvyuiPTz988JpuV5ZR4fb1D1Nt5vgddT
-3rwUFWFeUbv2YqUvmhWbjrhOsYeob1Z7qm2i2FUMRlIUxxS7gpeZc57iOYx3D25qpYFVenzL
-bcruyras6Wyxfbba9OW1x9s6ujaeuEyUz+g3KzxUNFKwriJ8XmpO3v76iF9OTjOldOXBNlmT
-zfIVykonNxWmUNCIHSs9WVJUVFIQkqTxU7knKVbvEFsldEenn754TTcryyjw+3qHqbbzfA66
-nvXgoKsK8o3fsxWk90I6XXpSxadbul8YZsjM5iNIQ8zxlNzAoPpXlspIIWQCEgjz551eMtNS
-TXun9aKuOa379PofrPTNpxi2xpExm5PobgQJV0msREoYg9bSktFxJdUpO7cDtSXNoPNR763G
-OlzTzl4FuVbb00jtCvTplrYb4ImpPJOQsqwryHb+3FYHehjSjjCIplXZMNcSDEnRg8jh3BEM
-AMF7xM5ASM7CjPmrc/yVae9Mun/KztX/ADrf+d/qfU/mvZ9b/aqj+zfH37/YsvOLT4Z//VnZ
-7wVdP8w674Q6v/I/5zZweJn+d/pbcfV55qUqL8Df/qztD4Vun+YdS8H9Y/kf85v43Dx/O/0d
-2fq8sVKVyyrijdX3FKUqpIpSlAKUpQCuI/SF6c3ujPUlr0/a7I1ebhMZD6mS8UEIKinyA4+q
-e+rV08dKFv6MdKCc42mVdpqixbIZOOM75z5kjIJr+fmu9VzHbzcbhNuCrnqS4LKp88nIbz/q
-m/IEgcuXkGK1x493L6FZSo9+dFfTTo3XVpkPiexaJ8I7ZsOY+hCmT3ZCicKST5RVv7Y6R9ab
-H8Qa/FX8obFd5lpuyJ8Y71DIcQrml1B+slXnBFXqYlnLUiKSY0ltLzOe/aryftByP2iuvTaO
-GeTi5UznzZ5Y0nR/Ta2XG33OOZFtnxZrIVtLkd5Lic+bKSRmtquGfQn/AOaJ/wD3o7/9KK7n
-XJnx+VkcPQ3xz3xUhSlc8+kbd79YuiC9XPTjzsea0GwXmkje02paQtQO4bSAe8AkeYfWFccH
-Oaiu5M5bYuXodDpVISbpYehq4TY5mquzFokSkdaeW+5xg0pSfrvPcsgeKHFD21RPo66ukrcu
-0PUWpFvxVtWbqL1ym7lOS5UJLjrKFLOVEryQ2O7JAFaLA5RlJPoUeVKSi+53KleaXNbzH+lG
-+u6n1Dq/Tdnl6Xek9WRHkR128plBKChLje1K1NtgcXGCt0oSrcUius9BTepRolyTqVU4GZOe
-k29ic+p6TGhrILTbq1EqUoDJ5knBAPdgWy6Z447myIZlOVJFsvlyXAQw3Hj9YlSneEw3u2hS
-sEnJ8gABJ9grU4+rPs6x/f3flV+akITfNOqPkmO/3Z2uK6w1bqWP09GLHus5uNHvtmgMQkPK
-DLkWQw+qQpTedqjuSPGIJG3kRWeHC8raT6Ky2TIsaTfc7Xx9WfZ1j+/u/Kpx9WfZ1j+/u/Kq
-S46POacdHnNYmhG8fVn2dY/v7vyq+VytVIGVwLEkZAyZ7o5k4A/mvPUpx0ec1q3R5KozaR5Z
-DH9qmgNfj6s+zrH9/d+VX4ZGrAM+DbKceQTnMn+LVa+rkIubMW0KvrlqbmOlDgYc4cmQkIKi
-204FAoPLJUnKtoOCk+MM+l3ym1dXdvKLwqO64wZQCQo7FEbXNpwXE4wogDJB5DuoCQsdxTdL
-emSGlNLC1NuNq70LSSlSf3EGtHUd6lQpsS2WyEiZcZSVuIQ47w0JQnG5SlYJxkgcge8V86HO
-bdOPnukz+2XXOPpKXe7WG3SbrY33Y89mySA2639dsKkxUrUD5CEqUc+Tvq+ODnJRXciUlFOX
-oX3ruvfsCxfE3PlU67r37AsXxNz5VQXQJcrjPseoo86dKnMW3Uk6DAkSXVOuLjNqTsytRJXj
-KhkknlXRanJDZJxIhLdGyr9d179gWL4m58qnXde/YFi+JufKq0UqhYjNO3N25RnxKjdVmRXi
-xJZ3bghe0KGD5QUqSQfMfJUnUFpn/TeqP96N/wBzjVO0ApSlAKUpQClKUApSlAKq3S3fezXR
-nqG9pXscjQHOCrPc6obW/wDvqTVppVotKSbIkrTSPO/QzDGnkToWtIbki66OtCJ9qt7HjNCO
-touLdaQQNz5c3pUo9xICcDv0oHS/dku3e5XnU78GzrsrEqAw29EdlmS85lCG1mMhGAlKkLCk
-uBBzlWe70rSup6qMpOUoXfv07mCwSSSjI4dN1tqOxaC02zO1Kb7edQvSHG7nBfiNxo4aRuLA
-dTHdQtXLaMNkqXuAxyFV26dLGrmOjayA3JZ1DIsL95cnx1R22nEh1SEtbCw6HHEjBWhIbwAr
-KhzI9J0qI6jGusF1v3wHhn2kch6Ib9q/WWobw/N1OPBNoMKMEwY7BblSkspVJ8coUeGVH+ic
-4I2lPl69SlYZZqcrSo1hFxVN2KUpWZcUpSgFKUoDi/0sujl7XWjoM63/AOkbLIMhoBG7ekpI
-Un2DOD+6v56X62T40pfX0bH0rLbifKCOXkr+uZqmzuizo9napb1NL0nbHbq2rcHy13q/WKfq
-k+0jNawybVTKONuzwf0afR56TdW2xu9Q7K1DgK5tme4GlPDzhJ549tdAjfRm6UGbfFhmPbVJ
-jNlCT1tPPK1LP/FRr3ClISkJSAAOQA7hX7WuLVzxPdFKyk8MZqmcw+jXoq+aD0A7Zb+2yiWq
-c48A04FjaUpA5j9hrp9KVhkyPJJyfVmkIqEVFCsclhmTHcjyWW3mXUlDjbiQpK0kYIIPIg+a
-slKoWNK0Wi1WeD1G0WyFbom4q4EVhLTeT3nakAZNarGltMx4zMZjTtoaYYliay2iE2lLcgdz
-yQBgODyKHP21L0q25+pFIi7tpzT13fdfuthtc911gRnFyYjbqlshYcDZKgcoCwFbe7cAe+st
-jslmsMRUOx2iBa4y3C4pmHGQyhSyACopSACcADPsFb9KbnVWKV2V/WLb6VW24NMuPIhSVOOp
-bTuVtU2tGQPLjdn91V56dpx26tXZ20rcuLKChqWq0Ol5CTnKUr4eQOZ5A+Wug0qvK6ElL7SQ
-f1Lh8Pf/AAU7SQf1Lh8Pf/BV0pUUTZS+0kH9S4fD3/wVje1DBcDY2T/FdbWf/wAvf7krCj/Q
-9lXilKFnPL/NsF9tbttukS4PR3MHAhSULQocwpK0pCkKB5hSSCD3Gs9uu9nt8FiBAhzI8ZhA
-baabtz6UpSO4DxKvlKULITRMZ+PZlqkNKaXIlPSAhXekOLKgD7edR2rIm3U1vusu3uT7YIUi
-HKbbjl84cKDktgEqT4mCAD392M1bKVJBWbXe9N2uC3AtlpuUGI0CG2I+npbbaMnJwlLIA51s
-9q7V6NfPgcz5VTtKO2CC7V2r0a+fA5nyqdq7X6NfPgcz5VTtKAg9Jtvqcu9yejuxkXCcH2W3
-k7VhCWWmgVDyE8MnB5gEZwanKUoBSlKAUpWrd3JjNpmPW+P1mYhhao7O4J4jgSSlOSQBk4GS
-QKLkEPpXXGltUXa6WqxXVMyZanOHMbDLiOGrcpPIqSAoZQoZSSOXtFWKvPvRt0Yaz03cLYq5
-N8WLctNy7fd1QFoZkRHVrU8klanSHXd7i0hxAAHLPIZrPpno5vzNk1DpmTYpUOwybahpmWyz
-AjXh55LiTtLjLpbcQUp8ZTiklWcHyk9k9Pi3PbPg545clcx5O90rgDehddO6QftR05bo9uj3
-yDK6iyxEhSbrDRkvsvpYWWMklOMqGcHOMgV86f6LtRuao0k5fLG0vT8a7XuS7b3X2nEW+JIb
-QI8dSdxCxuSfFRuSM8+VR9nhzc17V+o86X/E7fKvtrjzuomSp+WHmmXGIrK5DjBd3cNTqWwo
-tIO1Xjr2p5czUlXnjVnRdqFzpue1Ba9KR129/U9nuiJzTkdHBZZQvreQVBe5TikrIAO8pycn
-FfHR90R3uC30bN3rTjaURWrqxqZKpLSgptZUqMhYSs8ROSCEp3AE88c6s9Pi2p7/ANvS/X8v
-xIWad1t93X+z0VSvMEbor1+9pXTEW/225T24VmlQl2+NcIYcjSTKcW25xHwtCUlooTvby4ja
-MeUGS1d0WavmMa+lRbS7KushqxGxSnJ7Snlux220SHA4SjCwEqBWpKN3PA54p9lx3XmL269f
-zHnzq9nur/0ehWZ0J+dIgszI7suKEKkMIdBcaC87CpIOUhWDjPfg4rTuWobPbtQWmwTJnCuV
-343UWeGs8XhI3ueMBtThJz4xGfJmqTobR8mx9N2udQLsEdm33lqKuDOaDQwpKP5QggHelS3C
-Fk4wopyTnFczsPRdr2PctNq8EdSukFF9RPv3XWlcd6Sy4mPIwFFZwVJHduGOYAAqsMGNt3Lt
-9L+T4LSyzS4j3+v8Hpalcd6A9DXnS1zclXO23SAs2tqNKL06IpmTISrKnENMNgnGDh11ZWQr
-BB767FWGWChKk7NMcnKNtUKUpWZcUpSgFKUoCL1LqKyabgpm325xrfHUrYlb69oUrzDzmtu1
-3CFdLexcLdKalRH072nmlBSVp84Iri/0sejnV3SPaLXb9MMRSIq1urW9I4fjEYAAx5s86tv0
-c9Nag0b0TWrS2pGGGplu4jYLLwcStCllYOfJ9Yj91AdEpWhfpsmBb1SIkJUx0EANpVt/fVeg
-6ycDiEXW3qilZwMc+eaynmhCSi3yy8ccpK0XClfLbiHE7kKyK+q1KClKUApSlAKUpQClatzn
-xbbFMiW5sRkJGBkqJ7gAOZJ81RvaaH9n3v4U/wDgoCcpUH2mh/Z97+FP/gp2mh/Z97+FP/go
-CcpUH2mh/Z97+FP/AIKdpof2fe/hT/4KAnKVB9pof2fe/hT/AOCh1PCAyqBekgd5NrfAH/do
-CcpWGDKjzYjcqK6l1lwbkqSeRFal9vdvsrTa5ziwXVbW22m1OOLOM4SlIJPLzUBI0qr9urP6
-Fffg8j8FO3Vn9CvvweR+CgLRSqv26s/oV9+DyPwU7dWf0K+/B5H4KAtFK1LRcod2gomwXeIy
-okZIwQQcEEHmCD5DW3QClKUApSlAKUpQFb1hrG36auVntb0OfOuF4dcbhxobaVLUG0b3Fncp
-ICUpwTzzz5A1yNHTbBuPRpp+TqWe5bLpc23Zs5u0hLShEakuNFLanXklKl8MDxCtZAXtSDgj
-rmr9HW7Utzs10fmT4M+zOuORJMNxKVgOI2OIO5KhtUnAPLPLkRVZtPQ1p6z262xrNe9RW1+B
-CegJmxpTaZDsd15Tym1K4eBhaiQpISoefPOuzFLBGK3df7/0c+RZXLjp/X+z81D01aUtDFxl
-Nw7xc4dtiRJcuTCYQW20ytpYB3rSdygoK7sAd5zyre/yq6e9Cun/ACs7KfzTf+d/r/X/AJr2
-/W/2aonS90Z3y+Tr7b9PWi5ITe2Lew9cFXZlcZ3gLT48htwcbehKcAoUvdnJwauz3RHp5y8G
-4JuV6bR2hRqMREPN8ETUnmrBQVbVeUbv2EVZx06im/fT62QpZnJr33NnRnSZa9YIlOaftFzl
-tMJdIVxoiFOKQSNobU+HEFRGBxEoHMEkDnVatnT1YDoy26ovllm2qJcHXEtfyyK4ShLxa4gR
-xUurTkc9rZKcK7wAo2uF0d2pnXUfWUq4T51zipdTHLjcdpKA4Nqs8FpCnOXIbyrGeXOqr/7P
-mizbvB6rnqBUUQ3IKGzJaGxhT/WAgEN5O13KwTk88EkYAiP2a+fh9b+nYPzq49++T7vXS+5F
-6RHdImxzIAjXy32xyY421JS8ZQWpKdqXkFoKSnclz9JgZ3ICsJMi100aUcZXKES7iGuJOlQZ
-RYRw7giGCXwz4+cgJON4Rnz1luXRFYrhq5rU8q83xU0ToE99AcZDciRDQUNLWOFkeKpWQgpB
-3HAHLGJroY0o2wuKJV2VDREnRIMYvI4dvRMBD5Z8TOSFHG8rxS9M0vfb+fkKzW/fvgltF9I9
-m1Te2rPFgXSFKftLV4jiY0hIeiuEJC0lK1dyjgg49mRzq51UdOdH9msOobbfIcmeuTbtPNaf
-ZS64goVHbWFpUoBIJcyBkggf7NW6ubLs3fc6G0N1feFKUrMuKUpQClKUBx36RnS4jo+Yj2iI
-pyNcpjJfRMXHLrbSEnBAA+s4e4A4HlJ8+x0a9LcjVnQ27rBFhuEi4xXHYsiNFaSVcRABDm1S
-gAkpUlRGeWSOeKt3SHoDSWt2o3amAJKYhJaVxVN7c9/MEZHKpHR+mdP6Y0+izaegMRbcCpXD
-QchRV3knyk+2tHKGxJLkqk7vsQvRjqmbq3QUS73O0T7dIMdtxxUhpKEvEp3FbYSpXi/twaiF
-SI991fDj2iVHlKZc4rpSdwbSnyqx+7lV7fmQbVBITwY0WM3zJwhttAH8AAKpWmulbo/vV4Nt
-sN+t78x5zYkNNKSHl4JwlZSAs4B7iawdM0Vo6FHaDSSNylqUcqUrvJrJWtDlB9RTjBAzyrZq
-yIZimPoiw3pLgyhltTihuSnkBnvUQB+0kDzkVzzoI15dekSyyr9LFujRQ8ptqGwgF1rCjtK1
-h5RyUjuU22eeRlOCekVXNE6QiaRZehWq43A2xTjjjFve4RZjFaytXDIQHMZJ5KUrGa2jKKhJ
-Nc8GclLcmuhTdV9IWp9K6+XbbtBsz1oVbp9yaDBdS+liM1vSS4vCHHFEKBbQklAwokg1KdCm
-t5+tbbMkXGTZlvNIjO8GC2+24wHmQ4EOpdHPGeS0EpWBkY7q25vRpY7hqld+u0+83M7JSGYc
-uXxI8YSWw28GxjckKSMbdxSMnAFamnOiay6fCFWu+ajYeEyHJdeRMShchuK2W2Yzm1ACmAg4
-KcZOBk1u5YHjrv7+hkllUr7HOYv0gbwNPXe8SbPb1I8DKu1rbbCwUp8IKhBDxKjuO7avKdvL
-Ix5a6t0T6qn6ptV4F1Zitz7PeZVpkKjJUlp1TJHjpSokpBChyJPl51DxehXRTEG8QSme9Guc
-RUMNuPJxEYL6n9jOEjADqivxtxyB5OVWzROlrdpK1PQLe7JkKky3ZkqRJUlTr77hytaikAZP
-LuAHIUzzwOL2LmxijlTW58DUePDmnQcY646SD7I7pH/Gueaj6V7nbOlnsy1BhLtTF1ttqkLU
-FcdTs1p1xK0qCtoSnYAQUknJ5ir9rBYZuFikLO1tuYsKUe4bmXEjP7VKA/fVVuegtPXDW7Wr
-X1SxLQ8xIWwlwBh15hK0suqGN25AWoDCgO7INYYZY4t712NMim0tp0fiD9YfxpxB+sP41EdY
-9tOse2sbNaJfiD9YfxrVubykxkFCykl9kZScci4kEfwrS6x7axSnStLSRz/TtE+wBxJJpYoz
-anlXtEJDGno8Zc59WxMiUcsRRgkuLSFBSxywEpwSSMlIyoZ7FMnyba2u6wkwpqSUOtodDiCQ
-cbkKHMoV3jIBweYB5VBalizbjCQbZdnbZcGFcSO+ElxvdgjDjeQHEEHmCQfKCkgEZ7Iwq2W1
-EZ2fJmuglbsiQvKnFk5UfMkZPJKQAByAAFLIo3NEf6OnAdwucsAeYcZVUrpv1W5omUnUzUZE
-p2DZ5CmmnCdhcW/HbSTjngFfPHkzVy0Cd9mkOjmh2fJcQodykqdUQR7CCDUB0j2C16l1NCsd
-8SrwdcbXKiqIVtO8raWkJP6w4ZUP+rV8bipJy6dyJ24vb1N/on1VP1TarwLqzFbn2e8yrTIV
-GSpLTqmSPHSlRJSCFDkSfLzq41BaJ0tbtJWp6Bb3ZMhUmW7MlSJKkqdffcOVrUUgDJ5dwA5C
-p2pyOLm3HoRBNRW7qKUpVCxBaY5XrU6RyAuiMD9sSOT/AMSTU7UBpNaHrlqSSyoLZdug4a0n
-KVbYzCFYPlwpCh+0Gp+gFKUoBSlKAUpSgFKUoDl30rv+YHUv/Zf70zXM3UydOayXETCs1qW/
-0gWRg2SOw3JjQ2lR1njMFxsBKnDnx0IQpJQQCK9O0rqxany4bKvr9P4MMmHfLdfvn+TiegNY
-akma3VpLUGpnJ9wltygiTYZEGRDi7QSlSkcEusqAI28VSgpQ5gjIqr/Rz1brHUOqbVYLhrW4
-SWUWV653Bh5thx1uQi4Lb4JWpsrSkt7CUqJICvFKRt2+lKVL1Maa2Ln/AH8CPJlae7ocH6Kt
-aa81PqlqBeb/AAIS5SJyJtraRul24oKktrSnq21opO3HHcWFg5Az4tUbTWr9aNWXo9uh1pe5
-0uS5ekzILzrRQZjKVqjxV+JuJdKkJ2LUojenh7DtI9Y0qy1UE3UF7v4fH5EeRKl973x/Bx3o
-Q1pqTUOpkwZt48OQF6fjz5j/AFZtvqFwWvC4mW0p7k5OFZUNvfXYqUrmyzU5WlRtji4qm7FK
-UrMuKUpQClKUBz3p0jX2bpuNFsUKZJeL/EXwMeKEpOM8/Pio76NEXU1v0JKt2qoVwjTW57ri
-DKH121gEbTnyHdy9tdTpWflrfvJviiDvljbucCRAlMtyokhBbdaX3LSe8Go+FpONHbjMMW+I
-wzFx1dKW0gNYGAU4HI4q2Uq2xE7masGGmMM7tyyMZrapSpSoq3YpSlSBSlKAUpSgMUuNHlx1
-R5TKHmljCkLGQah+x2lvsGB7kVO0oCC7HaW+wIHuRTsdpb7Age5FTtKAgux2lvsCB7kU7HaW
-+wIHuRU7SgILsdpb7Age5FBo/S4IIsMAEdx4QqdpQHwy02y0lppCUISMJSByFYrhBhXCMqNP
-iR5bCu9t5sLSf3HlWxSgILsbpD1Wsf3Br8NOxukPVax/cGvw1O0oCC7G6Q9VrH9wa/DTsbpD
-1Wsf3Br8NTtKAxxmGIrCI8ZltllAwhttISlI8wA7qyUpQCuZ9IPSl2X1w5pndoyJw7bHndY1
-DqjwXxeK6+jY0ngOb9vAyo5GN6eVdMqmXvTOqu3EzU2mdR2W39dtsWDIj3GzOzP83dkrStKk
-SWsZ6yoEEH6o50B9Tek3RUJ+4NSrq+ym3olKfeVb5AYPVkqVIS27w9jq2w2vchClKGxXLka+
-HOlLRLbe5dymBfWkREMeCpRfccW246gIa4e9aVoacKVJBSraQkk8qqPSJ0XX+fA1jNtV4ivP
-XO13JtiDGgJivTHH4zjbbL7wdDTiUqUkpUptKxsTuWRuzYYfR7cXNawdWXrUjM6dDlsrSlm3
-cBCo7MWcw22RxFePunuLUvuO0AISO4CYkdIWkI1xmQZN2UwuEl9TzzsV5Ef9CkreSl8o4S1o
-SlRUhKipO1WQMHGunpN0cYi3zMuSVpfbY6ouzzEy1rWla0BEctcZYUltxQKUEEIUc+KcV6B0
-Pw4OrrlfIkixM9cenSUPjTkddxQ7KC9+6WvcVtpLqylOwHGEqKk5SccXopurOn5lsXqOzLS8
-/HdZieASbc1wgsHEdT6lIUreklTTjWC2jaE+NuAssjpO0RHYhvuXhZaltl1K0Qn1hlsOFsrf
-KUHq6QtKkEu7AFJUDzBxHdLHSP2Hu9nt3C06nwjFlyePer74NaHAUwnhoVwXOI4rj5CeXJCu
-dRsnoour1petvbNS27nafA96W/AU6uRFDr60pYUp3LJSmS62FLLp27c5Uncb3MsXWNcWvU3W
-tvULbMg9X4eeJ1h2Kvfuzy29WxjBzv7xjmBHWLXliuWnGry8uRA/TwYkmO+wsOxpUtEdTLCw
-E/W/lbAJGUgq5kYVjWj9KGi5NiiXuNPnyIU0nqqmbRLWt9IQlanENhorU2kLTlwDYknBIIIr
-RvvR7cp9+nyYupWotquN7t17lQ1W/iOqfiKi4Sl3iAJbUmI2CNhIVz3Yykxd66HItw0joyzq
-lWSbK0tavBjTt3sSJ8Z5BaZQtzgKWNjmWEKSoKO3KgdwJoC46n1W1brNapdnipvUm9SG49qa
-bfDbchS21OhRcwdqA22tZUAThPIE4FQrfSXEtUqRa9awFWW7tPstNxoXGuKJXGbeW0WS20Fq
-3CM+MFtJy2Rg5TmTvGjus6XsdsttyFunWBbLttltxG9jbjbSmubKNqNim1uIKE7QAo7duBiM
-hdH85zVNu1VfNQNT7zGuCJTy2IHAZUy3Elx22G0FxRQEmY45uUpZJJHIEbQPub0raPtUORIv
-dzTH6uuaXjFiyZKGWo0l1hTjiksjh5UypPjAArCkoU4AFK+k9KmkWHZEa43EMyY7zyXkxosl
-9tlpEuRGDriwyA2nfGcClKwhBB8dSSlaud9IXRzrONGv9o0il+ajVMGdEnyVR44ZaTImzZKA
-SuQlbezrriVKS27vHclBxi4o6KNto1zA8PZ7V22XA39T/wA148u4yN+N/j7fCO3Hi54Wcjdh
-IFsh6005L1IrT0ec6qeHHGk5iPJZccbBLjaHikNLWkA7kJUVDarIGDjLqDVmn7BPhQLtcBHk
-zXWmmGw0tZUp15DLYO0EJ3OOJSCrA7z3JURUtNdFMGxdIb+qY5sRS5NlzgrwCz4RLskrK0qm
-klZbBcXtCUpVghJUUjB+ekLRGor/AKvdl2i5QrexJYta1SZUMyktOW6c5KQ3ww80r9Ip1GVA
-nxWlDkVJUAL/AGy5Qrm285CfDoYfcjujaUlDiFFKkkEAjmP3ggjIINbdVvRNpm2+dqefNbDJ
-u95VLaZ3BWxtDDMdJ5EjxwxxMeTfzwcirJQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKU
-pQClKUApSlAKUpQClKUApSlAKUpQClKUBjkuLajuutsOPrQgqS02UhSyB9UbiBk93MgecioX
-w9dfUq/++hfmKnqUBA+Hrr6lX/30L8xTw9dfUq/++hfmKnqUBA+Hrr6lX/30L8xTw9dfUq/+
-+hfmKnqUBA+Hrr6lX/30L8xTw9dfUq/++hfmKnqUBA+Hrr6lX/30L8xTw9dfUq/++hfmKnqU
-BA+Hrr6lX/30L8xTw9dfUq/++hfmKnqUBA+Hrr6lX/30L8xTw9dfUq/++hfmKnqUBA+Hrr6l
-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
-IVsZZfbzsWknIyCD5fMTUxSld2LBjwrbjior4KjglOUncnYpSlalRSlKAUpSgIzUNqVc2GSy
-/wBXkxnOKw4U7gFYIII8oIJH76iPBGqvtOz/AHNz5lWlSgkFSiAB5Sax9ZjekNf1xQFa8Eaq
-+07P9zc+ZTwRqr7Ts/3Nz5lWXrMb0hr+uKdZjekNf1xUUTZWvBGqvtOz/c3PmV+Ks2qFbc3K
-znaoKH8jd7wQR/rPOBVm6zG9Ia/rinWY3pDX9cUoWVrwRqr7Ts/3Nz5lPA+qfLc7Rj2RHM/2
-lWXrMb0hr+uKdZj+kNf1xShZq2C2ptVuTFDqnVlanHFn+ktRyo/vJrWvlmdmXCJdIExMO4RU
-rQ2txritqQvG5Kk5SSOQPIg5AqYBBGQcivlxaG07nFpQnzqOBUkEJ1XWH23YvhDv5mnVdYfb
-di+EO/mal+txPSmPeCnW4npTHvBQER1XWH23YvhDv5mnVdYfbdi+EO/mal+txPSmPeCnW4np
-THvBQGpYbYq2syC9JMqVKeL8l4oCQte0JGEjuASlKQOfIDmTzqRr8SpK0hSVBQPcQciv2gFK
-UoBSlKAUpSgFKUoBSlKAVB631Ta9IWZNzuvHWl2Q3FjsR0b3ZDzhwhtCcjKifOQOR51OVTul
-rSErV9ltibdKYjXKz3eNd4RfBLS3WSSELxzCSFEZGccuRoWjV8m9atXQ34Fwm3m33HTDdvcC
-JCr0lthsAjkpLoWppafJlKzg8jitmTq3SkW0MXiTqaysW2QcMTHJ7SWXT5krKtp/capet9J6
-41lYogui9ORJtsvsW6wYbDrzjDqGSSWn3VIBVuyTlLYxgcjVfY6ILqxZDIUiG7qJV9nXdh+J
-eX4KbYZO0KbZWlhZWnCRnchOefnqC6jB9WdRt+qrTcNRtWWBIYll63eEW5DEyOtC2uJw+SA5
-xSM/09mzybt3Kp2uWaA0FrK2dI1t1bqm+wLu8zpQ2eU+2FJddkdcLwUE7QnYEEJ3ZBJGdvOu
-p1JSaSfApSlCopSlAKUpQGtdp8a12uVcprqWo0VlbzqyeSUpBJP8BX84umnpRvnSHrFy4TVP
-M2kKPg6NkhCW88lEfrEcya949O1luuouh7VNlsiVLuMq3uIYQk4K1d+0ftAI/fXhRWmpUmxM
-M3SzTrZMYSG1syo6m1ZSMEpyOdUndHVpau+5XrYtwPNvsuFLiFBSfYa9KW/6UZ07p+128aF6
-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
---------------090109030206070103090500--
-
---------------050702060806040107070701--
-
---------------080809000000030101030405--
diff --git a/mailbox/elasticsearch/src/test/resources/eml/emailWith3Attachments.eml b/mailbox/elasticsearch/src/test/resources/eml/emailWith3Attachments.eml
deleted file mode 100644
index 7cacfcb..0000000
--- a/mailbox/elasticsearch/src/test/resources/eml/emailWith3Attachments.eml
+++ /dev/null
@@ -1,50 +0,0 @@
-To: Laura ROYET <la...@linagora.com>
-From: Laura Royet <la...@linagora.com>
-Subject: test
-Message-ID: <cb...@linagora.com>
-Date: Wed, 11 Jan 2017 11:52:35 +0100
-User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
- Thunderbird/45.6.0
-MIME-Version: 1.0
-Content-Type: multipart/mixed;
- boundary="------------36566F1E9D791340FFB75FF8"
-
-This is a multi-part message in MIME format.
---------------36566F1E9D791340FFB75FF8
-Content-Type: text/plain; charset=utf-8; format=flowed
-Content-Transfer-Encoding: 7bit
-
-
-
---
-Laura Royet
-
-
---------------36566F1E9D791340FFB75FF8
-Content-Type: application/vnd.oasis.opendocument.text;
- name="attachment1.odt"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment;
- filename="attachment1.odt"
-
-UEsDBBQAAAgAAGJVK0pexjIMJwAAACcAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi92bmQu
-dC54bWxQSwUGAAAAABEAEQBwBAAAjyUAAAAA
---------------36566F1E9D791340FFB75FF8
-Content-Type: application/vnd.oasis.opendocument.text;
- name="attachment2-nonIndexableAttachment.html"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment;
- filename="attachment2-nonIndexableAttachment.odt"
-
-PCFET0NUWVBFIGh0bWw+CjxodG1sIGNsYXNzPSJtb3ppbGxhIiBsYW5nPSJlbiI+PGhlYWQ+
-CI+PC9kaXY+PC9kaXY+PC9ib2R5PjwvaHRtbD4=
---------------36566F1E9D791340FFB75FF8
-Content-Type: application/vnd.oasis.opendocument.text;
- name="attachment3.odt"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment;
- filename="attachment3.odt"
-
-UEsDBBQAAAgAAG9VK0pexjIMJwAAACcAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi92bmQu
-AAAAEgkAABNRVRBLUlORi9tYW5pZmVzdC54bWxQSwUGAAAAABEAEQBwBAAApyUAAAAA
---------------36566F1E9D791340FFB75FF8--
diff --git a/mailbox/elasticsearch/src/test/resources/eml/htmlContent.txt b/mailbox/elasticsearch/src/test/resources/eml/htmlContent.txt
deleted file mode 100644
index 5523279..0000000
--- a/mailbox/elasticsearch/src/test/resources/eml/htmlContent.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Linked Applications OpenPaas-Linagora Stash - OpenPaas Jenkins - OpenPaas Configure… Dashboards Projects Issues Agile More Create Help Online Help JIRA Agile Help Keyboard Shortcuts About JIRA JIRA Credits Administration JIRA administration Projects Issues User management System Add-ons Profile Atlassian Marketplace My JIRA Home Dashboard Agile Issue Navigator Disable new project navigation Log Out OpenPaaS RSE OR-2349 Docker-compose doesn't activate attachments and dwld/upld url are wro [...]
- "name" : "uploadUrl",
- "value" : "http://10.69.0.163:1080/jmap/upload",
- "_id" : ObjectId("5785f85cd7f4033c00fc606d")
- },
- {
- "name" : "downloadUrl",
- "value" : "http://10.69.0.163:1080/jmap/download",
- "_id" : ObjectId("5785f85cd7f4033c00fc606c")
- },
- should be replaced with {
- "name" : "uploadUrl",
- "value" : "http://10.69.0.163:1080/upload",
- "_id" : ObjectId("5785f85cd7f4033c00fc606d")
- },
- {
- "name" : "downloadUrl",
- "value" : "http://10.69.0.163:1080/download",
- "_id" : ObjectId("5785f85cd7f4033c00fc606c")
- },
- {
- "name" : "composer.attachments",
- "value" : true
- }
-
- Activity All Comments Work Log History Activity There are no comments yet on this issue. Comment Paragraph Heading 1 Heading 2 Heading 3 Heading 4 Heading 5 Heading 6 Preformatted Paragraph quote Block quote Strikethrough Superscript Subscript Citation External link Mail link Anchor link Attachment link Attachment link External image Attached image Attached image User mention Table Code Preformatted Panel Horizontal ruler Style BoldItalicUnderlineText colorMore colorsMore LinkImage Bull [...]
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/resources/eml/mailCustomDateHeader.eml b/mailbox/elasticsearch/src/test/resources/eml/mailCustomDateHeader.eml
deleted file mode 100644
index 2f42d75..0000000
--- a/mailbox/elasticsearch/src/test/resources/eml/mailCustomDateHeader.eml
+++ /dev/null
@@ -1,9 +0,0 @@
-Content-Type: text/plain; Charset=UTF-8
-Subject: my subject test
-MIME-Version: 1.0
-Message-Id: <20...@lenny>
-From: B <b...@test>
-To: c@test
-Custom-header: 2015/09/02
-
-Mail content
diff --git a/mailbox/elasticsearch/src/test/resources/eml/mailCustomStringHeader.eml b/mailbox/elasticsearch/src/test/resources/eml/mailCustomStringHeader.eml
deleted file mode 100644
index 0abb9f8..0000000
--- a/mailbox/elasticsearch/src/test/resources/eml/mailCustomStringHeader.eml
+++ /dev/null
@@ -1,9 +0,0 @@
-Content-Type: text/plain; Charset=UTF-8
-Subject: subject
-MIME-Version: 1.0
-Message-Id: <20...@lenny>
-From: a@test
-To: b@test
-Custom-header: custom header
-
-Mail content
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml b/mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml
deleted file mode 100644
index 2aff55d..0000000
--- a/mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml
+++ /dev/null
@@ -1,14 +0,0 @@
-Content-Type: text/plain; Charset=UTF-8
-Date: Fri, 17 Sep 2010 17:12:26 +0200
-Subject: my subject
-To: a@test, B <b...@test>
-Cc: c@test
-Bcc: dD <d...@test>
-MIME-Version: 1.0
-Message-Id: <20...@lenny>
-From: Ad Min <ad...@opush.test>
-
-Mail content
-
---
-Ad Min
diff --git a/server/container/guice/cassandra-guice/pom.xml b/server/container/guice/cassandra-guice/pom.xml
index 30a45da..5660b98 100644
--- a/server/container/guice/cassandra-guice/pom.xml
+++ b/server/container/guice/cassandra-guice/pom.xml
@@ -217,7 +217,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>metrics-es-reporter</artifactId>
+ <artifactId>metrics-es-reporter-v7</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerESMetricReporterModule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerESMetricReporterModule.java
index 3b9e438..def9e5d 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerESMetricReporterModule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/modules/TestDockerESMetricReporterModule.java
@@ -21,7 +21,7 @@ package org.apache.james.modules;
import javax.inject.Singleton;
-import org.apache.james.metrics.es.ESReporterConfiguration;
+import org.apache.james.metrics.es.v7.ESReporterConfiguration;
import org.apache.james.util.Host;
import com.google.inject.AbstractModule;
diff --git a/server/container/guice/es-metric-reporter/pom.xml b/server/container/guice/es-metric-reporter/pom.xml
index 6ba956d..6330bf9 100644
--- a/server/container/guice/es-metric-reporter/pom.xml
+++ b/server/container/guice/es-metric-reporter/pom.xml
@@ -45,7 +45,7 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
- <artifactId>metrics-es-reporter</artifactId>
+ <artifactId>metrics-es-reporter-v7</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
diff --git a/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java b/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
index f38f0ef..74a5ce8 100644
--- a/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
+++ b/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
@@ -23,8 +23,8 @@ import java.io.FileNotFoundException;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.metrics.es.ESMetricReporter;
-import org.apache.james.metrics.es.ESReporterConfiguration;
+import org.apache.james.metrics.es.v7.ESMetricReporter;
+import org.apache.james.metrics.es.v7.ESReporterConfiguration;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.PropertiesProvider;
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 24/32: JAMES-3492,
pass JamesWithNonCompatibleElasticSearchServerTest
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 6f7a4285b20aabfb19bcb0641ab128c6b6c8c95e
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Thu Mar 11 13:17:33 2021 +0200
JAMES-3492, pass JamesWithNonCompatibleElasticSearchServerTest
---
.../org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
index f5598f2..88ee9e8 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesWithNonCompatibleElasticSearchServerTest.java
@@ -29,7 +29,6 @@ import org.apache.james.modules.TestJMAPServerModule;
import org.apache.james.modules.mailbox.ElasticSearchStartUpCheck;
import org.apache.james.util.docker.Images;
import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -52,7 +51,6 @@ class JamesWithNonCompatibleElasticSearchServerTest {
}
@Test
- @Disabled("JAMES-3492, fails because communication fails with lower than 7.x nodes, maybe should be removed ")
void jamesShouldStopWhenStartingWithANonCompatibleElasticSearchServer(GuiceJamesServer server) throws Exception {
assertThatThrownBy(server::start)
.isInstanceOfSatisfying(
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 14/32: JAMES-3492 Remove NodeMappingFactory & tests
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 6ec3409fa6aedfb800432051b3089d12b8d3c7e3
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Mon Mar 8 11:17:54 2021 +0700
JAMES-3492 Remove NodeMappingFactory & tests
---
.../james/backends/es/v7/IndexCreationFactory.java | 16 +++
.../james/backends/es/v7/NodeMappingFactory.java | 83 ---------------
.../backends/es/v7/NodeMappingFactoryAuthTest.java | 111 ---------------------
.../backends/es/v7/NodeMappingFactoryTest.java | 100 -------------------
.../elasticsearch/v7/MailboxMappingFactory.java | 34 +++----
.../elasticsearch/v7/query/CriterionConverter.java | 2 +-
.../elasticsearch/v7/query/SortConverter.java | 10 +-
.../elasticsearch/v7/QuotaRatioMappingFactory.java | 12 +--
8 files changed, 45 insertions(+), 323 deletions(-)
diff --git a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
index fcac158..f2116f1 100644
--- a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
+++ b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/IndexCreationFactory.java
@@ -191,6 +191,22 @@ public class IndexCreationFactory {
public static final String KEEP_MAIL_AND_URL = "keep_mail_and_url";
public static final String SNOWBALL_KEEP_MAIL_AND_URL = "snowball_keep_mail_and_token";
public static final String ENGLISH_SNOWBALL = "english_snowball";
+ public static final String BOOLEAN = "boolean";
+ public static final String TYPE = "type";
+ public static final String LONG = "long";
+ public static final String DOUBLE = "double";
+ public static final String KEYWORD = "keyword";
+ public static final String PROPERTIES = "properties";
+ public static final String ROUTING = "_routing";
+ public static final String REQUIRED = "required";
+ public static final String DATE = "date";
+ public static final String FORMAT = "format";
+ public static final String NESTED = "nested";
+ public static final String FIELDS = "fields";
+ public static final String RAW = "raw";
+ public static final String ANALYZER = "analyzer";
+ public static final String NORMALIZER = "normalizer";
+ public static final String SEARCH_ANALYZER = "search_analyzer";
@Inject
public IndexCreationFactory(ElasticSearchConfiguration configuration) {
diff --git a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
deleted file mode 100644
index 02e927c..0000000
--- a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es.v7;
-
-import java.io.IOException;
-
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.indices.GetMappingsRequest;
-import org.elasticsearch.client.indices.GetMappingsResponse;
-import org.elasticsearch.client.indices.PutMappingRequest;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-
-public class NodeMappingFactory {
-
- public static final String BOOLEAN = "boolean";
- public static final String TYPE = "type";
- public static final String LONG = "long";
- public static final String DOUBLE = "double";
- public static final String INDEX = "index";
- public static final String NOT_ANALYZED = "not_analyzed";
- public static final String STRING = "string";
- public static final String TEXT = "text";
- public static final String KEYWORD = "keyword";
- public static final String PROPERTIES = "properties";
- public static final String ROUTING = "_routing";
- public static final String REQUIRED = "required";
- public static final String DATE = "date";
- public static final String FORMAT = "format";
- public static final String NESTED = "nested";
- public static final String FIELDS = "fields";
- public static final String RAW = "raw";
- public static final String ANALYZER = "analyzer";
- public static final String NORMALIZER = "normalizer";
- public static final String SEARCH_ANALYZER = "search_analyzer";
- public static final String SNOWBALL = "snowball";
- public static final String IGNORE_ABOVE = "ignore_above";
-
- public static ReactorElasticSearchClient applyMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
- if (!mappingAlreadyExist(client, indexName)) {
- createMapping(client, indexName, mappingsSources);
- }
- return client;
- }
-
- public static boolean mappingAlreadyExist(ReactorElasticSearchClient client, IndexName indexName) throws IOException {
- GetMappingsResponse getMappingResponse =
- client.indices().getMapping(
- new GetMappingsRequest()
- .indices(indexName.getValue()),
- RequestOptions.DEFAULT);
-
- return !getMappingResponse
- .mappings()
- .get(indexName.getValue())
- .sourceAsMap()
- .isEmpty();
- }
-
- public static void createMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
- client.indices().putMapping(
- new PutMappingRequest(indexName.getValue())
- .source(mappingsSources),
- RequestOptions.DEFAULT);
- }
-
-}
diff --git a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java
deleted file mode 100644
index eb98550..0000000
--- a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryAuthTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es.v7;
-
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-import java.io.IOException;
-import java.util.Optional;
-
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class NodeMappingFactoryAuthTest {
- private static final String MESSAGE = "message";
- private static final IndexName INDEX_NAME = new IndexName("index");
- private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-
- @RegisterExtension
- static ElasticSearchClusterExtension extension = new ElasticSearchClusterExtension(new ElasticSearchClusterExtension.ElasticSearchCluster(
- DockerAuthElasticSearchSingleton.INSTANCE,
- new DockerElasticSearch.WithAuth()));
-
- private ReactorElasticSearchClient client;
-
- @BeforeEach
- void setUp(ElasticSearchClusterExtension.ElasticSearchCluster esCluster) throws Exception {
- client = new ClientProvider(ElasticSearchConfiguration.builder()
- .credential(Optional.of(DockerElasticSearch.WithAuth.DEFAULT_CREDENTIAL))
- .hostScheme(Optional.of(ElasticSearchConfiguration.HostScheme.HTTPS))
- .sslTrustConfiguration(ElasticSearchConfiguration.SSLConfiguration.builder()
- .strategyIgnore()
- .acceptAnyHostNameVerifier()
- .build())
- .addHost(esCluster.es1.getHttpHost())
- .build()).get();
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliasesWithMapping(client, Optional.of(getMappingsSources()));
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void applyMappingShouldNotThrowWhenCalledSeveralTime() throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
- }
-
- @Test
- void applyMappingShouldNotThrowWhenIncrementalChanges(ElasticSearchClusterExtension.ElasticSearchCluster esCluster) throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
-
- esCluster.es1.flushIndices();
-
- assertThatCode(() -> NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getOtherMappingsSources()))
- .doesNotThrowAnyException();
- }
-
- private XContentBuilder getMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .endObject()
- .endObject()
- .endObject();
- }
-
- private XContentBuilder getOtherMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .field(NodeMappingFactory.INDEX, false)
- .endObject()
- .endObject()
- .endObject();
- }
-}
\ No newline at end of file
diff --git a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java b/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java
deleted file mode 100644
index ade2309..0000000
--- a/backends-common/elasticsearch-v7/src/test/java/org/apache/james/backends/es/v7/NodeMappingFactoryTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.backends.es.v7;
-
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-import java.io.IOException;
-import java.util.Optional;
-
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class NodeMappingFactoryTest {
- private static final String MESSAGE = "message";
- private static final IndexName INDEX_NAME = new IndexName("index");
- private static final ReadAliasName ALIAS_NAME = new ReadAliasName("alias");
-
- @RegisterExtension
- public DockerElasticSearchExtension elasticSearch = new DockerElasticSearchExtension();
- private ReactorElasticSearchClient client;
-
- @BeforeEach
- void setUp() throws Exception {
- client = elasticSearch.getDockerElasticSearch().clientProvider().get();
- new IndexCreationFactory(ElasticSearchConfiguration.DEFAULT_CONFIGURATION)
- .useIndex(INDEX_NAME)
- .addAlias(ALIAS_NAME)
- .createIndexAndAliasesWithMapping(client, Optional.of(getMappingsSources()));
- }
-
- @AfterEach
- void tearDown() throws IOException {
- client.close();
- }
-
- @Test
- void applyMappingShouldNotThrowWhenCalledSeveralTime() throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
- }
-
- @Test
- void applyMappingShouldNotThrowWhenIncrementalChanges() throws Exception {
- NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getMappingsSources());
-
- elasticSearch.awaitForElasticSearch();
-
- assertThatCode(() -> NodeMappingFactory.applyMapping(client,
- INDEX_NAME,
- getOtherMappingsSources()))
- .doesNotThrowAnyException();
- }
-
- private XContentBuilder getMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .endObject()
- .endObject()
- .endObject();
- }
-
- private XContentBuilder getOtherMappingsSources() throws Exception {
- return jsonBuilder()
- .startObject()
- .startObject(NodeMappingFactory.PROPERTIES)
- .startObject(MESSAGE)
- .field(NodeMappingFactory.TYPE, NodeMappingFactory.TEXT)
- .field(NodeMappingFactory.INDEX, false)
- .endObject()
- .endObject()
- .endObject();
- }
-}
\ No newline at end of file
diff --git a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java
index 9289338..4769095 100644
--- a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java
+++ b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java
@@ -19,22 +19,22 @@
package org.apache.james.mailbox.elasticsearch.v7;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.ANALYZER;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.BOOLEAN;
import static org.apache.james.backends.es.v7.IndexCreationFactory.CASE_INSENSITIVE;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.FIELDS;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.FORMAT;
import static org.apache.james.backends.es.v7.IndexCreationFactory.KEEP_MAIL_AND_URL;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.ANALYZER;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.BOOLEAN;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.FIELDS;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.FORMAT;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.KEYWORD;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.LONG;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.NESTED;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.NORMALIZER;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.PROPERTIES;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.RAW;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.REQUIRED;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.ROUTING;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.SEARCH_ANALYZER;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.TYPE;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.KEYWORD;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.LONG;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.NESTED;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.NORMALIZER;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.PROPERTIES;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.RAW;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.REQUIRED;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.ROUTING;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.SEARCH_ANALYZER;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.TYPE;
import static org.apache.james.mailbox.elasticsearch.v7.json.JsonMessageConstants.ATTACHMENTS;
import static org.apache.james.mailbox.elasticsearch.v7.json.JsonMessageConstants.BCC;
import static org.apache.james.mailbox.elasticsearch.v7.json.JsonMessageConstants.CC;
@@ -67,7 +67,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import java.io.IOException;
-import org.apache.james.backends.es.v7.NodeMappingFactory;
+import org.apache.james.backends.es.v7.IndexCreationFactory;
import org.apache.james.mailbox.elasticsearch.v7.json.JsonMessageConstants.Attachment;
import org.apache.james.mailbox.elasticsearch.v7.json.JsonMessageConstants.EMailer;
import org.apache.james.mailbox.elasticsearch.v7.json.JsonMessageConstants.HEADER;
@@ -135,12 +135,12 @@ public class MailboxMappingFactory {
.endObject()
.startObject(DATE)
- .field(TYPE, NodeMappingFactory.DATE)
+ .field(TYPE, IndexCreationFactory.DATE)
.field(FORMAT, "uuuu-MM-dd'T'HH:mm:ssX||uuuu-MM-dd'T'HH:mm:ssXXX||uuuu-MM-dd'T'HH:mm:ssXXXXX")
.endObject()
.startObject(SENT_DATE)
- .field(TYPE, NodeMappingFactory.DATE)
+ .field(TYPE, IndexCreationFactory.DATE)
.field(FORMAT, "uuuu-MM-dd'T'HH:mm:ssX||uuuu-MM-dd'T'HH:mm:ssXXX||uuuu-MM-dd'T'HH:mm:ssXXXXX")
.endObject()
diff --git a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/CriterionConverter.java b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/CriterionConverter.java
index 5a8d73e..a8de7bc 100644
--- a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/CriterionConverter.java
+++ b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/CriterionConverter.java
@@ -19,7 +19,7 @@
package org.apache.james.mailbox.elasticsearch.v7.query;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.RAW;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.RAW;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
diff --git a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/SortConverter.java b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/SortConverter.java
index 3ecdb40..48db609 100644
--- a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/SortConverter.java
+++ b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/query/SortConverter.java
@@ -19,7 +19,7 @@
package org.apache.james.mailbox.elasticsearch.v7.query;
-import org.apache.james.backends.es.v7.NodeMappingFactory;
+import org.apache.james.backends.es.v7.IndexCreationFactory;
import org.apache.james.mailbox.elasticsearch.v7.json.JsonMessageConstants;
import org.apache.james.mailbox.model.SearchQuery;
import org.elasticsearch.search.sort.FieldSortBuilder;
@@ -43,15 +43,15 @@ public class SortConverter {
return SortBuilders.fieldSort(JsonMessageConstants.DATE);
case MailboxCc :
return SortBuilders.fieldSort(JsonMessageConstants.CC + PATH_SEPARATOR + JsonMessageConstants.EMailer.ADDRESS
- + PATH_SEPARATOR + NodeMappingFactory.RAW);
+ + PATH_SEPARATOR + IndexCreationFactory.RAW);
case MailboxFrom :
return SortBuilders.fieldSort(JsonMessageConstants.FROM + PATH_SEPARATOR + JsonMessageConstants.EMailer.ADDRESS
- + PATH_SEPARATOR + NodeMappingFactory.RAW);
+ + PATH_SEPARATOR + IndexCreationFactory.RAW);
case MailboxTo :
return SortBuilders.fieldSort(JsonMessageConstants.TO + PATH_SEPARATOR + JsonMessageConstants.EMailer.ADDRESS
- + PATH_SEPARATOR + NodeMappingFactory.RAW);
+ + PATH_SEPARATOR + IndexCreationFactory.RAW);
case BaseSubject :
- return SortBuilders.fieldSort(JsonMessageConstants.SUBJECT + PATH_SEPARATOR + NodeMappingFactory.RAW);
+ return SortBuilders.fieldSort(JsonMessageConstants.SUBJECT + PATH_SEPARATOR + IndexCreationFactory.RAW);
case Size :
return SortBuilders.fieldSort(JsonMessageConstants.SIZE);
case SentDate :
diff --git a/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaRatioMappingFactory.java b/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaRatioMappingFactory.java
index e82eb37..7785629 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaRatioMappingFactory.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v7/src/main/java/org/apache/james/quota/search/elasticsearch/v7/QuotaRatioMappingFactory.java
@@ -19,12 +19,12 @@
package org.apache.james.quota.search.elasticsearch.v7;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.DOUBLE;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.KEYWORD;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.PROPERTIES;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.REQUIRED;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.ROUTING;
-import static org.apache.james.backends.es.v7.NodeMappingFactory.TYPE;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.DOUBLE;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.KEYWORD;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.PROPERTIES;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.REQUIRED;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.ROUTING;
+import static org.apache.james.backends.es.v7.IndexCreationFactory.TYPE;
import static org.apache.james.quota.search.elasticsearch.v7.json.JsonMessageConstants.DOMAIN;
import static org.apache.james.quota.search.elasticsearch.v7.json.JsonMessageConstants.QUOTA_RATIO;
import static org.apache.james.quota.search.elasticsearch.v7.json.JsonMessageConstants.USER;
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 23/32: JAMES-3502, fix indent in tests
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit ad3d344090d9f876d2e98f5eb195dcc37e9baeef
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Thu Mar 11 10:53:46 2021 +0200
JAMES-3502, fix indent in tests
---
.../james/webadmin/routes/UserQuotaRoutesTest.java | 26 +++++++++++-----------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
index d936a14..699d285 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
@@ -120,7 +120,7 @@ class UserQuotaRoutesTest {
.untilAsserted(() -> {
given()
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.contentType(ContentType.JSON)
.body("username", containsInAnyOrder(
@@ -142,9 +142,9 @@ class UserQuotaRoutesTest {
.untilAsserted(() -> {
given()
.param("domain", LOST_LOCAL)
- .when()
+ .when()
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.contentType(ContentType.JSON)
.body("username", containsInAnyOrder(
@@ -165,9 +165,9 @@ class UserQuotaRoutesTest {
.untilAsserted(() -> {
given()
.param("limit", 2)
- .when()
+ .when()
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.contentType(ContentType.JSON)
.body("username", containsInAnyOrder(
@@ -188,9 +188,9 @@ class UserQuotaRoutesTest {
.untilAsserted(() -> {
given()
.param("offset", 1)
- .when()
+ .when()
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.contentType(ContentType.JSON)
.body("username", containsInAnyOrder(
@@ -214,9 +214,9 @@ class UserQuotaRoutesTest {
.untilAsserted(() -> {
given()
.param("minOccupationRatio", 0.5)
- .when()
+ .when()
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.contentType(ContentType.JSON)
.body("username", containsInAnyOrder(
@@ -240,9 +240,9 @@ class UserQuotaRoutesTest {
.untilAsserted(() -> {
given()
.param("maxOccupationRatio", 0.5)
- .when()
+ .when()
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.contentType(ContentType.JSON)
.body("username", containsInAnyOrder(
@@ -266,7 +266,7 @@ class UserQuotaRoutesTest {
.untilAsserted(() -> {
given()
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.contentType(ContentType.JSON)
.body("username", contains(
@@ -435,7 +435,7 @@ class UserQuotaRoutesTest {
with()
.param("minOccupationRatio", 0.5)
.get("/quota/users")
- .then()
+ .then()
.statusCode(HttpStatus.OK_200)
.extract()
.body()
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 10/32: JAMES-3492 Check Mapping existence by
GetMappingsAPI
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit d9150fb78503c4beadc2c7118e1612228233e9c0
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Wed Mar 3 16:27:55 2021 +0700
JAMES-3492 Check Mapping existence by GetMappingsAPI
---
.../james/backends/es/v7/NodeMappingFactory.java | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
index 2f526d8..02e927c 100644
--- a/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
+++ b/backends-common/elasticsearch-v7/src/main/java/org/apache/james/backends/es/v7/NodeMappingFactory.java
@@ -22,6 +22,8 @@ package org.apache.james.backends.es.v7;
import java.io.IOException;
import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.indices.GetMappingsRequest;
+import org.elasticsearch.client.indices.GetMappingsResponse;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -51,10 +53,26 @@ public class NodeMappingFactory {
public static final String IGNORE_ABOVE = "ignore_above";
public static ReactorElasticSearchClient applyMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
- createMapping(client, indexName, mappingsSources);
+ if (!mappingAlreadyExist(client, indexName)) {
+ createMapping(client, indexName, mappingsSources);
+ }
return client;
}
+ public static boolean mappingAlreadyExist(ReactorElasticSearchClient client, IndexName indexName) throws IOException {
+ GetMappingsResponse getMappingResponse =
+ client.indices().getMapping(
+ new GetMappingsRequest()
+ .indices(indexName.getValue()),
+ RequestOptions.DEFAULT);
+
+ return !getMappingResponse
+ .mappings()
+ .get(indexName.getValue())
+ .sourceAsMap()
+ .isEmpty();
+ }
+
public static void createMapping(ReactorElasticSearchClient client, IndexName indexName, XContentBuilder mappingsSources) throws IOException {
client.indices().putMapping(
new PutMappingRequest(indexName.getValue())
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 05/32: JAMES-3492 Migrate to Java time date format
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit bb08901750b8d0b8c03a7e35283e14328a9fe999
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Thu Mar 4 15:19:30 2021 +0700
JAMES-3492 Migrate to Java time date format
---
.../apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java
index 403d8b9..9289338 100644
--- a/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java
+++ b/mailbox/elasticsearch-v7/src/main/java/org/apache/james/mailbox/elasticsearch/v7/MailboxMappingFactory.java
@@ -136,12 +136,12 @@ public class MailboxMappingFactory {
.startObject(DATE)
.field(TYPE, NodeMappingFactory.DATE)
- .field(FORMAT, "yyyy-MM-dd'T'HH:mm:ssZ")
+ .field(FORMAT, "uuuu-MM-dd'T'HH:mm:ssX||uuuu-MM-dd'T'HH:mm:ssXXX||uuuu-MM-dd'T'HH:mm:ssXXXXX")
.endObject()
.startObject(SENT_DATE)
.field(TYPE, NodeMappingFactory.DATE)
- .field(FORMAT, "yyyy-MM-dd'T'HH:mm:ssZ")
+ .field(FORMAT, "uuuu-MM-dd'T'HH:mm:ssX||uuuu-MM-dd'T'HH:mm:ssXXX||uuuu-MM-dd'T'HH:mm:ssXXXXX")
.endObject()
.startObject(USER_FLAGS)
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 26/32: JAMES-3492, add upgrade instructions
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 1df64b0a4e62cc42f2e8be8438eea2a9f51c29bf
Author: andreasvaldma <andreas.valdmanortal.com>
AuthorDate: Fri Mar 12 08:41:39 2021 +0200
JAMES-3492, add upgrade instructions
---
upgrade-instructions.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index ba2c70d..6b929df 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -62,7 +62,7 @@ JIRA: https://issues.apache.org/jira/browse/JAMES-2492
Concerned products: Cassandra Guice server (with and without rabbitMQ)
-James is no longer tested against Elasticsearch 6.3.2 but instead against Elasticsearch 7.10.2 Users are recommended to upgrade to this
+James is no longer compatible with Elasticsearch 6.x. The new environment uses Elasticsearch 7.10.2 and users are recommended to upgrade to this
version as well.
This [link](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/rolling-upgrades.html) describes a possible update procedure:
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 31/32: JAMES-3499 Fix LDAP related dockerfiles
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit a30dff6537d8d8d62e9a36bbf2a3fdc9eb3e939a
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 12 17:42:28 2021 +0700
JAMES-3499 Fix LDAP related dockerfiles
---
dockerfiles/run/guice/cassandra-ldap/Dockerfile | 4 ++--
dockerfiles/run/guice/cassandra-rabbitmq-ldap/Dockerfile | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dockerfiles/run/guice/cassandra-ldap/Dockerfile b/dockerfiles/run/guice/cassandra-ldap/Dockerfile
index e6f1e85..a2c33a7 100644
--- a/dockerfiles/run/guice/cassandra-ldap/Dockerfile
+++ b/dockerfiles/run/guice/cassandra-ldap/Dockerfile
@@ -19,8 +19,8 @@ EXPOSE 25 110 143 465 587 993 4000 8000
WORKDIR /root
# Get data we need to run James : build results and configuration
-ADD destination/james-server-cassandra-ldap-guice.jar /root/james-server.jar
-ADD destination/james-server-cassandra-ldap-guice.lib /root/james-server-cassandra-ldap-guice.lib
+ADD destination/james-server-cassandra-guice.jar /root/james-server.jar
+ADD destination/james-server-cassandra-guice.lib /root/james-server-cassandra-guice.lib
ADD destination/james-server-cli.jar /root/james-cli.jar
ADD destination/james-server-cli.lib /root/james-server-cli.lib
ADD destination/conf /root/conf
diff --git a/dockerfiles/run/guice/cassandra-rabbitmq-ldap/Dockerfile b/dockerfiles/run/guice/cassandra-rabbitmq-ldap/Dockerfile
index ee3cccd..9c1f5cf 100644
--- a/dockerfiles/run/guice/cassandra-rabbitmq-ldap/Dockerfile
+++ b/dockerfiles/run/guice/cassandra-rabbitmq-ldap/Dockerfile
@@ -19,8 +19,8 @@ EXPOSE 25 110 143 465 587 993 4000 8000
WORKDIR /root
# Get data we need to run James : build results and configuration
-ADD destination/james-server-cassandra-rabbitmq-ldap-guice.jar /root/james-server.jar
-ADD destination/james-server-cassandra-rabbitmq-ldap-guice.lib /root/james-server-cassandra-rabbitmq-ldap-guice.lib
+ADD destination/james-server-cassandra-rabbitmq-guice.jar /root/james-server.jar
+ADD destination/james-server-cassandra-rabbitmq-guice.lib /root/james-server-cassandra-rabbitmq-guice.lib
ADD destination/james-server-cli.jar /root/james-cli.jar
ADD destination/james-server-cli.lib /root/james-server-cli.lib
ADD destination/conf /root/conf
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 13/32: JAMES-3492 Use assertion with Awaitility in
QuotaSearcherContract
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit d3b31b47865126905b982a783e2ab374ca9f077a
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Thu Mar 4 14:40:59 2021 +0700
JAMES-3492 Use assertion with Awaitility in QuotaSearcherContract
---
.../v7/ElasticSearchQuotaSearcherTest.java | 96 +++-------------
mailbox/plugin/quota-search-scanning/pom.xml | 5 +
mailbox/plugin/quota-search/pom.xml | 5 +
.../james/quota/search/QuotaSearcherContract.java | 122 ++++++++++++---------
4 files changed, 95 insertions(+), 133 deletions(-)
diff --git a/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/ElasticSearchQuotaSearcherTest.java b/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/ElasticSearchQuotaSearcherTest.java
index c69e158..9cc724b 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/ElasticSearchQuotaSearcherTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/ElasticSearchQuotaSearcherTest.java
@@ -26,21 +26,15 @@ import java.util.stream.IntStream;
import org.apache.james.core.Username;
import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.domainlist.api.DomainListException;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.quota.search.Limit;
import org.apache.james.quota.search.Offset;
import org.apache.james.quota.search.QuotaQuery;
import org.apache.james.quota.search.QuotaSearchTestSystem;
import org.apache.james.quota.search.QuotaSearcherContract;
-import org.apache.james.user.api.UsersRepositoryException;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(ElasticSearchQuotaSearchTestSystemExtension.class)
-@Disabled("JAMES-3492")
class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
@Test
void searchShouldNotBeLimitedByElasticSearchDefaultSearchLimit(QuotaSearchTestSystem testSystem) throws Exception {
@@ -49,17 +43,18 @@ class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
testSystem.getMaxQuotaManager().setGlobalMaxStorage(QuotaSizeLimit.size(100));
IntStream.range(0, userCount)
- .boxed()
- .map(i -> Username.fromLocalPartWithDomain("user" + i, SIMPSON_COM))
- .forEach(user -> provisionUser(testSystem, user));
+ .boxed()
+ .map(i -> Username.fromLocalPartWithDomain("user" + i, SIMPSON_COM))
+ .forEach(user -> provisionUser(testSystem, user));
testSystem.await();
- assertThat(
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withLimit(Limit.unlimited())
- .build()))
- .hasSize(userCount);
+ .search(QuotaQuery.builder()
+ .withLimit(Limit.unlimited())
+ .build()))
+ .hasSize(userCount));
}
@Test
@@ -74,13 +69,14 @@ class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
.forEach(user -> provisionUser(testSystem, user));
testSystem.await();
- assertThat(
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withLimit(Limit.unlimited())
- .withOffset(Offset.of(1))
- .build()))
- .hasSize(userCount - 1);
+ .search(QuotaQuery.builder()
+ .withLimit(Limit.unlimited())
+ .withOffset(Offset.of(1))
+ .build()))
+ .hasSize(userCount - 1));
}
private void provisionUser(QuotaSearchTestSystem testSystem, Username username) {
@@ -91,64 +87,4 @@ class ElasticSearchQuotaSearcherTest implements QuotaSearcherContract {
throw new RuntimeException(e);
}
}
-
- @Override
- public void moreThanShouldFilterOutTooSmallValues(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void lessThanShouldFilterOutTooBigValues(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void rangeShouldFilterValuesOutOfRange(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void hasDomainShouldFilterOutValuesWithDifferentDomains(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void andShouldCombineClauses(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void resultShouldBeAlphabeticallyOrdered(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void limitShouldBeTheMaximumValueOfReturnedResults(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void offsetShouldSkipSomeResults(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void searchShouldReturnEmptyOnTooBigOffset(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void pagingShouldBeSupported(QuotaSearchTestSystem testSystem) throws Exception {
-
- }
-
- @Override
- public void appendMessage(QuotaSearchTestSystem testSystem, Username username, MessageManager.AppendCommand appendCommand) throws MailboxException, UsersRepositoryException, DomainListException {
-
- }
-
- @Override
- public MessageManager.AppendCommand withSize(int size) {
- return null;
- }
}
diff --git a/mailbox/plugin/quota-search-scanning/pom.xml b/mailbox/plugin/quota-search-scanning/pom.xml
index 36c278a..9bb57bc 100644
--- a/mailbox/plugin/quota-search-scanning/pom.xml
+++ b/mailbox/plugin/quota-search-scanning/pom.xml
@@ -95,6 +95,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
diff --git a/mailbox/plugin/quota-search/pom.xml b/mailbox/plugin/quota-search/pom.xml
index fc808c0..24f9145 100644
--- a/mailbox/plugin/quota-search/pom.xml
+++ b/mailbox/plugin/quota-search/pom.xml
@@ -73,6 +73,11 @@
<artifactId>testing-base</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java b/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java
index db0da2e..89f5920 100644
--- a/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java
+++ b/mailbox/plugin/quota-search/src/test/java/org/apache/james/quota/search/QuotaSearcherContract.java
@@ -25,6 +25,7 @@ import static org.apache.james.core.CoreFixture.Users.BENOIT_AT_DOMAIN_TLD;
import static org.apache.james.quota.search.QuotaBoundaryFixture._50;
import static org.apache.james.quota.search.QuotaBoundaryFixture._75;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Durations.ONE_HUNDRED_MILLISECONDS;
import java.nio.charset.StandardCharsets;
@@ -40,13 +41,18 @@ import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.ByteContent;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.user.api.UsersRepositoryException;
-import org.junit.jupiter.api.Disabled;
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionFactory;
import org.junit.jupiter.api.Test;
import com.google.common.base.Strings;
public interface QuotaSearcherContract {
+ ConditionFactory CALMLY_AWAIT = Awaitility
+ .with().pollInterval(ONE_HUNDRED_MILLISECONDS)
+ .and().pollDelay(ONE_HUNDRED_MILLISECONDS)
+ .await();
String PASSWORD = "any";
@Test
@@ -62,11 +68,12 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, Simpson.LISA, withSize(51));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .moreThan(_50)))
- .containsOnly(Simpson.HOMER, Simpson.LISA);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .moreThan(_50)))
+ .containsOnly(Simpson.HOMER, Simpson.LISA));
}
@Test
@@ -82,11 +89,12 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, Simpson.LISA, withSize(51));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .lessThan(_50)))
- .containsOnly(Simpson.HOMER, Simpson.BART);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .lessThan(_50)))
+ .containsOnly(Simpson.HOMER, Simpson.BART));
}
@Test
@@ -103,12 +111,13 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(80));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .moreThan(_50)
- .lessThan(_75)))
- .containsOnly(Simpson.HOMER, Simpson.LISA);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .moreThan(_50)
+ .lessThan(_75)))
+ .containsOnly(Simpson.HOMER, Simpson.LISA));
}
@Test
@@ -125,11 +134,12 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(50));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .hasDomain(SIMPSON_COM)))
- .containsOnly(Simpson.BART, Simpson.LISA);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .hasDomain(SIMPSON_COM)))
+ .containsOnly(Simpson.BART, Simpson.LISA));
}
@Test
@@ -146,12 +156,13 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(50));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .hasDomain(SIMPSON_COM)
- .lessThan(_50)))
- .containsOnly(Simpson.BART);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .hasDomain(SIMPSON_COM)
+ .lessThan(_50)))
+ .containsOnly(Simpson.BART));
}
@Test
@@ -169,10 +180,11 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, Alphabet.ABB, withSize(50));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()))
- .containsExactly(Alphabet.AAA, Alphabet.ABA, Alphabet.ABB, Alphabet.ACB);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()))
+ .containsExactly(Alphabet.AAA, Alphabet.ABA, Alphabet.ABB, Alphabet.ACB));
}
@Test
@@ -190,11 +202,12 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, Alphabet.ABB, withSize(50));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withLimit(Limit.of(2))))
- .containsOnly(Alphabet.AAA, Alphabet.ABA);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .withLimit(Limit.of(2))))
+ .containsOnly(Alphabet.AAA, Alphabet.ABA));
}
@Test
@@ -212,11 +225,12 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, Alphabet.ABB, withSize(50));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withOffset(Offset.of(2))))
- .containsOnly(Alphabet.ABB, Alphabet.ACB);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .withOffset(Offset.of(2))))
+ .containsOnly(Alphabet.ABB, Alphabet.ACB));
}
@Test
@@ -235,11 +249,12 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, BENOIT_AT_DOMAIN_TLD, withSize(50));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withOffset(Offset.of(5))))
- .isEmpty();
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .withOffset(Offset.of(5))))
+ .isEmpty());
}
@Test
@@ -257,12 +272,13 @@ public interface QuotaSearcherContract {
appendMessage(testSystem, Alphabet.ABB, withSize(50));
testSystem.await();
- assertThat(
- testSystem.getQuotaSearcher()
- .search(QuotaQuery.builder()
- .withLimit(Limit.of(2))
- .withOffset(Offset.of(1))))
- .containsExactly(Alphabet.ABA, Alphabet.ABB);
+ CALMLY_AWAIT.untilAsserted(() ->
+ assertThat(
+ testSystem.getQuotaSearcher()
+ .search(QuotaQuery.builder()
+ .withLimit(Limit.of(2))
+ .withOffset(Offset.of(1))))
+ .containsExactly(Alphabet.ABA, Alphabet.ABB));
}
default void appendMessage(QuotaSearchTestSystem testSystem, Username username, MessageManager.AppendCommand appendCommand) throws MailboxException, UsersRepositoryException, DomainListException {
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 12/32: JAMES-3492 Adapt
ElasticSearchQuotaMailboxListenerTest
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit decee0cf3970772ed06852f21e6404c13be5c5a3
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Thu Mar 4 14:30:53 2021 +0700
JAMES-3492 Adapt ElasticSearchQuotaMailboxListenerTest
---
.../ElasticSearchQuotaMailboxListenerTest.java | 29 +++++++++++++---------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/events/ElasticSearchQuotaMailboxListenerTest.java b/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/events/ElasticSearchQuotaMailboxListenerTest.java
index 34c6ac0..c609e22 100644
--- a/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/events/ElasticSearchQuotaMailboxListenerTest.java
+++ b/mailbox/plugin/quota-search-elasticsearch-v7/src/test/java/org/apache/james/quota/search/elasticsearch/v7/events/ElasticSearchQuotaMailboxListenerTest.java
@@ -23,6 +23,7 @@ import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.BOB
import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.NOW;
import static org.apache.james.quota.search.QuotaSearchFixture.TestConstants.QUOTAROOT;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Durations.ONE_HUNDRED_MILLISECONDS;
import java.io.IOException;
@@ -39,17 +40,24 @@ import org.apache.james.quota.search.elasticsearch.v7.QuotaRatioElasticSearchCon
import org.apache.james.quota.search.elasticsearch.v7.QuotaSearchIndexCreationUtil;
import org.apache.james.quota.search.elasticsearch.v7.UserRoutingKeyFactory;
import org.apache.james.quota.search.elasticsearch.v7.json.QuotaRatioToElasticSearchJson;
+import org.awaitility.Awaitility;
+import org.awaitility.Durations;
+import org.awaitility.core.ConditionFactory;
import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class ElasticSearchQuotaMailboxListenerTest {
+
+ private static final ConditionFactory CALMLY_AWAIT = Awaitility
+ .with().pollInterval(ONE_HUNDRED_MILLISECONDS)
+ .and().pollDelay(ONE_HUNDRED_MILLISECONDS)
+ .await();
static Event.EventId EVENT_ID = Event.EventId.of("6e0dd59d-660e-4d9b-b22f-0354479f47b4");
@RegisterExtension
@@ -79,14 +87,12 @@ class ElasticSearchQuotaMailboxListenerTest {
}
@Test
- @Disabled
void deserializeElasticSearchQuotaMailboxListenerGroup() throws Exception {
assertThat(Group.deserialize("org.apache.james.quota.search.elasticsearch.v7.events.ElasticSearchQuotaMailboxListener$ElasticSearchQuotaMailboxListenerGroup"))
.isEqualTo(new ElasticSearchQuotaMailboxListener.ElasticSearchQuotaMailboxListenerGroup());
}
@Test
- @Disabled
void eventShouldIndexEventWhenQuotaEvent() throws Exception {
quotaMailboxListener.event(EventFactory.quotaUpdated()
.eventId(EVENT_ID)
@@ -97,13 +103,12 @@ class ElasticSearchQuotaMailboxListenerTest {
.instant(NOW)
.build());
- elasticSearch.awaitForElasticSearch();
-
- SearchRequest searchRequest = new SearchRequest(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS.getValue())
- .source(new SearchSourceBuilder()
- .query(QueryBuilders.matchAllQuery()));
- SearchResponse searchResponse = client.search(searchRequest).block();
-
- assertThat(searchResponse.getHits().getTotalHits()).isEqualTo(1);
+ CALMLY_AWAIT.atMost(Durations.TEN_SECONDS)
+ .untilAsserted(() -> assertThat(client.search(
+ new SearchRequest(QuotaRatioElasticSearchConstants.DEFAULT_QUOTA_RATIO_READ_ALIAS.getValue())
+ .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())),
+ RequestOptions.DEFAULT)
+ .block()
+ .getHits().getTotalHits().value).isEqualTo(1));
}
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org