This is an automated email from the ASF dual-hosted git repository. jhelou pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit f8f200f506b57b369d4a62ed8b349e17883ec44d Author: Jean Helou <j...@xn--gml-cma.com> AuthorDate: Mon Mar 17 23:22:48 2025 +0100 [JAMES-4120] Switches scaling-pulsar-smtp from jpa/postgres to jooq/postgres --- .../james/mpt/smtp/JpaPulsarForwardSmtpTest.java | 4 +- .../mpt/smtp/JpaPulsarSmtpStarttlsCommandTest.java | 4 +- server/apps/scaling-pulsar-smtp/README.adoc | 9 +- server/apps/scaling-pulsar-smtp/docker-compose.yml | 11 ++- server/apps/scaling-pulsar-smtp/pom.xml | 8 +- .../sample-configuration/james-database.properties | 38 --------- .../sample-configuration/mailetcontainer.xml | 2 +- .../sample-configuration/postgres.properties | 51 +++++++++++ .../src/main/java/org/apache/james/Main.java | 99 +++++++++++++--------- .../org/apache/james/PostgresJPAExtension.java | 72 ---------------- .../java/org/apache/james/SMTPJamesServerTest.java | 3 +- 11 files changed, 132 insertions(+), 169 deletions(-) diff --git a/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarForwardSmtpTest.java b/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarForwardSmtpTest.java index 056e412080..3278751f48 100644 --- a/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarForwardSmtpTest.java +++ b/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarForwardSmtpTest.java @@ -23,9 +23,9 @@ import static org.apache.james.modules.protocols.SmtpGuiceProbe.SmtpServerConnec import org.apache.james.JamesServerExtension; import org.apache.james.Main; -import org.apache.james.PostgresJPAExtension; import org.apache.james.PulsarExtension; import org.apache.james.TestingSmtpRelayJamesServerBuilder; +import org.apache.james.backends.postgres.PostgresExtension; import org.apache.james.modules.AwsS3BlobStoreExtension; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.extension.RegisterExtension; @@ -35,7 +35,7 @@ public class JpaPulsarForwardSmtpTest implements ForwardSmtpTest { @Order(1) @RegisterExtension static JamesServerExtension testExtension = TestingSmtpRelayJamesServerBuilder.forConfiguration(c -> c) - .extension(new PostgresJPAExtension()) + .extension(PostgresExtension.empty()) .extension(new PulsarExtension()) .extension(new AwsS3BlobStoreExtension()) .extension(new InMemoryDnsExtension()) diff --git a/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarSmtpStarttlsCommandTest.java b/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarSmtpStarttlsCommandTest.java index 27e6e33ffe..113263deb7 100644 --- a/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarSmtpStarttlsCommandTest.java +++ b/mpt/impl/smtp/jpa-pulsar/src/test/java/org/apache/james/mpt/smtp/JpaPulsarSmtpStarttlsCommandTest.java @@ -23,9 +23,9 @@ import static org.apache.james.modules.protocols.SmtpGuiceProbe.SmtpServerConnec import org.apache.james.JamesServerExtension; import org.apache.james.Main; -import org.apache.james.PostgresJPAExtension; import org.apache.james.PulsarExtension; import org.apache.james.TestingSmtpRelayJamesServerBuilder; +import org.apache.james.backends.postgres.PostgresExtension; import org.apache.james.modules.AwsS3BlobStoreExtension; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.extension.RegisterExtension; @@ -35,7 +35,7 @@ public class JpaPulsarSmtpStarttlsCommandTest extends SmtpStarttlsCommandTest { @Order(1) @RegisterExtension static JamesServerExtension testExtension = TestingSmtpRelayJamesServerBuilder.forConfiguration(c -> c) - .extension(new PostgresJPAExtension()) + .extension(PostgresExtension.empty()) .extension(new PulsarExtension()) .extension(new AwsS3BlobStoreExtension()) .extension(new InMemoryDnsExtension()) diff --git a/server/apps/scaling-pulsar-smtp/README.adoc b/server/apps/scaling-pulsar-smtp/README.adoc index d4be3e810a..c600ae6308 100644 --- a/server/apps/scaling-pulsar-smtp/README.adoc +++ b/server/apps/scaling-pulsar-smtp/README.adoc @@ -77,4 +77,11 @@ Note that you can create a domain via an environment variable. This domain will ---- --environment DOMAIN=domain.tld ----- \ No newline at end of file +---- + +== Database backend migration + +Starting with James 3.9, the scaling-pulsar-smtp application uses the newly introduced Postgres backend instead of the JPA backend. + +If you previously deployed the scaling-pulsar-smtp application, you will want to run the https://github.com/apache/james-project/tree/master/server/apps/migration/migration-core-data-jpa-to-pg/sample-configuration[core data JPA to PG migration tool]. + diff --git a/server/apps/scaling-pulsar-smtp/docker-compose.yml b/server/apps/scaling-pulsar-smtp/docker-compose.yml index 79e41a514e..40eef41b86 100644 --- a/server/apps/scaling-pulsar-smtp/docker-compose.yml +++ b/server/apps/scaling-pulsar-smtp/docker-compose.yml @@ -22,14 +22,17 @@ services: - "5005:5005" environment: #- JDK_JAVA_OPTIONS=-Dlogback.configurationFile=/root/conf/logback.xml -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=0.0.0.0:5005 -Dworking.directory=/root/ - - JDK_JAVA_OPTIONS=-Dlogback.configurationFile=/root/conf/logback.xml -Dworking.directory=/root/ + - JDK_JAVA_OPTIONS=-Dlogback.configurationFile=/root/conf/logback.xml -Dworking.directory=/root/ --add-opens java.base/sun.net=ALL-UNNAMED - OBJECTSTORAGE_S3_ENDPOINT=http://s3.docker.test:8000/ - OBJECTSTORAGE_S3_REGION=us-east-1 - OBJECTSTORAGE_S3_ACCESSKEYID=accessKey1 - OBJECTSTORAGE_S3_SECRETKEY=secretKey1 - - DATABASE_URL=jdbc:postgresql://postgres/postgres - - DATABASE_USERNAME=postgres - - DATABASE_PASSWORD=password + - POSTGRESQL_DATABASE_NAME=postgres + - POSTGRESQL_DATABASE_SCHEMA=public + - POSTGRESQL_HOST=postgres + - POSTGRESQL_PORT=5432 + - POSTGRESQL_USERNAME=postgres + - POSTGRESQL_PASSWORD=password - PULSAR_BROKER_URI=pulsar://pulsar:6650 - PULSAR_ADMIN_URI=http://pulsar:8080/ - PULSAR_NAMESPACE=public/default diff --git a/server/apps/scaling-pulsar-smtp/pom.xml b/server/apps/scaling-pulsar-smtp/pom.xml index 31a7ab5383..8a16c764a7 100644 --- a/server/apps/scaling-pulsar-smtp/pom.xml +++ b/server/apps/scaling-pulsar-smtp/pom.xml @@ -88,10 +88,6 @@ <type>test-jar</type> <scope>test</scope> </dependency> - <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>james-server-data-jpa</artifactId> - </dependency> <dependency> <groupId>${james.groupId}</groupId> <artifactId>james-server-guice-common</artifactId> @@ -128,11 +124,11 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-jpa-common-guice</artifactId> + <artifactId>james-server-mailets</artifactId> </dependency> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-mailets</artifactId> + <artifactId>james-server-postgres-common-guice</artifactId> </dependency> <dependency> <groupId>${james.groupId}</groupId> diff --git a/server/apps/scaling-pulsar-smtp/sample-configuration/james-database.properties b/server/apps/scaling-pulsar-smtp/sample-configuration/james-database.properties deleted file mode 100644 index 81427a5ba4..0000000000 --- a/server/apps/scaling-pulsar-smtp/sample-configuration/james-database.properties +++ /dev/null @@ -1,38 +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. - -# This template file can be used as example for James Server configuration -# DO NOT USE IT AS SUCH AND ADAPT IT TO YOUR NEEDS - -# Read https://james.apache.org/server/config-system.html#james-database.properties for further details - -# Use derby as default -database.driverClassName=org.postgresql.Driver -#database.url=jdbc:postgresql://postgres/postgres -database.url=${env:DATABASE_URL} -#database.username=postgres -database.username=${env:DATABASE_USERNAME} -#database.password=password -database.password=${env:DATABASE_PASSWORD} - -# Validate the data source before using it -# datasource.testOnBorrow=true -# datasource.validationQueryTimeoutSec=2 -# This is different per database. See https://stackoverflow.com/questions/10684244/dbcp-validationquery-for-different-databases#10684260 -# datasource.validationQuery=select 1 -# The maximum number of active connections that can be allocated from this pool at the same time, or negative for no limit. -# datasource.maxTotal=8 diff --git a/server/apps/scaling-pulsar-smtp/sample-configuration/mailetcontainer.xml b/server/apps/scaling-pulsar-smtp/sample-configuration/mailetcontainer.xml index b5e1b674b1..8339741952 100644 --- a/server/apps/scaling-pulsar-smtp/sample-configuration/mailetcontainer.xml +++ b/server/apps/scaling-pulsar-smtp/sample-configuration/mailetcontainer.xml @@ -79,7 +79,7 @@ <delayTime>3 hours</delayTime> <delayTime>6 hours</delayTime> --> - <maxRetries>0</maxRetries> + <maxRetries>2</maxRetries> <maxDnsProblemRetries>0</maxDnsProblemRetries> <deliveryThreads>1</deliveryThreads> <sendpartial>false</sendpartial> diff --git a/server/apps/scaling-pulsar-smtp/sample-configuration/postgres.properties b/server/apps/scaling-pulsar-smtp/sample-configuration/postgres.properties new file mode 100644 index 0000000000..623ec937ef --- /dev/null +++ b/server/apps/scaling-pulsar-smtp/sample-configuration/postgres.properties @@ -0,0 +1,51 @@ +# String. Optional, default to 'postgres'. Database name. +#database.name=james +database.name=${env:POSTGRESQL_DATABASE_NAME} + +# String. Optional, default to 'public'. Database schema. +#database.schema=public +database.schema=${env:POSTGRESQL_DATABASE_SCHEMA} + +# String. Optional, default to 'localhost'. Database host. +#database.host=postgres +database.host=${env:POSTGRESQL_HOST} + +# Integer. Optional, default to 5432. Database port. +#database.port=5432 +database.port=${env:POSTGRESQL_PORT} + +# String. Required. Database username. +#database.username=james +database.username=${env:POSTGRESQL_USERNAME} + +# String. Required. Database password of the user. +#database.password=secret1 +database.password=${env:POSTGRESQL_PASSWORD} + +# Boolean. Optional, default to false. Whether to enable row level security. +row.level.security.enabled=false + +# String. It is required when row.level.security.enabled is true. Database username with the permission of bypassing RLS. +#database.by-pass-rls.username=bypassrlsjames + +# String. It is required when row.level.security.enabled is true. Database password of by-pass-rls user. +#database.by-pass-rls.password=secret1 + +# Integer. Optional, default to 10. Database connection pool initial size. +pool.initial.size=10 + +# Integer. Optional, default to 15. Database connection pool max size. +pool.max.size=15 + +# Integer. Optional, default to 5. rls-bypass database connection pool initial size. +by-pass-rls.pool.initial.size=5 + +# Integer. Optional, default to 10. rls-bypass database connection pool max size. +by-pass-rls.pool.max.size=10 + +# String. Optional, defaults to allow. SSLMode required to connect to the Postgresql db server. +# Check https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-PROTECTION for a list of supported SSLModes. +ssl.mode=allow + +## Duration. Optional, defaults to 10 second. jOOQ reactive timeout when executing Postgres query. This setting prevent jooq reactive bug from causing hanging issue. +#jooq.reactive.timeout=10second \ No newline at end of file diff --git a/server/apps/scaling-pulsar-smtp/src/main/java/org/apache/james/Main.java b/server/apps/scaling-pulsar-smtp/src/main/java/org/apache/james/Main.java index 71401164e2..ec942a85e9 100644 --- a/server/apps/scaling-pulsar-smtp/src/main/java/org/apache/james/Main.java +++ b/server/apps/scaling-pulsar-smtp/src/main/java/org/apache/james/Main.java @@ -19,19 +19,23 @@ package org.apache.james; +import org.apache.james.backends.postgres.PostgresModule; import org.apache.james.blob.api.BlobStore; import org.apache.james.blob.api.BlobStoreDAO; import org.apache.james.blob.api.MetricableBlobStore; import org.apache.james.blob.objectstorage.aws.S3BlobStoreDAO; import org.apache.james.blob.objectstorage.aws.S3RequestOption; +import org.apache.james.mailrepository.api.MailRepositoryFactory; import org.apache.james.mailrepository.api.MailRepositoryUrlStore; -import org.apache.james.mailrepository.jpa.JPAMailRepositoryUrlStore; +import org.apache.james.mailrepository.postgres.PostgresMailRepositoryFactory; +import org.apache.james.mailrepository.postgres.PostgresMailRepositoryUrlStore; import org.apache.james.modules.RunArgumentsModule; -import org.apache.james.modules.data.JPADomainListModule; -import org.apache.james.modules.data.JPAEntityManagerModule; -import org.apache.james.modules.data.JPARecipientRewriteTableModule; -import org.apache.james.modules.data.JPAUsersRepositoryModule; import org.apache.james.modules.data.MemoryDelegationStoreModule; +import org.apache.james.modules.data.PostgresCommonModule; +import org.apache.james.modules.data.PostgresDomainListModule; +import org.apache.james.modules.data.PostgresDropListsModule; +import org.apache.james.modules.data.PostgresRecipientRewriteTableModule; +import org.apache.james.modules.data.PostgresUsersRepositoryModule; import org.apache.james.modules.mailbox.BlobStoreAPIModule; import org.apache.james.modules.mailrepository.BlobstoreMailRepositoryModule; import org.apache.james.modules.objectstorage.S3BlobStoreModule; @@ -53,60 +57,71 @@ import org.apache.james.server.blob.deduplication.PassThroughBlobStore; import com.google.inject.Module; import com.google.inject.Scopes; +import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import com.google.inject.util.Modules; public class Main implements JamesServerMain { public static final Module WEBADMIN = Modules.combine( - new DataRoutesModules(), - new MailQueueRoutesModule(), - new MailRepositoriesRoutesModule(), - new NoJwtModule(), - new WebAdminServerModule(), - new WebAdminMailOverWebModule()); + new DataRoutesModules(), + new MailQueueRoutesModule(), + new MailRepositoriesRoutesModule(), + new NoJwtModule(), + new WebAdminServerModule(), + new WebAdminMailOverWebModule()); public static final Module PROTOCOLS = Modules.combine( - new SMTPServerModule(), - new ProtocolHandlerModule()); + new SMTPServerModule(), + new ProtocolHandlerModule()); private static final Module BLOB_MODULE = Modules.combine( - new BlobStoreAPIModule(), - new S3BlobStoreModule(), - new S3BucketModule(), - binder -> { - binder.bind(S3RequestOption.class).toInstance(S3RequestOption.DEFAULT); - binder.bind(BlobStoreDAO.class).to(S3BlobStoreDAO.class) - .in(Scopes.SINGLETON); - binder.bind(BlobStore.class) - .annotatedWith(Names.named(MetricableBlobStore.BLOB_STORE_IMPLEMENTATION)) - .to(PassThroughBlobStore.class); - }); + new BlobStoreAPIModule(), + new S3BlobStoreModule(), + new S3BucketModule(), + binder -> { + binder.bind(S3RequestOption.class).toInstance(S3RequestOption.DEFAULT); + binder.bind(BlobStoreDAO.class).to(S3BlobStoreDAO.class) + .in(Scopes.SINGLETON); + binder.bind(BlobStore.class) + .annotatedWith(Names.named(MetricableBlobStore.BLOB_STORE_IMPLEMENTATION)) + .to(PassThroughBlobStore.class); + }); public static final Module QUEUE_MODULES = Modules.combine( - new RawPostDequeueDecoratorModule(), - new PulsarQueueModule()); + new RawPostDequeueDecoratorModule(), + new PulsarQueueModule()); public static final Module SERVER_CORE_MODULES = Modules.combine( - new DefaultProcessorsConfigurationProviderModule(), - new JPAEntityManagerModule(), - new MailStoreRepositoryModule(), - new MailetContainerModule(), - new BlobstoreMailRepositoryModule(), - binder -> binder.bind(MailRepositoryUrlStore.class).to(JPAMailRepositoryUrlStore.class).in(Scopes.SINGLETON), - new CoreDataModule(), - new JPADomainListModule(), - new JPARecipientRewriteTableModule(), - new JPAUsersRepositoryModule(), - new MemoryDelegationStoreModule(), - new TaskManagerModule()); + new DefaultProcessorsConfigurationProviderModule(), + new MailStoreRepositoryModule(), + new MailetContainerModule(), + new BlobstoreMailRepositoryModule(), + new PostgresCommonModule(), + new PostgresDomainListModule(), + new PostgresRecipientRewriteTableModule(), + new PostgresUsersRepositoryModule(), + PostgresUsersRepositoryModule.USER_CONFIGURATION_MODULE, + new PostgresDropListsModule(), + binder -> { + Multibinder.newSetBinder(binder, MailRepositoryFactory.class) + .addBinding().to(PostgresMailRepositoryFactory.class); + Multibinder.newSetBinder(binder, PostgresModule.class) + .addBinding().toInstance(org.apache.james.mailrepository.postgres.PostgresMailRepositoryModule.MODULE); + binder.bind(MailRepositoryUrlStore.class).to(PostgresMailRepositoryUrlStore.class).in(Scopes.SINGLETON); + }, + new CoreDataModule(), + new MemoryDelegationStoreModule(), + new TaskManagerModule() + + ); public static void main(String[] args) throws Exception { SMTPRelayConfiguration configuration = SMTPRelayConfiguration.builder() - .useWorkingDirectoryEnvProperty() - .build(); + .useWorkingDirectoryEnvProperty() + .build(); LOGGER.info("Loading configuration {}", configuration.toString()); GuiceJamesServer server = createServer(configuration) - .overrideWith(new RunArgumentsModule(args)); + .overrideWith(new RunArgumentsModule(args)); try { JamesServerMain.main(server); @@ -118,6 +133,6 @@ public class Main implements JamesServerMain { public static GuiceJamesServer createServer(SMTPRelayConfiguration configuration) { return GuiceJamesServer.forConfiguration(configuration) - .combineWith(SERVER_CORE_MODULES, BLOB_MODULE, QUEUE_MODULES, PROTOCOLS, WEBADMIN); + .combineWith(SERVER_CORE_MODULES, BLOB_MODULE, QUEUE_MODULES, PROTOCOLS, WEBADMIN); } } diff --git a/server/apps/scaling-pulsar-smtp/src/test/java/org/apache/james/PostgresJPAExtension.java b/server/apps/scaling-pulsar-smtp/src/test/java/org/apache/james/PostgresJPAExtension.java deleted file mode 100644 index 6bb3e82e9e..0000000000 --- a/server/apps/scaling-pulsar-smtp/src/test/java/org/apache/james/PostgresJPAExtension.java +++ /dev/null @@ -1,72 +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; - -import java.util.UUID; - -import org.apache.james.backends.jpa.JPAConfiguration; -import org.apache.james.backends.postgres.DockerPostgresSingleton; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.PostgreSQLContainer; - -import com.google.inject.Module; -import com.google.inject.util.Modules; - -public class PostgresJPAExtension implements GuiceModuleTestExtension { - - private static final Logger logger = LoggerFactory.getLogger(PostgresJPAExtension.class); - - private final PostgreSQLContainer container = DockerPostgresSingleton.SINGLETON; - private JPAConfiguration jpaConfiguration; - - public PostgresJPAExtension() { - } - - @Override - public void beforeAll(ExtensionContext extensionContext) { - container.start(); - } - - @Override - public void afterAll(ExtensionContext extensionContext) throws Exception { - container.stop(); - } - - @Override - public void beforeEach(ExtensionContext extensionContext) throws Exception { - var dbName = UUID.randomUUID().toString(); - container.execInContainer("psql", "-U", container.getUsername(), "-c", "create database \"" + dbName + "\""); - container.withDatabaseName(dbName); - jpaConfiguration = JPAConfiguration.builder() - .driverName(container.getDriverClassName()) - .driverURL(container.getJdbcUrl()) - .username(container.getUsername()) - .password(container.getPassword()) - .build(); - } - - @Override - public Module getModule() { - return Modules.combine(binder -> binder.bind(JPAConfiguration.class) - .toInstance(jpaConfiguration)); - } -} diff --git a/server/apps/scaling-pulsar-smtp/src/test/java/org/apache/james/SMTPJamesServerTest.java b/server/apps/scaling-pulsar-smtp/src/test/java/org/apache/james/SMTPJamesServerTest.java index 115da78c08..572008da2c 100644 --- a/server/apps/scaling-pulsar-smtp/src/test/java/org/apache/james/SMTPJamesServerTest.java +++ b/server/apps/scaling-pulsar-smtp/src/test/java/org/apache/james/SMTPJamesServerTest.java @@ -27,6 +27,7 @@ import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; +import org.apache.james.backends.postgres.PostgresExtension; import org.apache.james.modules.AwsS3BlobStoreExtension; import org.apache.james.modules.protocols.SmtpGuiceProbe; import org.junit.jupiter.api.Test; @@ -37,7 +38,7 @@ class SMTPJamesServerTest { @RegisterExtension static JamesServerExtension testExtension = TestingSmtpRelayJamesServerBuilder.forConfiguration(c -> c) - .extension(new PostgresJPAExtension()) + .extension(PostgresExtension.empty()) .extension(new PulsarExtension()) .extension(new AwsS3BlobStoreExtension()) .server(Main::createServer) --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org