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 no...@apache.org on 2010/04/03 18:31:28 UTC

svn commit: r930538 - in /james/server/trunk: core-library/src/main/java/org/apache/james/core/ spoolmanager/src/main/java/org/apache/james/ spoolmanager/src/main/java/org/apache/james/transport/camel/ spoolmanager/src/main/java/org/apache/james/transp...

Author: norman
Date: Sat Apr  3 16:31:27 2010
New Revision: 930538

URL: http://svn.apache.org/viewvc?rev=930538&view=rev
Log:
Store the MimeMessage on extra storage and not in jms. At the moment only fs is supported (See JAMES-985)

Added:
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/FileSpoolMessageStore.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/SpoolMessageStore.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailClaimCheck.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailEnricher.java
    james/server/trunk/spoolmanager/src/test/java/org/apache/james/InMemorySpoolMessageStore.java
Removed:
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/InMemoryMail.java
Modified:
    james/server/trunk/core-library/src/main/java/org/apache/james/core/MailImpl.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/AbstractMailServer.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/AbstractProcessorRouteBuilder.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/DisposeProcessor.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MatcherSplitter.java
    james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/mailets/AbstractRemoteDelivery.java
    james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml

Modified: james/server/trunk/core-library/src/main/java/org/apache/james/core/MailImpl.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/core/MailImpl.java?rev=930538&r1=930537&r2=930538&view=diff
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/core/MailImpl.java (original)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/core/MailImpl.java Sat Apr  3 16:31:27 2010
@@ -25,10 +25,8 @@ import org.apache.james.lifecycle.Dispos
 import org.apache.james.lifecycle.LifecycleUtil;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailAddress;
-import org.apache.mailet.base.RFC2822Headers;
 
 import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.ParseException;
 
@@ -214,30 +212,7 @@ public class MailImpl implements Disposa
         this.setMessage(new MimeMessageCopyOnWriteProxy(message));
     }
 
-    /**
-     * Gets the MailAddress corresponding to the existing "Return-Path" of
-     * <I>message</I>.
-     * If missing or empty returns <CODE>null</CODE>,
-     */
-    private MailAddress getReturnPath(MimeMessage message) throws MessagingException {
-        MailAddress mailAddress = null;
-        String[] returnPathHeaders = message.getHeader(RFC2822Headers.RETURN_PATH);
-        String returnPathHeader = null;
-        if (returnPathHeaders != null) {
-            returnPathHeader = returnPathHeaders[0];
-            if (returnPathHeader != null) {
-                returnPathHeader = returnPathHeader.trim();
-                if (!returnPathHeader.equals("<>")) {
-                    try {
-                        mailAddress = new MailAddress(new InternetAddress(returnPathHeader, false));
-                    } catch (ParseException pe) {
-                        throw new MessagingException("Could not parse address: " + returnPathHeader + " from " + message.getHeader(RFC2822Headers.RETURN_PATH, ", "), pe);
-                    }
-                }
-            }
-        }
-        return mailAddress;
-    }
+
     /**
      * Duplicate the MailImpl.
      *

Modified: james/server/trunk/spoolmanager/src/main/java/org/apache/james/AbstractMailServer.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/AbstractMailServer.java?rev=930538&r1=930537&r2=930538&view=diff
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/AbstractMailServer.java (original)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/AbstractMailServer.java Sat Apr  3 16:31:27 2010
@@ -39,8 +39,13 @@ import javax.mail.internet.InternetAddre
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.ParseException;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
+import org.apache.camel.Processor;
 import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.commons.logging.Log;
@@ -55,7 +60,7 @@ import org.apache.james.lifecycle.Config
 import org.apache.james.lifecycle.LifecycleUtil;
 import org.apache.james.lifecycle.LogEnabled;
 import org.apache.james.services.MailServer;
-import org.apache.james.transport.camel.InMemoryMail;
+import org.apache.james.transport.camel.DisposeProcessor;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailAddress;
 
@@ -72,7 +77,7 @@ import org.apache.mailet.MailAddress;
  */
 @SuppressWarnings("unchecked")
 public abstract class AbstractMailServer
-    implements MailServer, LogEnabled, Configurable {
+    implements MailServer, LogEnabled, Configurable, CamelContextAware {
 
     /**
      * The software name and version
@@ -118,6 +123,8 @@ public abstract class AbstractMailServer
 
     private ProducerTemplate producerTemplate;
 
+    private CamelContext context;
+
     @Resource(name="domainlist")
     public void setDomainList(DomainList domains) {
         this.domains = domains;
@@ -154,6 +161,9 @@ public abstract class AbstractMailServer
     public void init() throws Exception {
 
         logger.info("JAMES init...");
+        // Add camel route
+        getCamelContext().addRoutes(new InjectionRouteBuilder());
+                
 
         if (conf.getKeys("usernames").hasNext()) {
             HierarchicalConfiguration userNamesConf = conf.configurationAt("usernames");
@@ -298,17 +308,15 @@ public abstract class AbstractMailServer
      * @see org.apache.james.services.MailServer#sendMail(Mail)
      */
     public void sendMail(Mail mail) throws MessagingException {
-        Mail newMail = null;
         try {
-        	newMail = new InMemoryMail(mail);
-            producerTemplate.sendBody(getToUri(mail), ExchangePattern.InOnly, newMail);
+            producerTemplate.sendBody("direct:mailserver", ExchangePattern.InOnly, mail);
                         
         } catch (Exception e) {
             logger.error("Error storing message: " + e.getMessage(),e);
-            throw new MessagingException("Exception spooling message: " + e.getMessage(), e);
-        } finally {
-            LifecycleUtil.dispose(newMail);
             LifecycleUtil.dispose(mail);
+
+            throw new MessagingException("Exception spooling message: " + e.getMessage(), e);
+
         }
         if (logger.isDebugEnabled()) {
             StringBuffer logBuffer =
@@ -436,4 +444,50 @@ public abstract class AbstractMailServer
      * 
      */
     protected abstract String getToUri(Mail mail);
+    
+    
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.camel.CamelContextAware#getCamelContext()
+     */
+    public CamelContext getCamelContext() {
+        return context;
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.camel.CamelContextAware#setCamelContext(org.apache.camel.CamelContext)
+     */
+    public void setCamelContext(CamelContext context) {      
+        this.context = context;
+    }
+    
+       
+    private final class InjectionRouteBuilder extends RouteBuilder {
+        private final static String SLIP ="JAMES_TO_SLIP";
+        @Override
+        public void configure() throws Exception {
+            Processor disposeProcessor = new DisposeProcessor();
+
+            from("direct:mailserver").inOnly()
+
+            // dispose the mail object if an exception was thrown while
+            // processing this route
+            .onException(Exception.class).process(disposeProcessor).end()
+
+            // dispose the mail object if route processing was complete
+           .onCompletion().process(disposeProcessor).end()
+
+           .transacted().pipeline().beanRef("mailClaimCheck").process(new Processor() {
+
+               public void process(Exchange ex) throws Exception {
+
+                   ex.getIn().setHeader(SLIP, getToUri(ex.getIn().getBody(Mail.class)));
+               }
+           }).routingSlip(SLIP);
+        }
+
+    }
+
 }

Added: james/server/trunk/spoolmanager/src/main/java/org/apache/james/FileSpoolMessageStore.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/FileSpoolMessageStore.java?rev=930538&view=auto
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/FileSpoolMessageStore.java (added)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/FileSpoolMessageStore.java Sat Apr  3 16:31:27 2010
@@ -0,0 +1,131 @@
+/****************************************************************
+ * 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;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.james.core.MimeMessageSource;
+import org.apache.james.lifecycle.Disposable;
+
+/**
+ * Use the filesystem as storage for the Email message while spooling
+ * 
+ *
+ */
+public class FileSpoolMessageStore implements SpoolMessageStore{
+
+    private final String PROCESSING_SUFFIX =".processing";
+
+    private File spooldir;
+    
+    public FileSpoolMessageStore(String storageDir) {
+        spooldir = new File(storageDir);
+        if (spooldir.exists()) {
+            if (spooldir.isFile()) {
+                throw new RuntimeException("Spooldirectory " + storageDir + " already exists and is a file!");
+            }
+        } else {
+            if (spooldir.mkdirs() == false) {
+                throw new RuntimeException("Unable to create Spooldirectory " + spooldir);
+            }
+        }
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.SpoolMessageStore#getMessage(java.lang.String)
+     */
+    public synchronized MimeMessageSource getMessage(String key) throws IOException{
+        File f = new File(spooldir, key);
+        File processingF = new File(f.getCanonicalPath() + PROCESSING_SUFFIX);
+
+        if (f.exists()) {
+            
+            // delete processing file
+            processingF.delete();
+            
+            // rename the old file .processing, so we don't get trouble when saving it back the the fs
+            if (f.renameTo(processingF) == false) {
+                throw new IOException("Unable to rename file " + f + " to " + processingF);
+            }
+            return new FileMimeMessageSource(processingF);
+        } else {
+            // delete processing file
+            processingF.delete();
+
+            if (processingF.createNewFile()) {
+                return new FileMimeMessageSource(processingF);
+            }
+            throw new IOException("Unable to create file " + processingF);
+
+        }
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.SpoolMessageStore#saveMessage(java.lang.String)
+     */
+    public synchronized OutputStream saveMessage(String key) throws IOException{
+        File f = new File(spooldir,key);
+        if (f.exists()) {
+            throw new IOException("Unable to create file because a file with the name " + f + " already exists");
+        } else {
+            // just create the file
+            f.createNewFile();
+            return new FileOutputStream(f);   
+        }
+
+        
+    }
+
+    /**
+     * {@link MimeMessageSource} which use the filesystem 
+     *
+     */
+    private final class FileMimeMessageSource extends MimeMessageSource implements Disposable {
+
+        private File file;
+        private String id;
+        
+        private FileMimeMessageSource(File file) throws IOException {
+            this.file = file;
+            this.id = file.getCanonicalPath();
+        }
+        
+        @Override
+        public InputStream getInputStream() throws IOException {
+            return new FileInputStream(file);
+        }
+
+        @Override
+        public String getSourceId() {
+            return id;
+        }
+
+        public void dispose() {
+            file.delete();
+        }
+        
+    }
+}

Added: james/server/trunk/spoolmanager/src/main/java/org/apache/james/SpoolMessageStore.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/SpoolMessageStore.java?rev=930538&view=auto
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/SpoolMessageStore.java (added)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/SpoolMessageStore.java Sat Apr  3 16:31:27 2010
@@ -0,0 +1,52 @@
+/****************************************************************
+ * 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;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.james.core.MimeMessageSource;
+
+
+/**
+ * Store which store the complete Email message for spooling. This is used via 
+ * Claim check in conjunction with JMS
+ * 
+ *
+ */
+public interface SpoolMessageStore {
+
+    /**
+     * Return a OutputStream for the given key which can be used to write the 
+     * Email message to
+     * 
+     * @param key
+     * @return out
+     */
+    public OutputStream saveMessage(String key) throws IOException;
+    
+    
+    /**
+     * Return the Email message as {@link MimeMessageSource}
+     * 
+     * @param key
+     * @return source
+     */
+    public MimeMessageSource getMessage(String key) throws IOException;
+}

Modified: james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/AbstractProcessorRouteBuilder.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/AbstractProcessorRouteBuilder.java?rev=930538&r1=930537&r2=930538&view=diff
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/AbstractProcessorRouteBuilder.java (original)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/AbstractProcessorRouteBuilder.java Sat Apr  3 16:31:27 2010
@@ -106,15 +106,9 @@ public abstract class AbstractProcessorR
                 
                 // use transaction
                 .transacted()
-                
-                // dispose the mail object if an exception was thrown while processing this route
-                .onException(Exception.class).process(disposeProcessor).end()
-                
-                // dispose the mail object if route processing was complete
-                .onCompletion().process(disposeProcessor).end()
-                
+               
                 // check that body is not null, just to be sure...
-                .choice().when(body().isNotNull());
+                .choice().when(body().isNotNull()).beanRef("mailEnricher");
             
             final List<HierarchicalConfiguration> mailetConfs = processorConf.configurationsAt("mailet");
             // Loop through the mailet configuration, load
@@ -219,11 +213,11 @@ public abstract class AbstractProcessorR
                             .choice()
                
                             // if the mailstate is GHOST whe should just dispose and stop here.
-                            .when(new MailStateEquals(Mail.GHOST)).stop()
+                            .when(new MailStateEquals(Mail.GHOST)).process(disposeProcessor).stop()
                              
                             // check if the state of the mail is the same as the
                             // current processor. If not just route it to the right endpoint via recipientList and stop processing.
-                            .when(new MailStateNotEquals(processorName)).recipientList().method(getRecipientList()).stop()
+                            .when(new MailStateNotEquals(processorName)).beanRef("mailClaimCheck").recipientList().method(getRecipientList()).stop()
                             
                             // end first choice
                             .end()
@@ -257,7 +251,7 @@ public abstract class AbstractProcessorR
                     .end()
                     
                      // route it to the right processor
-                    .recipientList().method(getRecipientList());
+                    .beanRef("mailClaimCheck").recipientList().method(getRecipientList());
                   
         }
     }

Modified: james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/DisposeProcessor.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/DisposeProcessor.java?rev=930538&r1=930537&r2=930538&view=diff
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/DisposeProcessor.java (original)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/DisposeProcessor.java Sat Apr  3 16:31:27 2010
@@ -22,6 +22,7 @@ package org.apache.james.transport.camel
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.james.lifecycle.LifecycleUtil;
+import org.apache.mailet.Mail;
 
 /**
  * Processor which dispose body object if needed
@@ -35,7 +36,10 @@ public class DisposeProcessor implements
      * @see org.apache.camel.Processor#process(org.apache.camel.Exchange)
      */
     public void process(Exchange arg0) throws Exception {
-        LifecycleUtil.dispose(arg0.getIn().getBody());
+        Mail mail = arg0.getIn().getBody(Mail.class);
+        LifecycleUtil.dispose(mail.getMessage());
+        LifecycleUtil.dispose(mail);
+
     }
 
 }

Added: james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailClaimCheck.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailClaimCheck.java?rev=930538&view=auto
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailClaimCheck.java (added)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailClaimCheck.java Sat Apr  3 16:31:27 2010
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.camel;
+
+
+
+import java.io.OutputStream;
+
+import javax.annotation.Resource;
+
+import org.apache.camel.Body;
+import org.apache.camel.Exchange;
+import org.apache.james.SpoolMessageStore;
+import org.apache.mailet.Mail;
+
+/**
+ * Bean which is used in the camel route to store the real message content to some external
+ * storage. This is needed because JMS is not really the best solution for big content
+ * 
+ * This Bean should get called before the Exchange object get send the JMS Endpoint
+ *
+ */
+public final class MailClaimCheck {
+    
+    private SpoolMessageStore spoolMessageStore;
+
+    @Resource(name="spoolMessageStore")
+    public void setSpooolMessageStore(SpoolMessageStore spoolMessageStore) {
+        this.spoolMessageStore = spoolMessageStore;
+    }
+    
+    
+    /**
+     * Save the Email Message to an external storage
+     * 
+     * @param exchange
+     * @param mail
+     * @throws Exception
+     */
+    public void saveMessage(Exchange exchange, @Body Mail mail) throws Exception{
+        
+        OutputStream out = spoolMessageStore.saveMessage(mail.getName());
+        // write the message to the store
+        mail.getMessage().writeTo(out);
+        
+        // close stream
+        out.close();
+        
+    }
+}

Added: james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailEnricher.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailEnricher.java?rev=930538&view=auto
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailEnricher.java (added)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MailEnricher.java Sat Apr  3 16:31:27 2010
@@ -0,0 +1,70 @@
+/****************************************************************
+ * 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.camel;
+
+import java.io.IOException;
+
+import javax.annotation.Resource;
+import javax.mail.MessagingException;
+
+import org.apache.camel.Body;
+import org.apache.camel.Exchange;
+import org.apache.james.SpoolMessageStore;
+import org.apache.james.core.MimeMessageCopyOnWriteProxy;
+import org.apache.james.core.MimeMessageWrapper;
+import org.apache.mailet.Mail;
+
+/**
+ * Enricher which will fetch the Email Message from an external storage and add it to the Mail
+ * object which is stored in the {@link Body} of the {@link Exchange}. 
+ * 
+ * This should be used after the {@link Exchange} was consumed from the JMS queue
+ * 
+ *
+ */
+public final class MailEnricher {
+    
+    
+    private SpoolMessageStore spoolMessageStore;
+
+    @Resource(name="spoolMessageStore")
+    public void setSpooolMessageStore(SpoolMessageStore spoolMessageStore) {
+        this.spoolMessageStore = spoolMessageStore;
+    }
+    
+    
+    /**
+     * Get the Email Message from external storage and add it to the Mail object in the {@link Body}
+     * 
+     * @param exchange
+     * @param mail
+     * @throws MessagingException
+     */
+    public void enrich(Exchange exchange, @Body Mail mail) throws MessagingException {
+        String key = mail.getName();
+        
+        // put back the MimeMessage
+        try {
+            mail.setMessage(new MimeMessageCopyOnWriteProxy(new MimeMessageWrapper(spoolMessageStore.getMessage(key))));
+        } catch (IOException e) {
+            throw new MessagingException("Unable to enrich mail " + mail, e);
+        }
+    }
+
+}

Modified: james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MatcherSplitter.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MatcherSplitter.java?rev=930538&r1=930537&r2=930538&view=diff
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MatcherSplitter.java (original)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/camel/MatcherSplitter.java Sat Apr  3 16:31:27 2010
@@ -32,6 +32,7 @@ import org.apache.camel.Handler;
 import org.apache.camel.InOnly;
 import org.apache.camel.Property;
 import org.apache.commons.logging.Log;
+import org.apache.james.core.MailImpl;
 import org.apache.james.transport.ProcessorUtil;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailAddress;
@@ -113,7 +114,7 @@ public class MatcherSplitter {
             Iterator<MailAddress> rcptsIterator = matchedRcpts.iterator();
             
             while(rcptsIterator.hasNext()) {
-                // loop through the recipients and remove the recipiends that matched
+                // loop through the recipients and remove the recipients that matched
                 rcpts.remove(rcptsIterator.next());
             }
             
@@ -123,7 +124,7 @@ public class MatcherSplitter {
             } else {
                 mail.setRecipients(rcpts);
                 
-                Mail newMail = new InMemoryMail(mail);
+                Mail newMail = new MailImpl(mail);
                 newMail.setRecipients(matchedRcpts);
                 
               

Modified: james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/mailets/AbstractRemoteDelivery.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/mailets/AbstractRemoteDelivery.java?rev=930538&r1=930537&r2=930538&view=diff
==============================================================================
--- james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/mailets/AbstractRemoteDelivery.java (original)
+++ james/server/trunk/spoolmanager/src/main/java/org/apache/james/transport/mailets/AbstractRemoteDelivery.java Sat Apr  3 16:31:27 2010
@@ -59,9 +59,9 @@ import org.apache.camel.ProducerTemplate
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.james.api.dnsservice.DNSService;
 import org.apache.james.api.dnsservice.TemporaryResolutionException;
+import org.apache.james.core.MailImpl;
 import org.apache.james.services.MailServer;
 import org.apache.james.transport.camel.DisposeProcessor;
-import org.apache.james.transport.camel.InMemoryMail;
 import org.apache.james.transport.camel.JamesCamelConstants;
 import org.apache.james.util.TimeConverter;
 import org.apache.mailet.HostAddress;
@@ -580,7 +580,7 @@ public abstract class AbstractRemoteDeli
                     StringBuilder logMessageBuffer = new StringBuilder(128).append("Sending mail to ").append(rec).append(" on host ").append(host);
                     log(logMessageBuffer.toString());
                 }
-                Mail m = new InMemoryMail(mail);
+                Mail m = new MailImpl(mail);
                 m.setRecipients(rec);
                 StringBuilder nameBuffer = new StringBuilder(128).append(name).append("-to-").append(host);
                 m.setName(nameBuffer.toString());
@@ -597,7 +597,7 @@ public abstract class AbstractRemoteDeli
                 log(logMessageBuffer.toString());
             }
 
-            producerTemplate.sendBody("activemq:queue:" + outgoingQueue, new InMemoryMail(mail));
+            producerTemplate.sendBody("activemq:queue:" + outgoingQueue, mail);
 
             // Set it to try to deliver (in a separate thread) immediately
             // (triggered by storage)
@@ -1553,26 +1553,12 @@ public abstract class AbstractRemoteDeli
         @Override
         public void configure() throws Exception {
             from(getOutgoingQueueEndpoint(outgoingQueue)).inOnly().transacted()
-
-            // dispose the mail object if an exception was thrown while
-            // processing this route
-                    .onException(Exception.class).process(disposeProcessor).end()
-
-                    // dispose the mail object if route processing was complete
-                    .onCompletion().process(disposeProcessor).end()
-
-                    .process(new DeliveryProcessor()).choice().when(header(JamesCamelConstants.JAMES_RETRY_DELIVERY).isNotNull()).to(getOutgoingRetryQueueEndpoint(outgoingRetryQueue)).otherwise().stop().end();
+            
+            .process(new DeliveryProcessor()).choice().when(header(JamesCamelConstants.JAMES_RETRY_DELIVERY).isNotNull()).to(getOutgoingRetryQueueEndpoint(outgoingRetryQueue)).otherwise().process(disposeProcessor).stop().end();
 
             fromF("pollingjms:queue?delay=30000&consumer.endpointUri=%s", getOutgoingRetryQueueEndpoint(outgoingRetryQueue)).inOnly().transacted()
 
-            // dispose the mail object if an exception was thrown while
-            // processing this route
-                    .onException(Exception.class).process(disposeProcessor).end()
-
-                    // dispose the mail object if route processing was complete
-                    .onCompletion().process(disposeProcessor).end()
-
-                    .process(new DeliveryProcessor()).choice().when(header(JamesCamelConstants.JAMES_RETRY_DELIVERY).isNotNull()).toF(getOutgoingRetryQueueEndpoint(outgoingRetryQueue)).otherwise().stop().end();
+            .process(new DeliveryProcessor()).choice().when(header(JamesCamelConstants.JAMES_RETRY_DELIVERY).isNotNull()).toF(getOutgoingRetryQueueEndpoint(outgoingRetryQueue)).otherwise().process(disposeProcessor).stop().end();
         }
 
     }

Added: james/server/trunk/spoolmanager/src/test/java/org/apache/james/InMemorySpoolMessageStore.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager/src/test/java/org/apache/james/InMemorySpoolMessageStore.java?rev=930538&view=auto
==============================================================================
--- james/server/trunk/spoolmanager/src/test/java/org/apache/james/InMemorySpoolMessageStore.java (added)
+++ james/server/trunk/spoolmanager/src/test/java/org/apache/james/InMemorySpoolMessageStore.java Sat Apr  3 16:31:27 2010
@@ -0,0 +1,79 @@
+/****************************************************************
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.james.SpoolMessageStore;
+import org.apache.james.core.MimeMessageSource;
+
+public class InMemorySpoolMessageStore implements SpoolMessageStore{
+
+    private Map<String, ByteArrayOutputStream> map = new HashMap<String, ByteArrayOutputStream>();
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.SpoolMessageStore#getMessage(java.lang.String)
+     */
+    public MimeMessageSource getMessage(final String key) {
+        return new MimeMessageSource() {
+            private InputStream in = new ByteArrayInputStream(map.get(key).toByteArray());
+            @Override
+            public InputStream getInputStream() throws IOException {
+                return in;
+            }
+
+            @Override
+            public String getSourceId() {
+                return key;
+            }
+            
+        };
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.SpoolMessageStore#saveMessage(java.lang.String)
+     */
+    public OutputStream saveMessage(String key) {
+        ByteArrayOutputStream out = map.get(key);
+        if (out == null) {
+            out = new ByteArrayOutputStream();
+            map.put(key, out);
+        } else {
+            out.reset();
+        }
+        return out;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.SpoolMessageStore#remove(java.lang.String)
+     */
+    public void remove(String key) {
+        map.remove(key);
+    }
+
+}

Modified: james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml
URL: http://svn.apache.org/viewvc/james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml?rev=930538&r1=930537&r2=930538&view=diff
==============================================================================
--- james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml (original)
+++ james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml Sat Apr  3 16:31:27 2010
@@ -159,6 +159,13 @@
         <property name="start" value="true" />
     </bean>
 
+    <bean id ="spoolMessageStore" class="org.apache.james.FileSpoolMessageStore">
+        <constructor-arg index="0" value="../var/mail/spool"/>
+    </bean> 
+    <bean id ="mailClaimCheck" class="org.apache.james.transport.camel.MailClaimCheck"/>
+    <bean id ="mailEnricher" class="org.apache.james.transport.camel.MailEnricher"/>
+
+
     <!-- mailserver implementation which use activemq for spooling the mail -->
     <bean id="mailserver" name="James" class="org.apache.james.ActiveMQMailServer"/>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org