You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by er...@apache.org on 2011/04/27 13:45:34 UTC
svn commit: r1097086 - in /james/mailet/standard/trunk: ./
src/main/java/org/apache/james/transport/mailets/
Author: eric
Date: Wed Apr 27 11:45:34 2011
New Revision: 1097086
URL: http://svn.apache.org/viewvc?rev=1097086&view=rev
Log:
Add submit emails to URLs contributed by Renen Watermeyer in standard mailets module (MAILET-39)
Added:
james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/ClassifyBounce.java
james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/HeadersToHTTP.java
james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/SerialiseToHTTP.java
Modified:
james/mailet/standard/trunk/pom.xml
Modified: james/mailet/standard/trunk/pom.xml
URL: http://svn.apache.org/viewvc/james/mailet/standard/trunk/pom.xml?rev=1097086&r1=1097085&r2=1097086&view=diff
==============================================================================
--- james/mailet/standard/trunk/pom.xml (original)
+++ james/mailet/standard/trunk/pom.xml Wed Apr 27 11:45:34 2011
@@ -75,6 +75,11 @@
<version>1.4.3</version>
</dependency>
<dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.0.1</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-mailet-base</artifactId>
<version>1.2-SNAPSHOT</version>
Added: james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/ClassifyBounce.java
URL: http://svn.apache.org/viewvc/james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/ClassifyBounce.java?rev=1097086&view=auto
==============================================================================
--- james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/ClassifyBounce.java (added)
+++ james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/ClassifyBounce.java Wed Apr 27 11:45:34 2011
@@ -0,0 +1,315 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.mail.BodyPart;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+
+
+/**
+ * Assesses the message to determine if it was a hard or soft bounce, and if it was a soft bounce, something of its nature..
+ *
+ * Sample configuration:
+ *
+ * <mailet match="All" class="ClassifyBounce">
+ * <headerName>X-MailetHeader</headerName>
+ * </mailet>
+ *
+ */
+public class ClassifyBounce extends GenericMailet {
+
+ /**
+ * The name of the header to be added.
+ */
+ private String headerName;
+
+ /**
+ * Initialize the mailet.
+ */
+ public void init() throws MessagingException {
+ headerName = getInitParameter("headerName");
+
+ // Check if needed config values are used
+ if (headerName == null || headerName.equals("")) {
+ throw new MessagingException("Please configure a header name to contain the classification (if any).");
+ }
+ }
+
+ /**
+ * Takes the message and adds a header to it.
+ *
+ * @param mail the mail being processed
+ *
+ * @throws MessagingException if an error arises during message processing
+ */
+ public void service(Mail mail) {
+ try {
+ MimeMessage message = mail.getMessage () ;
+ Classifier classifier = this.new Classifier(message);
+ String classification = classifier.getClassification();
+ //if ( !classification.equals("Normal") ) {
+ message.setHeader(headerName, classification);
+ message.saveChanges();
+ //}
+ } catch (javax.mail.MessagingException me) {
+ log ("Error classifying message: " + me.getMessage());
+ }
+ }
+
+ /**
+ * Return a string describing this mailet.
+ *
+ * @return a string describing this mailet
+ */
+ public String getMailetInfo() {
+ return "SetMimeHeader Mailet" ;
+ }
+
+ private class Classifier {
+
+ public Classifier(Message message) throws MessagingException {
+ subject = message.getSubject();
+ try {
+ text = getRawText(message.getContent());
+ } catch (IOException e) {
+ throw(new MessagingException("Unable to extract message body. [" + e.getClass().getName() + "] " + e.getMessage()));
+ }
+ }
+
+ public String getClassification() throws MessagingException {
+ String classification = "Normal";
+ switch(assess()) {
+ case TYPE_DELIVERY_FAILURE: classification = "Delivery failure"; break;
+ case TYPE_MAILBOX_FULL: classification = "Mailbox full"; break;
+ case TYPE_OUT_OF_OFFICE: classification = "Out of the office"; break;
+ }
+ return classification;
+ }
+
+ private int assess() throws MessagingException {
+
+ int messageNature = TYPE_NORMAL;
+
+ boolean outOfOffice = false;
+ boolean mailBoxFull = false;
+ boolean failure = false;
+
+ outOfOffice = assessMessageSubjectOutOfOffice();
+ if (!outOfOffice) { mailBoxFull = assessMessageSubjectMailboxFull(); }
+ if ((!outOfOffice) && (!mailBoxFull)) { failure = assessMessageSubjectFailure(); }
+ if (!(outOfOffice || mailBoxFull || failure)) {
+ if (assessMessageUnreadable()) {
+ //get quite a few of these
+ failure = true;
+ } else {
+ outOfOffice = assessMessageOutOfOffice();
+ if (!mailBoxFull) { mailBoxFull = assessMessageMailboxFull(); }
+ if ((!outOfOffice) && (!mailBoxFull)) { failure = assessMessageFailure(); }
+ }
+ }
+
+ if (failure) { messageNature = TYPE_DELIVERY_FAILURE; }
+ if (mailBoxFull) { messageNature = TYPE_MAILBOX_FULL; }
+ if (outOfOffice) { messageNature = TYPE_OUT_OF_OFFICE; }
+
+ return messageNature;
+ }
+
+ private String getRawText(Object o) throws MessagingException, IOException {
+
+ String s = null;
+
+ if (o instanceof Multipart){
+ Multipart multi = (Multipart)o;
+ for(int i=0; i < multi.getCount(); i++) {
+ s = getRawText(multi.getBodyPart(i));
+ if (s!=null) {
+ if (s.length()>0) {
+ break;
+ }
+ }
+ }
+ } else if (o instanceof BodyPart) {
+ BodyPart aBodyContent = (BodyPart)o;
+ StringTokenizer aTypeTokenizer = new StringTokenizer(aBodyContent.getContentType(), "/");
+ String abstractType = aTypeTokenizer.nextToken();
+ if(abstractType.compareToIgnoreCase("MESSAGE")==0) {
+ Message inlineMessage = (Message)aBodyContent.getContent();
+ s = getRawText(inlineMessage.getContent());
+ }
+ if (abstractType.compareToIgnoreCase("APPLICATION")==0) {
+ s = "Attached File: " + aBodyContent.getFileName();
+ }
+ if (abstractType.compareToIgnoreCase("TEXT")==0) {
+ try {
+ Object oS = aBodyContent.getContent();
+ if (oS instanceof String) {
+ s = (String)oS;
+ } else {
+ throw( new MessagingException("Unkown MIME Type (?): " + oS.getClass() ) );
+ }
+ } catch(Exception e) {
+ throw( new MessagingException("Unable to read message contents (" + e.getMessage() + ")" ) );
+ }
+ }
+ if (abstractType.compareToIgnoreCase("MULTIPART")==0 ) {
+ s = getRawText(aBodyContent.getContent());
+ }
+ }
+
+ if (o instanceof String) {
+ s = (String)o;
+ }
+
+// else {
+// if (m.isMimeType("text/html")) {
+// s = m.getContent().toString();
+// }
+// if (m.isMimeType("text/plain")) {
+// s = m.getContent().toString();
+// }
+// }
+
+ return s;
+ }
+
+ private boolean assessMessageUnreadable() throws MessagingException {
+ boolean evil = false;
+ if (subject.compareToIgnoreCase("Delivery Status Notification (Failure)")==0) {
+ evil = findInBody("Unable to read message contents");
+ }
+ return evil;
+ }
+
+ private boolean assessMessageFailure() {
+ boolean failed = false;
+ if (!failed) { failed = findInBody("User[\\s]+unknown"); }
+ if (!failed) { failed = findInBody("No[\\s]+such[\\s]+user"); }
+ if (!failed) { failed = findInBody("550[\\s]+Invalid[\\s]+recipient"); }
+ if (!failed) { failed = findInBody("550[\\s]+Bogus[\\s]+Address"); }
+ if (!failed) { failed = findInBody("addresses[\\s]+were[\\s]+unknown"); }
+ if (!failed) { failed = findInBody("user[\\s]+is[\\s]+no[\\s]+longer[\\s]+associated[\\s]+with[\\s]+this[\\s]+company"); }
+ if (!failed) { failed = findInBody("Unknown[\\s]+Recipient"); }
+ if (!failed) { failed = findInBody("destination[\\s]+addresses[\\s]+were[\\s]+unknown"); }
+ if (!failed) { failed = findInBody("unknown[\\s]+user"); }
+ if (!failed) { failed = findInBody("recipient[\\s]+name[\\s]+is[\\s]+not[\\s]+recognized"); }
+ if (!failed) { failed = findInBody("not[\\s]+listed[\\s]+in[\\s]+Domino[\\s]+Directory"); }
+ if (!failed) { failed = findInBody("Delivery[\\s]+Status[\\s]+Notification[\\s]+\\Q(\\EFailure\\Q)\\E"); }
+ if (!failed) { failed = findInBody("This[\\s]+is[\\s]+a[\\s]+permanent[\\s]+error"); }
+ if (!failed) { failed = findInBody("This[\\s]+account[\\s]+has[\\s]+been[\\s]+closed"); }
+ if (!failed) { failed = findInBody("addresses[\\s]+had[\\s]+permanent[\\s]+fatal[\\s]+errors"); }
+ return failed;
+ }
+
+ private boolean assessMessageMailboxFull() {
+ boolean full = false;
+ if (!full) { full = findInBody("Connection[\\s]+timed[\\s]+out"); }
+ if (!full) { full = findInBody("Over[\\s]+quota"); }
+ if (!full) { full = findInBody("size[\\s]+limit"); }
+ if (!full) { full = findInBody("account[\\s]+is[\\s]+full"); }
+ if (!full) { full = findInBody("diskspace[\\s]+quota"); }
+ if (!full) { full = findInBody("rejected[\\s]+for[\\s]+policy[\\s]+reasons"); }
+ if (!full) { full = findInBody("mailbox[\\s]+size[\\s]+limit"); }
+ return full;
+ }
+
+ private boolean assessMessageOutOfOffice() {
+ boolean out = false;
+ //if ( subject.toLowerCase().startsWith("re:") ) {
+ if (!out) { out = findInBody("out[\\s]+of[\\s]+the[\\s]+office"); }
+ if (!out) { out = findInBody("out[\\s]+of[\\s]+my[\\s]+office"); }
+ if (!out) { out = findInBody("back[\\s]+in[\\s]+the[\\s]+office"); }
+ if (!out) { out = findInBody("I[\\s]+am[\\s]+overseas"); }
+ if (!out) { out = findInBody("I[\\s]+am[\\s]+away"); }
+ if (!out) { out = findInBody("I[\\s]+am[\\s]+on[\\s]+leave"); }
+ if (!out) { out = (findInBody("Auto[\\s]*generated") && findInBody("on[\\s]+leave")); }
+ //}
+ return out;
+ }
+
+ private boolean assessMessageSubjectOutOfOffice() {
+ boolean out = false;
+ if (!out) { out = findInSubject("Out[\\s]+of[\\s]+office"); }
+ if (!out) { out = findInSubject("Out[\\s]+of[\\s]+my[\\s]+office"); }
+ if (!out) { out = findInSubject("out[\\s]+of[\\s]+the[\\s]+office"); }
+ if (!out) { out = findInSubject("away[\\s]+from[\\s]+my[\\s]+mail"); }
+ if (!out) { out = findInSubject("on[\\s]+leave"); }
+ return out;
+ }
+
+ private boolean assessMessageSubjectMailboxFull() {
+ boolean full = false;
+ if (!full) { full = ((findInSubject("Email[\\s]+message[\\s]+blocked") && findInSubject("Image[\\s]+File[\\s]+Type"))); }
+ return full;
+ }
+
+ private boolean assessMessageSubjectFailure() {
+ boolean failed = false;
+ if (!failed) { failed = ((findInSubject("DELIVERY[\\s]+FAILURE") && findInSubject("does[\\s]+not[\\s]+exist"))); }
+ if (!failed) { failed = ((findInSubject("DELIVERY[\\s]+FAILURE") && findInSubject("not[\\s]+listed"))); }
+ if (!failed) { failed = findInSubject("Permanent[\\s]+Delivery[\\s]+Failure"); }
+ if (!failed) { failed = findInSubject("User[\\s]+unknown"); }
+ if (!failed) { //no idea...
+ String s = subject.toLowerCase();
+ failed = ( s.indexOf("user") > 0 && ( s.indexOf("unknown") > s.indexOf("user") ) );
+ }
+ return failed;
+ }
+
+ private boolean findInBody(String regExp) {
+ boolean retval = false;
+ if (text!=null) {
+ Pattern pat = Pattern.compile(regExp, Pattern.CASE_INSENSITIVE);
+ Matcher m = pat.matcher(text);
+ retval = m.find();
+ }
+ return retval;
+ }
+
+ private boolean findInSubject(String regExp) {
+ Pattern pat = Pattern.compile(regExp, Pattern.CASE_INSENSITIVE);
+ Matcher m = pat.matcher(subject);
+ return m.find();
+ }
+
+ private String subject;
+ private String text;
+
+ public final static int TYPE_NORMAL = 1;
+ public final static int TYPE_SPAM = 2; // should be trapped elsewhere
+ public final static int TYPE_OUT_OF_OFFICE = 3;
+ public final static int TYPE_DELIVERY_FAILURE = 4;
+ public final static int TYPE_MAILBOX_FULL = 5;
+ public final static int TYPE_OUTBOUND = 6;
+
+ }
+
+}
+
Added: james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/HeadersToHTTP.java
URL: http://svn.apache.org/viewvc/james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/HeadersToHTTP.java?rev=1097086&view=auto
==============================================================================
--- james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/HeadersToHTTP.java (added)
+++ james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/HeadersToHTTP.java Wed Apr 27 11:45:34 2011
@@ -0,0 +1,200 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashSet;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+
+/**
+ * Serialise the email and pass it to an HTTP call
+ *
+ * Sample configuration:
+ *
+ <mailet match="All" class="HeadersToHTTP">
+ <url>http://192.168.0.252:3000/alarm</url>
+ <parameterKey>Test</parameterKey>
+ <parameterValue>ParameterValue</parameterValue>
+ <passThrough>true</passThrough>
+ </mailet>
+
+ *
+ */
+public class HeadersToHTTP extends GenericMailet {
+
+ /**
+ * The name of the header to be added.
+ */
+ private String url;
+ private String parameterKey = null;
+ private String parameterValue = null;
+ private boolean passThrough = true;
+
+ /**
+ * Initialize the mailet.
+ */
+ public void init() throws MessagingException {
+
+ passThrough = (getInitParameter("passThrough", "true").compareToIgnoreCase("true") == 0);
+ String targetUrl = getInitParameter("url");
+ parameterKey = getInitParameter("parameterKey");
+ parameterValue = getInitParameter("parameterValue");
+
+ // Check if needed config values are used
+ if (targetUrl == null || targetUrl.equals("")) {
+ throw new MessagingException("Please configure a targetUrl (\"url\")");
+ } else {
+ try {
+ // targetUrl = targetUrl + ( targetUrl.contains("?") ? "&" :
+ // "?") + parameterKey + "=" + parameterValue;
+ url = new URL(targetUrl).toExternalForm();
+ } catch (MalformedURLException e) {
+ throw new MessagingException(
+ "Unable to contruct URL object from url");
+ }
+ }
+
+ // record the result
+ log("I will attempt to deliver serialised messages to "
+ + targetUrl
+ + ". "
+ + ( ((parameterKey==null) || (parameterKey.length()<1)) ? "I will not add any fields to the post. " : "I will prepend: " + parameterKey + "=" + parameterValue + ". ")
+ + (passThrough ? "Messages will pass through." : "Messages will be ghosted."));
+ }
+
+ /**
+ * Takes the message, serialises it and sends it to the URL
+ *
+ * @param mail
+ * the mail being processed
+ *
+ * @throws MessagingException
+ * if an error arises during message processing
+ */
+ public void service(Mail mail) {
+ try {
+ log(mail.getName() + "HeadersToHTTP: Starting");
+ MimeMessage message = mail.getMessage();
+ HashSet<NameValuePair> pairs = getNameValuePairs(message);
+ log(mail.getName() + "HeadersToHTTP: " + pairs.size() + " named value pairs found");
+ String result = httpPost(pairs);
+ if (passThrough == true) {
+ addHeader(mail, true, result);
+ } else {
+ mail.setState(Mail.GHOST);
+ }
+ } catch (javax.mail.MessagingException me) {
+ log(me.getMessage());
+ addHeader(mail, false, me.getMessage());
+ } catch (IOException e) {
+ log(e.getMessage());
+ addHeader(mail, false, e.getMessage());
+ }
+ }
+
+ private void addHeader(Mail mail, boolean success, String errorMessage) {
+ try {
+ MimeMessage message = mail.getMessage();
+ message.setHeader("X-headerToHTTP", (success ? "Succeeded" : "Failed"));
+ if (!success && errorMessage!=null && errorMessage.length()>0) {
+ message.setHeader("X-headerToHTTPFailure", errorMessage);
+ }
+ message.saveChanges();
+ } catch (MessagingException e) {
+ log(e.getMessage());
+ }
+ }
+
+ private String httpPost(HashSet<NameValuePair> pairs) throws HttpException, IOException {
+
+ HttpClient client = new HttpClient();
+ PostMethod post = new PostMethod(url);
+
+ post.setRequestBody(setToArray(pairs));
+
+ int statusCode = client.executeMethod(post);
+ String result = statusCode + ": " + post.getStatusLine().toString();
+ log("HeadersToHTTP: " + result);
+
+ return result;
+
+ }
+
+ private NameValuePair[] setToArray(HashSet<NameValuePair> pairs) {
+ NameValuePair[] r = new NameValuePair[pairs.size()];
+ int i = 0;
+ for(NameValuePair p : pairs) {
+ r[i] = p;
+ i = i + 1;
+ }
+ return r;
+ }
+
+ private HashSet<NameValuePair> getNameValuePairs(MimeMessage message) throws UnsupportedEncodingException, MessagingException {
+
+ // to_address
+ // from
+ // reply to
+ // subject
+
+ HashSet<NameValuePair> pairs = new HashSet<NameValuePair>();
+
+ if (message!=null) {
+ if (message.getSender()!=null) {
+ pairs.add( new NameValuePair( "from", message.getSender().toString() ) );
+ }
+ if (message.getReplyTo()!=null) {
+ pairs.add( new NameValuePair( "reply_to", message.getReplyTo().toString() ) );
+ }
+ if (message.getMessageID()!=null) {
+ pairs.add( new NameValuePair( "message_id", message.getMessageID() ) );
+ }
+ if (message.getSubject()!=null) {
+ pairs.add( new NameValuePair( "subject", message.getSubject() ) );
+ }
+ pairs.add( new NameValuePair( "size", Integer.toString(message.getSize()) ) );
+ }
+
+ pairs.add( new NameValuePair( parameterKey, parameterValue) );
+
+ return pairs;
+ }
+
+ /**
+ * Return a string describing this mailet.
+ *
+ * @return a string describing this mailet
+ */
+ public String getMailetInfo() {
+ return "HTTP POST serialised message";
+ }
+
+}
Added: james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/SerialiseToHTTP.java
URL: http://svn.apache.org/viewvc/james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/SerialiseToHTTP.java?rev=1097086&view=auto
==============================================================================
--- james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/SerialiseToHTTP.java (added)
+++ james/mailet/standard/trunk/src/main/java/org/apache/james/transport/mailets/SerialiseToHTTP.java Wed Apr 27 11:45:34 2011
@@ -0,0 +1,213 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.PostMethod;
+
+import org.apache.mailet.base.GenericMailet;
+import org.apache.mailet.Mail;
+
+/**
+ * Serialise the email and pass it to an HTTP call
+ *
+ * Sample configuration:
+ *
+ * <mailet match="All" class="SerialiseToHTTP">
+ * <name>URL</name> <value>url where serialised message will be posted</value>
+ * <name>ParameterKey</name> <value>An arbitrary parameter be added to the post</value>
+ * <name>ParameterValue</name> <value>A value for the arbitrary parameter</value>
+ * <name>MessageKeyName</name> <value>Field name for the serialised message</value>
+ * <name>passThrough</name> <value>true or false</value>
+ * </mailet>
+ *
+ */
+public class SerialiseToHTTP extends GenericMailet {
+
+ /**
+ * The name of the header to be added.
+ */
+ private String url;
+ private String parameterKey = null;
+ private String parameterValue = null;
+ private String messageKeyName = "message";
+ private boolean passThrough = true;
+
+ /**
+ * Initialize the mailet.
+ */
+ public void init() throws MessagingException {
+
+ passThrough = (getInitParameter("passThrough", "true").compareToIgnoreCase("true") == 0);
+ String targetUrl = getInitParameter("url");
+ parameterKey = getInitParameter("parameterKey");
+ parameterValue = getInitParameter("parameterValue");
+ String m = getInitParameter("MessageKeyName");
+ if (m != null) {
+ messageKeyName = m;
+ }
+
+ // Check if needed config values are used
+ if (targetUrl == null || targetUrl.equals("")) {
+ throw new MessagingException(
+ "Please configure a targetUrl (\"url\")");
+ } else {
+ try {
+ // targetUrl = targetUrl + ( targetUrl.contains("?") ? "&" :
+ // "?") + parameterKey + "=" + parameterValue;
+ url = new URL(targetUrl).toExternalForm();
+ } catch (MalformedURLException e) {
+ throw new MessagingException(
+ "Unable to contruct URL object from url");
+ }
+ }
+
+ // record the result
+ log("I will attempt to deliver serialised messages to "
+ + targetUrl
+ + " as "
+ + messageKeyName
+ + ". "
+ + (parameterKey==null || parameterKey.length()<2 ? "I will not add any fields to the post. " : "I will prepend: " + parameterKey + "=" + parameterValue + ". ")
+ + (passThrough ? "Messages will pass through."
+ : "Messages will be ghosted."));
+ }
+
+ /**
+ * Takes the message, serialises it and sends it to the URL
+ *
+ * @param mail
+ * the mail being processed
+ *
+ * @throws MessagingException
+ * if an error arises during message processing
+ */
+ public void service(Mail mail) {
+ try {
+ MimeMessage message = mail.getMessage();
+ String serialisedMessage = getSerialisedMessage(message);
+ NameValuePair[] nameValuePairs = getNameValuePairs(serialisedMessage);
+ String result = httpPost(nameValuePairs);
+ if (passThrough == true) {
+ addHeader(mail, (result == null || result.length() == 0), result);
+ } else {
+ mail.setState(Mail.GHOST);
+ }
+ } catch (javax.mail.MessagingException me) {
+ log(me.getMessage());
+ addHeader(mail, false, me.getMessage());
+ } catch (IOException e) {
+ log(e.getMessage());
+ addHeader(mail, false, e.getMessage());
+ }
+ }
+
+ private void addHeader(Mail mail, boolean success, String errorMessage) {
+ try {
+ MimeMessage message = mail.getMessage();
+ message.setHeader("X-toHTTP", (success ? "Succeeded" : "Failed"));
+ if (!success && errorMessage!=null && errorMessage.length()>0) {
+ message.setHeader("X-toHTTPFailure", errorMessage);
+ }
+ message.saveChanges();
+ } catch (MessagingException e) {
+ log(e.getMessage());
+ }
+ }
+
+ private String getSerialisedMessage(MimeMessage message)
+ throws IOException, MessagingException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ message.writeTo(os);
+ return os.toString();
+ }
+
+ private String httpPost(NameValuePair[] data) {
+
+ String response = null;
+ HttpClient client = new HttpClient();
+ PostMethod post = new PostMethod(url);
+
+ if( data.length>1 && data[1]!=null ) {
+ log( data[1].getName() + "::" + data[1].getValue() );
+ }
+ post.setRequestBody(data);
+
+ try {
+ int statusCode = client.executeMethod(post);
+
+ if (statusCode != HttpStatus.SC_OK) {
+ log("POST failed: " + post.getStatusLine());
+ response = post.getStatusLine().toString();
+ }// else {
+ // byte[] responseBody = post.getResponseBody();
+ // response = new String(responseBody);
+ //}
+
+ } catch (HttpException e) {
+ log("Fatal protocol violation: " + e.getMessage());
+ response = "Fatal protocol violation: " + e.getMessage();
+ } catch (IOException e) {
+ log("Fatal transport error: " + e.getMessage());
+ response = "Fatal transport error: " + e.getMessage();
+ } finally {
+ post.releaseConnection();
+ }
+
+ return response;
+ }
+
+ private NameValuePair[] getNameValuePairs(String message) throws UnsupportedEncodingException {
+
+ int l = 1;
+ if (parameterKey!=null && parameterKey.length()>0) {
+ l = 2;
+ }
+
+ NameValuePair[] data = new NameValuePair[l];
+ data[0] = new NameValuePair( messageKeyName, message);
+ if (l==2) {
+ data[1] = new NameValuePair( parameterKey, parameterValue);
+ }
+
+ return data;
+ }
+
+ /**
+ * Return a string describing this mailet.
+ *
+ * @return a string describing this mailet
+ */
+ public String getMailetInfo() {
+ return "HTTP POST serialised message";
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org