[06/13] james-project git commit: JAMES-2346 Allow direct convertion from MDN to Mime4J entities
JAMES-2346 Allow direct convertion from MDN to Mime4J entities Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/0f11476b Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/0f11476b Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/0f11476b Branch: refs/heads/master Commit: 0f11476b3f727789c3d542f16f2a8d11b53488c0 Parents: 890cede Author: benwa Authored: Thu Mar 8 13:36:47 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- mdn/pom.xml | 4 ++ mdn/src/main/java/org/apache/james/mdn/MDN.java | 40 +++- .../test/java/org/apache/james/mdn/MDNTest.java | 34 + 3 files changed, 76 insertions(+), 2 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/0f11476b/mdn/pom.xml -- diff --git a/mdn/pom.xml b/mdn/pom.xml index 37a85c2..87511c1 100644 --- a/mdn/pom.xml +++ b/mdn/pom.xml @@ -35,6 +35,10 @@ org.apache.james +apache-mime4j-dom + + +org.apache.james james-server-util-java8 http://git-wip-us.apache.org/repos/asf/james-project/blob/0f11476b/mdn/src/main/java/org/apache/james/mdn/MDN.java -- diff --git a/mdn/src/main/java/org/apache/james/mdn/MDN.java b/mdn/src/main/java/org/apache/james/mdn/MDN.java index e0d8965..9b7b22c 100644 --- a/mdn/src/main/java/org/apache/james/mdn/MDN.java +++ b/mdn/src/main/java/org/apache/james/mdn/MDN.java @@ -19,6 +19,7 @@ package org.apache.james.mdn; +import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Objects; import java.util.Properties; @@ -30,9 +31,22 @@ import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; +import org.apache.james.mime4j.Charsets; +import org.apache.james.mime4j.dom.Message; +import org.apache.james.mime4j.dom.Multipart; +import org.apache.james.mime4j.message.BasicBodyFactory; +import org.apache.james.mime4j.message.BodyPartBuilder; +import org.apache.james.mime4j.message.MultipartBuilder; +import org.apache.james.mime4j.stream.NameValuePair; + import com.google.common.base.Preconditions; public class MDN { +private static final NameValuePair UTF_8_CHARSET = new NameValuePair("charset", Charsets.UTF_8.name()); + +public static final String DISPOSITION_CONTENT_TYPE = "message/disposition-notification"; +public static final String REPORT_SUB_TYPE = "report"; + public static class Builder { private String humanReadableText; private MDNReport report; @@ -80,7 +94,7 @@ public class MDN { public MimeMultipart asMultipart() throws MessagingException { MimeMultipart multipart = new MimeMultipart(); -multipart.setSubType("report"); +multipart.setSubType(REPORT_SUB_TYPE); multipart.addBodyPart(computeHumanReadablePart()); multipart.addBodyPart(computeReportPart()); // The optional third part, the original message is omitted. @@ -107,10 +121,32 @@ public class MDN { public BodyPart computeReportPart() throws MessagingException { MimeBodyPart mdnPart = new MimeBodyPart(); -mdnPart.setContent(report.formattedValue(), "message/disposition-notification"); +mdnPart.setContent(report.formattedValue(), DISPOSITION_CONTENT_TYPE); return mdnPart; } +public Message.Builder asMime4JMessageBuilder() throws IOException { +Message.Builder messageBuilder = Message.Builder.of(); +messageBuilder.setBody(asMime4JMultipart()); +return messageBuilder; +} + +private Multipart asMime4JMultipart() throws IOException { +MultipartBuilder builder = MultipartBuilder.create(REPORT_SUB_TYPE); +builder.addBodyPart(BodyPartBuilder.create() +.use(new BasicBodyFactory()) +.setBody(humanReadableText, Charsets.UTF_8) +.setContentType("text/plain", UTF_8_CHARSET) +.build()); +builder.addBodyPart(BodyPartBuilder.create() +.use(new BasicBodyFactory()) +.setBody(report.formattedValue(), Charsets.UTF_8) +.setContentType(DISPOSITION_CONTENT_TYPE, UTF_8_CHARSET) +.build()); + +return builder.build(); +} + @Override public final boolean equals(Object o) { if (o instanceof MDN) { http://git-wip-us.apache.org/repos/asf/james-project/blob/0f11476b/mdn/src/test/java/org/apache/james/mdn/MDNTest.java -- diff
[04/13] james-project git commit: JAMES-2346 Factorize Awaitability constants in JMAP integration tests
JAMES-2346 Factorize Awaitability constants in JMAP integration tests Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/85ae28e0 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/85ae28e0 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/85ae28e0 Branch: refs/heads/master Commit: 85ae28e07cc2095fd5d3ec43dfea3969cc308cdb Parents: 9481435 Author: benwa Authored: Fri Mar 9 14:58:45 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../james/jmap/HttpJmapAuthentication.java | 16 ++--- .../org/apache/james/jmap/TestingConstants.java | 36 .../james/jmap/VacationIntegrationTest.java | 12 +-- .../jmap/VacationRelayIntegrationTest.java | 14 +--- .../methods/integration/SendMDNMethodTest.java | 1 + .../integration/SetMessagesMethodTest.java | 7 +--- .../integration/SpamAssassinContract.java | 28 +-- .../cucumber/SetMailboxesMethodStepdefs.java| 6 ++-- 8 files changed, 46 insertions(+), 74 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/85ae28e0/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/HttpJmapAuthentication.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/HttpJmapAuthentication.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/HttpJmapAuthentication.java index e24034b..8cebfb9 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/HttpJmapAuthentication.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/HttpJmapAuthentication.java @@ -19,9 +19,10 @@ package org.apache.james.jmap; +import static org.apache.james.jmap.TestingConstants.calmlyAwait; + import java.io.IOException; import java.net.URISyntaxException; -import java.util.concurrent.TimeUnit; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.fluent.Request; @@ -31,23 +32,12 @@ import org.apache.http.entity.ContentType; import org.apache.james.jmap.api.access.AccessToken; import org.hamcrest.core.IsAnything; -import com.jayway.awaitility.Awaitility; -import com.jayway.awaitility.Duration; -import com.jayway.awaitility.core.ConditionFactory; import com.jayway.jsonpath.JsonPath; public class HttpJmapAuthentication { -private static final ConditionFactory CALMLY_AWAIT = Awaitility.with() -.pollInterval(Duration.FIVE_HUNDRED_MILLISECONDS) -.and().with() -.pollDelay(Duration.ONE_HUNDRED_MILLISECONDS) -.await() -.atMost(30, TimeUnit.SECONDS) -.ignoreExceptions(); - public static AccessToken authenticateJamesUser(URIBuilder uriBuilder, String username, String password) { -return CALMLY_AWAIT.until( +return calmlyAwait.until( () -> doAuthenticate(uriBuilder, username, password), IsAnything.anything()); } http://git-wip-us.apache.org/repos/asf/james-project/blob/85ae28e0/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/TestingConstants.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/TestingConstants.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/TestingConstants.java new file mode 100644 index 000..9e9e37d --- /dev/null +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/TestingConstants.java @@ -0,0 +1,36 @@ +/ + * 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 r
[10/13] james-project git commit: JAMES-2346 sendMDN should be part of JMAP response and requests
JAMES-2346 sendMDN should be part of JMAP response and requests Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b54014d1 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b54014d1 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b54014d1 Branch: refs/heads/master Commit: b54014d10c65c6609fd52c2bf7a9cb946b6be1a4 Parents: 4e7d6a0 Author: benwa Authored: Thu Mar 8 10:58:04 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../apache/james/jmap/methods/ValueWithId.java | 7 + .../james/jmap/model/SetMessagesRequest.java| 31 ++-- .../james/jmap/model/SetMessagesResponse.java | 26 ++-- .../jmap/model/SetMessagesRequestTest.java | 2 +- .../jmap/model/SetMessagesResponseTest.java | 4 ++- 5 files changed, 64 insertions(+), 6 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/b54014d1/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/ValueWithId.java -- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/ValueWithId.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/ValueWithId.java index 194e6d1..e8ce60c 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/ValueWithId.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/ValueWithId.java @@ -21,6 +21,7 @@ package org.apache.james.jmap.methods; import org.apache.james.jmap.model.CreationMessage; import org.apache.james.jmap.model.CreationMessageId; +import org.apache.james.jmap.model.MDN; import org.apache.james.jmap.model.Message; import org.apache.james.jmap.model.SetError; @@ -50,6 +51,12 @@ public class ValueWithId { } } +public static class CreationMDNEntry extends ValueWithId { +public CreationMDNEntry(CreationMessageId creationId, MDN mdn) { +super(creationId, mdn); +} +} + public static class ErrorWithId extends ValueWithId { public ErrorWithId(CreationMessageId creationId, SetError error) { super(creationId, error); http://git-wip-us.apache.org/repos/asf/james-project/blob/b54014d1/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java -- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java index 9e213ec..2f3cd68 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java @@ -28,6 +28,7 @@ import java.util.function.Function; import org.apache.commons.lang.NotImplementedException; import org.apache.james.jmap.methods.JmapRequest; import org.apache.james.jmap.methods.UpdateMessagePatchConverter; +import org.apache.james.jmap.methods.ValueWithId.CreationMDNEntry; import org.apache.james.jmap.methods.ValueWithId.CreationMessageEntry; import org.apache.james.mailbox.model.MessageId; @@ -53,12 +54,14 @@ public class SetMessagesRequest implements JmapRequest { private String accountId; private String ifInState; private HashMap create; +private HashMap sendMDN; private ImmutableMap.Builder> updatesProvider; private ImmutableList.Builder destroy; private Builder() { create = new HashMap<>(); +sendMDN = new HashMap<>(); updatesProvider = ImmutableMap.builder(); destroy = ImmutableList.builder(); } @@ -87,6 +90,16 @@ public class SetMessagesRequest implements JmapRequest { return this; } +public Builder sendMDN(CreationMessageId creationMessageId, MDN mdn) { +this.sendMDN.put(creationMessageId, mdn); +return this; +} + +public Builder sendMDN(Map mdns) { +this.sendMDN.putAll(mdns); +return this; +} + public Builder update(Map updates) { this.updatesProvider.putAll(Maps.transformValues(updates, json -> converter -> converter.fromJsonNode(json))); return this; @@ -99,7 +112,7 @@ public class SetMessagesRequest implements JmapRequest { public SetMessagesRequest build() { return new SetMessagesRequest(Optional.ofNullable(accountId), Optional.ofNullable(ifInState), -messageCreations(), updatesProvider.build(), destroy.build()); +messageCreatio
[03/13] james-project git commit: JAMES-2346 Add a simplistic MDN processor
JAMES-2346 Add a simplistic MDN processor Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/7802c730 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/7802c730 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/7802c730 Branch: refs/heads/master Commit: 7802c7304359ee122c1e6e0487b2f85c78dfdab9 Parents: b54014d Author: benwa Authored: Thu Mar 8 10:58:50 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../org/apache/james/jmap/MethodsModule.java| 2 + .../james/jmap/methods/SendMDNProcessor.java| 58 2 files changed, 60 insertions(+) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/7802c730/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/MethodsModule.java -- diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/MethodsModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/MethodsModule.java index 9feb897..37b2863 100644 --- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/MethodsModule.java +++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/MethodsModule.java @@ -29,6 +29,7 @@ import org.apache.james.jmap.methods.JmapRequestParserImpl; import org.apache.james.jmap.methods.JmapResponseWriter; import org.apache.james.jmap.methods.JmapResponseWriterImpl; import org.apache.james.jmap.methods.Method; +import org.apache.james.jmap.methods.SendMDNProcessor; import org.apache.james.jmap.methods.SetMailboxesCreationProcessor; import org.apache.james.jmap.methods.SetMailboxesDestructionProcessor; import org.apache.james.jmap.methods.SetMailboxesMethod; @@ -79,6 +80,7 @@ public class MethodsModule extends AbstractModule { setMessagesProcessors.addBinding().to(SetMessagesUpdateProcessor.class); setMessagesProcessors.addBinding().to(SetMessagesCreationProcessor.class); setMessagesProcessors.addBinding().to(SetMessagesDestructionProcessor.class); +setMessagesProcessors.addBinding().to(SendMDNProcessor.class); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/7802c730/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SendMDNProcessor.java -- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SendMDNProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SendMDNProcessor.java new file mode 100644 index 000..c0dfa27 --- /dev/null +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SendMDNProcessor.java @@ -0,0 +1,58 @@ +/ + * 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.jmap.methods; + +import static org.apache.james.jmap.methods.Method.JMAP_PREFIX; + +import javax.inject.Inject; + +import org.apache.james.jmap.model.SetError; +import org.apache.james.jmap.model.SetMessagesRequest; +import org.apache.james.jmap.model.SetMessagesResponse; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.metrics.api.MetricFactory; + +public class SendMDNProcessor implements SetMessagesProcessor { +private final MetricFactory metricFactory; + +@Inject +public SendMDNProcessor(MetricFactory metricFactory) { +this.metricFactory = metricFactory; +} + +@Override +public SetMessagesResponse process(SetMessagesRequest request, MailboxSession mailboxSession) { +re
[02/13] james-project git commit: JAMES-2346 Improve james-mdn module description
JAMES-2346 Improve james-mdn module description Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/890cedec Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/890cedec Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/890cedec Branch: refs/heads/master Commit: 890cedecc80c8e50b0fea8a7d7c3ecc14b4eb221 Parents: ec73d3f Author: benwa Authored: Fri Mar 9 16:19:19 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:10:28 2018 +0700 -- mdn/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/890cedec/mdn/pom.xml -- diff --git a/mdn/pom.xml b/mdn/pom.xml index 9e8441a..37a85c2 100644 --- a/mdn/pom.xml +++ b/mdn/pom.xml @@ -30,7 +30,7 @@ james-mdn Apache James :: MDN -Provides parser and representations for MDN messages +Provides builders for RFC 8098 Message Delivery Notification - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[09/13] james-project git commit: JAMES-2346 Comply with the RFC-8098 toward determining a MDN recipient
JAMES-2346 Comply with the RFC-8098 toward determining a MDN recipient The Disposition-Notification-To field should be used. It should then be checked against the Return-Path to avoid mail bombing. Note that MDN generation had been extracted from processor for easy unit testing logic. Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a11ce53c Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a11ce53c Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a11ce53c Branch: refs/heads/master Commit: a11ce53c06ad97534334562fc583dab7b73d1294 Parents: af5a472 Author: benwa Authored: Fri Mar 9 11:29:58 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../methods/integration/SendMDNMethodTest.java | 71 + .../InvalidOriginMessageForMDNException.java| 38 ++ .../james/jmap/methods/SendMDNProcessor.java| 55 +- .../org/apache/james/jmap/model/JmapMDN.java| 80 .../apache/james/jmap/model/JmapMDNTest.java| 60 --- 5 files changed, 257 insertions(+), 47 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/a11ce53c/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java index 6e72316..fbe6f58 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java @@ -105,6 +105,39 @@ public abstract class SendMDNMethodTest { "\"setMessages\"," + "{" + " \"create\": { \"" + messageCreationId + "\" : {" + +"\"headers\":{\"Disposition-Notification-To\":\"" + BOB + "\"}," + +"\"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," + +"\"to\": [{ \"name\": \"User\", \"email\": \"" + USERNAME + "\"}]," + +"\"subject\": \"Message with an attachment\"," + +"\"textBody\": \"Test body, plain text version\"," + +"\"htmlBody\": \"Test body, HTML version\"," + +"\"mailboxIds\": [\"" + outboxId + "\"] " + +" }}" + +"}," + +"\"#0\"" + +" ]" + +"]"; + +with() +.header("Authorization", bobAccessToken.serialize()) +.body(requestBody) +.post("/jmap") +.then() +.extract() +.body() +.path(ARGUMENTS + ".created." + messageCreationId + ".id"); + +calmlyAwait.until(() -> !getMessageIdListForAccount(accessToken.serialize()).isEmpty()); +} + +private void sendAWrongInitialMessage() { +String messageCreationId = "creationId"; +String outboxId = getOutboxId(bobAccessToken); +String requestBody = "[" + +" [" + +"\"setMessages\"," + +"{" + +" \"create\": { \"" + messageCreationId + "\" : {" + "\"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," + "\"to\": [{ \"name\": \"User\", \"email\": \"" + USERNAME + "\"}]," + "\"subject\": \"Message with an attachment\"," + @@ -210,6 +243,44 @@ public abstract class SendMDNMethodTest { } @Test +public void sendMDNShouldFailOnInvalidMessages() { +sendAWrongInitialMessage(); +List messageIds = getMessageIdListForAccount(accessToken.serialize()); + +String creationId = "creation-1"; + +given() +.header("Authorization", accessToken.serialize()) +.body("[[\"setMessages\", {\"sendMDN\": {" + +"\"" + creationId + "\":{" + +"\"messageId\":\"" + messageIds.get(0) + "\"," + +"\"subject\":\"subject\"," + +"\"textBody\":\"textBody\"," + +"\"reportingUA\":\"reportingUA\"," + +"\"disposition\":{" + +"\"actionMode\":\"automatic-action\","+ +
[01/13] james-project git commit: JAMES-2346 OptionalUtils.or can now take more than 2 parameters
Repository: james-project Updated Branches: refs/heads/master c383bdf3a -> a11ce53c0 JAMES-2346 OptionalUtils.or can now take more than 2 parameters Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ec73d3f7 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ec73d3f7 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ec73d3f7 Branch: refs/heads/master Commit: ec73d3f77f9eac10b0f0e675ea0275e64aa47bd0 Parents: c383bdf Author: Raphael Ouazana Authored: Fri Mar 9 17:27:57 2018 +0100 Committer: benwa Committed: Tue Mar 13 15:10:18 2018 +0700 -- .../org/apache/james/util/OptionalUtils.java| 9 -- .../apache/james/util/OptionalUtilsTest.java| 32 2 files changed, 38 insertions(+), 3 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/ec73d3f7/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java -- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java b/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java index b08abfe..117efa3 100644 --- a/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java +++ b/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java @@ -18,6 +18,7 @@ / package org.apache.james.util; +import java.util.Arrays; import java.util.Optional; import java.util.stream.Stream; @@ -40,10 +41,12 @@ public class OptionalUtils { .orElse(Stream.of()); } -public static Optional or(Optional optional1, Optional optional2) { -return optional1.map(Optional::of) +@SafeVarargs +public static Optional or(Optional... optionals) { +return Arrays.stream(optionals) .filter(Optional::isPresent) -.orElse(optional2); +.findFirst() +.orElse(Optional.empty()); } public static boolean containsDifferent(Optional requestValue, T storeValue) { http://git-wip-us.apache.org/repos/asf/james-project/blob/ec73d3f7/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java -- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java index fcf237c..3428c60 100644 --- a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java +++ b/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java @@ -85,6 +85,28 @@ public class OptionalUtilsTest { } @Test +public void orShouldReturnEmptyWhenNoParameter() { +assertThat(OptionalUtils.or()) +.isEmpty(); +} + +@Test +public void orShouldReturnEmptyWhenEmpty() { +assertThat( +OptionalUtils.or( +Optional.empty())) +.isEmpty(); +} + +@Test +public void orShouldReturnValueWhenValue() { +assertThat( +OptionalUtils.or( +Optional.of(1))) +.contains(1); +} + +@Test public void orShouldReturnEmptyWhenBothEmpty() { assertThat( OptionalUtils.or( @@ -121,6 +143,16 @@ public class OptionalUtilsTest { } @Test +public void orShouldReturnThirdValueWhenOnlyThirdValue() { +assertThat( +OptionalUtils.or( +Optional.empty(), +Optional.empty(), +Optional.of(1))) +.contains(1); +} + +@Test public void containsDifferentShouldReturnTrueWhenNullStoreValue() throws Exception { assertThat(OptionalUtils.containsDifferent(Optional.of("any"), null)).isTrue(); } - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[12/13] james-project git commit: JAMES-2346 Await is not enough for SendMDN integration tests
JAMES-2346 Await is not enough for SendMDN integration tests We need polling to ensure the messages are well received. Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/af5a4720 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/af5a4720 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/af5a4720 Branch: refs/heads/master Commit: af5a4720073116097d92520976adf81aff17f686 Parents: 85ae28e Author: benwa Authored: Fri Mar 9 15:05:56 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../cassandra/CassandraSendMDNMethodTest.java| 5 - .../methods/integration/SendMDNMethodTest.java | 19 +++ .../jmap/memory/MemorySendMDNMethodTest.java | 4 3 files changed, 7 insertions(+), 21 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/af5a4720/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java -- diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java index 231e5e8..515d7cc 100644 --- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java +++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java @@ -47,11 +47,6 @@ public class CassandraSendMDNMethodTest extends SendMDNMethodTest { protected GuiceJamesServer createJmapServer() { return rule.jmapServer(cassandra.getModule()); } - -@Override -protected void await() { -rule.await(); -} @Override protected MessageId randomMessageId() { http://git-wip-us.apache.org/repos/asf/james-project/blob/af5a4720/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java index 694d42b..6e72316 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java @@ -23,6 +23,7 @@ import static com.jayway.restassured.RestAssured.given; import static com.jayway.restassured.RestAssured.with; import static com.jayway.restassured.config.EncoderConfig.encoderConfig; import static com.jayway.restassured.config.RestAssuredConfig.newConfig; +import static org.apache.james.jmap.TestingConstants.calmlyAwait; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -69,8 +70,6 @@ public abstract class SendMDNMethodTest { protected abstract MessageId randomMessageId(); -protected abstract void await(); - private AccessToken accessToken; private AccessToken bobAccessToken; private GuiceJamesServer jmapServer; @@ -96,10 +95,9 @@ public abstract class SendMDNMethodTest { mailboxProbe.createMailbox("#private", USERNAME, DefaultMailboxes.INBOX); accessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), USERNAME, PASSWORD); bobAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), BOB, BOB_PASSWORD); -await(); } -public void sendAnInitialMessage() { +private void sendAnInitialMessage() { String messageCreationId = "creationId"; String outboxId = getOutboxId(bobAccessToken); String requestBody = "[" + @@ -128,7 +126,7 @@ public abstract class SendMDNMethodTest { .body() .path(ARGUMENTS + ".created." + messageCreationId + ".id"); -await(); +calmlyAwait.until(() -> !getMessageIdListForAccount(accessToken.serialize()).isEmpty()); } private URIBuilder baseUri() { @@ -236
[08/13] james-project git commit: JAMES-2346 Model for MDN related data
JAMES-2346 Model for MDN related data Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4e7d6a00 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4e7d6a00 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4e7d6a00 Branch: refs/heads/master Commit: 4e7d6a000942771f4125601c9c02238d2bf4b9a5 Parents: 857074e Author: benwa Authored: Thu Mar 8 10:56:03 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../java/org/apache/james/jmap/model/MDN.java | 148 +++ .../apache/james/jmap/model/MDNDisposition.java | 119 +++ .../james/jmap/model/MDNDispositionTest.java| 84 +++ .../org/apache/james/jmap/model/MDNTest.java| 125 4 files changed, 476 insertions(+) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/4e7d6a00/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MDN.java -- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MDN.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MDN.java new file mode 100644 index 000..cf54031 --- /dev/null +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MDN.java @@ -0,0 +1,148 @@ +/ + * 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.jmap.model; + +import java.util.Objects; + +import org.apache.james.mailbox.model.MessageId; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; + +@JsonDeserialize(builder = MDN.Builder.class) +public class MDN { + +public static Builder builder() { +return new Builder(); +} + +@JsonPOJOBuilder(withPrefix = "") +public static class Builder { +private MessageId messageId; +private String subject; +private String textBody; +private String reportingUA; +private MDNDisposition disposition; + +public Builder messageId(MessageId messageId) { +this.messageId = messageId; +return this; +} + +public Builder subject(String subject) { +this.subject = subject; +return this; +} + +public Builder textBody(String textBody) { +this.textBody = textBody; +return this; +} + +public Builder reportingUA(String reportingUA) { +this.reportingUA = reportingUA; +return this; +} + +public Builder disposition(MDNDisposition disposition) { +this.disposition = disposition; +return this; +} + +public MDN build() { +Preconditions.checkState(messageId != null, "'messageId' is mandatory"); +Preconditions.checkState(subject != null, "'subject' is mandatory"); +Preconditions.checkState(textBody != null, "'textBody' is mandatory"); +Preconditions.checkState(reportingUA != null, "'reportingUA' is mandatory"); +Preconditions.checkState(disposition != null, "'disposition' is mandatory"); + +return new MDN(messageId, subject, textBody, reportingUA, disposition); +} + +} + +private final MessageId messageId; +private final String subject; +private final String textBody; +private final String reportingUA; +private final MDNDisposit
[05/13] james-project git commit: JAMES-2346 Add integration tests for sendMDN
JAMES-2346 Add integration tests for sendMDN This demonstrate that our response/request wiring works, even if no action is taken yet upon **sendMDN**. Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/20709660 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/20709660 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/20709660 Branch: refs/heads/master Commit: 2070966092d51cc8a73f007348d70f010f3605da Parents: 7802c73 Author: benwa Authored: Thu Mar 8 11:45:59 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../cassandra/CassandraSendMDNMethodTest.java | 61 + .../methods/integration/SendMDNMethodTest.java | 232 +++ .../jmap/memory/MemorySendMDNMethodTest.java| 51 3 files changed, 344 insertions(+) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/20709660/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java -- diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java new file mode 100644 index 000..231e5e8 --- /dev/null +++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSendMDNMethodTest.java @@ -0,0 +1,61 @@ +/ + * 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.jmap.cassandra; + +import org.apache.james.CassandraJmapTestRule; +import org.apache.james.DockerCassandraRule; +import org.apache.james.GuiceJamesServer; +import org.apache.james.backends.cassandra.ContainerLifecycleConfiguration; +import org.apache.james.jmap.methods.integration.SendMDNMethodTest; +import org.apache.james.mailbox.cassandra.ids.CassandraMessageId; +import org.apache.james.mailbox.model.MessageId; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.rules.TestRule; + +public class CassandraSendMDNMethodTest extends SendMDNMethodTest { + +@ClassRule +public static DockerCassandraRule cassandra = new DockerCassandraRule(); + +public static ContainerLifecycleConfiguration cassandraLifecycleConfiguration = ContainerLifecycleConfiguration.withDefaultIterationsBetweenRestart().container(cassandra.getRawContainer()).build(); + +@Rule +public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule(); + +@Rule +public TestRule cassandraLifecycleTestRule = cassandraLifecycleConfiguration.asTestRule(); + +@Override +protected GuiceJamesServer createJmapServer() { +return rule.jmapServer(cassandra.getModule()); +} + +@Override +protected void await() { +rule.await(); +} + +@Override +protected MessageId randomMessageId() { +return new CassandraMessageId.Factory().generate(); +} + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/20709660/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/Se
[13/13] james-project git commit: JAMES-2346 sendMDN should send a notification back to the original sender
JAMES-2346 sendMDN should send a notification back to the original sender Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/9481435b Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/9481435b Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/9481435b Branch: refs/heads/master Commit: 9481435b89ec32e3220202e4e2198e1bbb8b3b73 Parents: 1be875b Author: benwa Authored: Thu Mar 8 16:20:15 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- .../java/org/apache/james/mdn/MDNReport.java| 5 + .../methods/integration/SendMDNMethodTest.java | 259 +-- .../jmap/methods/MIMEMessageConverter.java | 5 +- .../james/jmap/methods/MessageAppender.java | 27 ++ .../james/jmap/methods/SendMDNProcessor.java| 179 - .../apache/james/jmap/methods/ValueWithId.java | 6 +- .../org/apache/james/jmap/model/Envelope.java | 31 +++ .../org/apache/james/jmap/model/JmapMDN.java| 148 +++ .../java/org/apache/james/jmap/model/MDN.java | 148 --- .../james/jmap/model/SetMessagesRequest.java| 21 +- .../james/jmap/model/SetMessagesResponse.java | 46 +++- .../apache/james/jmap/model/JmapMDNTest.java| 125 + .../org/apache/james/jmap/model/MDNTest.java| 125 - .../jmap/model/SetMessagesResponseTest.java | 6 +- 14 files changed, 794 insertions(+), 337 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/9481435b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java -- diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java index 2878bfa..8785737 100644 --- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java +++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java @@ -57,6 +57,11 @@ public class MDNReport { private ImmutableList.Builder errorField = ImmutableList.builder(); private ImmutableList.Builder extensionFields = ImmutableList.builder(); +public Builder reportingUserAgentField(String userAgentName) { +this.reportingUserAgentField = Optional.of(new ReportingUserAgent(userAgentName, Optional.empty())); +return this; +} + public Builder reportingUserAgentField(String userAgentName, String userAgentProduct) { this.reportingUserAgentField = Optional.of(new ReportingUserAgent(userAgentName, Optional.ofNullable(userAgentProduct))); return this; http://git-wip-us.apache.org/repos/asf/james-project/blob/9481435b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java index 059a7bb..d7690c7 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java @@ -20,26 +20,29 @@ package org.apache.james.jmap.methods.integration; import static com.jayway.restassured.RestAssured.given; +import static com.jayway.restassured.RestAssured.with; import static com.jayway.restassured.config.EncoderConfig.encoderConfig; import static com.jayway.restassured.config.RestAssuredConfig.newConfig; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; import org.apache.http.client.utils.URIBuilder; import org.apache.james.GuiceJamesServer; import org.apache.james.jmap.HttpJmapAuthentication; import org.apache.james.jmap.api.access.AccessToken; import org.apache.james.mailbox.DefaultMailboxes; -import org.apache.james.mailbox.model.MailboxConstants; +import org.apache.james.mailbox.Role; import org.apache.james.mailbox.model.MessageId; import org.apache.james.mailbox.store.probe.MailboxProbe; -import
[11/13] james-project git commit: JAMES-2346 MDN reports should be reported as attachments
JAMES-2346 MDN reports should be reported as attachments Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/1be875be Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/1be875be Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/1be875be Branch: refs/heads/master Commit: 1be875be2682a146dcb74fef6720615e014edfc5 Parents: 2070966 Author: benwa Authored: Thu Mar 8 16:19:14 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- mailbox/store/pom.xml | 5 +++ .../store/mail/model/impl/MessageParser.java| 5 +-- .../mail/model/impl/MessageParserTest.java | 37 3 files changed, 45 insertions(+), 2 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/1be875be/mailbox/store/pom.xml -- diff --git a/mailbox/store/pom.xml b/mailbox/store/pom.xml index 9befb3a..ac6dc19 100644 --- a/mailbox/store/pom.xml +++ b/mailbox/store/pom.xml @@ -60,6 +60,11 @@ ${project.groupId} +james-mdn +test + + +${project.groupId} james-server-util http://git-wip-us.apache.org/repos/asf/james-project/blob/1be875be/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java -- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java index 3331b7b..ed09191 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java @@ -57,7 +57,6 @@ public class MessageParser { .setMaxContentLen(-1) .setMaxHeaderCount(-1) .setMaxHeaderLen(-1) -.setMaxHeaderCount(-1) .setMaxLineLen(-1) .build(); private static final String TEXT_MEDIA_TYPE = "text"; @@ -68,7 +67,9 @@ public class MessageParser { private static final List ATTACHMENT_CONTENT_DISPOSITIONS = ImmutableList.of( ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT.toLowerCase(Locale.US), ContentDispositionField.DISPOSITION_TYPE_INLINE.toLowerCase(Locale.US)); -private static final ImmutableList ATTACHMENT_CONTENT_TYPES = ImmutableList.of("application/pgp-signature"); +private static final ImmutableList ATTACHMENT_CONTENT_TYPES = ImmutableList.of( +"application/pgp-signature", +"message/disposition-notification"); private static final Logger LOGGER = LoggerFactory.getLogger(MessageParser.class); private final Cid.CidParser cidParser; http://git-wip-us.apache.org/repos/asf/james-project/blob/1be875be/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java -- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java index 61df5a9..4fd3ca9 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java @@ -21,12 +21,22 @@ package org.apache.james.mailbox.store.mail.model.impl; import static org.assertj.core.api.Assertions.assertThat; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Optional; import org.apache.james.mailbox.model.Attachment; import org.apache.james.mailbox.model.Cid; import org.apache.james.mailbox.model.MessageAttachment; +import org.apache.james.mdn.MDN; +import org.apache.james.mdn.MDNReport; +import org.apache.james.mdn.action.mode.DispositionActionMode; +import org.apache.james.mdn.fields.Disposition; +import org.apache.james.mdn.sending.mode.DispositionSendingMode; +import org.apache.james.mdn.type.DispositionType; +import org.apache.james.mime4j.dom.Message; +import org.apache.james.mime4j.message.DefaultMessageWriter; import org.junit.Before; import org.junit.Test; @@ -266,4 +276,31 @@ public class MessageParserTest { .extracting(Optional::get) .containsOnly("message suivi", "signature.asc"); } + +@Test +public void mdnReportShouldBeConsideredAsAttachmentWhenDispositionContentType() throws Exception {
[07/13] james-project git commit: JAMES-2346 JSON de-serialization for MDN disposition types
JAMES-2346 JSON de-serialization for MDN disposition types Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/857074e4 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/857074e4 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/857074e4 Branch: refs/heads/master Commit: 857074e42956c7075eb047beede625964243d425 Parents: 0f11476 Author: benwa Authored: Thu Mar 8 10:55:24 2018 +0700 Committer: benwa Committed: Tue Mar 13 15:11:54 2018 +0700 -- server/protocols/jmap/pom.xml | 4 + .../james/jmap/json/ObjectMapperFactory.java| 63 +- .../jmap/json/ObjectMapperFactoryTest.java | 116 ++- 3 files changed, 176 insertions(+), 7 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/857074e4/server/protocols/jmap/pom.xml -- diff --git a/server/protocols/jmap/pom.xml b/server/protocols/jmap/pom.xml index 546afd7..e58ce38 100644 --- a/server/protocols/jmap/pom.xml +++ b/server/protocols/jmap/pom.xml @@ -82,6 +82,10 @@ ${project.groupId} +james-mdn + + +${project.groupId} james-server-core http://git-wip-us.apache.org/repos/asf/james-project/blob/857074e4/server/protocols/jmap/src/main/java/org/apache/james/jmap/json/ObjectMapperFactory.java -- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/json/ObjectMapperFactory.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/json/ObjectMapperFactory.java index 36c76fa..42fbc0b 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/json/ObjectMapperFactory.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/json/ObjectMapperFactory.java @@ -20,6 +20,7 @@ package org.apache.james.jmap.json; import java.io.IOException; +import java.util.Arrays; import java.util.Set; import javax.inject.Inject; @@ -28,6 +29,9 @@ import org.apache.james.jmap.model.mailbox.Rights; import org.apache.james.mailbox.Role; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MessageId; +import org.apache.james.mdn.action.mode.DispositionActionMode; +import org.apache.james.mdn.sending.mode.DispositionSendingMode; +import org.apache.james.mdn.type.DispositionType; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; @@ -45,7 +49,9 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.guava.GuavaModule; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.github.steveash.guavate.Guavate; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; public class ObjectMapperFactory { @@ -72,9 +78,16 @@ public class ObjectMapperFactory { mailboxIdModule.addKeyDeserializer(Rights.Username.class, new UsernameKeyDeserializer()); mailboxIdModule.addDeserializer(Rights.Right.class, new RightDeserializer()); +SimpleModule mdnModule = new SimpleModule(); +mailboxIdModule.addDeserializer(DispositionActionMode.class, new MDNActionModeDeserializer()); +mailboxIdModule.addDeserializer(DispositionSendingMode.class, new MDNSendingModeDeserializer()); +mailboxIdModule.addDeserializer(DispositionType.class, new MDNTypeDeserializer()); + mailboxIdModule.setMixInAnnotation(Role.class, RoleMixIn.class); -jacksonModules = JACKSON_BASE_MODULES.add(mailboxIdModule).build(); +jacksonModules = JACKSON_BASE_MODULES.add(mailboxIdModule) +.add(mdnModule) +.build(); } public ObjectMapper forParsing() { @@ -89,6 +102,48 @@ public class ObjectMapperFactory { .registerModules(jacksonModules); } +public static class MDNActionModeDeserializer extends JsonDeserializer { +private static final ImmutableList ALLOWED_VALUES = Arrays.stream(DispositionActionMode.values()) +.map(DispositionActionMode::getValue) +.collect(Guavate.toImmutableList()); + +@Override +public DispositionActionMode deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { +String value = jsonParser.getValueAsString(); +return DispositionActionMode.fromString(value) +.orElseThrow(() -> new IllegalStateException( +String.
[jira] [Commented] (JAMES-2346) Add a JMAP API to send MDN
[ https://issues.apache.org/jira/browse/JAMES-2346?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16396671#comment-16396671 ] Tellier Benoit commented on JAMES-2346: --- https://github.com/linagora/james-project/pull/1311 solved the issue > Add a JMAP API to send MDN > -- > > Key: JAMES-2346 > URL: https://issues.apache.org/jira/browse/JAMES-2346 > Project: James Server > Issue Type: New Feature > Components: JMAP >Affects Versions: master >Reporter: Tellier Benoit >Assignee: Antoine Duprat >Priority: Major > Fix For: 3.1.0 > > > The goal is to allow Inbox to send MDN without requiring them to forge the > message. > For that we need to to add a new argument to setMessages method (for the > moment the migration to MessageSubmission is out of scope). We already have > create / update / destroy. > Here we add: > {code:java} > sendMDN: String[MDN]|null a map of creation id (an arbitrary string set by > the client) to MDN objects (see below for a detailed description). > {code} > And here is for the MDN object: > {code:java} > messageId: String id of the message which we want to send an MDN for > subject: String human readable summary of the MDN (eg. "Read: subject of the > original message") > textBody: String human readable explanation of the MDN > reportingUA: String will be used as is as the reporting-UA field > disposition: Disposition > {code} > And Disposition: > {code:java} > actionMode: "manual-action" | "automatic-action" > sendingMode: "MDN-sent-manually" | "MDN-sent-automatically" > type: "displayed" | "deleted" | "dispatched" | "processed" > {code} > Note that here messageId is the JMAP Message Id, not the header one. > In case of error, the `creationId` used should be returned in a `MDNNotSent` > property. -- This message was sent by Atlassian JIRA (v7.6.3#76005) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[jira] [Resolved] (JAMES-2346) Add a JMAP API to send MDN
[ https://issues.apache.org/jira/browse/JAMES-2346?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Tellier Benoit resolved JAMES-2346. --- Resolution: Fixed > Add a JMAP API to send MDN > -- > > Key: JAMES-2346 > URL: https://issues.apache.org/jira/browse/JAMES-2346 > Project: James Server > Issue Type: New Feature > Components: JMAP >Affects Versions: master >Reporter: Tellier Benoit >Assignee: Antoine Duprat >Priority: Major > Fix For: 3.1.0 > > > The goal is to allow Inbox to send MDN without requiring them to forge the > message. > For that we need to to add a new argument to setMessages method (for the > moment the migration to MessageSubmission is out of scope). We already have > create / update / destroy. > Here we add: > {code:java} > sendMDN: String[MDN]|null a map of creation id (an arbitrary string set by > the client) to MDN objects (see below for a detailed description). > {code} > And here is for the MDN object: > {code:java} > messageId: String id of the message which we want to send an MDN for > subject: String human readable summary of the MDN (eg. "Read: subject of the > original message") > textBody: String human readable explanation of the MDN > reportingUA: String will be used as is as the reporting-UA field > disposition: Disposition > {code} > And Disposition: > {code:java} > actionMode: "manual-action" | "automatic-action" > sendingMode: "MDN-sent-manually" | "MDN-sent-automatically" > type: "displayed" | "deleted" | "dispatched" | "processed" > {code} > Note that here messageId is the JMAP Message Id, not the header one. > In case of error, the `creationId` used should be returned in a `MDNNotSent` > property. -- This message was sent by Atlassian JIRA (v7.6.3#76005) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[jira] [Closed] (JAMES-2346) Add a JMAP API to send MDN
[ https://issues.apache.org/jira/browse/JAMES-2346?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Tellier Benoit closed JAMES-2346. - > Add a JMAP API to send MDN > -- > > Key: JAMES-2346 > URL: https://issues.apache.org/jira/browse/JAMES-2346 > Project: James Server > Issue Type: New Feature > Components: JMAP >Affects Versions: master >Reporter: Tellier Benoit >Assignee: Antoine Duprat >Priority: Major > Fix For: 3.1.0 > > > The goal is to allow Inbox to send MDN without requiring them to forge the > message. > For that we need to to add a new argument to setMessages method (for the > moment the migration to MessageSubmission is out of scope). We already have > create / update / destroy. > Here we add: > {code:java} > sendMDN: String[MDN]|null a map of creation id (an arbitrary string set by > the client) to MDN objects (see below for a detailed description). > {code} > And here is for the MDN object: > {code:java} > messageId: String id of the message which we want to send an MDN for > subject: String human readable summary of the MDN (eg. "Read: subject of the > original message") > textBody: String human readable explanation of the MDN > reportingUA: String will be used as is as the reporting-UA field > disposition: Disposition > {code} > And Disposition: > {code:java} > actionMode: "manual-action" | "automatic-action" > sendingMode: "MDN-sent-manually" | "MDN-sent-automatically" > type: "displayed" | "deleted" | "dispatched" | "processed" > {code} > Note that here messageId is the JMAP Message Id, not the header one. > In case of error, the `creationId` used should be returned in a `MDNNotSent` > property. -- This message was sent by Atlassian JIRA (v7.6.3#76005) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[2/3] james-mime4j git commit: MIME4J-268 DefaultMessageWriter should expose a convenient *asBytes* method
MIME4J-268 DefaultMessageWriter should expose a convenient *asBytes* method Project: http://git-wip-us.apache.org/repos/asf/james-mime4j/repo Commit: http://git-wip-us.apache.org/repos/asf/james-mime4j/commit/9d0a79dd Tree: http://git-wip-us.apache.org/repos/asf/james-mime4j/tree/9d0a79dd Diff: http://git-wip-us.apache.org/repos/asf/james-mime4j/diff/9d0a79dd Branch: refs/heads/master Commit: 9d0a79dd2382440a2c2c1ceee660eb996643f972 Parents: 861f009 Author: benwa Authored: Fri Mar 9 14:29:07 2018 +0700 Committer: benwa Committed: Tue Mar 13 16:55:59 2018 +0700 -- .../mime4j/message/DefaultMessageWriter.java| 8 .../message/DefaultMessageWriterTest.java | 50 2 files changed, 58 insertions(+) -- http://git-wip-us.apache.org/repos/asf/james-mime4j/blob/9d0a79dd/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java -- diff --git a/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java b/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java index 34890a7..4ce7f7b 100644 --- a/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java +++ b/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java @@ -19,6 +19,7 @@ package org.apache.james.mime4j.message; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -48,6 +49,13 @@ public class DefaultMessageWriter implements MessageWriter { private static final byte[] CRLF = { '\r', '\n' }; private static final byte[] DASHES = { '-', '-' }; +public static byte[] asBytes(Message message) throws IOException { +ByteArrayOutputStream buffer = new ByteArrayOutputStream(); +DefaultMessageWriter writer = new DefaultMessageWriter(); +writer.writeMessage(message, buffer); +return buffer.toByteArray(); +} + /** * Protected constructor prevents direct instantiation. */ http://git-wip-us.apache.org/repos/asf/james-mime4j/blob/9d0a79dd/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java -- diff --git a/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java b/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java new file mode 100644 index 000..dece2b5 --- /dev/null +++ b/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java @@ -0,0 +1,50 @@ +/ + * 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.mime4j.message; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.james.mime4j.Charsets; +import org.apache.james.mime4j.dom.Message; +import org.junit.Test; + +public class DefaultMessageWriterTest { + +@Test +public void asBytesShouldSerializeTheMessage() throws Exception { +byte[] bytes = DefaultMessageWriter.asBytes( +Message.Builder.of() +.setBody("this is the body", Charsets.UTF_8) +.setFrom("sender@localhost") +.setTo("receiver@localhost") +.setSubject("Cool subject") +.build()); + +assertThat(new String(bytes, Charsets.UTF_8.name())) +.isEqualTo("MIME-Version: 1.0\r\n" + +"Content-Type: text/plain; charset=UTF-8\r\n" + +"From: sender@localhost\r\n" + +"To: receiver@localhost\r\n" + +"Subject: Cool subject\r\n" + +"\r\n" + +"this
[3/3] james-mime4j git commit: MIME4J-269 Introduce a Lenient default mimeConfig object
MIME4J-269 Introduce a Lenient default mimeConfig object Project: http://git-wip-us.apache.org/repos/asf/james-mime4j/repo Commit: http://git-wip-us.apache.org/repos/asf/james-mime4j/commit/861f009a Tree: http://git-wip-us.apache.org/repos/asf/james-mime4j/tree/861f009a Diff: http://git-wip-us.apache.org/repos/asf/james-mime4j/diff/861f009a Branch: refs/heads/master Commit: 861f009ae29af1d7df0d19fe26872b5e0ba769e2 Parents: a07e489 Author: benwa Authored: Fri Mar 9 14:23:06 2018 +0700 Committer: benwa Committed: Tue Mar 13 16:55:59 2018 +0700 -- .../main/java/org/apache/james/mime4j/stream/MimeConfig.java | 6 ++ 1 file changed, 6 insertions(+) -- http://git-wip-us.apache.org/repos/asf/james-mime4j/blob/861f009a/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java -- diff --git a/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java b/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java index e2e8477..09c4b28 100644 --- a/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java +++ b/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java @@ -26,6 +26,12 @@ import org.apache.james.mime4j.MimeException; */ public final class MimeConfig { +public static final MimeConfig LENIENT = MimeConfig.custom() +.setMaxContentLen(-1) +.setMaxHeaderCount(-1) +.setMaxHeaderLen(-1) +.setMaxLineLen(-1) +.build(); public static final MimeConfig DEFAULT = new Builder().build(); public static final MimeConfig STRICT = new Builder() .setStrictParsing(true) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[1/3] james-mime4j git commit: MIME4J-269 Expose a convenient 100 Mo limited "permissive" mime config limit
Repository: james-mime4j Updated Branches: refs/heads/master a07e48939 -> 06852dd8b MIME4J-269 Expose a convenient 100 Mo limited "permissive" mime config limit This aims at remaining very permissive while still denying a single email to use all JVM memory. Project: http://git-wip-us.apache.org/repos/asf/james-mime4j/repo Commit: http://git-wip-us.apache.org/repos/asf/james-mime4j/commit/06852dd8 Tree: http://git-wip-us.apache.org/repos/asf/james-mime4j/tree/06852dd8 Diff: http://git-wip-us.apache.org/repos/asf/james-mime4j/diff/06852dd8 Branch: refs/heads/master Commit: 06852dd8b3f6b55f41aba12a02a7aa0c0c0e8aea Parents: 9d0a79d Author: benwa Authored: Tue Mar 13 09:36:55 2018 +0700 Committer: benwa Committed: Tue Mar 13 16:55:59 2018 +0700 -- .../apache/james/mime4j/stream/MimeConfig.java | 4 +- .../mime4j/dom/LargeMessageParsingTest.java | 82 2 files changed, 84 insertions(+), 2 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-mime4j/blob/06852dd8/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java -- diff --git a/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java b/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java index 09c4b28..e58d063 100644 --- a/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java +++ b/core/src/main/java/org/apache/james/mime4j/stream/MimeConfig.java @@ -26,8 +26,8 @@ import org.apache.james.mime4j.MimeException; */ public final class MimeConfig { -public static final MimeConfig LENIENT = MimeConfig.custom() -.setMaxContentLen(-1) +public static final MimeConfig PERMISSIVE = MimeConfig.custom() +.setMaxContentLen(100 * 1024 * 1024) .setMaxHeaderCount(-1) .setMaxHeaderLen(-1) .setMaxLineLen(-1) http://git-wip-us.apache.org/repos/asf/james-mime4j/blob/06852dd8/dom/src/test/java/org/apache/james/mime4j/dom/LargeMessageParsingTest.java -- diff --git a/dom/src/test/java/org/apache/james/mime4j/dom/LargeMessageParsingTest.java b/dom/src/test/java/org/apache/james/mime4j/dom/LargeMessageParsingTest.java new file mode 100644 index 000..abde787 --- /dev/null +++ b/dom/src/test/java/org/apache/james/mime4j/dom/LargeMessageParsingTest.java @@ -0,0 +1,82 @@ +/ + * 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.mime4j.dom; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +import org.apache.james.mime4j.message.DefaultMessageBuilder; +import org.apache.james.mime4j.stream.MimeConfig; +import org.junit.Test; + +public class LargeMessageParsingTest { + +@Test +public void parsingALargeMessageWithPermissiveConfigShouldSucceed() throws Exception { +ByteArrayOutputStream outputStream = new ByteArrayOutputStream(100 * 1024 * 1024); +// 32 * 1.000.000 = ~ 30,5 Mo of headers +for (int i = 0; i < 100; i++) { +outputStream.write(String.format("header: static important value\r\n", i, i).getBytes()); +} +outputStream.write("\r\n".getBytes()); +// 38 * 1.600.000 = ~ 58 Mo of body +for (int i = 0; i < 160; i++) { + outputStream.write(String.format("abcdeghijklmnopqrstuvwxyz0123456789\r\n", i, i).getBytes()); +} + +DefaultMessageBuilder messageBuilder = new DefaultMessageBuilder(); +messageBuilder.setMimeEntityConfig(MimeConfig.PERMISSIVE); +messageBuilder.parseMessage(new ByteArrayInputStream(outputStream.toByteArray())); +} + +@Test +pu
[jira] [Created] (JAMES-2349) Document new WebAdmin endpoints on quotas
Antoine Duprat created JAMES-2349: - Summary: Document new WebAdmin endpoints on quotas Key: JAMES-2349 URL: https://issues.apache.org/jira/browse/JAMES-2349 Project: James Server Issue Type: New Feature Components: Documentation, webadmin Reporter: Antoine Duprat Following the previous development, we should update the documentation on WebAdmin endpoints: [http://james.apache.org/server/manage-webadmin.html] This includes managing quotas by users and by domains. -- This message was sent by Atlassian JIRA (v7.6.3#76005) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[1/8] james-project git commit: JAMES-2346 fix checkstyle issues
Repository: james-project Updated Branches: refs/heads/master a11ce53c0 -> a3f1ad022 JAMES-2346 fix checkstyle issues Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5fd52fce Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5fd52fce Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5fd52fce Branch: refs/heads/master Commit: 5fd52fce9dcbc8e3fb2c8f691e143d291e45c654 Parents: a11ce53 Author: Matthieu Baechler Authored: Tue Mar 13 16:02:25 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:02:25 2018 +0100 -- .../methods/integration/SendMDNMethodTest.java | 46 ++-- 1 file changed, 23 insertions(+), 23 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/5fd52fce/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java index fbe6f58..4ff2828 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SendMDNMethodTest.java @@ -192,9 +192,9 @@ public abstract class SendMDNMethodTest { "\"textBody\":\"textBody\"," + "\"reportingUA\":\"reportingUA\"," + "\"disposition\":{" + -"\"actionMode\":\"automatic-action\","+ -"\"sendingMode\":\"MDN-sent-automatically\","+ -"\"type\":\"processed\""+ +"\"actionMode\":\"automatic-action\"," + +"\"sendingMode\":\"MDN-sent-automatically\"," + +"\"type\":\"processed\"" + "}" + "}" + "}}, \"#0\"]]") @@ -222,9 +222,9 @@ public abstract class SendMDNMethodTest { "\"textBody\":\"textBody\"," + "\"reportingUA\":\"reportingUA\"," + "\"disposition\":{" + -"\"actionMode\":\"automatic-action\","+ -"\"sendingMode\":\"MDN-sent-automatically\","+ -"\"type\":\"processed\""+ +"\"actionMode\":\"automatic-action\"," + +"\"sendingMode\":\"MDN-sent-automatically\"," + +"\"type\":\"processed\"" + "}" + "}" + "}}, \"#0\"]]") @@ -258,9 +258,9 @@ public abstract class SendMDNMethodTest { "\"textBody\":\"textBody\"," + "\"reportingUA\":\"reportingUA\"," + "\"disposition\":{" + -"\"actionMode\":\"automatic-action\","+ -"\"sendingMode\":\"MDN-sent-automatically\","+ -"\"type\":\"processed\""+ +"\"actionMode\":\"automatic-action\"," + +"\"sendingMode\":\"MDN-sent-automatically\"," + +"\"type\":\"processed\"" + "}" + "}" + "}}, \"#0\"]]") @@ -297,9 +297,9 @@ public abstract class SendMDNMethodTest { "\"textBody\":\"Read confirmation\"," + "\"reportingUA\":\"reportingUA\"," + "\"disposition\":{" + -"\"actionMode\":\"automatic-action\","+ -"\"sendingMode\":\"MDN-sent-automatically\","+ -"\"type\":\"processed\""+ +"\"actionMode\":\"automatic-action\"," + +"\"sendingMode\":\"MDN-sent-automatically\"," + +"\"type\":\"processed\"" + "}" + "}" + "}}, \"#0\"]]") @@ -342,9 +342,9 @@ public abstract class SendMDNMethodTest { "\"textBody\":\"Read confirmation\"," + "\"reportingUA\":\"reportingUA\"," + "\"disposition\":{" + -"\"actionMode\":\"
[2/8] james-project git commit: JAMES-2344 Return a complete Quota overview on user quota route
JAMES-2344 Return a complete Quota overview on user quota route Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/630bf0a8 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/630bf0a8 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/630bf0a8 Branch: refs/heads/master Commit: 630bf0a86a8b3a138df99b4e9aa1ac956cb24ce2 Parents: c45b0f3 Author: Matthieu Baechler Authored: Fri Mar 9 14:21:46 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:10:28 2018 +0100 -- .../james/webadmin/dto/QuotaDetailsDTO.java | 95 .../webadmin/service/UserQuotaService.java | 40 +++-- .../webadmin/routes/UserQuotaRoutesTest.java| 73 --- 3 files changed, 192 insertions(+), 16 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/630bf0a8/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java -- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java new file mode 100644 index 000..6c563ec --- /dev/null +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java @@ -0,0 +1,95 @@ +/ + * 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.webadmin.dto; + +import java.util.Optional; + +import org.apache.james.mailbox.model.Quota; + +public class QuotaDetailsDTO { + +public static Builder builder() { +return new Builder(); +} + +public static class Builder { +private Optional global; +private Optional user; +private Optional computed; + +private Builder() { +global = Optional.empty(); +user = Optional.empty(); +computed = Optional.empty(); +} + +public Builder global(QuotaDTO global) { +this.global = Optional.of(global); +return this; +} + +public Builder user(QuotaDTO user) { +this.user = Optional.of(user); +return this; +} + +public Builder computed(QuotaDTO computed) { +this.computed = Optional.of(computed); +return this; +} + +public Builder valueForScope(Quota.Scope scope, QuotaDTO value) { +switch (scope) { +case Global: +return global(value); +case User: +return user(value); +} +return this; +} + +public QuotaDetailsDTO build() { +return new QuotaDetailsDTO(global, user, computed); +} +} + +private final Optional global; +private final Optional user; +private final Optional computed; + +private QuotaDetailsDTO(Optional global, Optional user, Optional computed) { +this.global = global; +this.user = user; +this.computed = computed; +} + +public Optional getGlobal() { +return global; +} + +public Optional getUser() { +return user; +} + +public Optional getComputed() { +return computed; +} +} http://git-wip-us.apache.org/repos/asf/james-project/blob/630bf0a8/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java -
[3/8] james-project git commit: JAMES-2344 remove optimization on quota computation
JAMES-2344 remove optimization on quota computation Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b90ce47a Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b90ce47a Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b90ce47a Branch: refs/heads/master Commit: b90ce47a6daa15f8af74f47fb66d95ecf62b689e Parents: a11ce53 Author: Matthieu Baechler Authored: Wed Mar 7 17:38:54 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:10:28 2018 +0100 -- .../org/apache/james/mailbox/model/Quota.java | 21 +-- .../apache/james/mailbox/model/QuotaTest.java | 10 .../manager/InMemoryIntegrationResources.java | 1 - .../store/mail/model/SerializableQuota.java | 10 ++-- .../mailbox/store/quota/NoQuotaManager.java | 15 +-- .../james/mailbox/store/quota/QuotaChecker.java | 4 +-- .../mailbox/store/quota/StoreQuotaManager.java | 27 +--- .../AbstractMessageIdManagerSideEffectTest.java | 8 +++--- .../store/quota/StoreQuotaManagerTest.java | 20 --- .../james/imap/encode/QuotaResponseEncoder.java | 6 ++--- .../james/imap/processor/GetQuotaProcessor.java | 4 +-- .../imap/processor/GetQuotaRootProcessor.java | 4 +-- .../org/apache/james/cli/ServerCmdTest.java | 5 ++-- .../apache/james/jmap/model/MailboxFactory.java | 4 +-- 14 files changed, 48 insertions(+), 91 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/b90ce47a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java -- diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java index 14e1494..c1dc033 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java @@ -18,8 +18,6 @@ / package org.apache.james.mailbox.model; -import java.util.Optional; - import org.apache.james.mailbox.quota.QuotaValue; import com.google.common.base.Objects; @@ -29,17 +27,13 @@ public class Quota> { public static > Quota quota(T used, T max) { Preconditions.checkNotNull(used); -return new Quota<>(Optional.of(used), max); -} - -public static > Quota unknownUsedQuota(T max) { -return new Quota<>(Optional.empty(), max); +return new Quota<>(used, max); } private final T max; -private final Optional used; +private final T used; -private Quota(Optional used, T max) { +private Quota(T used, T max) { this.used = used; this.max = max; } @@ -48,12 +42,12 @@ public class Quota> { return max; } -public Optional getUsed() { +public T getUsed() { return used; } public Quota addValueToQuota(T value) { -return new Quota(used.map(x -> x.add(value)), max); +return new Quota<>(used.add(value), max); } /** @@ -67,10 +61,7 @@ public class Quota> { public boolean isOverQuotaWithAdditionalValue(long additionalValue) { Preconditions.checkArgument(additionalValue >= 0); -if (!max.isLimited()) { -return false; -} -return used.map(x -> x.add(additionalValue).isGreaterThan(max)).orElse(false); +return max.isLimited() && used.add(additionalValue).isGreaterThan(max); } @Override http://git-wip-us.apache.org/repos/asf/james-project/blob/b90ce47a/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java -- diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java index 82f4c95..79ce320 100644 --- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java +++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java @@ -33,11 +33,6 @@ public class QuotaTest { public ExpectedException expectedException = ExpectedException.none(); @Test -public void unlimitedQuotaShouldNotBeOverQuota() { - assertThat(Quota.unknownUsedQuota(QuotaCount.unlimited()).isOverQuota()).isFalse(); -} - -@Test public void isOverQuotaShouldReturnFalseWhenQuotaIsNotExceeded() { assertThat(Quota.quota(QuotaCount.count(36), QuotaCount.count(360)).isOverQuota()).isFalse(); } @@ -48,11 +43,6 @@ public class QuotaTest { } @Test -public void isOverQuotaShouldReturnFalseWhenUsedValueIsUnknown() { - assertThat(
[4/8] james-project git commit: JAMES-2344 rename Quota max field to limit
JAMES-2344 rename Quota max field to limit Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ece93d03 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ece93d03 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ece93d03 Branch: refs/heads/master Commit: ece93d03d13d3ed184db2daa24c940cdc85a66c1 Parents: b90ce47 Author: Matthieu Baechler Authored: Thu Mar 8 10:22:22 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:10:28 2018 +0100 -- .../org/apache/james/mailbox/model/Quota.java | 24 ++-- .../store/mail/model/SerializableQuota.java | 2 +- .../james/mailbox/store/quota/QuotaChecker.java | 4 ++-- .../james/imap/encode/QuotaResponseEncoder.java | 4 ++-- .../imap/message/response/QuotaResponse.java| 2 +- .../james/imap/processor/GetQuotaProcessor.java | 4 ++-- .../imap/processor/GetQuotaRootProcessor.java | 4 ++-- .../apache/james/jmap/model/MailboxFactory.java | 2 +- 8 files changed, 23 insertions(+), 23 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/ece93d03/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java -- diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java index c1dc033..b4579f6 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java @@ -25,21 +25,21 @@ import com.google.common.base.Preconditions; public class Quota> { -public static > Quota quota(T used, T max) { +public static > Quota quota(T used, T limit) { Preconditions.checkNotNull(used); -return new Quota<>(used, max); +return new Quota<>(used, limit); } -private final T max; +private final T limit; private final T used; -private Quota(T used, T max) { +private Quota(T used, T limit) { this.used = used; -this.max = max; +this.limit = limit; } -public T getMax() { -return max; +public T getLimit() { +return limit; } public T getUsed() { @@ -47,7 +47,7 @@ public class Quota> { } public Quota addValueToQuota(T value) { -return new Quota<>(used.add(value), max); +return new Quota<>(used.add(value), limit); } /** @@ -61,12 +61,12 @@ public class Quota> { public boolean isOverQuotaWithAdditionalValue(long additionalValue) { Preconditions.checkArgument(additionalValue >= 0); -return max.isLimited() && used.add(additionalValue).isGreaterThan(max); +return limit.isLimited() && used.add(additionalValue).isGreaterThan(limit); } @Override public String toString() { -return used + "/" + max; +return used + "/" + limit; } @Override @@ -76,12 +76,12 @@ public class Quota> { } Quota other = (Quota) o; return Objects.equal(used, other.getUsed()) -&& Objects.equal(max,other.getMax()); +&& Objects.equal(limit,other.getLimit()); } @Override public int hashCode() { -return Objects.hashCode(used, max); +return Objects.hashCode(used, limit); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ece93d03/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/SerializableQuota.java -- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/SerializableQuota.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/SerializableQuota.java index d5a6c24..bbd5bbd 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/SerializableQuota.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/SerializableQuota.java @@ -34,7 +34,7 @@ public class SerializableQuota> implements Serializable public static final long UNLIMITED = -1; public static > SerializableQuota newInstance(Quota quota) { -return newInstance(quota.getUsed(), quota.getMax()); +return newInstance(quota.getUsed(), quota.getLimit()); } public static > SerializableQuota newInstance(U used, U max) { http://git-wip-us.apache.org/repos/asf/james-project/blob/ece93d03/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/QuotaChecker.java -- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/QuotaC
[7/8] james-project git commit: JAMES-2344 Quota now uses a builder
JAMES-2344 Quota now uses a builder Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fa0612a7 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fa0612a7 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fa0612a7 Branch: refs/heads/master Commit: fa0612a7c10adb620b3c03f6cc10c9db7f7499a8 Parents: ece93d0 Author: Matthieu Baechler Authored: Thu Mar 8 10:29:35 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:10:28 2018 +0100 -- .../org/apache/james/mailbox/model/Quota.java | 35 -- .../apache/james/mailbox/model/QuotaTest.java | 50 +++- .../mailbox/store/quota/NoQuotaManager.java | 15 +++--- .../mailbox/store/quota/StoreQuotaManager.java | 14 +++--- .../AbstractMessageIdManagerSideEffectTest.java | 17 +-- .../mailbox/store/quota/QuotaCheckerTest.java | 30 .../store/quota/StoreQuotaManagerTest.java | 14 +++--- .../imap/encode/QuotaResponseEncoderTest.java | 6 ++- .../imap/processor/GetQuotaProcessorTest.java | 6 ++- .../processor/GetQuotaRootProcessorTest.java| 6 ++- 10 files changed, 135 insertions(+), 58 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/fa0612a7/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java -- diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java index b4579f6..53c1dd7 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java @@ -25,17 +25,42 @@ import com.google.common.base.Preconditions; public class Quota> { -public static > Quota quota(T used, T limit) { -Preconditions.checkNotNull(used); -return new Quota<>(used, limit); +public static > Builder builder() { +return new Builder<>(); +} + +public static class Builder> { + +private T computedLimit; +private T used; + +private Builder() { +} + +public Builder computedLimit(T limit) { +this.computedLimit = limit; +return this; +} + +public Builder used(T used) { +this.used = used; +return this; +} + +public Quota build() { +Preconditions.checkState(used != null); +Preconditions.checkState(computedLimit != null); +return new Quota<>(used, computedLimit); +} + } private final T limit; private final T used; -private Quota(T used, T limit) { +private Quota(T used, T max) { this.used = used; -this.limit = limit; +this.limit = max; } public T getLimit() { http://git-wip-us.apache.org/repos/asf/james-project/blob/fa0612a7/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java -- diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java index 79ce320..ef5a1d6 100644 --- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java +++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaTest.java @@ -20,53 +20,77 @@ package org.apache.james.mailbox.model; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; -import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.quota.QuotaCount; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; public class QuotaTest { -@Rule -public ExpectedException expectedException = ExpectedException.none(); @Test public void isOverQuotaShouldReturnFalseWhenQuotaIsNotExceeded() { -assertThat(Quota.quota(QuotaCount.count(36), QuotaCount.count(360)).isOverQuota()).isFalse(); +Quota quota = Quota.builder().used(QuotaCount.count(36)).computedLimit(QuotaCount.count(360)).build(); +assertThat(quota.isOverQuota()).isFalse(); } @Test public void isOverQuotaShouldReturnFalseWhenMaxValueIsUnlimited() { -assertThat(Quota.quota(QuotaCount.count(36), QuotaCount.unlimited()).isOverQuota()).isFalse(); +Quota quota = Quota.builder().used(QuotaCount.count(36)).computedLimit(QuotaCount.unlimited()).build(); +assertThat(quota.isOverQuota()).isFalse(); } @Test public void isOverQuotaShouldReturnTrueWhenQuotaIsExceeded() { -assertThat(Quota.quota(QuotaCount.count(
[8/8] james-project git commit: Merge branch 'add-raw-get-methods-for-quota'
Merge branch 'add-raw-get-methods-for-quota' Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a3f1ad02 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a3f1ad02 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a3f1ad02 Branch: refs/heads/master Commit: a3f1ad02245e4ed115d85dd13b543c8cd187f580 Parents: 5fd52fc 565b180 Author: Matthieu Baechler Authored: Tue Mar 13 16:16:20 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:16:20 2018 +0100 -- .../org/apache/james/mailbox/model/Quota.java | 84 - .../james/mailbox/quota/MaxQuotaManager.java| 6 ++ .../apache/james/mailbox/model/QuotaTest.java | 60 - .../quota/CassandraPerUserMaxQuotaManager.java | 23 + .../jpa/quota/JPAPerUserMaxQuotaManager.java| 24 + .../quota/InMemoryPerUserMaxQuotaManager.java | 23 + .../manager/InMemoryIntegrationResources.java | 1 - .../store/mail/model/SerializableQuota.java | 10 ++- .../store/quota/FixedMaxQuotaManager.java | 18 .../mailbox/store/quota/NoMaxQuotaManager.java | 14 +++ .../mailbox/store/quota/NoQuotaManager.java | 15 ++-- .../james/mailbox/store/quota/QuotaChecker.java | 8 +- .../mailbox/store/quota/StoreQuotaManager.java | 31 +++ .../AbstractMessageIdManagerSideEffectTest.java | 17 ++-- .../store/quota/GenericMaxQuotaManagerTest.java | 67 ++ .../mailbox/store/quota/QuotaCheckerTest.java | 30 --- .../store/quota/StoreQuotaManagerTest.java | 34 ++- .../james/imap/encode/QuotaResponseEncoder.java | 10 +-- .../imap/message/response/QuotaResponse.java| 2 +- .../james/imap/processor/GetQuotaProcessor.java | 4 +- .../imap/processor/GetQuotaRootProcessor.java | 4 +- .../imap/encode/QuotaResponseEncoderTest.java | 6 +- .../imap/processor/GetQuotaProcessorTest.java | 6 +- .../processor/GetQuotaRootProcessorTest.java| 6 +- .../app/spring/JamesSpringContextTest.java | 4 +- .../org/apache/james/cli/ServerCmdTest.java | 5 +- .../modules/mailbox/DefaultQuotaModule.java | 2 +- .../apache/james/jmap/model/MailboxFactory.java | 6 +- .../james/webadmin/dto/QuotaDetailsDTO.java | 95 .../webadmin/service/UserQuotaService.java | 40 +++-- .../webadmin/routes/UserQuotaRoutesTest.java| 73 --- 31 files changed, 567 insertions(+), 161 deletions(-) -- - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[6/8] james-project git commit: JAMES-2344 implement limitByScope quota information in backends
JAMES-2344 implement limitByScope quota information in backends Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c45b0f3d Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c45b0f3d Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c45b0f3d Branch: refs/heads/master Commit: c45b0f3d7dc3744a3f2ac75cfb764aa47e6b5adc Parents: fa0612a Author: Matthieu Baechler Authored: Fri Mar 9 10:42:34 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:10:28 2018 +0100 -- .../org/apache/james/mailbox/model/Quota.java | 32 +- .../james/mailbox/quota/MaxQuotaManager.java| 6 ++ .../quota/CassandraPerUserMaxQuotaManager.java | 23 +++ .../jpa/quota/JPAPerUserMaxQuotaManager.java| 24 +++ .../quota/InMemoryPerUserMaxQuotaManager.java | 23 +++ .../store/quota/FixedMaxQuotaManager.java | 18 ++ .../mailbox/store/quota/NoMaxQuotaManager.java | 14 .../mailbox/store/quota/StoreQuotaManager.java | 2 + .../store/quota/GenericMaxQuotaManagerTest.java | 67 9 files changed, 206 insertions(+), 3 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/c45b0f3d/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java -- diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java index 53c1dd7..dd82bd2 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java @@ -18,23 +18,33 @@ / package org.apache.james.mailbox.model; +import java.util.Map; + import org.apache.james.mailbox.quota.QuotaValue; import com.google.common.base.Objects; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; public class Quota> { +public enum Scope { +Global, +User +} + public static > Builder builder() { return new Builder<>(); } public static class Builder> { +private final ImmutableMap.Builder limitsByScope; private T computedLimit; private T used; private Builder() { +limitsByScope = ImmutableMap.builder(); } public Builder computedLimit(T limit) { @@ -47,20 +57,32 @@ public class Quota> { return this; } +public Builder limitsByScope(Map limits) { +limitsByScope.putAll(limits); +return this; +} + +public Builder limitForScope(T limit, Scope scope) { +limitsByScope.put(scope, limit); +return this; +} + public Quota build() { Preconditions.checkState(used != null); Preconditions.checkState(computedLimit != null); -return new Quota<>(used, computedLimit); +return new Quota<>(used, computedLimit, limitsByScope.build()); } } private final T limit; +private final ImmutableMap limitByScope; private final T used; -private Quota(T used, T max) { +private Quota(T used, T max, ImmutableMap limitByScope) { this.used = used; this.limit = max; +this.limitByScope = limitByScope; } public T getLimit() { @@ -71,8 +93,12 @@ public class Quota> { return used; } +public ImmutableMap getLimitByScope() { +return limitByScope; +} + public Quota addValueToQuota(T value) { -return new Quota<>(used.add(value), limit); +return new Quota<>(used.add(value), limit, limitByScope); } /** http://git-wip-us.apache.org/repos/asf/james-project/blob/c45b0f3d/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java -- diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java index 13d8ba2..81814cc 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java @@ -19,9 +19,11 @@ package org.apache.james.mailbox.quota; +import java.util.Map; import java.util.Optional; import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.QuotaRoot; /** @@ -115,4 +117,8 @@ public interface MaxQuotaManager { * @return maximum of allowed m
[5/8] james-project git commit: JAMES-2344 Solve a Spring error with Quotas
JAMES-2344 Solve a Spring error with Quotas Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/565b1802 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/565b1802 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/565b1802 Branch: refs/heads/master Commit: 565b18022c13cb981eddd3a770c6678fb91b5cda Parents: 630bf0a Author: benwa Authored: Tue Mar 13 10:59:19 2018 +0700 Committer: Matthieu Baechler Committed: Tue Mar 13 16:10:28 2018 +0100 -- .../apache/james/mailbox/store/quota/NoQuotaManager.java | 11 ++- .../apache/james/app/spring/JamesSpringContextTest.java | 4 ++-- .../apache/james/modules/mailbox/DefaultQuotaModule.java | 2 +- 3 files changed, 5 insertions(+), 12 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/565b1802/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java -- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java index 878effa..852f91c 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java @@ -19,9 +19,6 @@ package org.apache.james.mailbox.store.quota; -import javax.inject.Inject; - -import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.QuotaRoot; import org.apache.james.mailbox.quota.QuotaCount; @@ -33,12 +30,8 @@ import org.apache.james.mailbox.quota.QuotaSize; */ public class NoQuotaManager implements QuotaManager { -@Inject -public NoQuotaManager() { -} - @Override -public Quota getMessageQuota(QuotaRoot quotaRoot) throws MailboxException { +public Quota getMessageQuota(QuotaRoot quotaRoot) { return Quota.builder() .used(QuotaCount.count(0)) .computedLimit(QuotaCount.unlimited()) @@ -46,7 +39,7 @@ public class NoQuotaManager implements QuotaManager { } @Override -public Quota getStorageQuota(QuotaRoot quotaRoot) throws MailboxException { +public Quota getStorageQuota(QuotaRoot quotaRoot) { return Quota.builder() .used(QuotaSize.size(0)) .computedLimit(QuotaSize.unlimited()) http://git-wip-us.apache.org/repos/asf/james-project/blob/565b1802/server/app/src/test/java/org/apache/james/app/spring/JamesSpringContextTest.java -- diff --git a/server/app/src/test/java/org/apache/james/app/spring/JamesSpringContextTest.java b/server/app/src/test/java/org/apache/james/app/spring/JamesSpringContextTest.java index 9478de1..5ff4917 100644 --- a/server/app/src/test/java/org/apache/james/app/spring/JamesSpringContextTest.java +++ b/server/app/src/test/java/org/apache/james/app/spring/JamesSpringContextTest.java @@ -41,14 +41,14 @@ public class JamesSpringContextTest { private JamesServerApplicationContext context; @Before -public void setup() throws Exception { +public void setup() { context = new JamesServerApplicationContext(new String[] { "META-INF/org/apache/james/spring-server.xml" }); context.registerShutdownHook(); context.start(); } @After -public void tearDown() throws Exception { +public void tearDown() { context.stop(); context.destroy(); } http://git-wip-us.apache.org/repos/asf/james-project/blob/565b1802/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultQuotaModule.java -- diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultQuotaModule.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultQuotaModule.java index f746791..831288c 100644 --- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultQuotaModule.java +++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultQuotaModule.java @@ -38,7 +38,7 @@ public class DefaultQuotaModule extends AbstractModule { bind(DefaultUserQuotaRootResolver.class).in(Scopes.SINGLETON); bind(NoMaxQuotaManager.class).in(Scopes.SINGLETON); -bind(MaxQuotaManager.class).to(NoMaxQuotaManager.class); +bind(MaxQuotaManager.class).toInstance(new NoMaxQuotaManager()); bind(QuotaManager.class).to(NoQuotaManager.class); bind(QuotaR
[2/2] james-project git commit: Merge remote-tracking branch 'linagora/pr/1318'
Merge remote-tracking branch 'linagora/pr/1318' Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c105847d Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c105847d Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c105847d Branch: refs/heads/master Commit: c105847d03ad3f72f2b64f640a3c7893ae722391 Parents: a3f1ad0 b8ecd7b Author: Matthieu Baechler Authored: Tue Mar 13 17:12:28 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 17:12:28 2018 +0100 -- .../apache/james/jmap/methods/integration/SpamAssassinContract.java | 1 + 1 file changed, 1 insertion(+) -- - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[1/2] james-project git commit: JAMES-2342 fix checkstyle
Repository: james-project Updated Branches: refs/heads/master a3f1ad022 -> c105847d0 JAMES-2342 fix checkstyle Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b8ecd7b7 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b8ecd7b7 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b8ecd7b7 Branch: refs/heads/master Commit: b8ecd7b74b08cb0b0e600219ce8720e1fba66486 Parents: 5fd52fc Author: Matthieu Baechler Authored: Tue Mar 13 16:06:02 2018 +0100 Committer: Matthieu Baechler Committed: Tue Mar 13 16:06:02 2018 +0100 -- .../apache/james/jmap/methods/integration/SpamAssassinContract.java | 1 + 1 file changed, 1 insertion(+) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/b8ecd7b7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java -- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java index a2b385a..0cdfd3b 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SpamAssassinContract.java @@ -617,6 +617,7 @@ public interface SpamAssassinContract { default String getSpamId(AccessToken accessToken) { return getMailboxId(accessToken, Role.SPAM); } + default String getTrashId(AccessToken accessToken) { return getMailboxId(accessToken, Role.TRASH); } - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[jira] [Resolved] (JAMES-2347) Demonstrate that bounce on reached quota works
[ https://issues.apache.org/jira/browse/JAMES-2347?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Tellier Benoit resolved JAMES-2347. --- Resolution: Fixed https://github.com/linagora/james-project/pull/1315 solved the issue > Demonstrate that bounce on reached quota works > -- > > Key: JAMES-2347 > URL: https://issues.apache.org/jira/browse/JAMES-2347 > Project: James Server > Issue Type: Test >Reporter: Antoine Duprat >Priority: Major > > We should check that given the right mailet configuration, an incoming email > should trigger a bounce message to the sender when recipient mailbox is full. -- This message was sent by Atlassian JIRA (v7.6.3#76005) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[jira] [Closed] (JAMES-2347) Demonstrate that bounce on reached quota works
[ https://issues.apache.org/jira/browse/JAMES-2347?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Tellier Benoit closed JAMES-2347. - > Demonstrate that bounce on reached quota works > -- > > Key: JAMES-2347 > URL: https://issues.apache.org/jira/browse/JAMES-2347 > Project: James Server > Issue Type: Test >Reporter: Antoine Duprat >Priority: Major > > We should check that given the right mailet configuration, an incoming email > should trigger a bounce message to the sender when recipient mailbox is full. -- This message was sent by Atlassian JIRA (v7.6.3#76005) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[5/6] james-project git commit: JAMES-2347 Add integration tests for Count quotas
JAMES-2347 Add integration tests for Count quotas Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/43d73249 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/43d73249 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/43d73249 Branch: refs/heads/master Commit: 43d7324975fddf30b0c4bfe16fa126cfeb569d59 Parents: dc43430 Author: benwa Authored: Tue Mar 13 10:20:15 2018 +0700 Committer: benwa Committed: Wed Mar 14 09:10:10 2018 +0700 -- .../mailets/IsOverQuotaMatcherTest.java | 46 +--- 1 file changed, 41 insertions(+), 5 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/43d73249/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java -- diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java index 213df73..493fff9 100644 --- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java @@ -29,6 +29,7 @@ import static org.apache.james.mailets.configuration.Constants.awaitAtMostOneMin import static org.assertj.core.api.Assertions.assertThat; import org.apache.james.MemoryJamesServerMain; +import org.apache.james.mailbox.quota.QuotaCount; import org.apache.james.mailbox.quota.QuotaSize; import org.apache.james.mailets.TemporaryJamesServer; import org.apache.james.mailets.configuration.CommonProcessors; @@ -57,9 +58,10 @@ public class IsOverQuotaMatcherTest { private static final String BOUNCE_SENDER = "bounce.sender@" + DEFAULT_DOMAIN; private static final String OVER_QUOTA_MESSAGE = "The recipient is over quota"; -private static final String RECIPIENT_QUOTA_ROOT = "#private&" + RECIPIENT; private static final QuotaSize SMALL_SIZE = QuotaSize.size(1); private static final QuotaSize LARGE_SIZE = QuotaSize.size(1); +private static final QuotaCount SMALL_COUNT = QuotaCount.count(0); +private static final QuotaCount LARGE_COUNT = QuotaCount.count(100); @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -81,8 +83,7 @@ public class IsOverQuotaMatcherTest { .addProperty("sender", BOUNCE_SENDER) .addProperty("message", OVER_QUOTA_MESSAGE) .addProperty("passThrough", "false")) -.addMailetsFrom(CommonProcessors.transport()) -.build()); +.addMailetsFrom(CommonProcessors.transport())); jamesServer = TemporaryJamesServer.builder() .withBase(MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE) @@ -107,7 +108,7 @@ public class IsOverQuotaMatcherTest { } @Test -public void aBounceMessageShouldBeSentToTheSenderWhenRecipientAsReachedHisQuota() throws Exception { +public void aBounceMessageShouldBeSentToTheSenderWhenRecipientAsReachedHisSizeQuota() throws Exception { webAdminApi.given() .body(SMALL_SIZE.asLong()) .put("/quota/users/" + RECIPIENT + "/size"); @@ -126,7 +127,7 @@ public class IsOverQuotaMatcherTest { } @Test -public void aBounceMessageShouldBeSentToTheRecipientWhenRecipientQuotaIsNotExceeded() throws Exception { +public void aBounceMessageShouldBeSentToTheRecipientWhenRecipientSizeQuotaIsNotExceeded() throws Exception { webAdminApi.given() .body(LARGE_SIZE.asLong()) .put("/quota/users/" + RECIPIENT + "/size"); @@ -140,4 +141,39 @@ public class IsOverQuotaMatcherTest { .select(IMAPMessageReader.INBOX) .awaitMessage(awaitAtMostOneMinute); } + +@Test +public void aBounceMessageShouldBeSentToTheSenderWhenRecipientAsReachedHisCountQuota() throws Exception { +webAdminApi.given() +.body(SMALL_COUNT.asLong()) +.put("/quota/users/" + RECIPIENT + "/count"); + +messageSender.connect(LOCALHOST_IP, SMTP_PORT) +.sendMessage(FROM, RECIPIENT) +.awaitSent(awaitAtMostOneMinute); + +IMAPMessageReader messageReader = imapMessageReader.connect(LOCALHOST_IP, IMAP_PORT) +.login(FROM, PASSWORD) +.select(IMAPMessageReader.INBOX) +.awaitMessage(awaitAtMostOneMinute); + +String bounceMessage = messageReader.readFirstMessage(); +
[2/6] james-project git commit: JAMES-2347 Solve some intelliJ warnings in UserQuotaRoutesTest
JAMES-2347 Solve some intelliJ warnings in UserQuotaRoutesTest Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/e235572c Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/e235572c Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/e235572c Branch: refs/heads/master Commit: e235572c3b77f5da3ea81b1eb7d503a9bea8c2ac Parents: 142438a Author: benwa Authored: Tue Mar 13 10:12:09 2018 +0700 Committer: benwa Committed: Wed Mar 14 09:06:02 2018 +0700 -- .../webadmin/routes/UserQuotaRoutesTest.java| 43 ++-- 1 file changed, 22 insertions(+), 21 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/e235572c/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java -- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java index fa3dd6e..4a9b82d 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java @@ -35,7 +35,6 @@ import org.apache.james.mailbox.quota.QuotaSize; import org.apache.james.mailbox.store.MailboxSessionMapperFactory; import org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver; import org.apache.james.metrics.api.NoopMetricFactory; -import org.apache.james.user.api.UsersRepositoryException; import org.apache.james.user.memory.MemoryUsersRepository; import org.apache.james.webadmin.WebAdminServer; import org.apache.james.webadmin.WebAdminUtils; @@ -65,7 +64,6 @@ public class UserQuotaRoutesTest { private static final String SIZE = "size"; private WebAdminServer webAdminServer; private InMemoryPerUserMaxQuotaManager maxQuotaManager; -private MemoryUsersRepository usersRepository; private DefaultUserQuotaRootResolver userQuotaRootResolver; @Before @@ -74,7 +72,7 @@ public class UserQuotaRoutesTest { MemoryDomainList memoryDomainList = new MemoryDomainList(new InMemoryDNSService()); memoryDomainList.setAutoDetect(false); memoryDomainList.addDomain(PERDU_COM); -usersRepository = MemoryUsersRepository.withVirtualHosting(); +MemoryUsersRepository usersRepository = MemoryUsersRepository.withVirtualHosting(); usersRepository.setDomainList(memoryDomainList); usersRepository.addUser(BOB.asString(), PASSWORD); MailboxSessionMapperFactory factory = null; @@ -107,7 +105,7 @@ public class UserQuotaRoutesTest { } @Test -public void getCountShouldReturnNoContentByDefault() throws UsersRepositoryException { +public void getCountShouldReturnNoContentByDefault() { given() .get(QUOTA_USERS + "/" + BOB.asString() + "/" + COUNT) .then() @@ -115,7 +113,7 @@ public class UserQuotaRoutesTest { } @Test -public void getCountShouldReturnStoredValue() throws Exception { +public void getCountShouldReturnStoredValue() { int value = 42; maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(value)); @@ -143,7 +141,7 @@ public class UserQuotaRoutesTest { @Test -public void putCountShouldRejectInvalid() throws Exception { +public void putCountShouldRejectInvalid() { Map errors = given() .body("invalid") .put(QUOTA_USERS + "/" + BOB.asString() + "/" + COUNT) @@ -175,7 +173,7 @@ public class UserQuotaRoutesTest { } @Test -public void putCountShouldRejectNegativeOtherThanMinusOne() throws Exception { +public void putCountShouldRejectNegativeOtherThanMinusOne() { Map errors = given() .body("-2") .put(QUOTA_USERS + "/" + BOB.asString() + "/" + COUNT) @@ -246,7 +244,7 @@ public class UserQuotaRoutesTest { } @Test -public void getSizeShouldReturnNoContentByDefault() throws UsersRepositoryException { +public void getSizeShouldReturnNoContentByDefault() { when() .get(QUOTA_USERS + "/" + BOB.asString() + "/" + SIZE) .then() @@ -254,7 +252,7 @@ public class UserQuotaRoutesTest { } @Test -public void getSizeShouldReturnStoredValue() throws Exception { +public void getSizeShouldReturnStoredValue() { long value = 42; maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(value)); @@ -272,7 +270,7
[3/6] james-project git commit: JAMES-2347 Bind users quota routes
JAMES-2347 Bind users quota routes Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ee22e0f0 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ee22e0f0 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ee22e0f0 Branch: refs/heads/master Commit: ee22e0f08ff48353a0c13cad119fdd47f9c675a4 Parents: 0769dba Author: benwa Authored: Tue Mar 13 10:15:33 2018 +0700 Committer: benwa Committed: Wed Mar 14 09:10:10 2018 +0700 -- .../java/org/apache/james/modules/server/MailboxRoutesModule.java | 3 +++ 1 file changed, 3 insertions(+) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/ee22e0f0/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/MailboxRoutesModule.java -- diff --git a/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/MailboxRoutesModule.java b/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/MailboxRoutesModule.java index d6431dc..00cea90 100644 --- a/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/MailboxRoutesModule.java +++ b/server/container/guice/protocols/webadmin-mailbox/src/main/java/org/apache/james/modules/server/MailboxRoutesModule.java @@ -23,6 +23,7 @@ import org.apache.james.webadmin.Routes; import org.apache.james.webadmin.jackson.QuotaModule; import org.apache.james.webadmin.routes.GlobalQuotaRoutes; import org.apache.james.webadmin.routes.UserMailboxesRoutes; +import org.apache.james.webadmin.routes.UserQuotaRoutes; import org.apache.james.webadmin.utils.JsonTransformerModule; import com.google.inject.AbstractModule; @@ -35,6 +36,8 @@ public class MailboxRoutesModule extends AbstractModule { Multibinder routesMultibinder = Multibinder.newSetBinder(binder(), Routes.class); routesMultibinder.addBinding().to(UserMailboxesRoutes.class); routesMultibinder.addBinding().to(GlobalQuotaRoutes.class); +routesMultibinder.addBinding().to(UserQuotaRoutes.class); + Multibinder jsonTransformerModuleMultibinder = Multibinder.newSetBinder(binder(), JsonTransformerModule.class); jsonTransformerModuleMultibinder.addBinding().to(QuotaModule.class); } - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org
[1/6] james-project git commit: JAMES-2347 Demonstrate that IsOverQuota matcher is working in mailet pipeline
Repository: james-project Updated Branches: refs/heads/master c105847d0 -> 43d732497 JAMES-2347 Demonstrate that IsOverQuota matcher is working in mailet pipeline Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/142438a5 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/142438a5 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/142438a5 Branch: refs/heads/master Commit: 142438a52e7c80b1f248bcaf1842afdc88b7b316 Parents: c105847 Author: Antoine Duprat Authored: Mon Mar 12 16:03:29 2018 +0100 Committer: benwa Committed: Wed Mar 14 09:05:15 2018 +0700 -- .../mailets/IsOverQuotaMatcherTest.java | 133 +++ 1 file changed, 133 insertions(+) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/142438a5/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java -- diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java new file mode 100644 index 000..7e514f9 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java @@ -0,0 +1,133 @@ +/ + * 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.transport.mailets; + +import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN; +import static org.apache.james.mailets.configuration.Constants.IMAP_PORT; +import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP; +import static org.apache.james.mailets.configuration.Constants.PASSWORD; +import static org.apache.james.mailets.configuration.Constants.SMTP_PORT; +import static org.apache.james.mailets.configuration.Constants.awaitAtMostOneMinute; +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.james.MemoryJamesServerMain; +import org.apache.james.mailbox.quota.QuotaSize; +import org.apache.james.mailbox.store.mail.model.SerializableQuotaValue; +import org.apache.james.mailbox.store.probe.QuotaProbe; +import org.apache.james.mailets.TemporaryJamesServer; +import org.apache.james.mailets.configuration.CommonProcessors; +import org.apache.james.mailets.configuration.MailetConfiguration; +import org.apache.james.mailets.configuration.MailetContainer; +import org.apache.james.mailets.configuration.ProcessorConfiguration; +import org.apache.james.modules.QuotaProbesImpl; +import org.apache.james.probe.DataProbe; +import org.apache.james.transport.matchers.IsOverQuota; +import org.apache.james.utils.DataProbeImpl; +import org.apache.james.utils.IMAPMessageReader; +import org.apache.james.utils.SMTPMessageSender; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class IsOverQuotaMatcherTest { + +private static final String FROM = "fromuser@" + DEFAULT_DOMAIN; +private static final String RECIPIENT = "touser@" + DEFAULT_DOMAIN; +private static final String BOUNCE_SENDER = "bounce.sender@" + DEFAULT_DOMAIN; + +private static final String OVER_QUOTA_MESSAGE = "The recipient is over quota"; +private static final String RECIPIENT_QUOTA_ROOT = "#private&" + RECIPIENT; +private static final QuotaSize SMALL_SIZE = QuotaSize.size(1); +private static final QuotaSize LARGE_SIZE = QuotaSize.size(1); + +@Rule +public Tempor
[6/6] james-project git commit: JAMES-2347 Users can be escaped in UsersQuotaRoutes
JAMES-2347 Users can be escaped in UsersQuotaRoutes RestAssured testing library tend to escape '@'. Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/0769dba5 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/0769dba5 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/0769dba5 Branch: refs/heads/master Commit: 0769dba5ac1d1b5daa4233129f1a3d4eac95ab82 Parents: e235572 Author: benwa Authored: Tue Mar 13 10:15:05 2018 +0700 Committer: benwa Committed: Wed Mar 14 09:10:10 2018 +0700 -- .../james/webadmin/routes/UserQuotaRoutes.java | 9 +++- .../webadmin/routes/UserQuotaRoutesTest.java| 54 2 files changed, 61 insertions(+), 2 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/0769dba5/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java -- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java index a5fff50..d9e2953 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java @@ -19,6 +19,9 @@ package org.apache.james.webadmin.routes; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -248,8 +251,10 @@ public class UserQuotaRoutes implements Routes { }, jsonTransformer); } -private User checkUserExist(Request request) throws UsersRepositoryException { -String user = request.params(USER); +private User checkUserExist(Request request) throws UsersRepositoryException, UnsupportedEncodingException { +String user = URLDecoder.decode(request.params(USER), +StandardCharsets.UTF_8.displayName()); + if (!usersRepository.contains(user)) { throw ErrorResponder.builder() .statusCode(HttpStatus.NOT_FOUND_404) http://git-wip-us.apache.org/repos/asf/james-project/blob/0769dba5/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java -- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java index 4a9b82d..0d84759 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java @@ -58,6 +58,7 @@ public class UserQuotaRoutesTest { private static final String QUOTA_USERS = "/quota/users"; private static final String PERDU_COM = "perdu.com"; private static final User BOB = User.fromUsername("bob@" + PERDU_COM); +private static final User ESCAPED_BOB = User.fromUsername("bob%40" + PERDU_COM); private static final User JOE = User.fromUsername("joe@" + PERDU_COM); private static final String PASSWORD = "secret"; private static final String COUNT = "count"; @@ -139,6 +140,25 @@ public class UserQuotaRoutesTest { .statusCode(HttpStatus.NOT_FOUND_404); } +@Test +public void putCountShouldAcceptEscapedUsers() { +given() +.body("35") +.when() +.put(QUOTA_USERS + "/" + ESCAPED_BOB.asString() + "/" + COUNT) +.then() +.statusCode(HttpStatus.NO_CONTENT_204); +} + +@Test +public void putCountSizeAcceptEscapedUsers() { +given() +.body("36") +.when() +.put(QUOTA_USERS + "/" + ESCAPED_BOB.asString() + "/" + SIZE) +.then() +.statusCode(HttpStatus.NO_CONTENT_204); +} @Test public void putCountShouldRejectInvalid() { @@ -442,6 +462,26 @@ public class UserQuotaRoutesTest { } @Test +public void getQuotaShouldReturnBothWhenValueSpecifiedAndEscaped() { +int maxStorage = 42; +int maxMessage = 52; +maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(maxStorage)); +maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCo
[4/6] james-project git commit: JAMES-2347 Use WebAdmin to set quotas in integration tests
JAMES-2347 Use WebAdmin to set quotas in integration tests This strengthen the integration test to match actual scenario and not rely on internal tools. Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/dc434304 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/dc434304 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/dc434304 Branch: refs/heads/master Commit: dc434304d73dde4a7f7c8a34018a1d3edb520dd9 Parents: ee22e0f Author: benwa Authored: Tue Mar 13 10:17:38 2018 +0700 Committer: benwa Committed: Wed Mar 14 09:10:10 2018 +0700 -- .../mailets/IsOverQuotaMatcherTest.java | 26 ++-- 1 file changed, 18 insertions(+), 8 deletions(-) -- http://git-wip-us.apache.org/repos/asf/james-project/blob/dc434304/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java -- diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java index 7e514f9..213df73 100644 --- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/IsOverQuotaMatcherTest.java @@ -19,6 +19,7 @@ package org.apache.james.transport.mailets; +import static com.jayway.restassured.RestAssured.given; import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN; import static org.apache.james.mailets.configuration.Constants.IMAP_PORT; import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP; @@ -29,25 +30,26 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.james.MemoryJamesServerMain; import org.apache.james.mailbox.quota.QuotaSize; -import org.apache.james.mailbox.store.mail.model.SerializableQuotaValue; -import org.apache.james.mailbox.store.probe.QuotaProbe; import org.apache.james.mailets.TemporaryJamesServer; import org.apache.james.mailets.configuration.CommonProcessors; import org.apache.james.mailets.configuration.MailetConfiguration; import org.apache.james.mailets.configuration.MailetContainer; import org.apache.james.mailets.configuration.ProcessorConfiguration; -import org.apache.james.modules.QuotaProbesImpl; import org.apache.james.probe.DataProbe; import org.apache.james.transport.matchers.IsOverQuota; import org.apache.james.utils.DataProbeImpl; import org.apache.james.utils.IMAPMessageReader; import org.apache.james.utils.SMTPMessageSender; +import org.apache.james.utils.WebAdminGuiceProbe; +import org.apache.james.webadmin.WebAdminUtils; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import com.jayway.restassured.specification.RequestSpecification; + public class IsOverQuotaMatcherTest { private static final String FROM = "fromuser@" + DEFAULT_DOMAIN; @@ -67,6 +69,7 @@ public class IsOverQuotaMatcherTest { public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN); private TemporaryJamesServer jamesServer; +private RequestSpecification webAdminApi; @Before public void setup() throws Exception { @@ -86,6 +89,11 @@ public class IsOverQuotaMatcherTest { .withMailetContainer(mailetContainer) .build(temporaryFolder); +WebAdminGuiceProbe webAdminGuiceProbe = jamesServer.getProbe(WebAdminGuiceProbe.class); +webAdminGuiceProbe.await(); +webAdminApi = given() + .spec(WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort()).build()); + DataProbe dataProbe = jamesServer.getProbe(DataProbeImpl.class); dataProbe.addDomain(DEFAULT_DOMAIN); dataProbe.addUser(FROM, PASSWORD); @@ -94,14 +102,15 @@ public class IsOverQuotaMatcherTest { } @After -public void tearDown() throws Exception { +public void tearDown() { jamesServer.shutdown(); } @Test public void aBounceMessageShouldBeSentToTheSenderWhenRecipientAsReachedHisQuota() throws Exception { -QuotaProbe quotaProbes = jamesServer.getProbe(QuotaProbesImpl.class); -quotaProbes.setMaxStorage(RECIPIENT_QUOTA_ROOT, new SerializableQuotaValue<>(SMALL_SIZE)); +webAdminApi.given() +.body(SMALL_SIZE.asLong()) +.put("/quota/users/" + RECIPIENT + "/size"); messageSender.connect(LOCALHOST_IP, SMTP_PORT) .sendMessage(FROM, RECIPIEN
[jira] [Created] (JAMES-2350) JPA max quota manager is not thread safe
Tellier Benoit created JAMES-2350: - Summary: JPA max quota manager is not thread safe Key: JAMES-2350 URL: https://issues.apache.org/jira/browse/JAMES-2350 Project: James Server Issue Type: Bug Components: IMAPServer, jpa Affects Versions: master Reporter: Tellier Benoit Fix For: master `Yeikel Santana` encountered the following error: {code:java} 15:24:39.824 [ERROR] o.a.j.i.p.b.AbstractChainedProcessor - Error while processing IMAP request org.apache.openjpa.persistence.PersistenceException: Multiple concurrent threads attempted to access a single broker. By default brokers are not thread safe; if you require and/or intend a broker to be accessed by more than one thread, set the openjpa.Multithreaded property to true to override the default behavior. at org.apache.openjpa.kernel.BrokerImpl.endOperation(BrokerImpl.java:1987) at org.apache.openjpa.kernel.BrokerImpl.isActive(BrokerImpl.java:1935) at org.apache.openjpa.kernel.DelegatingBroker.isActive(DelegatingBroker.java:47 5) at org.apache.openjpa.persistence.EntityManagerImpl.isActive(EntityManagerImpl. java:678) at org.apache.openjpa.persistence.PersistenceExceptions$2.translate(Persistence Exceptions.java:74) at org.apache.openjpa.kernel.DelegatingBroker.translate(DelegatingBroker.java:1 06) at org.apache.openjpa.kernel.DelegatingBroker.newObjectId(DelegatingBroker.java :317) at org.apache.openjpa.persistence.EntityManagerImpl.find(EntityManagerImpl.java :487) at org.apache.james.mailbox.jpa.quota.JPAPerUserMaxQuotaManager.getMaxMessage(J PAPerUserMaxQuotaManager.java:104) at org.apache.james.mailbox.store.quota.StoreQuotaManager.getMessageQuota(Store QuotaManager.java:52) at org.apache.james.imap.processor.GetQuotaRootProcessor.doProcess(GetQuotaRoot Processor.java:81) at org.apache.james.imap.processor.GetQuotaRootProcessor.doProcess(GetQuotaRoot Processor.java:53) at org.apache.james.imap.processor.AbstractMailboxProcessor.doProcess(AbstractM ailboxProcessor.java:110) at org.apache.james.imap.processor.AbstractMailboxProcessor.process(AbstractMai lboxProcessor.java:97) at org.apache.james.imap.processor.AbstractMailboxProcessor.doProcess(AbstractM ailboxProcessor.java:89) at org.apache.james.imap.processor.AbstractMailboxProcessor.doProcess(AbstractM ailboxProcessor.java:71) at org.apache.james.imap.processor.base.AbstractChainedProcessor.process(Abstra ctChainedProcessor.java:65) at org.apache.james.imap.processor.base.AbstractChainedProcessor.process(Abstra ctChainedProcessor.java:74) at org.apache.james.imapserver.netty.ImapChannelUpstreamHandler.messageReceived (ImapChannelUpstreamHandler.java:196) at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleCh annelUpstreamHandler.java:70) at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPi peline.java:564) at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext. sendUpstream(DefaultChannelPipeline.java:791) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceive d(FrameDecoder.java:462) at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.jav a:443) at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecode r.java:303) at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleCh annelUpstreamHandler.java:70) at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPi peline.java:564) at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext. sendUpstream(DefaultChannelPipeline.java:791) at org.jboss.netty.handler.execution.ChannelUpstreamEventRunnable.doRun(Channel UpstreamEventRunnable.java:43) at org.jboss.netty.handler.execution.ChannelEventRunnable.run(ChannelEventRunna ble.java:67) at org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor$Child Executor.run(OrderedMemoryAwareThreadPoolExecutor.java:314) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:11 49) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:6 24) at java.lang.Thread.run(Thread.java:748) {code} We need to issue parallel IMAP `GETQUOTAROOT` calls on top of JPA James Server and ensure that we reproduce this bug. Then we need to solve it. Then ensure our test pass. -- This message was sent by Atlassian JIRA (v7.6.3#76005) - To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org