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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]