
org.apache.servicemix.mail.MailSenderEndpoint Maven / Gradle / Ivy
Show all versions of servicemix-mail Show documentation
/*
* 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.servicemix.mail;
import org.apache.servicemix.common.endpoints.ProviderEndpoint;
import org.apache.servicemix.jbi.jaxp.StringSource;
import org.apache.servicemix.mail.marshaler.AbstractMailMarshaler;
import org.apache.servicemix.mail.marshaler.DefaultMailMarshaler;
import org.apache.servicemix.mail.utils.IgnoreList;
import org.apache.servicemix.mail.utils.MailConnectionConfiguration;
import org.apache.servicemix.mail.utils.MailUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jbi.management.DeploymentException;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.NormalizedMessage;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* this is the sending endpoint for the mail component
*
* @org.apache.xbean.XBean element="sender"
* @author lhein
*/
public class MailSenderEndpoint extends ProviderEndpoint implements MailEndpointType {
private final Logger logger = LoggerFactory.getLogger(MailSenderEndpoint.class);
private AbstractMailMarshaler marshaler = new DefaultMailMarshaler();
private MailConnectionConfiguration config;
private String customTrustManagers;
private String connection;
private String sender;
private String receiver;
private boolean debugMode;
private Map customProperties = new HashMap();
private IgnoreList ignoreMessageProperties = new IgnoreList();
/*
* (non-Javadoc)
* @see org.apache.servicemix.common.Endpoint#validate()
*/
public void validate() throws DeploymentException {
super.validate();
if (this.config == null || this.connection == null) {
throw new DeploymentException("No valid connection uri provided.");
}
}
/*
* (non-Javadoc)
* @see
* org.apache.servicemix.common.endpoints.ProviderEndpoint#processInOnly
* (javax.jbi.messaging.MessageExchange,
* javax.jbi.messaging.NormalizedMessage)
*/
@Override
protected void processInOnly(MessageExchange exchange, NormalizedMessage in) throws Exception {
// Exchange is finished
if (exchange.getStatus() == ExchangeStatus.DONE) {
//return;
} else if (exchange.getStatus() == ExchangeStatus.ERROR) {
// Exchange has been aborted with an exception
//return;
} else if (exchange.getFault() != null) {
// Fault message
exchange.setStatus(ExchangeStatus.DONE);
getChannel().send(exchange);
} else {
try {
sendMail(exchange, in);
} catch (MessagingException mex) {
logger.error("Error sending mail...", mex);
throw mex;
} finally {
// delete all temporary allocated resources
this.marshaler.cleanUpResources(exchange.getExchangeId());
}
}
}
/*
* (non-Javadoc)
* @see
* org.apache.servicemix.common.endpoints.ProviderEndpoint#processInOut(
* javax.jbi.messaging.MessageExchange,
* javax.jbi.messaging.NormalizedMessage,
* javax.jbi.messaging.NormalizedMessage)
*/
@Override
protected void processInOut(MessageExchange exchange, NormalizedMessage in, NormalizedMessage out)
throws Exception {
// Exchange is finished
if (exchange.getStatus() == ExchangeStatus.DONE) {
//return;
} else if (exchange.getStatus() == ExchangeStatus.ERROR) {
// Exchange has been aborted with an exception
//return;
} else if (exchange.getFault() != null) {
// Fault message
exchange.setStatus(ExchangeStatus.DONE);
getChannel().send(exchange);
} else {
try {
sendMail(exchange, in);
// quit the exchange
out.setContent(new StringSource(" "));
} catch (MessagingException mex) {
logger.error("Error sending mail...", mex);
throw mex;
} finally {
// delete all temporary allocated resources
this.marshaler.cleanUpResources(exchange.getExchangeId());
}
}
}
private String getUsername(NormalizedMessage in) {
if (in.getProperty(AbstractMailMarshaler.MSG_TAG_USER) != null) {
return (String)in.getProperty(AbstractMailMarshaler.MSG_TAG_USER);
} else {
return config.getUsername();
}
}
private String getPassword(NormalizedMessage in) {
if (in.getProperty(AbstractMailMarshaler.MSG_TAG_PASSWORD) != null) {
return (String)in.getProperty(AbstractMailMarshaler.MSG_TAG_PASSWORD);
} else {
return config.getPassword();
}
}
private String getProtocol(NormalizedMessage in) {
if (in.getProperty(AbstractMailMarshaler.MSG_TAG_PROTOCOL) != null) {
return (String)in.getProperty(AbstractMailMarshaler.MSG_TAG_PROTOCOL);
} else {
return config.getProtocol();
}
}
private String getHost(NormalizedMessage in) {
if (in.getProperty(AbstractMailMarshaler.MSG_TAG_HOST) != null) {
return (String)in.getProperty(AbstractMailMarshaler.MSG_TAG_HOST);
} else {
return config.getHost();
}
}
private int getPort(NormalizedMessage in) {
if (in.getProperty(AbstractMailMarshaler.MSG_TAG_PORT) != null) {
return (Integer)in.getProperty(AbstractMailMarshaler.MSG_TAG_PORT);
} else {
return config.getPort();
}
}
private void sendMail(MessageExchange exchange, NormalizedMessage in) throws Exception {
Session session;
Properties props = MailUtils.getPropertiesForProtocol(this.config, this.customTrustManagers);
props.put("mail.debug", isDebugMode() ? "true" : "false");
String user = getUsername(in);
String passwd = getPassword(in);
String protocol = getProtocol(in);
String host = getHost(in);
int port = getPort(in);
// apply the custom properties
applyCustomProperties(props);
// Get session
session = Session.getInstance(props, config.getAuthenticator(user, passwd));
// debug the session
session.setDebug(this.debugMode);
// get the transport from session
Transport transport = session.getTransport(protocol);
// Connect only once here
// Transport.send() disconnects after each send
// Usually, no username and password is required for SMTP
transport.connect(host, port, user, passwd);
// Define message
MimeMessage msg = new MimeMessage(session);
// handle ignore properties
handleIgnoreProperties(in);
// let the marshaler to the conversion of message to mail
this.marshaler.convertJBIToMail(msg, exchange, in, this.sender, this.receiver);
// Send message
transport.sendMessage(msg, msg.getAllRecipients());
// close transport
transport.close();
}
/**
* handles the normalized messages ignored properties, means it will set every
* property value to null for each key inside the list of properties to ignore
*
* @param in the normalized message
*/
private void handleIgnoreProperties(NormalizedMessage in) {
if (getIgnoreMessageProperties() != null && getIgnoreMessageProperties().size()>0) {
for (String key : getIgnoreMessageProperties()) {
if (in.getProperty(key) != null) {
in.setProperty(key, null);
}
}
}
}
/**
* this will apply the custom properties to the properties map used for
* connection to mail server
*
* @param props the properties to apply to
*/
private void applyCustomProperties(Properties props) {
// allow custom properties
if (customProperties != null) {
props.putAll(customProperties);
}
}
public AbstractMailMarshaler getMarshaler() {
return this.marshaler;
}
/**
* With this method you can specify a marshaler class which provides the
* logic for converting a normalized message into a mail. This class has
* to extend the abstract class AbstractMailMarshaler
or an
* extending class. If you don't specify a marshaler, the
* DefaultMailMarshaler
will be used.
*
* @param marshaler
* a class which extends AbstractMailMarshaler
*/
public void setMarshaler(AbstractMailMarshaler marshaler) {
this.marshaler = marshaler;
}
public String getSender() {
return this.sender;
}
/**
* Specifies the sender address of the mail which is being sent.
* The default value is no-reply@localhost
*
* @param sender
* a String
value containing the sender address
*/
public void setSender(String sender) {
this.sender = sender;
}
public String getConnection() {
return this.connection;
}
/**
* Specifies the connection URI used to connect to a mail server.
*
* Templates:
* <protocol>://<user>@<host>[:<port>][/<folder>]?password=<password>
*
OR
* <protocol>://<host>[:<port>][/<folder>]?user=<user>;password=<password>
*
* Details:
*
*
* Name
* Description
*
*
* protocol
* the protocol to use (example: pop3 or imap)
*
*
* user
* the user name used to log into an account
*
*
* host
* the name or ip address of the mail server
*
*
* port
* the port number to use (optional)
*
*
* folder
* the folder to poll from (optional)
*
*
* password
* the password for the login
*
*
*
* Example:
* smtp://lhein@myserver?password=myPass
* The default value is null
*
* @param connection
* a String
value containing the connection details
*/
public void setConnection(String connection) {
this.connection = connection;
try {
this.config = MailUtils.configure(this.connection);
} catch (ParseException ex) {
logger.error("The configured connection uri is invalid", ex);
}
}
public boolean isDebugMode() {
return this.debugMode;
}
/**
* Specifies if the JavaMail is run in DEBUG
mode. This means
* that while connecting to server and processing mails a detailed log
* is written to debug output.
* This mode is very handy if you are experiencing problems with your
* mail server connection and you want to find out what is going wrong
* in communication with the server.
*
* true - the debug mode is enabled
*
* false - the debug mode is disabled
* The default value is false
*
* @param debugMode
* a boolean
value for debug mode
*/
public void setDebugMode(boolean debugMode) {
this.debugMode = debugMode;
}
public String getCustomTrustManagers() {
return this.customTrustManagers;
}
/**
* Specifies one or more trust manager classes separated by a semicolon (;).
* These classes have to implement the Trustmanager
interface and need to provide
* an empty default constructor to be valid.
* If you want to accept all security certificates without a check you may
* consider using the DummyTrustManager
class. It is actually only
* an empty stub without any checking logic.
But be aware that this will be
* a security risk in production environments.
* The default value is null
*
* @param customTrustManagers
* a String
value containing one or more full class names separated by ; char
*/
public void setCustomTrustManagers(String customTrustManagers) {
this.customTrustManagers = customTrustManagers;
}
public String getReceiver() {
return this.receiver;
}
/**
* Specifies the receiver address(es) of the mail which is being sent.
* The default value is null
*
* @param receiver
* a String
value containing the receiver address(es)
*/
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public Map getCustomProperties() {
return this.customProperties;
}
/**
* Specifies a java.util.Map
which may contain additional
* properties for the connection.
*
Example for disabling TOP for POP3 headers:
* key: "mail.pop3.disabletop"
* value: "true"
* The default value is null
*
* @param customProperties
* a java.util.Map<String, String>
containing connection properties
*/
public void setCustomProperties(Map customProperties) {
this.customProperties = customProperties;
}
public IgnoreList getIgnoreMessageProperties() {
return this.ignoreMessageProperties;
}
/**
* Specifies a java.util.List
which may contain message
* properties to skip.
*
Example for skipping all kind of addresses from the normalized message:
* value: "org.apache.servicemix.mail.to"
* value: "org.apache.servicemix.mail.cc"
* value: "org.apache.servicemix.mail.bcc"
* value: "org.apache.servicemix.mail.from"
* value: "org.apache.servicemix.mail.replyto"
* The default value is null
*
* @param ignoreMessageProperties
* a list containing keys of properties to ignore
* @see org.apache.servicemix.mail.utils.IgnoreList
*/
public void setIgnoreMessageProperties(IgnoreList ignoreMessageProperties) {
this.ignoreMessageProperties = ignoreMessageProperties;
}
}