Skip to content

Commit

Permalink
Improve mail test coverage #3674
Browse files Browse the repository at this point in the history
  • Loading branch information
JiriOndrusek committed Mar 31, 2022
1 parent b951eea commit b8bfb8a
Show file tree
Hide file tree
Showing 7 changed files with 447 additions and 3 deletions.
9 changes: 9 additions & 0 deletions integration-tests/mail/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
<groupId>org.jvnet.mock-javamail</groupId>
<artifactId>mock-javamail</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>

<!-- test dependencies -->
<dependency>
Expand All @@ -60,6 +64,11 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,46 @@
*/
package org.apache.camel.quarkus.component.mail;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Store;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.sun.mail.imap.SortTerm;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Producer;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.attachment.DefaultAttachment;
import org.apache.camel.component.mail.DefaultJavaMailSender;
import org.apache.camel.component.mail.JavaMailSender;
import org.apache.camel.component.mail.MailConverters;
import org.apache.camel.component.mail.MailMessage;
import org.apache.camel.component.mail.MailSorter;
import org.jvnet.mock_javamail.Mailbox;

@Path("/mail")
@ApplicationScoped
Expand All @@ -38,6 +64,16 @@ public class CamelResource {
@Inject
ProducerTemplate template;

@Inject
Store store;

@Inject
CamelContext camelContext;

@Inject
@Named("mailReceivedMessages")
List<Map<String, Object>> mailReceivedMessages;

@Path("/route/{route}")
@POST
@Consumes(MediaType.TEXT_PLAIN)
Expand All @@ -46,6 +82,14 @@ public String route(String statement, @PathParam("route") String route) throws E
return template.requestBody("direct:" + route, statement, String.class);
}

@Path("/sendWithHeaders/{direct}/{msg}")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void sendWithHeaders(Map<String, Object> headers, @PathParam("direct") String direct, @PathParam("msg") String msg)
throws Exception {
template.requestBodyAndHeaders("direct:" + direct, msg, headers);
}

@Path("/mimeMultipartMarshal/{fileName}/{fileContent}")
@POST
@Consumes(MediaType.TEXT_PLAIN)
Expand All @@ -67,4 +111,126 @@ public String mimeMultipart(String body, @PathParam("fileName") String fileName,
}).getMessage().getBody(String.class);
}

@Path("/send")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void send(List<String> messages) throws Exception {
JavaMailSender sender = new DefaultJavaMailSender();
store.connect("localhost", "jones", "secret");
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
folder.expunge();

// inserts new messages
Message[] msgs = new Message[messages.size()];
int i = 0;
for (String msg : messages) {
msgs[i] = new MimeMessage(sender.getSession());
msgs[i].setHeader("Message-ID", "" + i);
msgs[i++].setText(msg);
}
folder.appendMessages(msgs);
folder.close(true);
store.close();
}

@Path("/getReceived")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getReceived() {
return mailReceivedMessages;
}

@Path("/getReceivedAsString")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getReceivedAsString() throws MessagingException, IOException {
List<Map<String, Object>> result = new LinkedList();
for (Map<String, Object> email : mailReceivedMessages) {
Message mm = ((MailMessage) email.get("body")).getMessage();
InputStream is = MailConverters.toInputStream(mm);
result.add(Collections.singletonMap("body", (Object) camelContext.getTypeConverter().convertTo(String.class, is)));
}
mailReceivedMessages.clear();
return result;

}

@Path("/clear")
@GET
public void clear() {
mailReceivedMessages.clear();
Mailbox.clearAll();
}

@GET
@Path("/route/{routeId}/{operation}")
@Produces(MediaType.TEXT_PLAIN)
public String controlRoute(@PathParam("routeId") String routeId, @PathParam("operation") String operation)
throws Exception {
switch (operation) {
case "stop":
camelContext.getRouteController().stopRoute(routeId);
break;
case "start":
camelContext.getRouteController().startRoute(routeId);
break;
case "status":
return camelContext.getRouteController().getRouteStatus(routeId).name();

}
return null;
}

@GET
@Path("/sendAttachment/{filename}")
public void sendAttachment(@PathParam("filename") String filename) throws Exception {
Endpoint endpoint = camelContext.getEndpoint("smtp://james@mymailserver.com?password=secret");

// create the exchange with the mail message that is multipart with a file and a Hello World text/plain message.
Exchange exchange = endpoint.createExchange();
AttachmentMessage in = exchange.getIn(AttachmentMessage.class);
in.setBody("Sending " + filename + "!");
DefaultAttachment att = new DefaultAttachment(
new ByteArrayDataSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("data/" + filename),
"image/jpeg"));
att.addHeader("Content-Description", "some sample content");
in.addAttachmentObject(filename, att);

// create a producer that can produce the exchange (= send the mail)
Producer producer = endpoint.createProducer();
// start the producer
producer.start();
// and let it go (processes the exchange by sending the email)
producer.process(exchange);

producer.stop();
}

@Path("/sort")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public List<String> sort(List<String> messages) throws Exception {
JavaMailSender sender = new DefaultJavaMailSender();
// inserts new messages
Message[] msgs = new Message[messages.size()];
int i = 0;
for (String msg : messages) {
msgs[i] = new MimeMessage(sender.getSession());
msgs[i].setHeader("Subject", msg);
msgs[i++].setText(msg);
}
MailSorter.sortMessages(msgs, new SortTerm[] {
SortTerm.SUBJECT });

return Stream.of(msgs).map(m -> {
try {
return String.valueOf(m.getContent());
} catch (Exception e) {
return "error";
}
}).collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,45 @@
*/
package org.apache.camel.quarkus.component.mail;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.activation.DataHandler;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.mail.Session;
import javax.mail.Store;

import org.apache.camel.CamelContext;
import org.apache.camel.ExchangePropertyKey;
import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mail.DefaultJavaMailSender;
import org.apache.camel.component.mail.JavaMailSender;
import org.apache.camel.component.mail.MailComponent;
import org.apache.camel.component.mail.MailMessage;
import org.apache.camel.util.CollectionHelper;
import org.jvnet.mock_javamail.Mailbox;

@ApplicationScoped
public class CamelRoute extends RouteBuilder {

@Inject
@Named("mailReceivedMessages")
List<Map<String, Object>> mailReceivedMessages;

@Inject
CamelContext camelContext;

@Override
public void configure() {
public void configure() throws Exception {
bindToRegistry("smtp", smtp());

from("direct:mailtext")
Expand All @@ -41,13 +69,67 @@ public void configure() {
.unmarshal().mimeMultipart()
.marshal().mimeMultipart();

from("pop3://jones@localhost?password=secret&initialDelay=100&delay=100"
+ "&delete=true").id("receiveRoute").autoStartup(false)
.process(e -> mailReceivedMessages
.add(Collections.singletonMap("body", e.getIn().getBody(String.class))));

from("pop3://jones@localhost?password=secret&initialDelay=100&delay=100"
+ "&delete=true&maxMessagesPerPoll=3").id("batchReceiveRoute")
.autoStartup(false)
.process(e -> mailReceivedMessages.add(
CollectionHelper.mapOf("body", e.getIn().getBody(String.class),
ExchangePropertyKey.BATCH_INDEX.getName(),
e.getProperty(ExchangePropertyKey.BATCH_INDEX),
ExchangePropertyKey.BATCH_COMPLETE.getName(),
e.getProperty(ExchangePropertyKey.BATCH_COMPLETE),
ExchangePropertyKey.BATCH_SIZE.getName(),
e.getProperty(ExchangePropertyKey.BATCH_SIZE))));

from("pop3://james@mymailserver.com?password=secret&initialDelay=100&delay=100")
.id("attachmentRoute").autoStartup(false)
.process(e -> {
Map<String, Object> values = new HashMap<>();
values.put("body", e.getIn().getBody(String.class));
for (Map.Entry<String, DataHandler> entry : e.getIn(AttachmentMessage.class).getAttachments().entrySet()) {
values.put(entry.getKey() + "_contentType", e.getIn(AttachmentMessage.class)
.getAttachmentObject(entry.getKey()).getDataHandler().getContentType());
}
mailReceivedMessages.add(values);
});

from("direct:send").to("smtp://localhost?username=james@localhost");

from("pop3://localhost?username=james&password=secret&initialDelay=100&delay=100").id("convertersRoute")
.autoStartup(false)
.process(e -> mailReceivedMessages.add(
CollectionHelper.mapOf("body", e.getIn().getBody(MailMessage.class))));
}

@Produces
MailComponent smtp() {
MailComponent mail = new MailComponent(getContext());
MailComponent mail = new MailComponent(camelContext);
Session session = Session.getInstance(new Properties());
mail.getConfiguration().setSession(session);
return mail;
}

static class Producers {

@Singleton
@Produces
@Named("mailReceivedMessages")
List<Map<String, Object>> mailReceivedMessages() {
return new CopyOnWriteArrayList<>();
}

@Produces
Store prepareMailbox() throws Exception {
// connect to mailbox
Mailbox.clearAll();
JavaMailSender sender = new DefaultJavaMailSender();
Store store = sender.getSession().getStore("pop3");
return store;
}

}
}
17 changes: 17 additions & 0 deletions integration-tests/mail/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## ---------------------------------------------------------------------------
## 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.
## ---------------------------------------------------------------------------
quarkus.native.resources.includes = data/logo.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b8bfb8a

Please sign in to comment.