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 ba...@apache.org on 2008/06/24 12:34:17 UTC
svn commit: r671119 [2/2] - in
/james/server/trunk/mailets-function/src/test/java/org: ./ apache/
apache/james/ apache/james/transport/ apache/james/transport/mailets/
apache/james/transport/remotedeliverytester/
Added: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/Tester.java
URL: http://svn.apache.org/viewvc/james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/Tester.java?rev=671119&view=auto
==============================================================================
--- james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/Tester.java (added)
+++ james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/Tester.java Tue Jun 24 03:34:16 2008
@@ -0,0 +1,659 @@
+/****************************************************************
+ * 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.remotedeliverytester;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.james.core.MailImpl;
+import org.apache.james.dnsserver.TemporaryResolutionException;
+import org.apache.james.services.DNSServer;
+import org.apache.mailet.HostAddress;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+
+import javax.mail.Address;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.NoSuchProviderException;
+import javax.mail.Provider;
+import javax.mail.SendFailedException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.URLName;
+import javax.mail.Provider.Type;
+import javax.mail.internet.MimeMessage;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Vector;
+
+/**
+ * Email lifecycle
+ * - in mailet.service it is accepted and sent to outgoing spool (an outgoing.store for each recipient).
+ * - another thread pool, in mailtet.run it is accepted from the outgoing spool and sent to the "deliver" method.
+ * - "deliver" calls transport.connect and transport.sendMessage from javaMail
+ * - on delivery error a call to "failMessage" is done. failMessage will call mailetContext.sendMail or mailetContext.bounce to send a delivery failure receipt.
+ * - Back to "run" results in outgoing.remove (permanent result) or outgoing.store (temporary failure)
+ */
+public class Tester {
+ private RemoteDeliveryTestable remoteDelivery;
+ private TesterMailetConfig mailetConfig;
+
+ private HashMap procMails = new HashMap();
+ private HashMap procMailsByName = new HashMap();
+
+ private TransportRule genericRule = null;
+ private Hashtable serverRules = new Hashtable();
+ private TestStatus testStatus = new TestStatus();
+
+ private Hashtable hostAddresses = new Hashtable();
+ private Hashtable domainsAssociated = new Hashtable();
+ private DNSServer dnsServer = new DNSServer() {
+
+ public Collection findMXRecords(String hostname)
+ throws TemporaryResolutionException {
+ throw new UnsupportedOperationException("DNSServer stub");
+ }
+
+ public Collection findTXTRecords(String hostname) {
+ throw new UnsupportedOperationException("DNSServer stub");
+ }
+
+ public InetAddress[] getAllByName(String host)
+ throws UnknownHostException {
+ throw new UnsupportedOperationException("DNSServer stub");
+ }
+
+ public InetAddress getByName(String host)
+ throws UnknownHostException {
+ throw new UnsupportedOperationException("DNSServer stub");
+ }
+
+ public String getHostName(InetAddress addr) {
+ throw new UnsupportedOperationException("DNSServer stub");
+ }
+
+ public InetAddress getLocalHost() throws UnknownHostException {
+ throw new UnsupportedOperationException("DNSServer stub");
+ }
+
+ public Iterator getSMTPHostAddresses(final String domainName)
+ throws TemporaryResolutionException {
+ return onMailetContextGetSMTPHostAddresses(domainName);
+ }
+
+ };
+
+ private static Tester instance;
+
+ /**
+ * Get the last static instance.
+ * Works only in a single Tester environment.
+ */
+ public static Tester getInstance() {
+ return instance;
+ }
+
+ public Tester(RemoteDeliveryTestable remoteDelivery) {
+ this.remoteDelivery = remoteDelivery;
+ remoteDelivery.setRemoteDeliveryTester(this);
+
+ //if (Tester.instance == null)
+ Tester.instance = this;
+ }
+
+ public void init(ServiceManager serviceManager, Properties mailetConfigProperties) throws MessagingException {
+ mailetConfig = new TesterMailetConfig(this, mailetConfigProperties, serviceManager);
+ remoteDelivery.init(mailetConfig);
+ // do this after the init because init would override it.
+ remoteDelivery.setDNSServer(dnsServer);
+
+ if (mailetConfig.getWrappedSpoolRepository() != null) log("DEBUG", "Init WrappedSpoolRepository OK");
+ else {
+ log("WARN", "Init WrappedSpoolRepository ERROR");
+ //throw new IllegalStateException();
+ }
+
+ Session session = obtainSession(new Properties());
+ Transport t = session.getTransport("smtp");
+ if (t instanceof SMTPTransport) log("DEBUG", "Init WrappedSMTPTransport OK");
+ else {
+ log("ERROR", "Init WrappedSMTPTransport ERROR");
+ throw new IllegalStateException();
+ }
+ }
+
+ public Session obtainSession(Properties props) {
+ /**
+ * Javamail1.4 allows for providers to be specified
+ */
+
+ props.put("mail.smtp.class", SMTPTransport.class.getName());
+ props.put("Tester", this);
+ Session s = Session.getInstance(props);
+ // Session s = Session.getDefaultInstance(props);
+ try {
+ if (!((s.getTransport("smtp")) instanceof SMTPTransport))
+ s.setProvider(new Provider(Type.TRANSPORT, "smtp", SMTPTransport.class.getName(), "test", "0"));
+ } catch (NoSuchProviderException e) {
+ // Let's do it twice, don't remember why.
+ try {
+ s.setProvider(new Provider(Type.TRANSPORT, "smtp", SMTPTransport.class.getName(), "test", "0"));
+ } catch (NoSuchProviderException e1) {
+ e1.printStackTrace();
+ }
+ e.printStackTrace();
+ }
+ return s;
+ }
+
+ protected void log(String type, String message) {
+ System.out.println("<RDT:" + type + "> " + message);
+ }
+
+ public ProcMail.Listing service(String name, String fromMail, String toMail, String body) throws MessagingException {
+ return service(name, fromMail, new String[] {toMail}, body, null);
+ }
+
+ public ProcMail.Listing service(String name, String fromMail, String toMail, String body, TransportRule rule) throws MessagingException {
+ return service(name, fromMail, new String[] {toMail}, body, rule);
+ }
+
+ public ProcMail.Listing service(String name, String fromMail, String[] toMail, String body) throws MessagingException {
+ return service(name, fromMail, toMail, body, null);
+ }
+
+ public ProcMail.Listing service(String name, String fromMail, String[] toMail, String body, TransportRule rule) throws MessagingException {
+ MimeMessage mm = new MimeMessage(Session.getInstance(new Properties()));
+ mm.setSubject(name);
+ mm.setText(body);
+// MimeMessageInputStreamSource mmis = new MimeMessageInputStreamSource("test", new SharedByteArrayInputStream((body).getBytes()));
+ Collection recipients = new ArrayList();
+ for (int i = 0; i < toMail.length; i++) recipients.add(new MailAddress(toMail[i]));
+// MailImpl mail = new MailImpl(name, new MailAddress(fromMail), recipients, new MimeMessageWrapper(mmis));
+ MailImpl mail = new MailImpl(name, new MailAddress(fromMail), recipients, mm);
+ return service(mail, rule);
+ }
+
+ public ProcMail.Listing service(Mail mail) throws MessagingException {
+ return service(mail, null);
+ }
+
+ public ProcMail.Listing service(Mail mail, TransportRule rule) throws MessagingException {
+ ProcMail.Listing listing = new ProcMail.Listing();
+ Iterator recipients = mail.getRecipients().iterator();
+ while (recipients.hasNext()) {
+ MailAddress address = (MailAddress)recipients.next();
+ ProcMail pmail = new ProcMail(this, mail, address);
+ pmail.setTransportRule(rule);
+ storeProcMail(pmail);
+ listing.add(pmail);
+ }
+ remoteDelivery.service(mail);
+ return listing;
+ }
+
+ public TestStatus getTestStatus() {
+ return testStatus;
+ }
+
+ public Collection getProcMails() {
+ return procMails.values();
+ }
+
+ public ProcMail getProcMail(Mail mail, MailAddress recipient) {
+ return getProcMailByKey(ProcMail.getKey(mail, recipient));
+ }
+
+ public ProcMail getProcMail(Message message, Address address) {
+ return getProcMailByKey(ProcMail.getKey(message, address));
+ }
+
+ public ProcMail getProcMailByKey(String key) {
+ return (ProcMail) procMails.get(key);
+ }
+
+ public ProcMail getProcMail(String name) {
+ return (ProcMail) procMailsByName.get(name);
+ }
+
+ public void storeProcMail(ProcMail pmail) {
+ procMails.put(pmail.getKey(), pmail);
+ procMailsByName.put(pmail.getMailName(), pmail);
+ log("DEBUG", "Stored procmail: "+pmail.getKey());
+ }
+
+ private String getServerName(URLName urlname) {
+ return urlname.toString();
+ }
+
+ public void setGenericRule(TransportRule rule) {
+ genericRule = rule;
+ }
+
+ public void addDomainServer(String domain, String url) {
+ if (!hostAddresses.containsKey(domain)) hostAddresses.put(domain, new Vector());
+ ((Vector)hostAddresses.get(domain)).add(new HostAddress(domain, url));
+ domainsAssociated.put(url, domain);
+ }
+
+ public void addServerRule(String url, TransportRule rule) {
+ serverRules.put(getServerName(new URLName(url)), rule);
+ }
+
+ public void addDomainServer(String domain, String url, TransportRule rule) {
+ addDomainServer(domain, url);
+ addServerRule(url, rule);
+ }
+
+ public String getDomainAssociated(String server) {
+ return (String) domainsAssociated.get(server);
+ }
+
+ public Iterator onMailetContextGetSMTPHostAddresses(String domainName) {
+ return ((List)hostAddresses.get(domainName)).iterator();
+ }
+
+ public void onTransportConnect(SMTPTransport tester) throws MessagingException {
+ String server = getServerName(tester.getURLName());
+ log("TRANSPORT", "Connection to " + server);
+
+ Exception ex = null;
+ try {
+ if (serverRules.containsKey(server)) ((TransportRule)serverRules.get(server)).onConnect(testStatus, server);
+ if (genericRule != null) genericRule.onConnect(testStatus, server);
+ } catch (MessagingException e) {
+ ex = e;
+ } catch (RuntimeException e) {
+ ex = e;
+ }
+
+ testStatus.incTransportConnectionCount(1);
+ testStatus.incTransportServerConnectionCount(server, 1);
+
+ if (ex != null) {
+ if (ex instanceof MessagingException) throw (MessagingException)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ }
+ }
+
+ public void onTransportSendMessage(SMTPTransport tester, Message message, Address[] recipients) throws MessagingException, SendFailedException {
+ String server = getServerName(tester.getURLName());
+ ProcMail.Listing listing = new ProcMail.Listing();
+ Vector rules = new Vector();
+ for (int i = 0; i < recipients.length; i++) {
+ ProcMail pmail = getProcMail(message, recipients[i]);
+ log("TRANSPORT.SEND", "Preparing send " + pmail.getKey() + " to " + server);
+
+ if (pmail == null) throw new IllegalStateException("Unknow mail for " + recipients[i]);
+ listing.add(pmail);
+ if (pmail.getTransportRule() != null && !rules.contains(pmail.getTransportRule())) rules.add(pmail.getTransportRule());
+ }
+
+ Exception ex = null;
+ try {
+
+ log("TRANSPORT.SEND", "Sending to " + server + ", applying " + rules.size() + " mail rules");
+ for (int i = 0; i < rules.size(); i++) ((TransportRule) rules.get(i)).onSendMessage(testStatus, server, listing);
+
+ if (serverRules.containsKey(server)) ((TransportRule)serverRules.get(server)).onSendMessage(testStatus, server, listing);
+ if (genericRule != null) genericRule.onSendMessage(testStatus, server, listing);
+
+ } catch (SendFailedException e) {
+ ex = e;
+ } catch (MessagingException e) {
+ ex = e;
+ } catch (RuntimeException e) {
+ ex = e;
+ }
+
+ if (ex != null) log("TRANSPORT.SEND", "Got Exception " + dumpException(ex));
+
+ // If we got a sendFailed then the specific recipient could be OK
+ Address[] validAddresses = ex instanceof SendFailedException ? ((SendFailedException)ex).getValidSentAddresses() : null;
+ for (int i = 0; i < listing.size(); i++) {
+ ProcMail pmail = listing.get(i);
+ boolean valid = false;
+ if (validAddresses != null)
+ for (int j = 0; !valid && j < validAddresses.length; j++)
+ valid = pmail.getRecipient().toString().equals(validAddresses[j].toString());
+
+ pmail.sent(server, !valid ? ex : null);
+// System.out.println("--------------------\r\n");
+// System.out.println("0. " + server + " " + pmail + " " + pmail.getKey() + " " + pmail.getSendCount() + valid + "\r\n");
+// System.out.println("--------------------\r\n");
+
+ testStatus.incTransportSendCount(1);
+ testStatus.incTransportServerSendCount(server, 1);
+ if (ex == null || valid) {
+ testStatus.incTransportSendSuccessfullCount(1);
+ testStatus.incTransportServerSendSuccessfullCount(server, 1);
+ } else {
+ testStatus.incTransportSendFailedCount(1);
+ testStatus.incTransportServerSendFailedCount(server, 1);
+ }
+ }
+
+ if (ex != null) {
+ if (ex instanceof SendFailedException) throw (SendFailedException)ex;
+ if (ex instanceof MessagingException) throw (MessagingException)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ }
+
+ }
+
+ private String dumpException(Exception ex) {
+ if (!(ex instanceof MessagingException)) return ex.toString();
+
+ StringBuffer res = new StringBuffer();
+ String exs = ex.getMessage();
+ int p = exs.indexOf("nested exception is:");
+ if (p >= 0) exs = exs.substring(0, p - 3);
+ res.append(exs);
+ //res.append(ex.toString());
+
+ while (ex != null && (ex instanceof MessagingException)) {
+ res.append(" > ");
+ if (ex instanceof SMTPSendFailedException) res.append("smtpsfe" + ((SMTPSendFailedException)ex).getReturnCode()); else
+ if (ex instanceof SMTPAddressFailedException) res.append("smtpafe" + ((SMTPAddressFailedException)ex).getReturnCode()); else
+ if (ex instanceof SMTPAddressSucceededException) res.append("smtpase" + ((SMTPAddressSucceededException)ex).getReturnCode()); else
+ if (ex instanceof SendFailedException) res.append("sfe"); else
+ if (ex instanceof NullPointerException) res.append("null"); else
+ res.append("me");
+ ex = ((MessagingException)ex).getNextException();
+ }
+
+ return res.toString();
+ }
+
+ public void onTransportClose(SMTPTransport tester) throws MessagingException {
+ String server = getServerName(tester.getURLName());
+ log("TRANSPORT", "Closing connection to " + server);
+
+ Exception ex = null;
+ try {
+ if (serverRules.containsKey(server)) ((TransportRule)serverRules.get(server)).onClose(testStatus, server);
+ if (genericRule != null) genericRule.onClose(testStatus, server);
+ } catch (MessagingException e) {
+ ex = e;
+ } catch (RuntimeException e) {
+ ex = e;
+ }
+
+ testStatus.incTransportCloseCount(1);
+ testStatus.incTransportServerCloseCount(server, 1);
+
+ if (ex != null) {
+ if (ex instanceof MessagingException) throw (MessagingException)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ }
+ }
+
+ public boolean OnTransportSupportsExtension(SMTPTransport tester, String arg0) {
+ String server = getServerName(tester.getURLName());
+ log("TRANSPORT", "Asking if " + server + " supports " + arg0);
+
+ boolean value = false;
+ if (serverRules.containsKey(server)) value = ((TransportRule)serverRules.get(server)).onSupportsExtension(testStatus, server, arg0, value);
+ if (genericRule != null) value = genericRule.onSupportsExtension(testStatus, server, arg0, value);
+
+ return value;
+ }
+
+ public void onMailetContextBounce(Mail mail, String message) {
+ throw new UnsupportedOperationException("Not supported old bounce method");
+ }
+
+ public void onMailetContextSendMail(Mail mail) {
+ Iterator recipients = mail.getRecipients().iterator();
+ while (recipients.hasNext()) {
+ MailAddress address = (MailAddress)recipients.next();
+ ProcMail pmail = getProcMail(mail, address);
+ if (pmail != null) onMailetContextSendMail(pmail, mail);
+ else throw new IllegalStateException("No ProcMail on " + address);
+ }
+ }
+
+ public void onMailetContextSendMail(ProcMail pmail, Mail mail) {
+ pmail.bounced(mail);
+ testStatus.incBouncedCount(1);
+ }
+
+ protected void onOutgoingStore(Mail mail) {
+// acceptedProcMailList.set(null);
+//
+// Iterator recipients = mail.getRecipients().iterator();
+// while (recipients.hasNext()) {
+// MailAddress address = (MailAddress)recipients.next();
+// ProcMail pmail = getProcMail(mail, address);
+// if (pmail == null) {
+// // (1) Chiamato per primo quando la mail viene accettata e messa nello spool
+// pmail = new ProcMail(this, mail, address);
+// storeProcMail(pmail);
+// onOutgoingStoreStart(pmail, mail);
+// } else {
+// // (5b) E anche per ultimo se la mail ha degli errori temporanei
+// onOutgoingStoreEnd(pmail, mail);
+// }
+// }
+}
+
+protected void onOutgoingAccept(Mail mail) {
+// Vector l = new Vector();
+// acceptedProcMailList.set(l);
+//
+// // (2) Chiamato per secondo, quando la mail viene presa in carico per la spedizione
+// Iterator recipients = mail.getRecipients().iterator();
+// while (recipients.hasNext()) {
+// MailAddress address = (MailAddress)recipients.next();
+// ProcMail pmail = getProcMail(mail, address);
+// if (pmail != null) {
+// onOutgoingAccept(pmail, mail);
+// l.add(new Object[] {pmail, mail});
+// }
+// else throw new IllegalStateException("No ProcMail on " + address);
+// }
+}
+
+protected void onOutgoingRemove(Mail mail) {
+// // (5a) Chiamato per ultimo se la mail è OK o ha avuto errori permanenti
+// Iterator recipients = mail.getRecipients().iterator();
+// while (recipients.hasNext()) {
+// MailAddress address = (MailAddress)recipients.next();
+// ProcMail pmail = getProcMail(mail, address);
+// if (pmail != null) onOutgoingRemove(pmail, mail);
+// else throw new IllegalStateException("No ProcMail on " + address);
+// }
+}
+
+protected void onOutgoingRemove(String key) {
+// // (5a) Chiamato per ultimo se la mail è OK o ha avuto errori permanenti
+//
+// // Cerca la stessa chiave tra le ultime accettate (dovrebbero averla tutte)
+// Vector l = (Vector) acceptedProcMailList.get();
+// if (l != null)
+// for (int i = 0; i < l.size(); i++) {
+// ProcMail pmail = (ProcMail)((Object[])l.get(i))[0];
+// Mail mail = (Mail)((Object[])l.get(i))[1];
+// if (!pmail.getMailName().equals(key)) throw new IllegalStateException("Mail not recognized.");
+// onOutgoingRemove(pmail, mail);
+// }
+}
+
+//protected void onOutgoingStoreStart(ProcMail pmail, Mail mail) {
+// // (1) Chiamato per primo quando la mail viene accettata e messa nello spool
+// log("DEBUG", "onOutgoingStore(start) "+pmail.getKey());
+// pmail.spool(mail);
+//}
+//
+//protected void onOutgoingAccept(ProcMail pmail, Mail mail) {
+// // (2) Chiamato per secondo, quando la mail viene presa in carico per la spedizione
+// log("DEBUG", "onOutgoingAccept "+pmail.getKey());
+// pmail.fetchFromSpool(mail);
+//}
+//
+//protected void onTransportConnect(ProcMail pmail, Exception e) {
+// // (3) Chiamata per inizializzare la connessione, in realtà non è un evento
+// // strettamento legato alla mail
+// log("DEBUG", "onTransportConnect "+pmail.getKey());
+// pmail.setState(ProcMail.STATE_SENDING);
+// if (e != null) pmail.setConnectException(e);
+//}
+//
+//protected void onTransportSend(ProcMail pmail, Exception e) {
+// // (4) Invio vero e proprio del messaggio
+// log("DEBUG", "onTransportSend "+pmail.getKey());
+// pmail.setState(ProcMail.STATE_SENDTERMINATED);
+// if (e != null) pmail.setSendException(e);
+//}
+//
+//protected void onOutgoingRemove(ProcMail pmail, Mail mail) {
+// // (5a) Chiamato per ultimo se la mail è OK o ha avuto errori permanenti
+// log("DEBUG", "onOutgoingRemove "+pmail.getKey());
+// pmail.terminate(mail, true);
+//}
+//
+//protected void onOutgoingStoreEnd(ProcMail pmail, Mail mail) {
+// // (5b) Chiamato per ultimo se la mail ha degli errori temporanei
+// log("DEBUG", "onOutgoingStore(end) "+pmail.getKey());
+// pmail.terminate(mail, false);
+//}
+
+ /**
+ * Runtime status of test.
+ * <p>Contains test statistics.
+ */
+ public class TestStatus {
+ private int transportConnectionCount = 0;
+ private int transportSendCount = 0;
+ private int transportSendSuccessfullCount = 0;
+ private int transportSendFailedCount = 0;
+ private int transportCloseCount = 0;
+ private Map transportServerConnectionCount = new HashMap();
+ private Map transportServerSendCount = new HashMap();
+ private Map transportServerSendSuccessfullCount = new HashMap();
+ private Map transportServerSendFailedCount = new HashMap();
+ private Map transportServerCloseCount = new HashMap();
+ private int bouncedCount = 0;
+
+ public int getIntMapValue(Map map, String key) {
+ return map.containsKey(key) ? ((Integer) map.get(key)).intValue() : 0;
+ }
+ public void setIntMapValue(Map map, String key, int v) {
+ map.put(key, new Integer(v));
+ }
+ public void incIntMapValue(Map map, String key, int v) {
+ setIntMapValue(map, key, getIntMapValue(map, key) + v);
+ }
+
+ public int getBouncedCount() {
+ return bouncedCount;
+ }
+ public int incBouncedCount(int v) {
+ return (bouncedCount += v);
+ }
+ public void setBouncedCount(int bouncedCount) {
+ this.bouncedCount = bouncedCount;
+ }
+ public int getTransportCloseCount() {
+ return transportCloseCount;
+ }
+ public int incTransportCloseCount(int v) {
+ return (transportCloseCount += v);
+ }
+ public void setTransportCloseCount(int transportCloseCount) {
+ this.transportCloseCount = transportCloseCount;
+ }
+ public int getTransportConnectionCount() {
+ return transportConnectionCount;
+ }
+ public int incTransportConnectionCount(int v) {
+ return (transportConnectionCount += v);
+ }
+ public void setTransportConnectionCount(int transportConnectionCount) {
+ this.transportConnectionCount = transportConnectionCount;
+ }
+ public int getTransportSendCount() {
+ return transportSendCount;
+ }
+ public int incTransportSendCount(int v) {
+ return (transportSendCount += v);
+ }
+ public void setTransportSendCount(int transportSendCount) {
+ this.transportSendCount = transportSendCount;
+ }
+ public int getTransportSendSuccessfullCount() {
+ return transportSendSuccessfullCount;
+ }
+ public int incTransportSendSuccessfullCount(int v) {
+ return (transportSendSuccessfullCount += v);
+ }
+ public void setTransportSendSuccessfullCount(int transportSendSuccessfullCount) {
+ this.transportSendSuccessfullCount = transportSendSuccessfullCount;
+ }
+ public int getTransportSendFailedCount() {
+ return transportSendFailedCount;
+ }
+ public int incTransportSendFailedCount(int v) {
+ return (transportSendFailedCount += v);
+ }
+ public void setTransportSendFailedCount(int transportSendFailedCount) {
+ this.transportSendFailedCount = transportSendFailedCount;
+ }
+ public int getTransportServerCloseCount(String server) {
+ return getIntMapValue(transportServerCloseCount, server);
+ }
+ public void incTransportServerCloseCount(String server, int v) {
+ incIntMapValue(transportServerCloseCount, server, v);
+ }
+ public int getTransportServerSendCount(String server) {
+ return getIntMapValue(transportServerSendCount, server);
+ }
+ public void incTransportServerSendCount(String server, int v) {
+ incIntMapValue(transportServerSendCount, server, v);
+ }
+ public int getTransportServerSendSuccessfullCount(String server) {
+ return getIntMapValue(transportServerSendSuccessfullCount, server);
+ }
+ public void incTransportServerSendSuccessfullCount(String server, int v) {
+ incIntMapValue(transportServerSendSuccessfullCount, server, v);
+ }
+ public int getTransportServerSendFailedCount(String server) {
+ return getIntMapValue(transportServerSendFailedCount, server);
+ }
+ public void incTransportServerSendFailedCount(String server, int v) {
+ incIntMapValue(transportServerSendFailedCount, server, v);
+ }
+ public int getTransportServerConnectionCount(String server) {
+ return getIntMapValue(transportServerConnectionCount, server);
+ }
+ public void incTransportServerConnectionCount(String server, int v) {
+ incIntMapValue(transportServerConnectionCount, server, v);
+ }
+
+ }
+}
Propchange: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/Tester.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/Tester.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TesterMailetConfig.java
URL: http://svn.apache.org/viewvc/james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TesterMailetConfig.java?rev=671119&view=auto
==============================================================================
--- james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TesterMailetConfig.java (added)
+++ james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TesterMailetConfig.java Tue Jun 24 03:34:16 2008
@@ -0,0 +1,293 @@
+/****************************************************************
+ * 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.remotedeliverytester;
+
+import org.apache.avalon.cornerstone.services.store.Store;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.james.Constants;
+import org.apache.james.services.SpoolRepository;
+import org.apache.james.test.mock.mailet.MockMailContext;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+import org.apache.mailet.MailetConfig;
+import org.apache.mailet.MailetContext;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Properties;
+
+public class TesterMailetConfig implements MailetConfig {
+
+ private class MailetContextTester extends MockMailContext {
+ private TesterMailetConfig owner;
+ private ServiceManager serviceManager;
+ private ServiceManager wrappedServiceManager;
+
+ public MailetContextTester(TesterMailetConfig owner, ServiceManager serviceManager) {
+ this.owner = owner;
+ this.serviceManager = serviceManager;
+ }
+
+ public Object getAttribute(String name) {
+ if (name.equals(Constants.AVALON_COMPONENT_MANAGER)) {
+ if (wrappedServiceManager == null) wrappedServiceManager = new ServiceManagerWrapper(owner, serviceManager);
+ return wrappedServiceManager;
+ } else if (name.equals(Constants.HELLO_NAME)) {
+ return "hello.name.com";
+ }
+ return null;
+ }
+
+ public MailetContext setServiceManager(ServiceManager serviceManager) {
+ this.serviceManager = serviceManager;
+ return this;
+ }
+
+ public void log(String message, Throwable t) {
+ log(message);
+ t.printStackTrace();
+ }
+
+ public void log(String message) {
+ System.out.println(message);
+ }
+
+ public Iterator getSMTPHostAddresses(String domainName) {
+ return owner.onMailetContextGetSMTPHostAddresses(domainName);
+ }
+
+ public void bounce(Mail mail, String message, MailAddress bouncer) throws MessagingException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void bounce(Mail mail, String message) throws MessagingException {
+ owner.onMailetContextBounce(mail, message);
+ }
+
+ public Collection getMailServers(String host) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void sendMail(Mail mail) throws MessagingException {
+ owner.onMailetContextSendMail(mail);
+ }
+
+ public void sendMail(MailAddress sender, Collection recipients, MimeMessage msg, String state) throws MessagingException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void sendMail(MailAddress sender, Collection recipients, MimeMessage msg) throws MessagingException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void sendMail(MimeMessage msg) throws MessagingException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void storeMail(MailAddress sender, MailAddress recipient, MimeMessage msg) throws MessagingException {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+ private class ServiceManagerWrapper implements ServiceManager {
+ private TesterMailetConfig owner;
+ private ServiceManager wrapped;
+ private Store wrappedStore;
+
+ public ServiceManagerWrapper(TesterMailetConfig owner, ServiceManager wrapped) {
+ this.owner = owner;
+ this.wrapped = wrapped;
+ }
+
+ public Object lookup(String arg0) throws ServiceException {
+ if (arg0.equals("org.apache.avalon.cornerstone.services.store.Store")) {
+ if (wrappedStore == null) wrappedStore = new StoreWrapper(owner, (Store) wrapped.lookup("org.apache.avalon.cornerstone.services.store.Store"));
+ return wrappedStore;
+ }
+ return wrapped.lookup(arg0);
+ }
+
+ public boolean hasService(String arg0) {
+ return wrapped.hasService(arg0);
+ }
+
+ public void release(Object arg0) {
+ wrapped.release(arg0);
+ }
+ }
+
+ private class StoreWrapper implements Store {
+ private TesterMailetConfig owner;
+ private Store wrapped;
+ private SpoolRepository wrappedSpoolRepository;
+
+ public StoreWrapper(TesterMailetConfig owner, Store wrapped) {
+ this.owner = owner;
+ this.wrapped = wrapped;
+ }
+
+ public Object select(Object arg0) throws ServiceException {
+ if ((arg0 instanceof Configuration) && ((Configuration) arg0).getLocation().equals("generated:RemoteDelivery.java")) {
+ if (wrappedSpoolRepository == null) wrappedSpoolRepository = new SpoolRepositoryWrapper(owner, (SpoolRepository) wrapped.select(arg0));
+ return wrappedSpoolRepository;
+ }
+ return wrapped.select(arg0);
+ }
+
+ public boolean isSelectable(Object arg0) {
+ return wrapped.isSelectable(arg0);
+ }
+
+ public void release(Object arg0) {
+ wrapped.release(arg0);
+ }
+ }
+
+ private class SpoolRepositoryWrapper implements SpoolRepository {
+ private TesterMailetConfig owner;
+ private SpoolRepository wrapped;
+
+ public SpoolRepositoryWrapper(TesterMailetConfig owner, SpoolRepository wrapped) {
+ this.owner = owner;
+ this.wrapped = wrapped;
+ owner.setWrappedSpoolRepository(this);
+ }
+
+ public void store(Mail mc) throws MessagingException {
+ owner.onOutgoingStore(mc);
+ wrapped.store(mc);
+ }
+
+ public void remove(Mail mail) throws MessagingException {
+ owner.onOutgoingRemove(mail);
+ wrapped.remove(mail);
+ }
+
+ public void remove(String key) throws MessagingException {
+ owner.onOutgoingRemove(key);
+ wrapped.remove(key);
+ }
+
+ public Mail accept(AcceptFilter filter) throws InterruptedException {
+ Mail mail = wrapped.accept(filter);
+ if (mail != null) owner.onOutgoingAccept(mail);
+ return mail;
+ }
+
+ public Mail accept() throws InterruptedException {
+ return wrapped.accept();
+ }
+
+ public Mail accept(long delay) throws InterruptedException {
+ return wrapped.accept(delay);
+ }
+
+ public Iterator list() throws MessagingException {
+ return wrapped.list();
+ }
+
+ public boolean lock(String key) throws MessagingException {
+ return wrapped.lock(key);
+ }
+
+ public void remove(Collection mails) throws MessagingException {
+ wrapped.remove(mails);
+ }
+
+ public Mail retrieve(String key) throws MessagingException {
+ return wrapped.retrieve(key);
+ }
+
+ public boolean unlock(String key) throws MessagingException {
+ return wrapped.unlock(key);
+ }
+ }
+
+ private Tester owner;
+ private Properties parameters;
+ private MailetContextTester mailetContext;
+
+ // wrappedSpoolRepository verrà settato solo se si decide di gestire l'outgoing
+ private SpoolRepository wrappedSpoolRepository;
+
+ public TesterMailetConfig(Tester owner, Properties properties, ServiceManager serviceManager) {
+ this.owner = owner;
+ this.parameters = properties;
+ mailetContext = new MailetContextTester(this, serviceManager);
+ }
+
+ public SpoolRepository getWrappedSpoolRepository() {
+ return wrappedSpoolRepository;
+ }
+
+ public void setWrappedSpoolRepository(SpoolRepository wrappedSpoolRepository) {
+ this.wrappedSpoolRepository = wrappedSpoolRepository;
+ }
+
+ public String getInitParameter(String name) {
+ return (String) parameters.get(name);
+ }
+
+ public Iterator getInitParameterNames() {
+ return parameters.keySet().iterator();
+ }
+
+ public MailetContext getMailetContext() {
+ return mailetContext;
+ }
+
+ public String getMailetName() {
+ return "Test";
+ }
+
+ public Iterator onMailetContextGetSMTPHostAddresses(String domainName) {
+ return owner.onMailetContextGetSMTPHostAddresses(domainName);
+ }
+
+ public void onMailetContextBounce(Mail mail, String message) {
+ owner.onMailetContextBounce(mail, message);
+ }
+
+ public void onMailetContextSendMail(Mail mail) {
+ owner.onMailetContextSendMail(mail);
+ }
+
+ public void onOutgoingAccept(Mail mail) {
+ owner.onOutgoingAccept(mail);
+ }
+
+ public void onOutgoingRemove(String key) {
+ owner.onOutgoingRemove(key);
+ }
+
+ public void onOutgoingRemove(Mail mail) {
+ owner.onOutgoingRemove(mail);
+ }
+
+ public void onOutgoingStore(Mail mc) {
+ owner.onOutgoingStore(mc);
+ }
+}
Propchange: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TesterMailetConfig.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TesterMailetConfig.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TransportRule.java
URL: http://svn.apache.org/viewvc/james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TransportRule.java?rev=671119&view=auto
==============================================================================
--- james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TransportRule.java (added)
+++ james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TransportRule.java Tue Jun 24 03:34:16 2008
@@ -0,0 +1,333 @@
+/****************************************************************
+ * 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.remotedeliverytester;
+
+import org.apache.james.transport.remotedeliverytester.ProcMail.Listing;
+import org.apache.james.transport.remotedeliverytester.Tester.TestStatus;
+
+import javax.mail.Address;
+import javax.mail.MessagingException;
+import javax.mail.SendFailedException;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+
+/**
+ * The TransportRule is a rule for the tester.
+ * It define the behaviour of a given server.
+ */
+public interface TransportRule {
+ void onConnect(TestStatus status, String server) throws MessagingException;
+ void onSendMessage(TestStatus status, String server, ProcMail.Listing pmails) throws MessagingException, SendFailedException;
+ void onClose(TestStatus status, String server) throws MessagingException;
+ boolean onSupportsExtension(TestStatus status, String server, String ext, boolean value);
+
+
+ public abstract class Default implements TransportRule {
+ public void onConnect(TestStatus status, String server) throws MessagingException {
+ }
+ public void onSendMessage(TestStatus status, String server, ProcMail.Listing pmails) throws MessagingException, SendFailedException {
+ }
+ public void onClose(TestStatus status, String server) throws MessagingException {
+ }
+ public boolean onSupportsExtension(TestStatus status, String server, String ext, boolean value) {
+ return value;
+ }
+ }
+
+ /**
+ * Server rule string format:
+ * id-rule.[*-userrule].[match*-userrule].string
+ *
+ * - id-rule are for "connect"-time exceptions
+ * - *-userrule are for "send"-time exceptions involving every mail (not depending on the recipients address)
+ * - match*-userrule are for "send"-time exceptions involving specific recipients (starting with match - ** to match every address)
+ *
+ * Available rules:
+ * - me[v]: MessagingException
+ * - sfe[v]: SendFailedException
+ * - smtpafeXXX[v]: SMTPAddressFailedException with XXX returnCode
+ * - smtpaseXXX[v]: SMTPAddressSuccededException with XXX returnCode
+ * - smtpsfeXXX[v]: SMTPSendFailedException with XXX returnCode
+ * - null: NullPointerException
+ * - io: IOException (nested in a MessagingException)
+ * - rpt: repeat the previous rule pattern
+ * - (*) if a "mail" rule (one involving addresses) ends with "v" resulting in a "valid" address (the failure is about some other error: valid unsent)
+ */
+ public class NameExpression extends Default {
+
+ // Se false ai recipient validi non vengono effettivamente fatti invii
+ private boolean propSendValid = true;
+
+ public NameExpression(boolean sendValid) {
+ propSendValid = sendValid;
+ }
+
+ /**
+ * Take a string like "name-action[-count]-[action2[-count2]...]"
+ * and convert it in a list "name, action, action, ..., action2, action2, ..., ..."
+ * @param data
+ * @return
+ */
+ private String[] getRules(String data) {
+ String[] pieces = data.toLowerCase().split("-");
+ Vector actions = new Vector();
+ actions.add(pieces[0]);
+ for (int i = 1; i < pieces.length; i += 2) {
+ int cnt = i + 1 < pieces.length ? Integer.parseInt(pieces[i + 1]) : 1;
+ for (int j = 0; j < cnt; j++) actions.add(pieces[i]);
+ }
+ return (String[]) actions.toArray(new String[0]);
+ }
+
+ private MessagingException getException(String[] actions, int idx, ProcMail pmail, String prefix) {
+ MessagingException result = null;
+ if (idx + 1 >= actions.length && actions[actions.length - 1].equals("rpt")) idx = 1 + (idx % actions.length - 2);
+ String action = idx + 1 < actions.length ? (String) actions[idx + 1] : actions[actions.length - 1];
+ if (action.equals("me") || action.equals("ex")) {
+ String flag = action.substring(2).trim();
+ boolean valid = flag != null && flag.equalsIgnoreCase("v");
+ result = new MessagingException("000" + (valid ? "V " : "I ") + prefix + "#" + idx);
+ } else if (action.equals("sfe")) {
+ String flag = action.substring(3).trim();
+ boolean valid = flag != null && flag.equalsIgnoreCase("v");
+ result = new SendFailedException("000" + (valid ? "V " : "I ") + prefix + "#" + idx);
+ } else if (action.startsWith("smtpafe")) {
+ String retcodes = action.substring(7, 10).trim();
+ int retcode = 500;
+ if (retcodes != null && retcodes.length() == 3) retcode = Integer.parseInt(retcodes);
+ String flag = action.substring(10).trim();
+ boolean valid = flag != null && flag.equalsIgnoreCase("v");
+ result = new SMTPAddressFailedException(pmail.getRecipient().toInternetAddress(), "CMD", retcode, retcode + (valid ? "V " : "I ") + pmail.getRecipient().toString()+ ":"+ prefix + "#" + idx);
+ } else if (action.startsWith("smtpase")) {
+ String retcodes = action.substring(7).trim();
+ int retcode = 200;
+ if (retcodes != null && retcodes.length() == 3) retcode = Integer.parseInt(retcodes);
+ String flag = action.substring(10).trim();
+ boolean valid = flag != null && flag.equalsIgnoreCase("v");
+ result = new SMTPAddressSucceededException(pmail.getRecipient().toInternetAddress(), "CMD", retcode, retcode + (valid ? "V " : "I ") + pmail.getRecipient().toString()+ ":"+ prefix + "#" + idx);
+ } else if (action.startsWith("smtpsfe")) {
+ String retcodes = action.substring(7).trim();
+ int retcode = 500;
+ if (retcodes != null && retcodes.length() == 3) retcode = Integer.parseInt(retcodes);
+ String flag = action.substring(10).trim();
+ boolean valid = flag != null && flag.equalsIgnoreCase("v");
+ result = new SMTPSendFailedException("CMD", retcode, retcode + (valid ? "V " : "I ") + prefix + "#" + idx, null, null, null, null);
+
+ } else if (action.startsWith("null")) {
+ result = new NullMessagingException();
+
+ } else if (action.startsWith("io")) {
+ result = new IOMessagingException();
+ }
+
+ return result;
+ }
+
+ private boolean isValid(Exception ex) {
+ return ex != null && ex.getMessage() != null && ex.getMessage().length() > 4 && ex.getMessage().charAt(3) == 'V';
+ }
+
+ /**
+ * Calculate the priority of an exception (in order to choose the right exception on multiple/conflicts)
+ * @param ex
+ * @return
+ */
+ private int getPrio(Exception ex) {
+ // Addresses exceptions are low priority
+ // Take care of exception hierarchy: parents are the last in this ifs list
+ if (ex instanceof NullMessagingException) return 7000;
+ if (ex instanceof IOMessagingException) return 6000;
+ if (ex instanceof SMTPSendFailedException) return 5000 + ((SMTPAddressFailedException)ex).getReturnCode();
+ if (ex instanceof SMTPAddressFailedException) return 2000 + ((SMTPAddressFailedException)ex).getReturnCode();
+ if (ex instanceof SMTPAddressSucceededException) return 1000 + ((SMTPAddressSucceededException)ex).getReturnCode();
+ if (ex instanceof SendFailedException) return 4000;
+ if (ex instanceof MessagingException) return 3000;
+ return -1;
+ }
+
+ /**
+ * Returns the exception with the greatest priority.
+ * @param newex
+ * @param oldex
+ * @return
+ */
+ private MessagingException getMajor(MessagingException newex, MessagingException oldex) {
+ if (newex == null) return oldex;
+ if (oldex == null) return newex;
+ return getPrio(newex) >= getPrio(oldex) ? newex : oldex;
+ }
+
+ private void addException(HashMap map, MessagingException ex, Address recipient) {
+ if (map.get(recipient) != null) {
+ MessagingException oldex = (MessagingException) map.get(recipient);
+ ex = getMajor(ex, oldex);
+ }
+ map.put(recipient, ex);
+ }
+
+ /**
+ * Clone the exception, sets the "invalid" addresses as invalidAddress (in the clone)
+ * If the exception does not support "invalidaddress" declaration rethrow the original exception.
+ * @return
+ */
+ private MessagingException generateClone(Exception ex, Address[] validUnsent, Address[] invalid, MessagingException next) {
+ // Attenzione: le eccezioni devono essere in ordine di gerarchia (le + generiche - MessagingException - per ultime)
+ if (ex instanceof SMTPSendFailedException) {
+ return new SMTPSendFailedException(((SMTPSendFailedException)ex).getCommand(), ((SMTPSendFailedException)ex).getReturnCode(), ex.getMessage(), next, new Address[0], validUnsent, invalid);
+
+ } else if (ex instanceof SendFailedException) {
+ return new SendFailedException(ex.getMessage(), next, new Address[0], validUnsent, invalid);
+
+ } else if ((ex instanceof MessagingException) || (ex instanceof SMTPAddressSucceededException) || (ex instanceof SMTPAddressFailedException)) {
+ //if (next != null) ex.setNextException(next);
+ return (MessagingException) ex;
+ }
+ return null;
+ }
+
+ private MessagingException generateParent(Exception majorChildEx, Address[] validSent, Address[] validUnsent, Address[] invalid, MessagingException next) {
+ // NOTE: exceptions must be checked considering their hierarchy
+ if (majorChildEx instanceof SMTPAddressSucceededException) {
+ // If the major exception is an address exception we generate a SendFailedException (non SMTP). If we generate an SMTP exception the return code must be 2xx (e.g: 250)
+ // ERR return new SMTPSendFailedException(((SMTPAddressSucceededException)majorChildEx).getCommand(), ((SMTPAddressSucceededException)majorChildEx).getReturnCode(), majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+ //return new SMTPSendFailedException(((SMTPAddressSucceededException)majorChildEx).getCommand(), 250, "250 "+majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+ return new SendFailedException(majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+
+ } else if (majorChildEx instanceof SMTPAddressFailedException) {
+ // ERR: return new SMTPSendFailedException(((SMTPAddressFailedException)majorChildEx).getCommand(), ((SMTPAddressFailedException)majorChildEx).getReturnCode(), majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+ //return new SMTPSendFailedException(((SMTPAddressFailedException)majorChildEx).getCommand(), 250, "250 "+majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+ return new SendFailedException(majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+
+ } else if (majorChildEx instanceof SMTPSendFailedException) {
+ return new SMTPSendFailedException(((SMTPSendFailedException)majorChildEx).getCommand(), ((SMTPSendFailedException)majorChildEx).getReturnCode(), majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+
+ } else if (majorChildEx instanceof SendFailedException) {
+ return new SendFailedException(majorChildEx.getMessage(), next, validSent, validUnsent, invalid);
+
+ } else if (majorChildEx instanceof MessagingException) {
+ //if (next != null) majorChildEx.setNextException(next);
+ return (MessagingException) majorChildEx;
+ }
+
+ return null;
+ }
+
+ private MessagingException getRootException(HashMap map) {
+ // x recipient: sfe (generate an sfe in root), smtpase (generate an smtafe), smtpafe (generate an smtafe),
+ // x root: me, sfe, smtpafe
+
+ MessagingException current = null, prev = null, major = null;
+ Vector invalid = new Vector();
+ Vector validSent = new Vector();
+ Vector validUnsent = new Vector();
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ Address address = (Address) i.next();
+ if (address != null) {
+ current = (MessagingException) map.get(address);
+ if (current != null) {
+ if (prev != null) current.setNextException(prev);
+ if (major != null) major = getMajor(major, current);
+ else major = current;
+ prev = current;
+
+ if (!(current instanceof SMTPAddressSucceededException)) {
+ if (isValid(current)) validUnsent.add(address);
+ else invalid.add(address);
+ }
+ else if (propSendValid) validSent.add(address); else validUnsent.add(address);
+ }
+ else if (propSendValid) validSent.add(address); else validUnsent.add(address);
+ }
+ }
+
+ // on generic exception (not a per-recipient exception) clone it with all "unsents" (validSent -> validUnsent)
+ MessagingException ex1 = (MessagingException) map.get(null);
+ if (ex1 != null) {
+ validUnsent.addAll(validSent);
+ ex1 = generateClone(ex1, (Address[]) validUnsent.toArray(new Address[0]), (Address[]) invalid.toArray(new Address[0]), prev);
+ }
+
+ // Create a container exception for the above exceptions
+ MessagingException ex2 = major != null ? (MessagingException) generateParent(major, (Address[]) validSent.toArray(new Address[0]), (Address[]) validUnsent.toArray(new Address[0]), (Address[]) invalid.toArray(new Address[0]), prev) : null;
+
+ return getMajor(ex1, ex2);
+
+ }
+
+ public void onConnect(TestStatus status, String server) throws MessagingException {
+ String serverData = server;
+ if (serverData.indexOf("://") >= 0) serverData = serverData.substring(serverData.indexOf("://") + 3);
+ if (serverData.indexOf(":") >= 0) serverData = serverData.substring(0, serverData.indexOf(":"));
+ String[] pieces = serverData.split("\\.");
+ String[] actions = getRules(pieces[0]);
+ int idx = status.getTransportServerConnectionCount(server);
+
+ MessagingException ex = getException(actions, idx, null, server);
+ if (ex != null) throwME(ex);
+ }
+
+ public void onSendMessage(TestStatus status, String server, Listing pmails) throws MessagingException, SendFailedException {
+ String serverData = server;
+ if (serverData.indexOf("://") >= 0) serverData = serverData.substring(serverData.indexOf("://") + 3);
+ if (serverData.indexOf(":") >= 0) serverData = serverData.substring(0, serverData.indexOf(":"));
+ String[] serverPieces = serverData.split("\\.");
+
+ HashMap exceptionMap = new HashMap();
+ int idx = status.getTransportServerSendCount(server);
+
+ for (int i = 1; i < serverPieces.length - 1; i++) {
+ String[] actions = getRules(serverPieces[i]);
+ if (actions[0].endsWith("*") && actions[0].length() > 1) {
+ String match = actions[0].substring(0, actions[0].length() - 1);
+ for (int j = 0; j < pmails.size(); j++) if (pmails.get(j).getRecipient().toString().startsWith(match) || match.equals("*")) {
+ MessagingException ex = getException(actions, idx, pmails.get(j), server);
+ addException(exceptionMap, ex, pmails.get(j).getRecipient().toInternetAddress());
+ } else addException(exceptionMap, null, pmails.get(j).getRecipient().toInternetAddress());
+ }
+ }
+
+ for (int i = 1; i < serverPieces.length - 1; i++) {
+ String[] actions = getRules(serverPieces[i]);
+ if (actions[0].equals("*")) {
+ MessagingException ex = getException(actions, idx, null, server);
+ addException(exceptionMap, ex, null);
+ }
+ }
+
+ MessagingException ex = getRootException(exceptionMap);
+ if (ex != null) throwME(ex);
+ }
+
+ public void throwME(MessagingException ex) throws MessagingException {
+ if (ex instanceof NullMessagingException) throw new NullPointerException();
+ if (ex instanceof IOMessagingException) {
+ MessagingException me = new MessagingException();
+ me.setNextException(new IOException());
+ throw me;
+ }
+ throw ex;
+ }
+ }
+
+}
Propchange: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TransportRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: james/server/trunk/mailets-function/src/test/java/org/apache/james/transport/remotedeliverytester/TransportRule.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org