You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2023/11/03 07:03:27 UTC

(james-project) 05/06: JAMES-2586 - Postgres - Init james-server-postgres-common-guice

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch postgresql
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit c5522a07458df17dcf0bee2d4db8c3920b73f930
Author: Tung Tran <vt...@linagora.com>
AuthorDate: Tue Oct 31 10:23:38 2023 +0700

    JAMES-2586 - Postgres - Init james-server-postgres-common-guice
---
 server/container/guice/pom.xml                     |   1 +
 server/container/guice/postgres-common/pom.xml     |  68 ++++++++++++
 .../james/modules/data/JPAAuthorizatorModule.java  |  35 +++++++
 .../apache/james/modules/data/JPADataModule.java   |  33 ++++++
 .../james/modules/data/JPADomainListModule.java    |  44 ++++++++
 .../james/modules/data/JPAEntityManagerModule.java | 116 +++++++++++++++++++++
 .../modules/data/JPAMailRepositoryModule.java      |  53 ++++++++++
 .../data/JPARecipientRewriteTableModule.java       |  52 +++++++++
 .../modules/data/JPAUsersRepositoryModule.java     |  44 ++++++++
 .../apache/james/TestJPAConfigurationModule.java   |  46 ++++++++
 ...estJPAConfigurationModuleWithSqlValidation.java | 108 +++++++++++++++++++
 11 files changed, 600 insertions(+)

diff --git a/server/container/guice/pom.xml b/server/container/guice/pom.xml
index 82a57ef589..e5b21e3df4 100644
--- a/server/container/guice/pom.xml
+++ b/server/container/guice/pom.xml
@@ -56,6 +56,7 @@
         <module>memory</module>
         <module>onami</module>
         <module>opensearch</module>
+        <module>postgres-common</module>
         <module>protocols/imap</module>
         <module>protocols/jmap</module>
         <module>protocols/lmtp</module>
diff --git a/server/container/guice/postgres-common/pom.xml b/server/container/guice/postgres-common/pom.xml
new file mode 100644
index 0000000000..dc1f2e8ad8
--- /dev/null
+++ b/server/container/guice/postgres-common/pom.xml
@@ -0,0 +1,68 @@
+<?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/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.james</groupId>
+        <artifactId>james-server-guice</artifactId>
+        <version>3.9.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>james-server-postgres-common-guice</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Apache James :: Server :: Postgres - guice common</name>
+
+    <properties>
+        <jpa.includes>empty</jpa.includes>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-data-file</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-data-postgres</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-guice-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-mailbox-adapter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>testing-base</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.derby</groupId>
+            <artifactId>derby</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAAuthorizatorModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAAuthorizatorModule.java
new file mode 100644
index 0000000000..4c28118779
--- /dev/null
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAAuthorizatorModule.java
@@ -0,0 +1,35 @@
+/****************************************************************
+ * 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.modules.data;
+
+import org.apache.james.adapter.mailbox.UserRepositoryAuthorizator;
+import org.apache.james.mailbox.Authorizator;
+
+import com.google.inject.AbstractModule;
+
+public class JPAAuthorizatorModule extends AbstractModule {
+
+
+    @Override
+    protected void configure() {
+        bind(Authorizator.class).to(UserRepositoryAuthorizator.class);
+    }
+
+}
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPADataModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPADataModule.java
new file mode 100644
index 0000000000..ff1b84b449
--- /dev/null
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPADataModule.java
@@ -0,0 +1,33 @@
+/****************************************************************
+ * 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.modules.data;
+
+import org.apache.james.CoreDataModule;
+
+import com.google.inject.AbstractModule;
+
+public class JPADataModule extends AbstractModule {
+    @Override
+    protected void configure() {
+        install(new CoreDataModule());
+        install(new JPADomainListModule());
+        install(new JPARecipientRewriteTableModule());
+        install(new JPAMailRepositoryModule());
+    }
+}
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPADomainListModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
new file mode 100644
index 0000000000..116fd4b8ac
--- /dev/null
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.modules.data;
+
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.jpa.JPADomainList;
+import org.apache.james.domainlist.lib.DomainListConfiguration;
+import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import com.google.inject.multibindings.ProvidesIntoSet;
+
+public class JPADomainListModule extends AbstractModule {
+    @Override
+    public void configure() {
+        bind(JPADomainList.class).in(Scopes.SINGLETON);
+        bind(DomainList.class).to(JPADomainList.class);
+    }
+
+    @ProvidesIntoSet
+    InitializationOperation configureDomainList(DomainListConfiguration configuration, JPADomainList jpaDomainList) {
+        return InitilizationOperationBuilder
+            .forClass(JPADomainList.class)
+            .init(() -> jpaDomainList.configure(configuration));
+    }
+}
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAEntityManagerModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAEntityManagerModule.java
new file mode 100644
index 0000000000..19432d372c
--- /dev/null
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAEntityManagerModule.java
@@ -0,0 +1,116 @@
+/****************************************************************
+ * 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.modules.data;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.inject.Singleton;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.apache.james.backends.jpa.JPAConfiguration;
+import org.apache.james.utils.PropertiesProvider;
+
+import com.google.common.base.Joiner;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+public class JPAEntityManagerModule extends AbstractModule {
+    @Provides
+    @Singleton
+    public EntityManagerFactory provideEntityManagerFactory(JPAConfiguration jpaConfiguration) {
+        HashMap<String, String> properties = new HashMap<>();
+
+        properties.put(JPAConfiguration.JPA_CONNECTION_DRIVER_NAME, jpaConfiguration.getDriverName());
+        properties.put(JPAConfiguration.JPA_CONNECTION_URL, jpaConfiguration.getDriverURL());
+        jpaConfiguration.getCredential()
+            .ifPresent(credential -> {
+                properties.put(JPAConfiguration.JPA_CONNECTION_USERNAME, credential.getUsername());
+                properties.put(JPAConfiguration.JPA_CONNECTION_PASSWORD, credential.getPassword());
+            });
+
+        List<String> connectionProperties = new ArrayList<>();
+        jpaConfiguration.isTestOnBorrow().ifPresent(testOnBorrow -> connectionProperties.add("TestOnBorrow=" + testOnBorrow));
+        jpaConfiguration.getValidationQueryTimeoutSec()
+            .ifPresent(timeoutSecond -> connectionProperties.add("ValidationTimeout=" + timeoutSecond * 1000));
+        jpaConfiguration.getValidationQuery()
+            .ifPresent(validationQuery -> connectionProperties.add("ValidationSQL='" + validationQuery + "'"));
+        jpaConfiguration.getMaxConnections()
+                .ifPresent(maxConnections -> connectionProperties.add("MaxTotal=" + maxConnections));
+
+        connectionProperties.addAll(jpaConfiguration.getCustomDatasourceProperties().entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.toList()));
+        properties.put(JPAConfiguration.JPA_CONNECTION_PROPERTIES, Joiner.on(",").join(connectionProperties));
+        properties.putAll(jpaConfiguration.getCustomOpenjpaProperties());
+
+        jpaConfiguration.isMultithreaded()
+            .ifPresent(isMultiThread ->
+                properties.put(JPAConfiguration.JPA_MULTITHREADED, jpaConfiguration.isMultithreaded().toString())
+            );
+
+        jpaConfiguration.isAttachmentStorageEnabled()
+            .ifPresent(isMultiThread ->
+                properties.put(JPAConfiguration.ATTACHMENT_STORAGE, jpaConfiguration.isAttachmentStorageEnabled().toString())
+            );
+
+        return Persistence.createEntityManagerFactory("Global", properties);
+    }
+
+    @Provides
+    @Singleton
+    JPAConfiguration provideConfiguration(PropertiesProvider propertiesProvider) throws FileNotFoundException, ConfigurationException {
+        Configuration dataSource = propertiesProvider.getConfiguration("james-database");
+
+        Map<String, String> openjpaProperties = getKeysForPrefix(dataSource, "openjpa", false);
+        Map<String, String> datasourceProperties = getKeysForPrefix(dataSource, "datasource", true);
+
+        return JPAConfiguration.builder()
+                .driverName(dataSource.getString("database.driverClassName"))
+                .driverURL(dataSource.getString("database.url"))
+                .testOnBorrow(dataSource.getBoolean("datasource.testOnBorrow", false))
+                .validationQueryTimeoutSec(dataSource.getInteger("datasource.validationQueryTimeoutSec", null))
+                .validationQuery(dataSource.getString("datasource.validationQuery", null))
+                .maxConnections(dataSource.getInteger("datasource.maxTotal", null))
+                .multithreaded(dataSource.getBoolean(JPAConfiguration.JPA_MULTITHREADED, true))
+                .username(dataSource.getString("database.username"))
+                .password(dataSource.getString("database.password"))
+                .setCustomOpenjpaProperties(openjpaProperties)
+                .setCustomDatasourceProperties(datasourceProperties)
+                .attachmentStorage(dataSource.getBoolean(JPAConfiguration.ATTACHMENT_STORAGE, false))
+                .build();
+    }
+
+    private static Map<String, String> getKeysForPrefix(Configuration dataSource, String prefix, boolean stripPrefix) {
+        Iterator<String> keys = dataSource.getKeys(prefix);
+        Map<String, String> properties = new HashMap<>();
+        while (keys.hasNext()) {
+            String key = keys.next();
+            String propertyKey = stripPrefix ? key.replace(prefix + ".", "") : key;
+            properties.put(propertyKey, dataSource.getString(key));
+        }
+        return properties;
+    }
+}
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAMailRepositoryModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAMailRepositoryModule.java
new file mode 100644
index 0000000000..bb6a0ffedb
--- /dev/null
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAMailRepositoryModule.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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.modules.data;
+
+import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
+import org.apache.james.mailrepository.api.MailRepositoryFactory;
+import org.apache.james.mailrepository.api.MailRepositoryUrlStore;
+import org.apache.james.mailrepository.api.Protocol;
+import org.apache.james.mailrepository.jpa.JPAMailRepository;
+import org.apache.james.mailrepository.jpa.JPAMailRepositoryFactory;
+import org.apache.james.mailrepository.jpa.JPAMailRepositoryUrlStore;
+import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import com.google.inject.multibindings.Multibinder;
+
+public class JPAMailRepositoryModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        bind(JPAMailRepositoryUrlStore.class).in(Scopes.SINGLETON);
+
+        bind(MailRepositoryUrlStore.class).to(JPAMailRepositoryUrlStore.class);
+
+        bind(MailRepositoryStoreConfiguration.Item.class)
+            .toProvider(() -> new MailRepositoryStoreConfiguration.Item(
+                ImmutableList.of(new Protocol("jpa")),
+                JPAMailRepository.class.getName(),
+                new BaseHierarchicalConfiguration()));
+
+        Multibinder.newSetBinder(binder(), MailRepositoryFactory.class)
+                .addBinding().to(JPAMailRepositoryFactory.class);
+    }
+}
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
new file mode 100644
index 0000000000..f00af56754
--- /dev/null
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
@@ -0,0 +1,52 @@
+/****************************************************************
+ * 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.modules.data;
+
+import org.apache.james.rrt.api.AliasReverseResolver;
+import org.apache.james.rrt.api.CanSendFrom;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.jpa.JPARecipientRewriteTable;
+import org.apache.james.rrt.lib.AliasReverseResolverImpl;
+import org.apache.james.rrt.lib.CanSendFromImpl;
+import org.apache.james.server.core.configuration.ConfigurationProvider;
+import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import com.google.inject.multibindings.ProvidesIntoSet;
+
+public class JPARecipientRewriteTableModule extends AbstractModule {
+    @Override
+    public void configure() {
+        bind(JPARecipientRewriteTable.class).in(Scopes.SINGLETON);
+        bind(RecipientRewriteTable.class).to(JPARecipientRewriteTable.class);
+        bind(AliasReverseResolverImpl.class).in(Scopes.SINGLETON);
+        bind(AliasReverseResolver.class).to(AliasReverseResolverImpl.class);
+        bind(CanSendFromImpl.class).in(Scopes.SINGLETON);
+        bind(CanSendFrom.class).to(CanSendFromImpl.class);
+    }
+
+    @ProvidesIntoSet
+    InitializationOperation configureRRT(ConfigurationProvider configurationProvider, JPARecipientRewriteTable recipientRewriteTable) {
+        return InitilizationOperationBuilder
+            .forClass(JPARecipientRewriteTable.class)
+            .init(() -> recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable")));
+    }
+}
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
new file mode 100644
index 0000000000..5a719244a4
--- /dev/null
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.modules.data;
+
+import org.apache.james.server.core.configuration.ConfigurationProvider;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.jpa.JPAUsersRepository;
+import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import com.google.inject.multibindings.ProvidesIntoSet;
+
+public class JPAUsersRepositoryModule extends AbstractModule {
+    @Override
+    public void configure() {
+        bind(JPAUsersRepository.class).in(Scopes.SINGLETON);
+        bind(UsersRepository.class).to(JPAUsersRepository.class);
+    }
+
+    @ProvidesIntoSet
+    InitializationOperation configureJpaUsers(ConfigurationProvider configurationProvider, JPAUsersRepository usersRepository) {
+        return InitilizationOperationBuilder
+            .forClass(JPAUsersRepository.class)
+            .init(() -> usersRepository.configure(configurationProvider.getConfiguration("usersrepository")));
+    }
+}
diff --git a/server/container/guice/postgres-common/src/test/java/org/apache/james/TestJPAConfigurationModule.java b/server/container/guice/postgres-common/src/test/java/org/apache/james/TestJPAConfigurationModule.java
new file mode 100644
index 0000000000..957cddc27d
--- /dev/null
+++ b/server/container/guice/postgres-common/src/test/java/org/apache/james/TestJPAConfigurationModule.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * 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 javax.inject.Singleton;
+
+import org.apache.james.backends.jpa.JPAConfiguration;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+public class TestJPAConfigurationModule extends AbstractModule {
+
+    private static final String JDBC_EMBEDDED_URL = "jdbc:derby:memory:mailboxintegration;create=true";
+    private static final String JDBC_EMBEDDED_DRIVER = org.apache.derby.jdbc.EmbeddedDriver.class.getName();
+
+    @Override
+    protected void configure() {
+    }
+
+    @Provides
+    @Singleton
+    JPAConfiguration provideConfiguration() {
+        return JPAConfiguration.builder()
+                .driverName(JDBC_EMBEDDED_DRIVER)
+                .driverURL(JDBC_EMBEDDED_URL)
+                .build();
+    }
+}
diff --git a/server/container/guice/postgres-common/src/test/java/org/apache/james/TestJPAConfigurationModuleWithSqlValidation.java b/server/container/guice/postgres-common/src/test/java/org/apache/james/TestJPAConfigurationModuleWithSqlValidation.java
new file mode 100644
index 0000000000..1cf89b519b
--- /dev/null
+++ b/server/container/guice/postgres-common/src/test/java/org/apache/james/TestJPAConfigurationModuleWithSqlValidation.java
@@ -0,0 +1,108 @@
+/****************************************************************
+ * 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.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import javax.inject.Singleton;
+
+import org.apache.james.backends.jpa.JPAConfiguration;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+public interface TestJPAConfigurationModuleWithSqlValidation {
+
+    class NoDatabaseAuthentication extends AbstractModule {
+        @Override
+        protected void configure() {
+        }
+
+        @Provides
+        @Singleton
+        JPAConfiguration provideConfiguration() {
+            return jpaConfigurationBuilder().build();
+        }
+    }
+
+    class WithDatabaseAuthentication extends AbstractModule {
+
+        @Override
+        protected void configure() {
+            setupAuthenticationOnDerby();
+        }
+
+        @Provides
+        @Singleton
+        JPAConfiguration provideConfiguration() {
+            return jpaConfigurationBuilder()
+                .username(DATABASE_USERNAME)
+                .password(DATABASE_PASSWORD)
+                .build();
+        }
+
+        private void setupAuthenticationOnDerby() {
+            try (Connection conn = DriverManager.getConnection(JDBC_EMBEDDED_URL, DATABASE_USERNAME, DATABASE_PASSWORD)) {
+                // Setting and Confirming requireAuthentication
+                setDerbyProperty(conn, "derby.connection.requireAuthentication", "true");
+
+                // Setting authentication scheme and username password to Derby
+                setDerbyProperty(conn, "derby.authentication.provider", "BUILTIN");
+                setDerbyProperty(conn, "derby.user." + DATABASE_USERNAME + "", DATABASE_PASSWORD);
+                setDerbyProperty(conn, "derby.database.propertiesOnly", "true");
+
+                // Setting default connection mode to no access to restrict accesses without authentication information
+                setDerbyProperty(conn, "derby.database.defaultConnectionMode", "noAccess");
+                setDerbyProperty(conn, "derby.database.fullAccessUsers", DATABASE_USERNAME);
+                setDerbyProperty(conn, "derby.database.propertiesOnly", "false");
+            } catch (SQLException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        private void setDerbyProperty(Connection conn, String key, String value) {
+            try (CallableStatement call = conn.prepareCall("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(?, ?)")) {
+                call.setString(1, key);
+                call.setString(2, value);
+                call.execute();
+            } catch (SQLException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    String DATABASE_USERNAME = "james";
+    String DATABASE_PASSWORD = "james-secret";
+    String JDBC_EMBEDDED_URL = "jdbc:derby:memory:mailboxintegration;create=true";
+    String JDBC_EMBEDDED_DRIVER = org.apache.derby.jdbc.EmbeddedDriver.class.getName();
+    String VALIDATION_SQL_QUERY = "VALUES 1";
+
+    static JPAConfiguration.ReadyToBuild jpaConfigurationBuilder() {
+        return JPAConfiguration.builder()
+                .driverName(JDBC_EMBEDDED_DRIVER)
+                .driverURL(JDBC_EMBEDDED_URL)
+                .testOnBorrow(true)
+                .validationQueryTimeoutSec(2)
+                .validationQuery(VALIDATION_SQL_QUERY);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org