diff --git a/build.gradle b/build.gradle index 5e778b006..31da959e1 100644 --- a/build.gradle +++ b/build.gradle @@ -131,7 +131,7 @@ ext { equalsverifierVersion = '1.1.3' ftpServerVersion = '1.0.6' apacheSshdVersion = '0.10.1' - greenmailVersion = '1.3.1b' + greenmailVersion = '1.4.1' httpClientVersion = '4.2.5' jcloudsVersion = '1.7.0' oracleToolsVersion = '1.2.2' diff --git a/extensions/spring-xd-extension-mail/src/main/java/org/springframework/xd/mail/MailSinkOptionsMetadata.java b/extensions/spring-xd-extension-mail/src/main/java/org/springframework/xd/mail/MailSinkOptionsMetadata.java index 2228e9131..fef25b8ed 100644 --- a/extensions/spring-xd-extension-mail/src/main/java/org/springframework/xd/mail/MailSinkOptionsMetadata.java +++ b/extensions/spring-xd-extension-mail/src/main/java/org/springframework/xd/mail/MailSinkOptionsMetadata.java @@ -20,15 +20,19 @@ import org.springframework.xd.module.options.spi.Mixin; import org.springframework.xd.module.options.spi.ModuleOption; - +import org.springframework.xd.module.options.spi.ProfileNamesProvider; /** * Captures options for the {@code mail} sink module. * * @author Eric Bottard + * @author Franck Marchand */ @Mixin(MailServerMixin.class) -public class MailSinkOptionsMetadata { +public class MailSinkOptionsMetadata implements ProfileNamesProvider { + + public static final String WITH_ATTACHMENT = "with-attachment"; + public static final String WITHOUT_ATTACHMENT = "without-attachment"; private String bcc = "null"; @@ -44,6 +48,61 @@ public class MailSinkOptionsMetadata { private String to = "null"; + private boolean auth = false; + + private boolean starttls = false; + + private boolean ssl = false; + + private String attachmentExpression; + + private String attachmentFilename; + + public String getAttachmentExpression() { + return attachmentExpression; + } + + @ModuleOption("file uri to attach to the mail") + public void setAttachmentExpression(String attachmentExpression) { + this.attachmentExpression = attachmentExpression; + } + + public String getAttachmentFilename() { + return attachmentFilename; + } + + @ModuleOption("name of the attachment that will appear in the mail") + public void setAttachmentFilename(String attachmentFilename) { + this.attachmentFilename = attachmentFilename; + } + + public boolean isAuth() { + return auth; + } + + @ModuleOption("enable authentication for mail sending connection") + public void setAuth(boolean auth) { + this.auth = auth; + } + + public boolean isSsl() { + return ssl; + } + + @ModuleOption("enable ssl for mail sending connection") + public void setSsl(boolean ssl) { + this.ssl = ssl; + } + + public boolean isStarttls() { + return starttls; + } + + @ModuleOption("enable ttl for mail sending connection") + public void setStarttls(boolean starttls) { + this.starttls = starttls; + } + // @NotNull as a String, but the contents can be the String // "null", which is a SpEL expression in its own right. @NotNull @@ -71,7 +130,6 @@ public String getReplyTo() { return replyTo; } - @NotNull public String getSubject() { return subject; @@ -117,5 +175,10 @@ public void setTo(String to) { this.to = to; } + @Override + public String[] profilesToActivate() { + return new String[] { (attachmentExpression != null && attachmentFilename != null) ? WITH_ATTACHMENT : WITHOUT_ATTACHMENT }; + } + } diff --git a/extensions/spring-xd-extension-mail/src/main/java/org/springframework/xd/mail/MailTransformer.java b/extensions/spring-xd-extension-mail/src/main/java/org/springframework/xd/mail/MailTransformer.java new file mode 100644 index 000000000..0d9033e3b --- /dev/null +++ b/extensions/spring-xd-extension-mail/src/main/java/org/springframework/xd/mail/MailTransformer.java @@ -0,0 +1,103 @@ +/* + * Copyright 2013-2014 the original author or authors. + * + * Licensed 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.springframework.xd.mail; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.integration.mail.MailHeaders; +import org.springframework.mail.MailException; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.mail.javamail.MimeMessagePreparator; +import org.springframework.messaging.Message; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.nio.file.Paths; + +/** + * This transformer can handle ssl, tls and attachments for + * the mail sink. + * + * @author Franck Marchand + */ +public class MailTransformer { + public static final String MAIL_ATTACHMENT = "mail_attachment"; + + @Autowired + private JavaMailSenderImpl sender; + + public Message sendMail(final Message msg) { + + MimeMessage mimeMsg = sender.createMimeMessage(); + + String subject = (String) msg.getHeaders().get(MailHeaders.SUBJECT); + final String validSubject = subject!=null ? subject : ""; + final String to = (String) msg.getHeaders().get(MailHeaders.TO); + final String cc = (String) msg.getHeaders().get(MailHeaders.CC); + final String bcc = (String) msg.getHeaders().get(MailHeaders.BCC); + final String from = (String) msg.getHeaders().get(MailHeaders.FROM); + final String replyTo = (String) msg.getHeaders().get(MailHeaders.REPLY_TO); + final String attachmentFilename = (String) msg.getHeaders().get(MailHeaders.ATTACHMENT_FILENAME); + final String attachment = (String) msg.getHeaders().get(MAIL_ATTACHMENT); + + try { + sender.send(new MimeMessagePreparator() { + @Override + public void prepare(MimeMessage mimeMessage) throws Exception { + MimeMessageHelper mMsg = new MimeMessageHelper(mimeMessage, true); + + mMsg.setTo(to); + mMsg.setFrom(from); + mMsg.setReplyTo(replyTo); + mMsg.setSubject(validSubject); + + if (bcc != null) + mMsg.setBcc(bcc); + if (cc != null) + mMsg.setCc(cc); + + mMsg.setText(msg.getPayload()); + + if (attachment != null && attachmentFilename != null) { + String[] attachments; + if(attachment.contains(";")) + attachments = StringUtils.split(attachment, ";"); + else attachments = new String[] { attachment }; + + String[] attachmentFilenames; + if(attachmentFilename.contains(";")) + attachmentFilenames = StringUtils.split(attachmentFilename, ";"); + else attachmentFilenames = new String[] { attachmentFilename }; + + for(int i=0; i + + + + + + + + + + + + + + + + ${auth} + ${ssl} + ${starttls} + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle/build-extensions.gradle b/gradle/build-extensions.gradle index c932b86ad..4e25718f5 100644 --- a/gradle/build-extensions.gradle +++ b/gradle/build-extensions.gradle @@ -6,7 +6,11 @@ project('spring-xd-extension-mail') { description = 'Spring XD Mail' dependencies { compile "org.springframework.integration:spring-integration-mail" + compile "com.sun.mail:javax.mail" compile project(":spring-xd-module-spi") + compile project(":spring-xd-dirt") + testCompile project(":spring-xd-test") + testCompile "com.icegreen:greenmail:$greenmailVersion" } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 0087cd3b1..2322723c7 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 485265bf2..0f07cfa55 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -#Wed May 13 10:44:31 CEST 2015 +#Tue Nov 10 21:53:09 CET 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/modules/sink/mail/config/mail.xml b/modules/sink/mail/config/mail.xml index b09ec86f8..2cc4fdbfc 100644 --- a/modules/sink/mail/config/mail.xml +++ b/modules/sink/mail/config/mail.xml @@ -1,32 +1,63 @@ + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - + + + - - - - - - - - - + - + + + + + + + + ${auth} + ${ssl} + ${starttls} + + + - + + + + + + + + + + + + +
+ - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-xd-starters/spring-xd-module-parent/publish-maven.gradle b/spring-xd-starters/spring-xd-module-parent/publish-maven.gradle index 6dea47fe7..d3802f570 100644 --- a/spring-xd-starters/spring-xd-module-parent/publish-maven.gradle +++ b/spring-xd-starters/spring-xd-module-parent/publish-maven.gradle @@ -28,7 +28,7 @@ def getAllDependentProjects(project) { // load versions def versions = new Properties() -def propertiesFile = new File('dependencies.properties') +def propertiesFile = new File("${project.rootDir}/dependencies.properties") propertiesFile.withInputStream { versions.load(it) } diff --git a/spring-xd-test-fixtures/src/main/java/org/springframework/xd/test/fixtures/MailSink.java b/spring-xd-test-fixtures/src/main/java/org/springframework/xd/test/fixtures/MailSink.java index 4ec2c8ad5..6d47eadbf 100644 --- a/spring-xd-test-fixtures/src/main/java/org/springframework/xd/test/fixtures/MailSink.java +++ b/spring-xd-test-fixtures/src/main/java/org/springframework/xd/test/fixtures/MailSink.java @@ -16,11 +16,10 @@ package org.springframework.xd.test.fixtures; -import javax.mail.internet.MimeMessage; - +import com.icegreen.greenmail.util.ServerSetup; import org.springframework.xd.test.fixtures.util.AvailableSocketPorts; -import com.icegreen.greenmail.util.ServerSetup; +import javax.mail.internet.MimeMessage; /** @@ -72,16 +71,9 @@ public MailSink from(String expression) { public MimeMessage waitForEmail() { ensureStarted(); - try { if (!greenMail.waitForIncomingEmail(1)) { throw new IllegalStateException("No email received"); } return greenMail.getReceivedMessages()[0]; - } - catch (InterruptedException e) { - throw new IllegalStateException("Interrupted while waiting for an email"); - } } - - } diff --git a/src/docs/asciidoc/Sinks.asciidoc b/src/docs/asciidoc/Sinks.asciidoc index a115edede..4a0e38851 100644 --- a/src/docs/asciidoc/Sinks.asciidoc +++ b/src/docs/asciidoc/Sinks.asciidoc @@ -1186,6 +1186,9 @@ You would then receive an email whose body contains "Hello" and whose subject is // THIS SNIPPET HAS BEEN GENERATED BY ModuleOptionsReferenceDoc AND MANUAL EDITS WILL BE LOST The **$$mail$$** $$sink$$ has the following options: +$$attachmentExpression$$:: $$file uri to attach to the mail$$ *($$String$$, no default)* +$$attachmentFilename$$:: $$name of the attachment that will appear in the mail$$ *($$String$$, no default)* +$$auth$$:: $$enable authentication for mail sending connection$$ *($$boolean$$, default: `false`)* $$bcc$$:: $$the recipient(s) that should receive a blind carbon copy (SpEL)$$ *($$String$$, default: `null`)* $$cc$$:: $$the recipient(s) that should receive a carbon copy (SpEL)$$ *($$String$$, default: `null`)* $$contentType$$:: $$the content type to use when sending the email (SpEL)$$ *($$String$$, default: `null`)* @@ -1194,6 +1197,8 @@ $$host$$:: $$the hostname of the mail server$$ *($$String$$, default: `localhost $$password$$:: $$the password to use to connect to the mail server $$ *($$String$$, no default)* $$port$$:: $$the port of the mail server$$ *($$int$$, default: `25`)* $$replyTo$$:: $$the address that will become the recipient if the original recipient decides to "reply to" the email (SpEL)$$ *($$String$$, default: `null`)* +$$ssl$$:: $$enable ssl for mail sending connection$$ *($$boolean$$, default: `false`)* +$$starttls$$:: $$enable ttl for mail sending connection$$ *($$boolean$$, default: `false`)* $$subject$$:: $$the email subject (SpEL)$$ *($$String$$, default: `null`)* $$to$$:: $$the primary recipient(s) of the email (SpEL)$$ *($$String$$, default: `null`)* $$username$$:: $$the username to use to connect to the mail server$$ *($$String$$, no default)*