This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 6a90e2bebe JAMES-4115 FileMailRepository: drop cacheKey & refactor
(#2662)
6a90e2bebe is described below
commit 6a90e2bebef53e2ac6bbd25754670923fc4b7cdd
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Mar 7 15:20:33 2025 +0700
JAMES-4115 FileMailRepository: drop cacheKey & refactor (#2662)
---
.../mailrepository/file/FileMailRepository.java | 107 +++++++--------------
.../mailrepository/FileMailRepositoryTest.java | 27 ------
2 files changed, 37 insertions(+), 97 deletions(-)
diff --git
a/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java
b/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java
index 31df9e1a04..a53371d291 100644
---
a/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java
+++
b/server/data/data-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java
@@ -27,7 +27,6 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
-import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -66,11 +65,7 @@ public class FileMailRepository implements MailRepository,
Configurable, Initial
private FilePersistentStreamRepository streamRepository;
private FilePersistentObjectRepository objectRepository;
private String destination;
- private Set<String> keys;
- private final Object lock = new Object();
private boolean fifo;
- private boolean cacheKeys; // experimental: for use with write mostly
- // repositories such as spam and error
private FileSystem fileSystem;
/**
@@ -114,8 +109,6 @@ public class FileMailRepository implements MailRepository,
Configurable, Initial
destination = config.getString("[@destinationURL]");
LOGGER.debug("FileMailRepository.destinationURL: {}", destination);
fifo = config.getBoolean("[@FIFO]", false);
- cacheKeys = config.getBoolean("[@CACHEKEYS]", true);
- // ignore model
}
@Override
@@ -135,10 +128,6 @@ public class FileMailRepository implements MailRepository,
Configurable, Initial
streamRepository.configure(reposConfiguration);
streamRepository.init();
- if (cacheKeys) {
- keys = Collections.synchronizedSet(new HashSet<>());
- }
-
// Finds non-matching pairs and deletes the extra files
HashSet<String> streamKeys =
streamRepository.list().collect(Collectors.toCollection(HashSet::new));
@@ -147,25 +136,19 @@ public class FileMailRepository implements
MailRepository, Configurable, Initial
@SuppressWarnings("unchecked")
Collection<String> strandedStreams = (Collection<String>)
streamKeys.clone();
strandedStreams.removeAll(objectKeys);
- for (Object strandedStream : strandedStreams) {
- MailKey key = new MailKey((String) strandedStream);
+ for (String strandedStream : strandedStreams) {
+ MailKey key = new MailKey(strandedStream);
remove(key);
}
@SuppressWarnings("unchecked")
Collection<String> strandedObjects = (Collection<String>)
objectKeys.clone();
strandedObjects.removeAll(streamKeys);
- for (Object strandedObject : strandedObjects) {
- MailKey key = new MailKey((String) strandedObject);
+ for (String strandedObject : strandedObjects) {
+ MailKey key = new MailKey(strandedObject);
remove(key);
}
- if (keys != null) {
- // Next get a list from the object repository
- // and use that for the list of keys
- keys.clear();
- objectRepository.list().forEach(keys::add);
- }
LOGGER.debug("{} created in {}", getClass().getName(),
destination);
} catch (Exception e) {
LOGGER.error("Failed to retrieve Store component", e);
@@ -218,15 +201,12 @@ public class FileMailRepository implements
MailRepository, Configurable, Initial
private void internalStore(Mail mc) throws MessagingException, IOException
{
String key = mc.getName();
- if (keys != null) {
- keys.add(key);
- }
+
boolean saveStream = true;
MimeMessage message = mc.getMessage();
- if (message instanceof MimeMessageWrapper) {
- MimeMessageWrapper wrapper = (MimeMessageWrapper) message;
+ if (message instanceof MimeMessageWrapper wrapper) {
LOGGER.trace("Retrieving from: {}", wrapper.getSourceId());
LOGGER.trace("Saving to: {}/{}", destination, mc.getName());
LOGGER.trace("Modified: {}", wrapper.isModified());
@@ -243,45 +223,30 @@ public class FileMailRepository implements
MailRepository, Configurable, Initial
}
}
if (saveStream) {
- OutputStream out = null;
- try {
- if (message instanceof MimeMessageWrapper) {
- // we need to force the loading of the message from the
- // stream as we want to override the old message
- ((MimeMessageWrapper) message).loadMessage();
- out = streamRepository.put(key);
-
- ((MimeMessageWrapper) message).writeTo(out, out, null,
true);
-
- } else {
- out = streamRepository.put(key);
- mc.getMessage().writeTo(out);
-
- }
-
- } finally {
- if (out != null) {
- out.close();
- }
- }
+ saveStream(mc, message, key);
}
// Always save the header information
objectRepository.put(key, mc);
}
+ private void saveStream(Mail mc, MimeMessage message, String key) throws
MessagingException, IOException {
+ try (OutputStream out = streamRepository.put(key)) {
+ if (message instanceof MimeMessageWrapper mimeMessageWrapper) {
+ // we need to force the loading of the message from the
+ // stream as we want to override the old message
+ mimeMessageWrapper.loadMessage();
+ mimeMessageWrapper.writeTo(out, out, null, true);
+ } else {
+ mc.getMessage().writeTo(out);
+ }
+ }
+ }
+
@Override
public Mail retrieve(MailKey key) throws MessagingException {
try {
- Mail mc;
- try {
- mc = (Mail) objectRepository.get(key.asString());
- } catch (RuntimeException re) {
- if (re.getCause() instanceof Error) {
- LOGGER.warn("Error when retrieving mail, not deleting:
{}", re, re);
- } else {
- LOGGER.warn("Exception retrieving mail: {}, so we're
deleting it.", re, re);
- remove(key);
- }
+ Mail mc = retrieveMailWithoutMessage(key);
+ if (mc == null) {
return null;
}
MimeMessageStreamRepositorySource source = new
MimeMessageStreamRepositorySource(streamRepository, destination,
key.asString());
@@ -294,6 +259,19 @@ public class FileMailRepository implements MailRepository,
Configurable, Initial
}
}
+ private Mail retrieveMailWithoutMessage(MailKey key) throws
MessagingException {
+ try {
+ return (Mail) objectRepository.get(key.asString());
+ } catch (RuntimeException re) {
+ if (re.getCause() instanceof Error) {
+ LOGGER.warn("Error when retrieving mail, not deleting: {}",
re, re);
+ } else {
+ LOGGER.warn("Exception retrieving mail: {}, so we're deleting
it.", re, re);
+ remove(key);
+ }
+ return null;
+ }
+ }
@Override
public void remove(MailKey key) throws MessagingException {
@@ -320,9 +298,6 @@ public class FileMailRepository implements MailRepository,
Configurable, Initial
}
private void internalRemove(MailKey key) {
- if (keys != null) {
- keys.remove(key.asString());
- }
streamRepository.remove(key.asString());
objectRepository.remove(key.asString());
}
@@ -336,20 +311,12 @@ public class FileMailRepository implements
MailRepository, Configurable, Initial
private Stream<MailKey> listStream() {
// Fix ConcurrentModificationException by cloning
// the keyset before getting an iterator
- final ArrayList<String> clone;
- if (keys != null) {
- synchronized (lock) {
- clone = new ArrayList<>(keys);
- }
- } else {
- clone =
objectRepository.list().collect(Collectors.toCollection(ArrayList::new));
- }
+ ArrayList<String> clone =
objectRepository.list().collect(Collectors.toCollection(ArrayList::new));
if (fifo) {
Collections.sort(clone); // Keys is a HashSet; impose FIFO for apps
}
// that need it
- return clone
- .stream()
+ return objectRepository.list()
.map(MailKey::new);
}
}
diff --git
a/server/data/data-file/src/test/java/org/apache/james/mailrepository/FileMailRepositoryTest.java
b/server/data/data-file/src/test/java/org/apache/james/mailrepository/FileMailRepositoryTest.java
index 2bb4845a3b..53df9b1f50 100644
---
a/server/data/data-file/src/test/java/org/apache/james/mailrepository/FileMailRepositoryTest.java
+++
b/server/data/data-file/src/test/java/org/apache/james/mailrepository/FileMailRepositoryTest.java
@@ -85,7 +85,6 @@ public class FileMailRepositoryTest {
@Override
protected BaseHierarchicalConfiguration
withConfigurationOptions(BaseHierarchicalConfiguration configuration) {
configuration.addProperty("[@FIFO]", "false");
- configuration.addProperty("[@CACHEKEYS]", "true");
return configuration;
}
}
@@ -111,7 +110,6 @@ public class FileMailRepositoryTest {
protected BaseHierarchicalConfiguration
withConfigurationOptions(BaseHierarchicalConfiguration configuration) {
configuration.addProperty("[@FIFO]", "false");
- configuration.addProperty("[@CACHEKEYS]", "true");
return configuration;
}
@@ -132,18 +130,6 @@ public class FileMailRepositoryTest {
}
}
- @Nested
- @DisplayName("No cache configuration")
- public class NoCacheFileMailRepositoryTest extends
GenericFileMailRepositoryTest {
-
- @Override
- protected BaseHierarchicalConfiguration
withConfigurationOptions(BaseHierarchicalConfiguration configuration) {
- configuration.addProperty("[@FIFO]", "false");
- configuration.addProperty("[@CACHEKEYS]", "false");
- return configuration;
- }
- }
-
@Nested
@DisplayName("Fifo configuration")
public class FifoFileMailRepositoryTest extends
GenericFileMailRepositoryTest {
@@ -151,19 +137,6 @@ public class FileMailRepositoryTest {
@Override
protected BaseHierarchicalConfiguration
withConfigurationOptions(BaseHierarchicalConfiguration configuration) {
configuration.addProperty("[@FIFO]", "true");
- configuration.addProperty("[@CACHEKEYS]", "true");
- return configuration;
- }
- }
-
- @Nested
- @DisplayName("Fifo no cache configuration")
- public class FifoNoCacheFileMailRepositoryTest extends
GenericFileMailRepositoryTest {
-
- @Override
- protected BaseHierarchicalConfiguration
withConfigurationOptions(BaseHierarchicalConfiguration configuration) {
- configuration.addProperty("[@FIFO]", "true");
- configuration.addProperty("[@CACHEKEYS]", "false");
return configuration;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]