You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2022/08/02 01:24:41 UTC
[james-project] branch master updated: JAMES-3775 Simplify and generify RSpamDHttpClient API
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 173844abfa JAMES-3775 Simplify and generify RSpamDHttpClient API
173844abfa is described below
commit 173844abfab35d59804f8c5c9ac2c790b4891db0
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Aug 1 11:06:43 2022 +0700
JAMES-3775 Simplify and generify RSpamDHttpClient API
- Avoid the javax.mail dependency: this undesired
dependency should likely not be relied upon.
This also enables callers to not parse the
resulting mime message at all.
- Upon reporting spam/ham do not split header/content. Reports can be done on the full message. Avoid pushing such a constraint to the caller.
---
.../CombinedHeaderAndContentInputStreamHelper.java | 44 -----------------
.../james/rspamd/client/RSpamDHttpClient.java | 33 +++++--------
.../james/rspamd/client/RSpamDHttpClientTest.java | 57 ++++++++++------------
3 files changed, 39 insertions(+), 95 deletions(-)
diff --git a/third-party/rspamd/src/main/java/org/apache/james/rspamd/client/CombinedHeaderAndContentInputStreamHelper.java b/third-party/rspamd/src/main/java/org/apache/james/rspamd/client/CombinedHeaderAndContentInputStreamHelper.java
deleted file mode 100644
index ee8929ed42..0000000000
--- a/third-party/rspamd/src/main/java/org/apache/james/rspamd/client/CombinedHeaderAndContentInputStreamHelper.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.rspamd.client;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.SequenceInputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Enumeration;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMessage;
-
-public class CombinedHeaderAndContentInputStreamHelper {
- public static InputStream mergeHeaderAndContentInputStream(InputStream headerInputStream, InputStream contentInputStream) {
- return new SequenceInputStream(new SequenceInputStream(headerInputStream, new ByteArrayInputStream("\r\n".getBytes())), contentInputStream);
- }
-
- public static InputStream getInputStreamOfMessageHeaders(MimeMessage message) throws MessagingException {
- Enumeration<String> heads = message.getAllHeaderLines();
- StringBuilder headBuffer = new StringBuilder();
- while (heads.hasMoreElements()) {
- headBuffer.append(heads.nextElement()).append("\n");
- }
- return new ByteArrayInputStream(headBuffer.toString().getBytes(StandardCharsets.UTF_8));
- }
-}
diff --git a/third-party/rspamd/src/main/java/org/apache/james/rspamd/client/RSpamDHttpClient.java b/third-party/rspamd/src/main/java/org/apache/james/rspamd/client/RSpamDHttpClient.java
index 36c2d268da..57f78e5362 100644
--- a/third-party/rspamd/src/main/java/org/apache/james/rspamd/client/RSpamDHttpClient.java
+++ b/third-party/rspamd/src/main/java/org/apache/james/rspamd/client/RSpamDHttpClient.java
@@ -19,18 +19,12 @@
package org.apache.james.rspamd.client;
-import static org.apache.james.rspamd.client.CombinedHeaderAndContentInputStreamHelper.getInputStreamOfMessageHeaders;
-import static org.apache.james.rspamd.client.CombinedHeaderAndContentInputStreamHelper.mergeHeaderAndContentInputStream;
import static org.apache.james.rspamd.client.RSpamDClientConfiguration.DEFAULT_TIMEOUT_IN_SECONDS;
-import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMessage;
-
import org.apache.james.rspamd.exception.RSpamDUnexpectedException;
import org.apache.james.rspamd.exception.UnauthorizedException;
import org.apache.james.rspamd.model.AnalysisResult;
@@ -42,7 +36,6 @@ import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.github.fge.lambdas.Throwing;
import io.netty.buffer.Unpooled;
-import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufMono;
import reactor.netty.http.client.HttpClient;
@@ -64,23 +57,21 @@ public class RSpamDHttpClient {
this.objectMapper = new ObjectMapper().registerModule(new Jdk8Module());
}
- public Mono<AnalysisResult> checkV2(MimeMessage mimeMessage) throws MessagingException, IOException {
- return Flux.just(getInputStreamOfMessageHeaders(mimeMessage), mimeMessage.getInputStream())
- .reduce(CombinedHeaderAndContentInputStreamHelper::mergeHeaderAndContentInputStream)
- .flatMap(inputStream -> httpClient.post()
- .uri(CHECK_V2_ENDPOINT)
- .send(ReactorUtils.toChunks(inputStream, BUFFER_SIZE)
- .map(Unpooled::wrappedBuffer))
- .responseSingle(this::checkMailHttpResponseHandler))
+ public Mono<AnalysisResult> checkV2(InputStream mimeMessage) {
+ return httpClient.post()
+ .uri(CHECK_V2_ENDPOINT)
+ .send(ReactorUtils.toChunks(mimeMessage, BUFFER_SIZE)
+ .map(Unpooled::wrappedBuffer))
+ .responseSingle(this::checkMailHttpResponseHandler)
.subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER);
}
- public Mono<Void> reportAsSpam(InputStream headerInputStream, InputStream contentInputStream) {
- return reportMail(headerInputStream, contentInputStream, LEARN_SPAM_ENDPOINT);
+ public Mono<Void> reportAsSpam(InputStream content) {
+ return reportMail(content, LEARN_SPAM_ENDPOINT);
}
- public Mono<Void> reportAsHam(InputStream headerInputStream, InputStream contentInputStream) {
- return reportMail(headerInputStream, contentInputStream, LEARN_HAM_ENDPOINT);
+ public Mono<Void> reportAsHam(InputStream content) {
+ return reportMail(content, LEARN_HAM_ENDPOINT);
}
private HttpClient buildReactorNettyHttpClient(RSpamDClientConfiguration configuration) {
@@ -91,10 +82,10 @@ public class RSpamDHttpClient {
.headers(headers -> headers.add("Password", configuration.getPassword()));
}
- private Mono<Void> reportMail(InputStream headerInputStream, InputStream contentInputStream, String endpoint) {
+ private Mono<Void> reportMail(InputStream content, String endpoint) {
return httpClient.post()
.uri(endpoint)
- .send(ReactorUtils.toChunks(mergeHeaderAndContentInputStream(headerInputStream, contentInputStream), BUFFER_SIZE)
+ .send(ReactorUtils.toChunks(content, BUFFER_SIZE)
.map(Unpooled::wrappedBuffer)
.subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER))
.responseSingle(this::reportMailHttpResponseHandler);
diff --git a/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RSpamDHttpClientTest.java b/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RSpamDHttpClientTest.java
index a77902ec9d..3b75928a14 100644
--- a/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RSpamDHttpClientTest.java
+++ b/third-party/rspamd/src/test/java/org/apache/james/rspamd/client/RSpamDHttpClientTest.java
@@ -20,23 +20,20 @@
package org.apache.james.rspamd.client;
import static org.apache.james.rspamd.DockerRSpamD.PASSWORD;
-import static org.apache.james.rspamd.client.CombinedHeaderAndContentInputStreamHelper.getInputStreamOfMessageHeaders;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
-import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.util.Optional;
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMessage;
-
import org.apache.james.rspamd.DockerRSpamDExtension;
import org.apache.james.rspamd.exception.UnauthorizedException;
import org.apache.james.rspamd.model.AnalysisResult;
-import org.apache.james.util.MimeMessageUtil;
+import org.apache.james.util.ClassLoaderUtils;
import org.apache.james.util.Port;
import org.apache.james.webadmin.WebAdminUtils;
import org.eclipse.jetty.http.HttpStatus;
@@ -47,58 +44,58 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import io.restassured.http.Header;
import io.restassured.specification.RequestSpecification;
-public class RSpamDHttpClientTest {
+class RSpamDHttpClientTest {
private final static String SPAM_MESSAGE_PATH = "mail/spam/spam8.eml";
private final static String HAM_MESSAGE_PATH = "mail/ham/ham1.eml";
@RegisterExtension
static DockerRSpamDExtension rSpamDExtension = new DockerRSpamDExtension();
- private MimeMessage spamMessage;
- private MimeMessage hamMessage;
+ private byte[] spamMessage;
+ private byte[] hamMessage;
@BeforeEach
- void setup() throws MessagingException {
- spamMessage = MimeMessageUtil.mimeMessageFromStream(ClassLoader.getSystemResourceAsStream(SPAM_MESSAGE_PATH));
- hamMessage = MimeMessageUtil.mimeMessageFromStream(ClassLoader.getSystemResourceAsStream(HAM_MESSAGE_PATH));
+ void setup() {
+ spamMessage = ClassLoaderUtils.getSystemResourceAsByteArray(SPAM_MESSAGE_PATH);
+ hamMessage = ClassLoaderUtils.getSystemResourceAsByteArray(HAM_MESSAGE_PATH);
}
@Test
- void checkMailWithWrongPasswordShouldThrowUnauthorizedExceptionException() throws IOException {
+ void checkMailWithWrongPasswordShouldThrowUnauthorizedExceptionException() throws Exception {
RSpamDClientConfiguration configuration = new RSpamDClientConfiguration(rSpamDExtension.getBaseUrl(), "wrongPassword", Optional.empty());
RSpamDHttpClient client = new RSpamDHttpClient(configuration);
- assertThatThrownBy(() -> client.checkV2(spamMessage).block())
+ assertThatThrownBy(() -> client.checkV2(new ByteArrayInputStream(spamMessage)).block())
.hasMessage("{\"error\":\"Unauthorized\"}")
.isInstanceOf(UnauthorizedException.class);
}
@Test
- void learnSpamWithWrongPasswordShouldThrowUnauthorizedExceptionException() throws IOException {
+ void learnSpamWithWrongPasswordShouldThrowUnauthorizedExceptionException() throws Exception {
RSpamDClientConfiguration configuration = new RSpamDClientConfiguration(rSpamDExtension.getBaseUrl(), "wrongPassword", Optional.empty());
RSpamDHttpClient client = new RSpamDHttpClient(configuration);
- assertThatThrownBy(() -> reportAsSpam(client, spamMessage))
+ assertThatThrownBy(() -> reportAsSpam(client, new ByteArrayInputStream(spamMessage)))
.hasMessage("{\"error\":\"Unauthorized\"}")
.isInstanceOf(UnauthorizedException.class);
}
@Test
- void learnHamWithWrongPasswordShouldThrowUnauthorizedExceptionException() throws IOException {
+ void learnHamWithWrongPasswordShouldThrowUnauthorizedExceptionException() throws Exception {
RSpamDClientConfiguration configuration = new RSpamDClientConfiguration(rSpamDExtension.getBaseUrl(), "wrongPassword", Optional.empty());
RSpamDHttpClient client = new RSpamDHttpClient(configuration);
- assertThatThrownBy(() -> reportAsHam(client, hamMessage))
+ assertThatThrownBy(() -> reportAsHam(client, new ByteArrayInputStream(spamMessage)))
.hasMessage("{\"error\":\"Unauthorized\"}")
.isInstanceOf(UnauthorizedException.class);
}
@Test
- void checkSpamMailUsingRSpamDClientWithExactPasswordShouldReturnAnalysisResultAsSameAsUsingRawClient() throws IOException, MessagingException {
+ void checkSpamMailUsingRSpamDClientWithExactPasswordShouldReturnAnalysisResultAsSameAsUsingRawClient() throws Exception {
RSpamDClientConfiguration configuration = new RSpamDClientConfiguration(rSpamDExtension.getBaseUrl(), PASSWORD, Optional.empty());
RSpamDHttpClient client = new RSpamDHttpClient(configuration);
- AnalysisResult analysisResult = client.checkV2(spamMessage).block();
+ AnalysisResult analysisResult = client.checkV2(new ByteArrayInputStream(spamMessage)).block();
assertThat(analysisResult.getAction()).isEqualTo(AnalysisResult.Action.REJECT);
RequestSpecification rspamdApi = WebAdminUtils.spec(Port.of(rSpamDExtension.dockerRSpamD().getPort()));
@@ -114,11 +111,11 @@ public class RSpamDHttpClientTest {
}
@Test
- void checkHamMailUsingRSpamDClientWithExactPasswordShouldReturnAnalysisResultAsSameAsUsingRawClient() throws IOException, MessagingException {
+ void checkHamMailUsingRSpamDClientWithExactPasswordShouldReturnAnalysisResultAsSameAsUsingRawClient() throws Exception {
RSpamDClientConfiguration configuration = new RSpamDClientConfiguration(rSpamDExtension.getBaseUrl(), PASSWORD, Optional.empty());
RSpamDHttpClient client = new RSpamDHttpClient(configuration);
- AnalysisResult analysisResult = client.checkV2(hamMessage).block();
+ AnalysisResult analysisResult = client.checkV2(new ByteArrayInputStream(hamMessage)).block();
assertThat(analysisResult).isEqualTo(AnalysisResult.builder()
.action(AnalysisResult.Action.NO_ACTION)
.score(0.99F)
@@ -139,29 +136,29 @@ public class RSpamDHttpClientTest {
}
@Test
- void learnSpamMailUsingRSpamDClientWithExactPasswordShouldWork() throws IOException {
+ void learnSpamMailUsingRSpamDClientWithExactPasswordShouldWork() throws Exception {
RSpamDClientConfiguration configuration = new RSpamDClientConfiguration(rSpamDExtension.getBaseUrl(), PASSWORD, Optional.empty());
RSpamDHttpClient client = new RSpamDHttpClient(configuration);
- assertThatCode(() -> client.reportAsSpam(getInputStreamOfMessageHeaders(spamMessage), spamMessage.getInputStream()).block())
+ assertThatCode(() -> client.reportAsSpam(new ByteArrayInputStream(spamMessage)).block())
.doesNotThrowAnyException();
}
@Test
- void learnHamMailUsingRSpamDClientWithExactPasswordShouldWork() throws IOException {
+ void learnHamMailUsingRSpamDClientWithExactPasswordShouldWork() throws Exception {
RSpamDClientConfiguration configuration = new RSpamDClientConfiguration(rSpamDExtension.getBaseUrl(), PASSWORD, Optional.empty());
RSpamDHttpClient client = new RSpamDHttpClient(configuration);
- assertThatCode(() -> client.reportAsHam(getInputStreamOfMessageHeaders(hamMessage), hamMessage.getInputStream()).block())
+ assertThatCode(() -> client.reportAsHam(new ByteArrayInputStream(hamMessage)).block())
.doesNotThrowAnyException();
}
- private void reportAsSpam(RSpamDHttpClient client, MimeMessage mimeMessage) throws MessagingException, IOException {
- client.reportAsSpam(getInputStreamOfMessageHeaders(mimeMessage), mimeMessage.getInputStream()).block();
+ private void reportAsSpam(RSpamDHttpClient client, InputStream inputStream) {
+ client.reportAsSpam(inputStream).block();
}
- private void reportAsHam(RSpamDHttpClient client, MimeMessage mimeMessage) throws MessagingException, IOException {
- client.reportAsHam(getInputStreamOfMessageHeaders(mimeMessage), mimeMessage.getInputStream()).block();
+ private void reportAsHam(RSpamDHttpClient client, InputStream inputStream) {
+ client.reportAsHam(inputStream).block();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org