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/12/19 02:40:13 UTC

(james-project) 02/05: JAMES-2586 Guice binding for PostgresMailRepository + remove related JPA code

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 3ea0846a0c1f6ac8e132ca2c0bc1860308c50fb6
Author: Quan Tran <hq...@linagora.com>
AuthorDate: Mon Dec 18 14:54:53 2023 +0700

    JAMES-2586 Guice binding for PostgresMailRepository + remove related JPA code
---
 .../src/main/resources/META-INF/persistence.xml    |   2 -
 .../modules/data/PostgresMailRepositoryModule.java |  10 +-
 server/data/data-postgres/pom.xml                  |   7 -
 .../mailrepository/jpa/JPAMailRepository.java      | 407 ---------------------
 .../jpa/JPAMailRepositoryFactory.java              |  52 ---
 .../mailrepository/jpa/MimeMessageJPASource.java   |  54 ---
 .../james/mailrepository/jpa/model/JPAMail.java    | 246 -------------
 .../postgres/PostgresMailRepository.java           |   2 +
 .../mailrepository/jpa/JPAMailRepositoryTest.java  |  70 ----
 .../src/test/resources/persistence.xml             |   1 -
 10 files changed, 7 insertions(+), 844 deletions(-)

diff --git a/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml b/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml
index 9c79e80651..80b798e907 100644
--- a/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml
+++ b/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml
@@ -24,8 +24,6 @@
     version="2.0">
 
     <persistence-unit name="Global" transaction-type="RESOURCE_LOCAL">
-        <class>org.apache.james.mailrepository.jpa.model.JPAMail</class>
-
         <properties>
             <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
             <property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade"/>
diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/PostgresMailRepositoryModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/PostgresMailRepositoryModule.java
index b0c3369815..f0bbbfa3ae 100644
--- a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/PostgresMailRepositoryModule.java
+++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/data/PostgresMailRepositoryModule.java
@@ -24,9 +24,9 @@ import org.apache.james.backends.postgres.PostgresModule;
 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.memory.MailRepositoryStoreConfiguration;
+import org.apache.james.mailrepository.postgres.PostgresMailRepository;
+import org.apache.james.mailrepository.postgres.PostgresMailRepositoryFactory;
 import org.apache.james.mailrepository.postgres.PostgresMailRepositoryUrlStore;
 
 import com.google.common.collect.ImmutableList;
@@ -43,12 +43,12 @@ public class PostgresMailRepositoryModule extends AbstractModule {
 
         bind(MailRepositoryStoreConfiguration.Item.class)
             .toProvider(() -> new MailRepositoryStoreConfiguration.Item(
-                ImmutableList.of(new Protocol("jpa")),
-                JPAMailRepository.class.getName(),
+                ImmutableList.of(new Protocol("postgres")),
+                PostgresMailRepository.class.getName(),
                 new BaseHierarchicalConfiguration()));
 
         Multibinder.newSetBinder(binder(), MailRepositoryFactory.class)
-            .addBinding().to(JPAMailRepositoryFactory.class);
+            .addBinding().to(PostgresMailRepositoryFactory.class);
         Multibinder.newSetBinder(binder(), PostgresModule.class)
             .addBinding().toInstance(org.apache.james.mailrepository.postgres.PostgresMailRepositoryModule.MODULE);
     }
diff --git a/server/data/data-postgres/pom.xml b/server/data/data-postgres/pom.xml
index 31a1d2a70e..107a939364 100644
--- a/server/data/data-postgres/pom.xml
+++ b/server/data/data-postgres/pom.xml
@@ -170,8 +170,6 @@
                 <artifactId>openjpa-maven-plugin</artifactId>
                 <version>${apache.openjpa.version}</version>
                 <configuration>
-                    <includes>org/apache/james/mailrepository/jpa/model/JPAUrl.class,
-                        org/apache/james/mailrepository/jpa/model/JPAMail.class</includes>
                     <addDefaultConstructor>true</addDefaultConstructor>
                     <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
                     <toolProperties>
@@ -179,11 +177,6 @@
                             <name>log</name>
                             <value>TOOL=TRACE</value>
                         </property>
-                        <property>
-                            <name>metaDataFactory</name>
-                            <value>jpa(Types=org.apache.james.mailrepository.jpa.model.JPAUrl;
-                                org.apache.james.mailrepository.jpa.model.JPAMail)</value>
-                        </property>
                     </toolProperties>
                     <persistenceXmlFile>${basedir}/src/test/resources/persistence.xml</persistenceXmlFile>
                 </configuration>
diff --git a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/JPAMailRepository.java b/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/JPAMailRepository.java
deleted file mode 100644
index a70b4be6f7..0000000000
--- a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/JPAMailRepository.java
+++ /dev/null
@@ -1,407 +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.mailrepository.jpa;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.sql.Timestamp;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.StringTokenizer;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.mail.MessagingException;
-import javax.mail.internet.AddressException;
-import javax.mail.internet.MimeMessage;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.EntityTransaction;
-import javax.persistence.NoResultException;
-
-import org.apache.commons.configuration2.HierarchicalConfiguration;
-import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.commons.configuration2.tree.ImmutableNode;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.james.backends.jpa.EntityManagerUtils;
-import org.apache.james.core.MailAddress;
-import org.apache.james.lifecycle.api.Configurable;
-import org.apache.james.mailrepository.api.Initializable;
-import org.apache.james.mailrepository.api.MailKey;
-import org.apache.james.mailrepository.api.MailRepository;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
-import org.apache.james.mailrepository.jpa.model.JPAMail;
-import org.apache.james.server.core.MailImpl;
-import org.apache.james.server.core.MimeMessageWrapper;
-import org.apache.james.util.AuditTrail;
-import org.apache.james.util.streams.Iterators;
-import org.apache.mailet.Attribute;
-import org.apache.mailet.AttributeName;
-import org.apache.mailet.AttributeValue;
-import org.apache.mailet.Mail;
-import org.apache.mailet.PerRecipientHeaders;
-import org.apache.mailet.PerRecipientHeaders.Header;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.github.fge.lambdas.Throwing;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Implementation of a MailRepository on a database via JPA.
- */
-public class JPAMailRepository implements MailRepository, Configurable, Initializable {
-    private static final Logger LOGGER = LoggerFactory.getLogger(JPAMailRepository.class);
-    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
-    private String repositoryName;
-
-    private final EntityManagerFactory entityManagerFactory;
-
-    @Inject
-    public JPAMailRepository(EntityManagerFactory entityManagerFactory) {
-        this.entityManagerFactory = entityManagerFactory;
-    }
-
-    public JPAMailRepository(EntityManagerFactory entityManagerFactory, MailRepositoryUrl url) throws ConfigurationException {
-        this.entityManagerFactory = entityManagerFactory;
-        this.repositoryName = url.getPath().asString();
-        if (repositoryName.isEmpty()) {
-            throw new ConfigurationException(
-                    "Malformed destinationURL - Must be of the format 'jpa://<repositoryName>'.  Was passed " + url);
-        }
-    }
-
-    public String getRepositoryName() {
-        return repositoryName;
-    }
-
-    // note: caller must close the returned EntityManager when done using it
-    protected EntityManager entityManager() {
-        return entityManagerFactory.createEntityManager();
-    }
-
-    @Override
-    public void configure(HierarchicalConfiguration<ImmutableNode> configuration) throws ConfigurationException {
-        LOGGER.debug("{}.configure()", getClass().getName());
-        String destination = configuration.getString("[@destinationURL]");
-        MailRepositoryUrl url = MailRepositoryUrl.from(destination); // also validates url and standardizes slashes
-        repositoryName = url.getPath().asString();
-        if (repositoryName.isEmpty()) {
-            throw new ConfigurationException(
-                "Malformed destinationURL - Must be of the format 'jpa://<repositoryName>'.  Was passed " + url);
-        }
-        LOGGER.debug("Parsed URL: repositoryName = '{}'", repositoryName);
-    }
-
-    /**
-     * Initialises the JPA repository.
-     *
-     * @throws Exception if an error occurs
-     */
-    @Override
-    @PostConstruct
-    public void init() throws Exception {
-        LOGGER.debug("{}.initialize()", getClass().getName());
-        list();
-    }
-
-    @Override
-    public MailKey store(Mail mail) throws MessagingException {
-        MailKey key = MailKey.forMail(mail);
-        EntityManager entityManager = entityManager();
-        try {
-            JPAMail jpaMail = new JPAMail();
-            jpaMail.setRepositoryName(repositoryName);
-            jpaMail.setMessageName(mail.getName());
-            jpaMail.setMessageState(mail.getState());
-            jpaMail.setErrorMessage(mail.getErrorMessage());
-            if (!mail.getMaybeSender().isNullSender()) {
-                jpaMail.setSender(mail.getMaybeSender().get().toString());
-            }
-            String recipients = mail.getRecipients().stream()
-                .map(MailAddress::toString)
-                .collect(Collectors.joining("\r\n"));
-            jpaMail.setRecipients(recipients);
-            jpaMail.setRemoteHost(mail.getRemoteHost());
-            jpaMail.setRemoteAddr(mail.getRemoteAddr());
-            jpaMail.setPerRecipientHeaders(serializePerRecipientHeaders(mail.getPerRecipientSpecificHeaders()));
-            jpaMail.setLastUpdated(new Timestamp(mail.getLastUpdated().getTime()));
-            jpaMail.setMessageBody(getBody(mail));
-            jpaMail.setMessageAttributes(serializeAttributes(mail.attributes()));
-            EntityTransaction transaction = entityManager.getTransaction();
-            transaction.begin();
-            jpaMail = entityManager.merge(jpaMail);
-            transaction.commit();
-
-            AuditTrail.entry()
-                .protocol("mailrepository")
-                .action("store")
-                .parameters(Throwing.supplier(() -> ImmutableMap.of("mailId", mail.getName(),
-                    "mimeMessageId", Optional.ofNullable(mail.getMessage())
-                        .map(Throwing.function(MimeMessage::getMessageID))
-                        .orElse(""),
-                    "sender", mail.getMaybeSender().asString(),
-                    "recipients", StringUtils.join(mail.getRecipients()))))
-                .log("JPAMailRepository stored mail.");
-
-            return key;
-        } catch (MessagingException e) {
-            LOGGER.error("Exception caught while storing mail {}", key, e);
-            throw e;
-        } catch (Exception e) {
-            LOGGER.error("Exception caught while storing mail {}", key, e);
-            throw new MessagingException("Exception caught while storing mail " + key, e);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    private byte[] getBody(Mail mail) throws MessagingException, IOException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream((int)mail.getMessageSize());
-        if (mail instanceof MimeMessageWrapper) {
-            // we need to force the loading of the message from the
-            // stream as we want to override the old message
-            ((MimeMessageWrapper) mail).loadMessage();
-            ((MimeMessageWrapper) mail).writeTo(out, out, null, true);
-        } else {
-            mail.getMessage().writeTo(out);
-        }
-        return out.toByteArray();
-    }
-
-    private String serializeAttributes(Stream<Attribute> attributes) {
-        Map<String, JsonNode> map = attributes
-            .flatMap(entry -> entry.getValue().toJson().map(value -> Pair.of(entry.getName().asString(), value)).stream())
-            .collect(ImmutableMap.toImmutableMap(Pair::getKey, Pair::getValue));
-
-        return new ObjectNode(JsonNodeFactory.instance, map).toString();
-    }
-
-    private List<Attribute> deserializeAttributes(String data) {
-        try {
-            JsonNode jsonNode = OBJECT_MAPPER.readTree(data);
-            if (jsonNode instanceof ObjectNode) {
-                ObjectNode objectNode = (ObjectNode) jsonNode;
-
-                return Iterators.toStream(objectNode.fields())
-                    .map(entry -> new Attribute(AttributeName.of(entry.getKey()), AttributeValue.fromJson(entry.getValue())))
-                    .collect(ImmutableList.toImmutableList());
-            }
-            throw new IllegalArgumentException("JSON object corresponding to mail attibutes must be a JSON object");
-        } catch (JsonProcessingException e) {
-            throw new IllegalArgumentException("Mail attributes is not a valid JSON object", e);
-        }
-    }
-
-    private String serializePerRecipientHeaders(PerRecipientHeaders perRecipientHeaders) {
-        if (perRecipientHeaders == null) {
-            return null;
-        }
-        Map<MailAddress, Collection<Header>> map = perRecipientHeaders.getHeadersByRecipient().asMap();
-        if (map.isEmpty()) {
-            return null;
-        }
-        ObjectNode node = JsonNodeFactory.instance.objectNode();
-        for (Map.Entry<MailAddress, Collection<Header>> entry : map.entrySet()) {
-            String recipient = entry.getKey().asString();
-            ObjectNode headers = node.putObject(recipient);
-            entry.getValue().forEach(header -> headers.put(header.getName(), header.getValue()));
-        }
-        return node.toString();
-    }
-
-    private PerRecipientHeaders deserializePerRecipientHeaders(String data) {
-        if (data == null || data.isEmpty()) {
-            return null;
-        }
-        PerRecipientHeaders perRecipientHeaders = new PerRecipientHeaders();
-        try {
-            JsonNode node = OBJECT_MAPPER.readTree(data);
-            if (node instanceof ObjectNode) {
-                ObjectNode objectNode = (ObjectNode) node;
-                Iterators.toStream(objectNode.fields()).forEach(
-                    entry -> addPerRecipientHeaders(perRecipientHeaders, entry.getKey(), entry.getValue()));
-                return perRecipientHeaders;
-            }
-            throw new IllegalArgumentException("JSON object corresponding to recipient headers must be a JSON object");
-        } catch (JsonProcessingException e) {
-            throw new IllegalArgumentException("per recipient headers is not a valid JSON object", e);
-        }
-    }
-
-    private void addPerRecipientHeaders(PerRecipientHeaders perRecipientHeaders, String recipient, JsonNode headers) {
-        try {
-            MailAddress address = new MailAddress(recipient);
-            Iterators.toStream(headers.fields()).forEach(
-                entry -> {
-                    String name = entry.getKey();
-                    String value = entry.getValue().textValue();
-                    Header header = Header.builder().name(name).value(value).build();
-                    perRecipientHeaders.addHeaderForRecipient(header, address);
-                });
-        } catch (AddressException ae) {
-            throw new IllegalArgumentException("invalid recipient address", ae);
-        }
-    }
-
-    @Override
-    public Mail retrieve(MailKey key) throws MessagingException {
-        EntityManager entityManager = entityManager();
-        try {
-            JPAMail jpaMail = entityManager.createNamedQuery("findMailMessage", JPAMail.class)
-                .setParameter("repositoryName", repositoryName)
-                .setParameter("messageName", key.asString())
-                .getSingleResult();
-
-            MailImpl.Builder mail = MailImpl.builder().name(key.asString());
-            if (jpaMail.getMessageAttributes() != null) {
-                mail.addAttributes(deserializeAttributes(jpaMail.getMessageAttributes()));
-            }
-            mail.state(jpaMail.getMessageState());
-            mail.errorMessage(jpaMail.getErrorMessage());
-            String sender = jpaMail.getSender();
-            if (sender == null) {
-                mail.sender((MailAddress)null);
-            } else {
-                mail.sender(new MailAddress(sender));
-            }
-            StringTokenizer st = new StringTokenizer(jpaMail.getRecipients(), "\r\n", false);
-            while (st.hasMoreTokens()) {
-                mail.addRecipient(st.nextToken());
-            }
-            mail.remoteHost(jpaMail.getRemoteHost());
-            mail.remoteAddr(jpaMail.getRemoteAddr());
-            PerRecipientHeaders perRecipientHeaders = deserializePerRecipientHeaders(jpaMail.getPerRecipientHeaders());
-            if (perRecipientHeaders != null) {
-                mail.addAllHeadersForRecipients(perRecipientHeaders);
-            }
-            mail.lastUpdated(jpaMail.getLastUpdated());
-
-            MimeMessageJPASource source = new MimeMessageJPASource(this, key.asString(), jpaMail.getMessageBody());
-            MimeMessageWrapper message = new MimeMessageWrapper(source);
-            mail.mimeMessage(message);
-            return mail.build();
-        } catch (NoResultException nre) {
-            LOGGER.debug("Did not find mail {} in repository {}", key, repositoryName);
-            return null;
-        } catch (Exception e) {
-            throw new MessagingException("Exception while retrieving mail: " + e.getMessage(), e);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public long size() throws MessagingException {
-        EntityManager entityManager = entityManager();
-        try {
-            return entityManager.createNamedQuery("countMailMessages", long.class)
-                .setParameter("repositoryName", repositoryName)
-                .getSingleResult();
-        } catch (Exception me) {
-            throw new MessagingException("Exception while listing messages: " + me.getMessage(), me);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public Iterator<MailKey> list() throws MessagingException {
-        EntityManager entityManager = entityManager();
-        try {
-            return entityManager.createNamedQuery("listMailMessages", String.class)
-                .setParameter("repositoryName", repositoryName)
-                .getResultStream()
-                .map(MailKey::new)
-                .iterator();
-        } catch (Exception me) {
-            throw new MessagingException("Exception while listing messages: " + me.getMessage(), me);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public void remove(MailKey key) throws MessagingException {
-        remove(Collections.singleton(key));
-    }
-
-    @Override
-    public void remove(Collection<MailKey> keys) throws MessagingException {
-        Collection<String> messageNames = keys.stream().map(MailKey::asString).collect(Collectors.toList());
-        EntityManager entityManager = entityManager();
-        EntityTransaction transaction = entityManager.getTransaction();
-        transaction.begin();
-        try {
-            entityManager.createNamedQuery("deleteMailMessages")
-                .setParameter("repositoryName", repositoryName)
-                .setParameter("messageNames", messageNames)
-                .executeUpdate();
-            transaction.commit();
-        } catch (Exception e) {
-            throw new MessagingException("Exception while removing message(s): " + e.getMessage(), e);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public void removeAll() throws MessagingException {
-        EntityManager entityManager = entityManager();
-        EntityTransaction transaction = entityManager.getTransaction();
-        transaction.begin();
-        try {
-            entityManager.createNamedQuery("deleteAllMailMessages")
-                .setParameter("repositoryName", repositoryName)
-                .executeUpdate();
-            transaction.commit();
-        } catch (Exception e) {
-            throw new MessagingException("Exception while removing message(s): " + e.getMessage(), e);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return obj instanceof JPAMailRepository
-            && Objects.equals(repositoryName, ((JPAMailRepository)obj).repositoryName);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(repositoryName);
-    }
-}
diff --git a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/JPAMailRepositoryFactory.java b/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/JPAMailRepositoryFactory.java
deleted file mode 100644
index 09bb004ef8..0000000000
--- a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/JPAMailRepositoryFactory.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.mailrepository.jpa;
-
-import javax.inject.Inject;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.james.mailrepository.api.MailRepository;
-import org.apache.james.mailrepository.api.MailRepositoryFactory;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
-
-import com.github.fge.lambdas.Throwing;
-
-public class JPAMailRepositoryFactory implements MailRepositoryFactory {
-    private final EntityManagerFactory entityManagerFactory;
-
-    @Inject
-    public JPAMailRepositoryFactory(EntityManagerFactory entityManagerFactory) {
-        this.entityManagerFactory = entityManagerFactory;
-    }
-
-    @Override
-    public Class<? extends MailRepository> mailRepositoryClass() {
-        return JPAMailRepository.class;
-    }
-
-    @Override
-    public MailRepository create(MailRepositoryUrl url) {
-        // Injecting the url here is redundant since the class is also a
-        // Configurable and the mail repository store will call #configure()
-        // with the same effect. However, this paves the way to drop the
-        // Configurable aspect in the future.
-        return Throwing.supplier(() -> new JPAMailRepository(entityManagerFactory, url)).sneakyThrow().get();
-    }
-}
diff --git a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/MimeMessageJPASource.java b/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/MimeMessageJPASource.java
deleted file mode 100644
index f5445c279c..0000000000
--- a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/MimeMessageJPASource.java
+++ /dev/null
@@ -1,54 +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.mailrepository.jpa;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.james.server.core.MimeMessageSource;
-
-public class MimeMessageJPASource implements MimeMessageSource {
-
-    private final JPAMailRepository jpaMailRepository;
-    private final String key;
-    private final byte[] body;
-
-    public MimeMessageJPASource(JPAMailRepository jpaMailRepository, String key, byte[] body) {
-        this.jpaMailRepository = jpaMailRepository;
-        this.key = key;
-        this.body = body;
-    }
-
-    @Override
-    public String getSourceId() {
-        return jpaMailRepository.getRepositoryName() + "/" + key;
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        return new ByteArrayInputStream(body);
-    }
-
-    @Override
-    public long getMessageSize() throws IOException {
-        return body.length;
-    }
-}
diff --git a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/model/JPAMail.java b/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/model/JPAMail.java
deleted file mode 100644
index 187241dfcb..0000000000
--- a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/jpa/model/JPAMail.java
+++ /dev/null
@@ -1,246 +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.mailrepository.jpa.model;
-
-import java.io.Serializable;
-import java.sql.Timestamp;
-import java.util.Objects;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Index;
-import javax.persistence.Lob;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-
-@Entity(name = "JamesMailStore")
-@IdClass(JPAMail.JPAMailId.class)
-@Table(name = "JAMES_MAIL_STORE", indexes = {
-   @Index(name = "REPOSITORY_NAME_MESSAGE_NAME_INDEX", columnList = "REPOSITORY_NAME, MESSAGE_NAME")
-})
-@NamedQueries({
-    @NamedQuery(name = "listMailMessages",
-        query = "SELECT mail.messageName FROM JamesMailStore mail WHERE mail.repositoryName = :repositoryName"),
-    @NamedQuery(name = "countMailMessages",
-        query = "SELECT COUNT(mail) FROM JamesMailStore mail WHERE mail.repositoryName = :repositoryName"),
-    @NamedQuery(name = "deleteMailMessages",
-        query = "DELETE FROM JamesMailStore mail WHERE mail.repositoryName = :repositoryName AND mail.messageName IN (:messageNames)"),
-    @NamedQuery(name = "deleteAllMailMessages",
-        query = "DELETE FROM JamesMailStore mail WHERE mail.repositoryName = :repositoryName"),
-    @NamedQuery(name = "findMailMessage",
-        query = "SELECT mail FROM JamesMailStore mail WHERE mail.repositoryName = :repositoryName AND mail.messageName = :messageName")
-})
-public class JPAMail {
-
-    static class JPAMailId implements Serializable {
-        public JPAMailId() {
-        }
-
-        String repositoryName;
-        String messageName;
-
-        public boolean equals(Object obj) {
-            return obj instanceof JPAMailId
-                && Objects.equals(messageName, ((JPAMailId) obj).messageName)
-                && Objects.equals(repositoryName, ((JPAMailId) obj).repositoryName);
-        }
-
-        public int hashCode() {
-            return Objects.hash(messageName, repositoryName);
-        }
-    }
-
-    @Id
-    @Basic(optional = false)
-    @Column(name = "REPOSITORY_NAME", nullable = false, length = 255)
-    private String repositoryName;
-
-    @Id
-    @Basic(optional = false)
-    @Column(name = "MESSAGE_NAME", nullable = false, length = 200)
-    private String messageName;
-
-    @Basic(optional = false)
-    @Column(name = "MESSAGE_STATE", nullable = false, length = 30)
-    private String messageState;
-
-    @Basic(optional = true)
-    @Column(name = "ERROR_MESSAGE", nullable = true, length = 200)
-    private String errorMessage;
-
-    @Basic(optional = true)
-    @Column(name = "SENDER", nullable = true, length = 255)
-    private String sender;
-
-    @Basic(optional = false)
-    @Column(name = "RECIPIENTS", nullable = false)
-    private String recipients; // CRLF delimited
-
-    @Basic(optional = false)
-    @Column(name = "REMOTE_HOST", nullable = false, length = 255)
-    private String remoteHost;
-
-    @Basic(optional = false)
-    @Column(name = "REMOTE_ADDR", nullable = false, length = 20)
-    private String remoteAddr;
-
-    @Basic(optional = false)
-    @Column(name = "LAST_UPDATED", nullable = false)
-    private Timestamp lastUpdated;
-
-    @Basic(optional = true)
-    @Column(name = "PER_RECIPIENT_HEADERS", nullable = true, length = 10485760)
-    @Lob
-    private String perRecipientHeaders;
-
-    @Basic(optional = false, fetch = FetchType.LAZY)
-    @Column(name = "MESSAGE_BODY", nullable = false, length = 1048576000)
-    @Lob
-    private byte[] messageBody; // TODO: support streaming body where possible (see e.g. JPAStreamingMailboxMessage)
-
-    @Basic(optional = true)
-    @Column(name = "MESSAGE_ATTRIBUTES", nullable = true, length = 10485760)
-    @Lob
-    private String messageAttributes;
-
-    public JPAMail() {
-    }
-
-    public String getRepositoryName() {
-        return repositoryName;
-    }
-
-    public void setRepositoryName(String repositoryName) {
-        this.repositoryName = repositoryName;
-    }
-
-    public String getMessageName() {
-        return messageName;
-    }
-
-    public void setMessageName(String messageName) {
-        this.messageName = messageName;
-    }
-
-    public String getMessageState() {
-        return messageState;
-    }
-
-    public void setMessageState(String messageState) {
-        this.messageState = messageState;
-    }
-
-    public String getErrorMessage() {
-        return errorMessage;
-    }
-
-    public void setErrorMessage(String errorMessage) {
-        this.errorMessage = errorMessage;
-    }
-
-    public String getSender() {
-        return sender;
-    }
-
-    public void setSender(String sender) {
-        this.sender = sender;
-    }
-
-    public String getRecipients() {
-        return recipients;
-    }
-
-    public void setRecipients(String recipients) {
-        this.recipients = recipients;
-    }
-
-    public String getRemoteHost() {
-        return remoteHost;
-    }
-
-    public void setRemoteHost(String remoteHost) {
-        this.remoteHost = remoteHost;
-    }
-
-    public String getRemoteAddr() {
-        return remoteAddr;
-    }
-
-    public void setRemoteAddr(String remoteAddr) {
-        this.remoteAddr = remoteAddr;
-    }
-
-    public Timestamp getLastUpdated() {
-        return lastUpdated;
-    }
-
-    public void setLastUpdated(Timestamp lastUpdated) {
-        this.lastUpdated = lastUpdated;
-    }
-
-    public String getPerRecipientHeaders() {
-        return perRecipientHeaders;
-    }
-
-    public void setPerRecipientHeaders(String perRecipientHeaders) {
-        this.perRecipientHeaders = perRecipientHeaders;
-    }
-
-    public byte[] getMessageBody() {
-        return messageBody;
-    }
-
-    public void setMessageBody(byte[] messageBody) {
-        this.messageBody = messageBody;
-    }
-
-    public String getMessageAttributes() {
-        return messageAttributes;
-    }
-
-    public void setMessageAttributes(String messageAttributes) {
-        this.messageAttributes = messageAttributes;
-    }
-
-    @Override
-    public String toString() {
-        return "JPAMail ( "
-            + "repositoryName = " + repositoryName
-            + ", messageName = " + messageName
-            + " )";
-    }
-
-    @Override
-    public final boolean equals(Object obj) {
-        return obj instanceof JPAMail
-            && Objects.equals(this.repositoryName, ((JPAMail)obj).repositoryName)
-            && Objects.equals(this.messageName, ((JPAMail)obj).messageName);
-    }
-
-    @Override
-    public final int hashCode() {
-        return Objects.hash(repositoryName, messageName);
-    }
-}
diff --git a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/postgres/PostgresMailRepository.java b/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/postgres/PostgresMailRepository.java
index c899f7da51..241fb21536 100644
--- a/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/postgres/PostgresMailRepository.java
+++ b/server/data/data-postgres/src/main/java/org/apache/james/mailrepository/postgres/PostgresMailRepository.java
@@ -48,6 +48,7 @@ import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
+import javax.inject.Inject;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
@@ -93,6 +94,7 @@ public class PostgresMailRepository implements MailRepository {
     private final Store<MimeMessage, MimeMessagePartsId> mimeMessageStore;
     private final BlobId.Factory blobIdFactory;
 
+    @Inject
     public PostgresMailRepository(PostgresExecutor postgresExecutor,
                                   MailRepositoryUrl url,
                                   MimeMessageStore.Factory mimeMessageStoreFactory,
diff --git a/server/data/data-postgres/src/test/java/org/apache/james/mailrepository/jpa/JPAMailRepositoryTest.java b/server/data/data-postgres/src/test/java/org/apache/james/mailrepository/jpa/JPAMailRepositoryTest.java
deleted file mode 100644
index 3c41aa53ab..0000000000
--- a/server/data/data-postgres/src/test/java/org/apache/james/mailrepository/jpa/JPAMailRepositoryTest.java
+++ /dev/null
@@ -1,70 +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.mailrepository.jpa;
-
-import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
-import org.apache.james.backends.jpa.JpaTestCluster;
-import org.apache.james.mailrepository.MailRepositoryContract;
-import org.apache.james.mailrepository.api.MailRepository;
-import org.apache.james.mailrepository.api.MailRepositoryPath;
-import org.apache.james.mailrepository.api.MailRepositoryUrl;
-import org.apache.james.mailrepository.api.Protocol;
-import org.apache.james.mailrepository.jpa.model.JPAMail;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
-
-public class JPAMailRepositoryTest implements MailRepositoryContract {
-
-    final JpaTestCluster JPA_TEST_CLUSTER = JpaTestCluster.create(JPAMail.class);
-
-    private JPAMailRepository mailRepository;
-
-    @BeforeEach
-    void setUp() throws Exception {
-        mailRepository = retrieveRepository(MailRepositoryPath.from("testrepo"));
-    }
-
-    @AfterEach
-    void tearDown() {
-        JPA_TEST_CLUSTER.clear("JAMES_MAIL_STORE");
-    }
-
-    @Override
-    public MailRepository retrieveRepository() {
-        return mailRepository;
-    }
-
-    @Override
-    public JPAMailRepository retrieveRepository(MailRepositoryPath url) throws Exception {
-        BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
-        conf.addProperty("[@destinationURL]", MailRepositoryUrl.fromPathAndProtocol(new Protocol("jpa"), url).asString());
-        JPAMailRepository mailRepository = new JPAMailRepository(JPA_TEST_CLUSTER.getEntityManagerFactory());
-        mailRepository.configure(conf);
-        mailRepository.init();
-        return mailRepository;
-    }
-
-    @Override
-    @Disabled("JAMES-3431 No support for Attribute collection Java serialization yet")
-    public void shouldPreserveDsnParameters() throws Exception {
-        MailRepositoryContract.super.shouldPreserveDsnParameters();
-    }
-}
diff --git a/server/data/data-postgres/src/test/resources/persistence.xml b/server/data/data-postgres/src/test/resources/persistence.xml
index d844186105..1e66a76c65 100644
--- a/server/data/data-postgres/src/test/resources/persistence.xml
+++ b/server/data/data-postgres/src/test/resources/persistence.xml
@@ -26,7 +26,6 @@
     <persistence-unit name="James" transaction-type="JTA">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
         <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/james)</jta-data-source>
-        <class>org.apache.james.mailrepository.jpa.model.JPAMail</class>
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
         <properties>
             <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>


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