diff --git a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Addressee.java b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Addressee.java index b4e76c7..7fa705e 100644 --- a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Addressee.java +++ b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Addressee.java @@ -6,13 +6,14 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlValue; +import java.io.Serializable; @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode(of = "email") @XmlAccessorType(XmlAccessType.FIELD) @Getter -public class Addressee { +public class Addressee implements Serializable { @XmlAttribute private @NonNull String email; @XmlValue diff --git a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Attachment.java b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Attachment.java index d383528..21d12ac 100644 --- a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Attachment.java +++ b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/Attachment.java @@ -8,12 +8,13 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlMimeType; +import java.io.Serializable; @Getter @AllArgsConstructor @NoArgsConstructor @XmlAccessorType(XmlAccessType.FIELD) -public class Attachment { +public class Attachment implements Serializable { // http://stackoverflow.com/questions/12250423/jax-ws-datahandler-getname-is-blank-when-called-from-client-side protected String name; diff --git a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/jms/JmsEmail.java b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/jms/JmsEmail.java new file mode 100644 index 0000000..9203553 --- /dev/null +++ b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/jms/JmsEmail.java @@ -0,0 +1,19 @@ +package ru.javaops.masterjava.service.mail.jms; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NonNull; +import ru.javaops.masterjava.service.mail.Addressee; +import java.io.Serializable; +import java.util.Set; + +@AllArgsConstructor +@Getter +public class JmsEmail implements Serializable { + private String subject; + private String body; + private String attachedFileName; + private Byte[] bytes; + @NonNull + Set emailsTo; +} diff --git a/services/mail-service/pom.xml b/services/mail-service/pom.xml index 3b87e07..36d5915 100644 --- a/services/mail-service/pom.xml +++ b/services/mail-service/pom.xml @@ -99,6 +99,17 @@ jersey-bean-validation ${jersey.version} + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey.version} + + + org.jvnet.mimepull + mimepull + + + org.apache.activemq diff --git a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailSender.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailSender.java index 006c4d4..86190f0 100644 --- a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailSender.java +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailSender.java @@ -46,6 +46,10 @@ static String sendToGroup(Set to, Set cc, String subject, email.setHeaders(ImmutableMap.of("List-Unsubscribe", "")); email.send(); + + for (Attachment attach : attachments) { + attach.getDataHandler().getDataSource().getInputStream().close(); + } } catch (Exception e) { log.error(e.getMessage(), e); state = e.getMessage(); diff --git a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/listeners/JmsMailListener.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/listeners/JmsMailListener.java index 50b6190..8bfcc90 100644 --- a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/listeners/JmsMailListener.java +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/listeners/JmsMailListener.java @@ -1,12 +1,19 @@ package ru.javaops.masterjava.service.mail.listeners; +import com.google.common.collect.ImmutableList; import lombok.extern.slf4j.Slf4j; +import org.apache.activemq.ActiveMQConnectionFactory; +import ru.javaops.masterjava.service.mail.MailServiceExecutor; +import ru.javaops.masterjava.service.mail.jms.JmsEmail; +import ru.javaops.masterjava.service.mail.util.Attachments; +import ru.javaops.masterjava.web.WebStateException; import javax.jms.*; import javax.naming.InitialContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; +import java.io.ByteArrayInputStream; @WebListener @Slf4j @@ -23,6 +30,8 @@ public void contextInitialized(ServletContextEvent sce) { connection = connectionFactory.createQueueConnection(); QueueSession queueSession = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue = (Queue) initCtx.lookup("java:comp/env/jms/queue/MailQueue"); + ActiveMQConnectionFactory activeMQConnectionFactory = (ActiveMQConnectionFactory) connectionFactory; + activeMQConnectionFactory.setTrustAllPackages(true); QueueReceiver receiver = queueSession.createReceiver(queue); connection.start(); log.info("Listen JMS messages ..."); @@ -30,12 +39,9 @@ public void contextInitialized(ServletContextEvent sce) { try { while (!Thread.interrupted()) { Message m = receiver.receive(); - // TODO implement mail sending - if (m instanceof TextMessage) { - TextMessage tm = (TextMessage) m; - String text = tm.getText(); - log.info("Received TextMessage with text '{}'", text); - } + ObjectMessage om = (ObjectMessage) m; + JmsEmail jmsEmail = (JmsEmail) om.getObject(); + sendEmail(jmsEmail); } } catch (Exception e) { log.error("Receiving messages failed: " + e.getMessage(), e); @@ -47,6 +53,16 @@ public void contextInitialized(ServletContextEvent sce) { } } + private void sendEmail(JmsEmail jmsEmail) throws WebStateException { + Byte[] jmsBytes = jmsEmail.getBytes(); + byte[] bytes = new byte[jmsBytes.length]; + for (int i = 0; i < jmsBytes.length; i++) { + bytes[i] = jmsBytes[i]; + } + MailServiceExecutor.sendBulk(jmsEmail.getEmailsTo(), jmsEmail.getSubject(), jmsEmail.getBody(), + ImmutableList.of(Attachments.getAttachment(jmsEmail.getAttachedFileName(), new ByteArrayInputStream(bytes)))); + } + @Override public void contextDestroyed(ServletContextEvent sce) { if (connection != null) { diff --git a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRS.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRS.java index 24cea66..dda7093 100644 --- a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRS.java +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRS.java @@ -1,17 +1,25 @@ package ru.javaops.masterjava.service.mail.rest; +import com.google.common.collect.ImmutableList; +import lombok.extern.slf4j.Slf4j; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; import org.hibernate.validator.constraints.NotBlank; import ru.javaops.masterjava.service.mail.GroupResult; import ru.javaops.masterjava.service.mail.MailServiceExecutor; import ru.javaops.masterjava.service.mail.MailWSClient; +import ru.javaops.masterjava.service.mail.util.Attachments; import ru.javaops.masterjava.web.WebStateException; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; +import java.io.*; import java.util.Collections; +import java.util.List; @Path("/") +@Slf4j public class MailRS { @GET @Path("test") @@ -22,11 +30,26 @@ public String test() { @POST @Path("send") + @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) - public GroupResult send(@NotBlank @FormParam("users") String users, - @FormParam("subject") String subject, - @NotBlank @FormParam("body") String body) throws WebStateException { + public GroupResult send(@NotBlank @QueryParam("users") String users, + @QueryParam("subject") String subject, + @NotBlank @QueryParam("body") String body, +// @FormDataParam("attach") InputStream attachInputStream, some problem with input stream + @FormDataParam("attach") File attachedFile, + @FormDataParam("attach") FormDataContentDisposition attachMetaData) throws WebStateException { - return MailServiceExecutor.sendBulk(MailWSClient.split(users), subject, body, Collections.emptyList()); + List attachments = Collections.emptyList(); + + try { + InputStream fileIs = new FileInputStream(attachedFile); + System.out.println(fileIs.available()); + attachments = ImmutableList.of(Attachments.getAttachment(attachMetaData.getFileName(), fileIs)); + } catch (IOException e) { + log.warn("Wrong attached file."); + e.printStackTrace(); + } + + return MailServiceExecutor.sendBulk(MailWSClient.split(users), subject, body, attachments); } } \ No newline at end of file diff --git a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRestConfig.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRestConfig.java index 7f8a6aa..0a1fa5c 100644 --- a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRestConfig.java +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/rest/MailRestConfig.java @@ -1,5 +1,6 @@ package ru.javaops.masterjava.service.mail.rest; +import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; import org.slf4j.bridge.SLF4JBridgeHandler; @@ -13,5 +14,6 @@ public MailRestConfig() { // http://stackoverflow.com/questions/4121722 SLF4JBridgeHandler.install(); packages("ru.javaops.masterjava.service.mail.rest"); + register(MultiPartFeature.class); } } \ No newline at end of file diff --git a/web/webapp/src/main/java/ru/javaops/masterjava/webapp/JmsSendServlet.java b/web/webapp/src/main/java/ru/javaops/masterjava/webapp/JmsSendServlet.java index e926385..301e36c 100644 --- a/web/webapp/src/main/java/ru/javaops/masterjava/webapp/JmsSendServlet.java +++ b/web/webapp/src/main/java/ru/javaops/masterjava/webapp/JmsSendServlet.java @@ -1,20 +1,35 @@ package ru.javaops.masterjava.webapp; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import lombok.extern.slf4j.Slf4j; +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.commons.io.IOUtils; +import ru.javaops.masterjava.service.mail.MailWSClient; +import ru.javaops.masterjava.service.mail.jms.JmsEmail; +import ru.javaops.masterjava.service.mail.util.Attachments; +import ru.javaops.masterjava.web.WsClient; import javax.jms.*; import javax.naming.InitialContext; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +import javax.servlet.http.Part; +import java.io.*; import java.lang.IllegalStateException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; @WebServlet("/sendJms") @Slf4j +@MultipartConfig public class JmsSendServlet extends HttpServlet { private Connection connection; private Session session; @@ -55,7 +70,12 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S String users = req.getParameter("users"); String subject = req.getParameter("subject"); String body = req.getParameter("body"); - result = sendJms(users, subject, body); + Part filePart = req.getPart("attach"); + +// List attachments = filePart == null ? Collections.emptyList() : +// ImmutableList.of(Attachments.getAttachment(filePart.getSubmittedFileName(), filePart.getInputStream())); + + result = sendJms(users, subject, body, filePart); log.info("Processing finished with result: {}", result); } catch (Exception e) { log.error("Processing failed", e); @@ -64,10 +84,27 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S resp.getWriter().write(result); } - private synchronized String sendJms(String users, String subject, String body) throws JMSException { - TextMessage testMessage = session.createTextMessage(); - testMessage.setText(subject); - producer.send(testMessage); + private synchronized String sendJms(String users, String subject, String body, Part attachment) throws JMSException, IOException { + +// TextMessage testMessage = session.createTextMessage(); +// testMessage.setText(subject); + ObjectMessage objectMessage = session.createObjectMessage(); + String fileName = attachment.getSubmittedFileName(); + byte[] byteArray = IOUtils.toByteArray(attachment.getInputStream()); + Byte[] bytes = new Byte[byteArray.length]; + for (int i = 0; i < byteArray.length; i++) { + bytes[i]=byteArray[i]; + } +// File tempFile = File.createTempFile("jms_attach", "tmp"); +// try (OutputStream outputStream = new FileOutputStream(tempFile)) { +// IOUtils.copy(attachment.getInputStream(), outputStream); +// } + + JmsEmail email = new JmsEmail(subject, body, fileName, bytes, MailWSClient.split(users)); +// JmsEmail email = new JmsEmail(subject, body, fileName, tempFile, MailWSClient.split(users)); + objectMessage.setObject(email); + producer.send(objectMessage); +// tempFile.deleteOnExit(); return "Successfully sent JMS message"; } } \ No newline at end of file diff --git a/web/webapp/src/main/webapp/WEB-INF/templates/users.html b/web/webapp/src/main/webapp/WEB-INF/templates/users.html index 0e9f0a0..510dcd8 100644 --- a/web/webapp/src/main/webapp/WEB-INF/templates/users.html +++ b/web/webapp/src/main/webapp/WEB-INF/templates/users.html @@ -71,25 +71,39 @@ } var param; + + var data = new FormData(); + data.append('users', users); + data.append('subject', $("#subject").val()); + data.append('body', $("#body").val()); + var attach = $('#attach')[0].files[0]; + if (attach) data.append('attach', attach); + if (transport === "SOAP") { // https://stackoverflow.com/a/5976031/548473 - var data = new FormData(); - data.append('users', users); - data.append('subject', $("#subject").val()); - data.append('body', $("#body").val()); - var attach = $('#attach')[0].files[0]; - if (attach) data.append('attach', attach); param = { url: "sendSoap", data: data, contentType: false, processData: false }; - } else if (transport === "REST" || transport === "JMS") { + } else if (transport === "REST") { + var attachedData = new FormData(); + var inputData = $('#attach')[0].files[0]; + if (inputData) attachedData.append('attach', inputData); + param = { + url: "/mail/rest/send?"+"users=" + users + "&subject=" + $("#subject").val() + "&body=" + $("#body").val(), + data: attachedData, + cache: false, + contentType: false, + processData : false + }; + } else if (transport === "JMS") { param = { - url: (transport === "REST" ? "/mail/rest/send" : "sendJms"), - data: "users=" + users + "&subject=" + $("#subject").val() + "&body=" + $("#body").val(), - contentType: "application/x-www-form-urlencoded" + url: "sendJms", + data: data, + contentType: false, + processData: false }; }