james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b...@apache.org
Subject svn commit: r531245 - in /james/jspf/branches/asynch-jspf/src: main/java/org/apache/james/jspf/ main/java/org/apache/james/jspf/core/ main/java/org/apache/james/jspf/impl/ test/java/org/apache/james/jspf/
Date Sun, 22 Apr 2007 18:14:30 GMT
Author: bago
Date: Sun Apr 22 11:14:29 2007
New Revision: 531245

URL: http://svn.apache.org/viewvc?view=rev&rev=531245
Log:
FutureSPFResult and first approach to asynchronous Lookup.
Created a StagedMultipleSPFExecutor that should handle asynchronous processing via 1 working
thread.
Currently the dns call is still synchronous (not yet imported dnsjnio)

Added:
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/FutureSPFResult.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponse.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponseQueue.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFExecutor.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/StagedMultipleSPFExecutor.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SynchronousSPFExecutor.java
    james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/ResponseImpl.java
Modified:
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPF.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPFResult.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/DNSService.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFSession.java
    james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java
    james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/AbstractYamlTest.java
    james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/LoggingDNSService.java

Added: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/FutureSPFResult.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/FutureSPFResult.java?view=auto&rev=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/FutureSPFResult.java
(added)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/FutureSPFResult.java
Sun Apr 22 11:14:29 2007
@@ -0,0 +1,78 @@
+/****************************************************************
+ * 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.jspf;
+
+import org.apache.james.jspf.core.SPFSession;
+
+public class FutureSPFResult extends SPFResult {
+    
+    boolean isReady;
+    
+    public FutureSPFResult() {
+        isReady = false;
+    }
+    
+    public synchronized void setSPFResult(SPFSession session) {
+        setSPFSession(session);
+        isReady = true;
+        notify();
+    }
+
+    private synchronized void checkReady() {
+        while (!isReady) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                //
+            }
+        }
+    }
+
+    public String getExplanation() {
+        checkReady();
+        return super.getExplanation();
+    }
+
+    public String getHeader() {
+        checkReady();
+        return super.getHeader();
+    }
+
+    public String getHeaderName() {
+        checkReady();
+        return super.getHeaderName();
+    }
+
+    public String getHeaderText() {
+        checkReady();
+        return super.getHeaderText();
+    }
+
+    public String getResult() {
+        checkReady();
+        return super.getResult();
+    }
+
+    public boolean isReady() {
+        return isReady;
+    }
+    
+
+}

Modified: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPF.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPF.java?view=diff&rev=531245&r1=531244&r2=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPF.java (original)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPF.java Sun Apr 22
11:14:29 2007
@@ -21,16 +21,16 @@
 package org.apache.james.jspf;
 
 import org.apache.james.jspf.core.DNSLookupContinuation;
-import org.apache.james.jspf.core.DNSResponse;
 import org.apache.james.jspf.core.DNSService;
 import org.apache.james.jspf.core.Logger;
 import org.apache.james.jspf.core.SPF1Constants;
 import org.apache.james.jspf.core.SPF1Record;
 import org.apache.james.jspf.core.SPFChecker;
 import org.apache.james.jspf.core.SPFCheckerExceptionCatcher;
+import org.apache.james.jspf.core.SPFExecutor;
 import org.apache.james.jspf.core.SPFRecordParser;
 import org.apache.james.jspf.core.SPFSession;
-import org.apache.james.jspf.core.DNSService.TimeoutException;
+import org.apache.james.jspf.core.SynchronousSPFExecutor;
 import org.apache.james.jspf.exceptions.NeutralException;
 import org.apache.james.jspf.exceptions.NoneException;
 import org.apache.james.jspf.exceptions.PermErrorException;
@@ -66,7 +66,44 @@
  */
 public class SPF implements SPFChecker {
 
-    private final class SPFRecordChecker implements SPFChecker {
+    private final class SPFCheckerExceptionCatcherImplementation implements
+            SPFCheckerExceptionCatcher {
+        private SPFChecker resultHandler;
+
+        public SPFCheckerExceptionCatcherImplementation(SPFChecker resultHandler) {
+            this.resultHandler = resultHandler;
+        }
+
+        /**
+         * @see org.apache.james.jspf.core.SPFCheckerExceptionCatcher#onException(java.lang.Exception,
org.apache.james.jspf.core.SPFSession)
+         */
+        public void onException(Exception exception, SPFSession session)
+                throws PermErrorException, NoneException, TempErrorException,
+                NeutralException {
+
+            SPFChecker checker;
+            while ((checker = session.popChecker())!=resultHandler) {
+                log.debug("Redirect resulted in exception. Removing checker: "+checker);
+            }
+
+            String result;
+            if (exception instanceof SPFResultException) {
+                result = ((SPFResultException) exception).getResult();
+                if (!SPF1Utils.NEUTRAL_CONV.equals(result)) {
+                    log.warn(exception.getMessage(),exception);
+                }
+            } else {
+                // this should never happen at all. But anyway we will set the
+                // result to neutral. Safety first ..
+                log.error(exception.getMessage(),exception);
+                result = SPF1Constants.NEUTRAL;
+            }
+            session.setCurrentResultExpanded(result);
+            
+        }
+    }
+
+    private static final class SPFRecordChecker implements SPFChecker {
         public DNSLookupContinuation checkSPF(SPFSession spfData)
                 throws PermErrorException, TempErrorException,
                 NeutralException, NoneException {
@@ -92,14 +129,20 @@
         }
     }
 
-    private final class PolicyChecker implements SPFChecker {
+    private static final class PolicyChecker implements SPFChecker {
+        
+        private LinkedList policies;
+        
+        public PolicyChecker(LinkedList policies) {
+            this.policies = policies;
+        }
+        
         public DNSLookupContinuation checkSPF(SPFSession spfData)
                 throws PermErrorException, TempErrorException,
                 NeutralException, NoneException {
-            LinkedList resultCheckers = getPolicies();
-
-            while (resultCheckers.size() > 0) {
-                SPFChecker removeLast = (SPFChecker) resultCheckers.removeLast();
+            
+            while (policies.size() > 0) {
+                SPFChecker removeLast = (SPFChecker) policies.removeLast();
                 spfData.pushChecker(removeLast);
             }
             
@@ -107,7 +150,7 @@
         }
     }
 
-    private final class SPFPolicyChecker implements SPFChecker {
+    private static final class SPFPolicyChecker implements SPFChecker {
         private Policy policy;
 
         /**
@@ -133,7 +176,7 @@
         }
     }
 
-    private final class SPFPolicyPostFilterChecker implements SPFChecker {
+    private static final class SPFPolicyPostFilterChecker implements SPFChecker {
         private PolicyPostFilter policy;
 
         /**
@@ -180,6 +223,8 @@
 
     private MacroExpand macroExpand;
 
+    private SPFExecutor executor;
+
     /**
      * Uses passed logger and passed dnsServicer
      * 
@@ -198,6 +243,7 @@
         this.parser = new DefaultSPF1Parser(logger.getChildLogger("parser"), new DefaultTermsFactory(logger.getChildLogger("termsfactory"),
wiringService));
         // We add this after the parser creation because services cannot be null
         wiringService.put(SPFCheckEnabled.class, this);
+        this.executor = new SynchronousSPFExecutor(log, dnsProbe);
     }
     
     
@@ -208,12 +254,13 @@
      * @param parser the parser to use
      * @param logger the logger to use
      */
-    public SPF(DNSService dnsProbe, SPFRecordParser parser, Logger logger, MacroExpand macroExpand)
{
+    public SPF(DNSService dnsProbe, SPFRecordParser parser, Logger logger, MacroExpand macroExpand,
SPFExecutor executor) {
         super();
         this.dnsProbe = dnsProbe;
         this.parser = parser;
         this.log = logger;
         this.macroExpand = macroExpand;
+        this.executor = executor;
     }
 
     /**
@@ -229,90 +276,59 @@
      */
     public SPFResult checkSPF(String ipAddress, String mailFrom, String hostName) {
         SPFSession spfData = null;
-        String result = null;
-        String explanation = null;
 
+        // Setup the data
         try {
-            // Setup the data
             spfData = new SPFSession(mailFrom, hostName, ipAddress);
-            
-            
-            spfData.pushChecker(this);
-            SPFChecker checker;
-            while ((checker = spfData.popChecker()) != null) {
-                // only execute checkers we added (better recursivity)
-                log.debug("Executing checker: "+checker);
-                try {
-                    DNSLookupContinuation cont = checker.checkSPF(spfData);
-                    // if the checker returns a continuation we return it
-                    while (cont != null) {
-                        DNSResponse response;
-                        try {
-                            response = new DNSResponse(dnsProbe.getRecords(
-                                    cont.getRequest().getHostname(), cont.getRequest().getRecordType()));
-                        } catch (TimeoutException e) {
-                            response = new DNSResponse(e);
-                        }
-                        cont = cont.getListener().onDNSResponse(response, spfData);
-                    }
-                } catch (Exception e) {
-                    SPFCheckerExceptionCatcher catcher = spfData.getExceptionCatcher();
-                    if (catcher != null) {
-                        catcher.onException(e, spfData);
-                    } else {
-                        log.debug("Checker execution resulted in unmanaged exception: "+checker+"
=> "+e);
-                        if (e instanceof PermErrorException) {
-                            throw (PermErrorException) e;
-                        } else if (e instanceof TempErrorException) {
-                            throw (TempErrorException) e;
-                        } else if (e instanceof NeutralException) {
-                            throw (NeutralException) e;
-                        } else if (e instanceof NoneException) {
-                            throw (NoneException) e;
-                        } else {
-                            throw new IllegalStateException(e);
-                        }
-                    }
+        } catch (PermErrorException e1) {
+            spfData.setCurrentResultExpanded(e1.getResult());
+        } catch (NoneException e1) {
+            spfData.setCurrentResultExpanded(e1.getResult());
+        }
+
+        SPFChecker resultHandler = new SPFChecker() {
+
+            public DNSLookupContinuation checkSPF(SPFSession spfData)
+                    throws PermErrorException, TempErrorException,
+                    NeutralException, NoneException {
+                if (spfData.getCurrentResultExpanded() == null) {
+                    String resultChar = spfData.getCurrentResult() != null ? spfData.getCurrentResult()
: "";
+                    String result = SPF1Utils.resultToName(resultChar);
+                    spfData.setCurrentResultExpanded(result);
                 }
+                return null;
             }
-            
-            
-            String resultChar = spfData.getCurrentResult() != null ? spfData.getCurrentResult()
: "";
-            result = SPF1Utils.resultToName(resultChar);
-            explanation = spfData.getExplanation();
-        } catch (SPFResultException e) {
-            result = e.getResult();
-            if (!SPF1Utils.NEUTRAL_CONV.equals(result)) {
-                log.warn(e.getMessage(),e);
-            }
-        } catch (IllegalStateException e) {
-            // this should never happen at all. But anyway we will set the
-            // result to neutral. Safety first ..
-            log.error(e.getMessage(),e);
-            result = SPF1Constants.NEUTRAL;
-        }
 
-        SPFResult ret = new SPFResult(result, explanation, spfData);
+        };
+        
+        spfData.pushChecker(resultHandler);
+        spfData.pushChecker(this);
+        spfData.pushExceptionCatcher(new SPFCheckerExceptionCatcherImplementation(resultHandler));
+        
+        FutureSPFResult ret = new FutureSPFResult();
         
+        executor.execute(spfData, ret);
+
         log.info("[ipAddress=" + ipAddress + "] [mailFrom=" + mailFrom
                 + "] [helo=" + hostName + "] => " + ret.getResult());
 
         return ret;
 
     }
-    
+
+
     /**
      * @see org.apache.james.jspf.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession)
      */
     public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException,
             NoneException, TempErrorException, NeutralException {
 
-        SPFChecker policyChecker = new PolicyChecker();
+        SPFChecker policyChecker = new PolicyChecker(getPolicies());
         SPFChecker recordChecker = new SPFRecordChecker();
         
         spfData.pushChecker(recordChecker);
         spfData.pushChecker(policyChecker);
-        // done
+        
         return null;
     }
 
@@ -439,4 +455,6 @@
     public synchronized void setSPFMustEqualsTXT(boolean mustEquals) {
         this.mustEquals = mustEquals;
     }
+
+
 }

Modified: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPFResult.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPFResult.java?view=diff&rev=531245&r1=531244&r2=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPFResult.java (original)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/SPFResult.java Sun
Apr 22 11:14:29 2007
@@ -28,14 +28,18 @@
  */
 public class SPFResult  {
 
-    private String headerTextAsString = "";
+    protected String headerTextAsString = "";
 
-    private String headerName = "Received-SPF";
+    protected String headerName = "Received-SPF";
     
-    private String result = null;
+    protected String result = null;
 
     protected String explanation = null;
     
+    protected SPFResult() {
+        
+    }
+    
     /**
      * Construct SPFResult
      * 
@@ -43,9 +47,17 @@
      * @param explanation the explanation
      * @param spf1data the SPF1Data
      */
-    public SPFResult(String result, String explanation, SPFSession spf1data) {
-        this.explanation = explanation;
-        this.result = result;
+    public SPFResult(SPFSession spf1data) {
+        setSPFSession(spf1data);
+    }
+    
+    /**
+     * Initialize the result.
+     * @param spf1data
+     */
+    protected void setSPFSession(SPFSession spf1data) {
+        this.explanation = spf1data.getExplanation();
+        this.result = spf1data.getCurrentResultExpanded();
         this.headerTextAsString = generateHeader(result, spf1data);
     }
 

Modified: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/DNSService.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/DNSService.java?view=diff&rev=531245&r1=531244&r2=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/DNSService.java
(original)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/DNSService.java
Sun Apr 22 11:14:29 2007
@@ -52,6 +52,10 @@
      * @throws TempErrorException on timeout.
      */
     public List getRecords(String hostname, int recordType) throws TimeoutException;
+    
+    
+    public void getRecordsAsynch(String hostname, int recordType, Object id, IResponseQueue
responsePool);
+    
 
     /**
      * Try to get all domain names for the running host

Added: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponse.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponse.java?view=auto&rev=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponse.java
(added)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponse.java
Sun Apr 22 11:14:29 2007
@@ -0,0 +1,30 @@
+/****************************************************************
+ * 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.jspf.core;
+
+public interface IResponse {
+    
+    public Object getId();
+    
+    public Object getValue();
+    
+    public Exception getException();
+
+}

Added: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponseQueue.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponseQueue.java?view=auto&rev=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponseQueue.java
(added)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/IResponseQueue.java
Sun Apr 22 11:14:29 2007
@@ -0,0 +1,31 @@
+/****************************************************************
+ * 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.jspf.core;
+
+import java.util.List;
+
+
+public interface IResponseQueue extends List {
+    
+    public IResponse removeResponse();
+    
+    public void insertResponse(IResponse r);
+
+}

Added: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFExecutor.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFExecutor.java?view=auto&rev=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFExecutor.java
(added)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFExecutor.java
Sun Apr 22 11:14:29 2007
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.jspf.core;
+
+import org.apache.james.jspf.FutureSPFResult;
+
+public interface SPFExecutor {
+
+    public void execute(SPFSession session, FutureSPFResult result);
+    
+}

Modified: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFSession.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFSession.java?view=diff&rev=531245&r1=531244&r2=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFSession.java
(original)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SPFSession.java
Sun Apr 22 11:14:29 2007
@@ -76,6 +76,8 @@
     
     private Stack catchers = new Stack();
 
+    private String currentResultExpanded;
+    
     /**
      * Build the SPF1Data from the given parameters
      * 
@@ -396,4 +398,19 @@
             return (SPFCheckerExceptionCatcher) catchers.peek();
         }
     }
+
+    /**
+     * @param result
+     */
+    public void setCurrentResultExpanded(String result) {
+        this.currentResultExpanded = result;
+    }
+
+    /**
+     * @return current result converted/expanded
+     */
+    public String getCurrentResultExpanded() {
+        return currentResultExpanded;
+    }
+
 }

Added: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/StagedMultipleSPFExecutor.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/StagedMultipleSPFExecutor.java?view=auto&rev=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/StagedMultipleSPFExecutor.java
(added)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/StagedMultipleSPFExecutor.java
Sun Apr 22 11:14:29 2007
@@ -0,0 +1,157 @@
+/****************************************************************
+ * 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.jspf.core;
+
+import org.apache.james.jspf.FutureSPFResult;
+import org.apache.james.jspf.core.DNSService.TimeoutException;
+import org.apache.james.jspf.exceptions.SPFResultException;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class StagedMultipleSPFExecutor implements SPFExecutor, Runnable {
+
+    private static final String ATTRIBUTE_STAGED_EXECUTOR_CONTINUATION = "StagedMultipleSPFExecutor.continuation";
+
+    private static class ResponseQueueImpl extends LinkedList implements IResponseQueue {
+
+        private int waitingThreads = 0;
+
+        public synchronized void insertResponse(IResponse r) {
+            addLast(r);
+            notify();
+        }
+
+        public synchronized IResponse removeResponse() {
+            if ( isEmpty() ) {
+                try { waitingThreads++; wait();}
+                catch (InterruptedException e)  {Thread.interrupted();}
+                waitingThreads--;
+            }
+            return (IResponse)removeFirst();        }
+
+        public boolean isEmpty() {
+            return  (size() - waitingThreads <= 0);
+        }
+
+    }
+
+    private Logger log;
+    private DNSService dnsProbe;
+    private Thread worker;
+    private Map sessions;
+    private ResponseQueueImpl responseQueue;
+
+    public StagedMultipleSPFExecutor(Logger log, DNSService service) {
+        this.log = log;
+        this.dnsProbe = service;
+
+        this.responseQueue = new ResponseQueueImpl();
+
+        this.sessions = new HashMap();
+
+        this.worker = new Thread(this);
+        this.worker.setDaemon(true);
+        this.worker.setName("SPFExecutor");
+        this.worker.start();
+    }
+
+    public void execute(SPFSession session, FutureSPFResult result) {
+        
+        SPFChecker checker;
+        while ((checker = session.popChecker()) != null) {
+            // only execute checkers we added (better recursivity)
+            log.debug("Executing checker: " + checker);
+            try {
+                DNSLookupContinuation cont = checker.checkSPF(session);
+                // if the checker returns a continuation we return it
+                if (cont != null) {
+                    dnsProbe.getRecordsAsynch(cont.getRequest().getHostname(), cont.getRequest().getRecordType(),
session, responseQueue);
+                    session.setAttribute(ATTRIBUTE_STAGED_EXECUTOR_CONTINUATION, cont);
+                    sessions.put(session, result);
+                    return;
+                } else {
+                    sessions.remove(sessions);
+                }
+            } catch (Exception e) {
+                while (e != null) {
+                    SPFCheckerExceptionCatcher catcher = session
+                            .getExceptionCatcher();
+                    try {
+                        catcher.onException(e, session);
+                        e = null;
+                    } catch (SPFResultException ex) {
+                        e = ex;
+                    }
+                }
+            }
+        }
+        System.out.println("================> RESULT!!!!!");
+        result.setSPFResult(session);
+    }
+
+    public void run() {
+
+        while (true) {
+            IResponse resp = responseQueue.removeResponse();
+            
+            SPFSession session = (SPFSession) resp.getId();
+            FutureSPFResult result = (FutureSPFResult) sessions.get(resp.getId());
+            sessions.remove(session);
+            DNSLookupContinuation cont = (DNSLookupContinuation) session.getAttribute(ATTRIBUTE_STAGED_EXECUTOR_CONTINUATION);
+            
+            DNSResponse response;
+            if (resp.getException() != null) {
+                response = new DNSResponse((TimeoutException) resp.getException());
+            } else {
+                response = new DNSResponse((List) resp.getValue());
+            }
+            
+            
+            try {
+                cont = cont.getListener().onDNSResponse(response, session);
+                
+                if (cont != null) {
+                    dnsProbe.getRecordsAsynch(cont.getRequest().getHostname(), cont.getRequest().getRecordType(),
session, responseQueue);
+                    session.setAttribute(ATTRIBUTE_STAGED_EXECUTOR_CONTINUATION, cont);
+                    sessions.put(session, result);
+                } else {
+                    execute(session, result);
+                }
+
+            } catch (Exception e) {
+                while (e != null) {
+                    SPFCheckerExceptionCatcher catcher = session
+                            .getExceptionCatcher();
+                    try {
+                        catcher.onException(e, session);
+                        e = null;
+                    } catch (SPFResultException ex) {
+                        e = ex;
+                    }
+                }
+                execute(session, result);
+            }
+        }
+    }
+
+}

Added: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SynchronousSPFExecutor.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SynchronousSPFExecutor.java?view=auto&rev=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SynchronousSPFExecutor.java
(added)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/core/SynchronousSPFExecutor.java
Sun Apr 22 11:14:29 2007
@@ -0,0 +1,71 @@
+/****************************************************************
+ * 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.jspf.core;
+
+import org.apache.james.jspf.FutureSPFResult;
+import org.apache.james.jspf.core.DNSService.TimeoutException;
+import org.apache.james.jspf.exceptions.SPFResultException;
+
+public class SynchronousSPFExecutor implements SPFExecutor {
+    
+    private Logger log;
+    private DNSService dnsProbe;
+
+    public SynchronousSPFExecutor(Logger log, DNSService service) {
+        this.log = log;
+        this.dnsProbe = service;
+    }
+
+    public void execute(SPFSession session, FutureSPFResult result) {
+        SPFChecker checker;
+        while ((checker = session.popChecker()) != null) {
+            // only execute checkers we added (better recursivity)
+            log.debug("Executing checker: " + checker);
+            try {
+                DNSLookupContinuation cont = checker.checkSPF(session);
+                // if the checker returns a continuation we return it
+                while (cont != null) {
+                    DNSResponse response;
+                    try {
+                        response = new DNSResponse(dnsProbe.getRecords(cont
+                                .getRequest().getHostname(), cont.getRequest()
+                                .getRecordType()));
+                    } catch (TimeoutException e) {
+                        response = new DNSResponse(e);
+                    }
+                    cont = cont.getListener().onDNSResponse(response, session);
+                }
+            } catch (Exception e) {
+                while (e != null) {
+                    SPFCheckerExceptionCatcher catcher = session
+                            .getExceptionCatcher();
+                    try {
+                        catcher.onException(e, session);
+                        e = null;
+                    } catch (SPFResultException ex) {
+                        e = ex;
+                    }
+                }
+            }
+        }
+        result.setSPFResult(session);
+    }
+
+}

Modified: james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java?view=diff&rev=531245&r1=531244&r2=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java
(original)
+++ james/jspf/branches/asynch-jspf/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java
Sun Apr 22 11:14:29 2007
@@ -19,14 +19,11 @@
 
 package org.apache.james.jspf.impl;
 
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-
+import org.apache.james.jspf.ResponseImpl;
 import org.apache.james.jspf.core.DNSService;
 import org.apache.james.jspf.core.IPAddr;
 import org.apache.james.jspf.core.Logger;
+import org.apache.james.jspf.core.IResponseQueue;
 import org.xbill.DNS.AAAARecord;
 import org.xbill.DNS.ARecord;
 import org.xbill.DNS.Lookup;
@@ -38,6 +35,11 @@
 import org.xbill.DNS.TextParseException;
 import org.xbill.DNS.Type;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * This class contains helper to get all neccassary DNS infos that are needed
  * for SPF
@@ -187,6 +189,16 @@
             records = null;
         }
         return records;
+    }
+
+    public void getRecordsAsynch(String hostname, int recordType, Object id,
+            IResponseQueue responsePool) {
+        try {
+            responsePool.insertResponse(new ResponseImpl(id, getRecords(hostname, recordType)));
+        } catch (TimeoutException e) {
+            responsePool.insertResponse(new ResponseImpl(id, e));
+        }
+
     }
 
 }

Modified: james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/AbstractYamlTest.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/AbstractYamlTest.java?view=diff&rev=531245&r1=531244&r2=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/AbstractYamlTest.java
(original)
+++ james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/AbstractYamlTest.java
Sun Apr 22 11:14:29 2007
@@ -20,8 +20,11 @@
 package org.apache.james.jspf;
 
 import org.apache.james.jspf.core.DNSService;
+import org.apache.james.jspf.core.IResponseQueue;
 import org.apache.james.jspf.core.Logger;
+import org.apache.james.jspf.core.SPFExecutor;
 import org.apache.james.jspf.core.SPFRecordParser;
+import org.apache.james.jspf.core.StagedMultipleSPFExecutor;
 import org.apache.james.jspf.macro.MacroExpand;
 import org.apache.james.jspf.parser.DefaultSPF1Parser;
 import org.apache.james.jspf.parser.DefaultTermsFactory;
@@ -53,6 +56,7 @@
     SPFYamlTestSuite data;
     String test;
     protected Logger log;
+    private SPFExecutor executor;
     protected static MacroExpand macroExpand;
     protected static SPF spf;
     protected static SPFRecordParser parser;
@@ -163,7 +167,8 @@
         }
         dns = new LoggingDNSService(getDNSService(), log.getChildLogger("dns"));
         macroExpand = new MacroExpand(log.getChildLogger("macroExpand"), dns);
-        spf = new SPF(dns, parser, log.getChildLogger("spf"), macroExpand);
+        executor = new StagedMultipleSPFExecutor(log, dns); 
+        spf = new SPF(dns, parser, log.getChildLogger("spf"), macroExpand, executor);
         /* PREVIOUS SLOW WAY 
         // we add this after the creation because it is a loop reference
         enabledServices.remove(DNSServiceEnabled.class);
@@ -331,6 +336,15 @@
                 return res.size() > 0 ? res : null;
             }
             return null;
+        }
+        
+        public void getRecordsAsynch(String hostname, int recordType, Object id,
+                IResponseQueue responsePool) {
+            try {
+                responsePool.insertResponse(new ResponseImpl(id, getRecords(hostname, recordType)));
+            } catch (TimeoutException e) {
+                responsePool.insertResponse(new ResponseImpl(id, e));
+            }
         }
     }
 

Modified: james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/LoggingDNSService.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/LoggingDNSService.java?view=diff&rev=531245&r1=531244&r2=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/LoggingDNSService.java
(original)
+++ james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/LoggingDNSService.java
Sun Apr 22 11:14:29 2007
@@ -21,6 +21,7 @@
 
 import org.apache.james.jspf.core.DNSService;
 import org.apache.james.jspf.core.Logger;
+import org.apache.james.jspf.core.IResponseQueue;
 
 import java.util.List;
 
@@ -91,5 +92,11 @@
                     + ") = TempErrorException[" + e.getMessage() + "]");
             throw e;
         }
+    }
+
+    public void getRecordsAsynch(String hostname, int recordType, Object id,
+            IResponseQueue responsePool) {
+        logger.debug("getRecordsAsynch("+hostname+","+recordType);
+        dnsService.getRecordsAsynch(hostname, recordType, id, responsePool);
     }
 }

Added: james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/ResponseImpl.java
URL: http://svn.apache.org/viewvc/james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/ResponseImpl.java?view=auto&rev=531245
==============================================================================
--- james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/ResponseImpl.java
(added)
+++ james/jspf/branches/asynch-jspf/src/test/java/org/apache/james/jspf/ResponseImpl.java
Sun Apr 22 11:14:29 2007
@@ -0,0 +1,34 @@
+/*
+ * Created on 22/apr/07
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package org.apache.james.jspf;
+
+import org.apache.james.jspf.core.IResponse;
+
+import java.util.List;
+
+public class ResponseImpl implements IResponse {
+    private Exception exception = null;
+    private List value = null;
+    private Object id = null;
+    public ResponseImpl(Object id, Exception e) {
+        this.exception = e;
+        this.id = id;
+    }
+    public ResponseImpl(Object id, List result) {
+        this.value = result;
+        this.id = id;
+    }
+    public Exception getException() {
+        return exception;
+    }
+    public Object getId() {
+        return id;
+    }
+    public Object getValue() {
+        return value;
+    }
+}
\ No newline at end of file



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


Mime
View raw message