Author: supun
Date: Wed Jun 23 06:18:50 2010
New Revision: 957118
URL: http://svn.apache.org/viewvc?rev=957118&view=rev
Log:
fixing issue SYNAPSE-665
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointFactory.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointSerializer.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/FailoverEndpoint.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/SALoadbalanceEndpoint.java
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java
Wed Jun 23 06:18:50 2010
@@ -90,6 +90,8 @@ public class XMLConfigConstants {
public static final String RETRIES_BEFORE_SUSPENSION =
"retriesBeforeSuspension";
public static final String RETRY_DELAY = "retryDelay";
+ public static final String RETRY_CONFIG = "retryConfig";
+
public static final String LOADBALANCE_POLICY = "policy";
public static final String LOADBALANCE_ALGORITHM = "algorithm";
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointFactory.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointFactory.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointFactory.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointFactory.java
Wed Jun 23 06:18:50 2010
@@ -403,6 +403,30 @@ public abstract class EndpointFactory im
}
}
}
+
+ OMElement retryConfig = elem.getFirstChildWithName(new QName(
+ SynapseConstants.SYNAPSE_NAMESPACE,
XMLConfigConstants.RETRY_CONFIG));
+
+ if (retryConfig != null) {
+
+ OMElement retryDisabledErrorCodes =
retryConfig.getFirstChildWithName(new QName(
+ SynapseConstants.SYNAPSE_NAMESPACE, "disabledErrorCodes"));
+ if (retryDisabledErrorCodes != null &&
retryDisabledErrorCodes.getText() != null) {
+
+ StringTokenizer st = new StringTokenizer(
+ retryDisabledErrorCodes.getText().trim(), ", ");
+ while (st.hasMoreTokens()) {
+ String s = st.nextToken();
+ try {
+
definition.addRetryDisabledErrorCode(Integer.parseInt(s));
+ } catch (NumberFormatException e) {
+ handleException("The suspend error codes should be
specified as valid " +
+ "numbers separated by commas : "
+ + retryDisabledErrorCodes.getText(), e);
+ }
+ }
+ }
+ }
}
protected void extractSpecificEndpointProperties(EndpointDefinition
definition,
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointSerializer.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointSerializer.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointSerializer.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/EndpointSerializer.java
Wed Jun 23 06:18:50 2010
@@ -255,6 +255,17 @@ public abstract class EndpointSerializer
element.addChild(markAsTimedout);
}
+
+ if (!endpointDefinition.getRetryDisabledErrorCodes().isEmpty()) {
+ OMElement retryConfig =
fac.createOMElement(XMLConfigConstants.RETRY_CONFIG,
+ SynapseConstants.SYNAPSE_OMNAMESPACE);
+ OMElement errorCodes = fac.createOMElement("disabledErrorCodes",
+ SynapseConstants.SYNAPSE_OMNAMESPACE);
+
errorCodes.setText(endpointDefinition.getRetryDisabledErrorCodes().
+ toString().replaceAll("[\\[\\] ]", ""));
+ retryConfig.addChild(errorCodes);
+ element.addChild(retryConfig);
+ }
}
protected void serializeSpecificEndpointProperties(EndpointDefinition
endpointDefinition,
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java
Wed Jun 23 06:18:50 2010
@@ -242,7 +242,7 @@ public abstract class AbstractEndpoint e
// if timeout codes are not defined, assume only HTTP timeout
and connection close
boolean isTimeout = SynapseConstants.NHTTP_CONNECTION_TIMEOUT
== errorCode;
boolean isClosed = SynapseConstants.NHTTP_CONNECTION_CLOSED ==
errorCode;
-
+
if (isTimeout || isClosed) {
if (log.isDebugEnabled()) {
@@ -256,7 +256,7 @@ public abstract class AbstractEndpoint e
if (log.isDebugEnabled()) {
log.debug("Encountered a mark for suspension error : "
+ errorCode
+ " defined " + "error codes are : "
- + definition.getTimeoutErrorCodes());
+ + definition.getTimeoutErrorCodes());
}
return true;
}
@@ -270,6 +270,43 @@ public abstract class AbstractEndpoint e
return false;
}
+
+ protected boolean isRetryDisabled(MessageContext synCtx) {
+ Integer errorCode = (Integer)
synCtx.getProperty(SynapseConstants.ERROR_CODE);
+ if (errorCode != null) {
+ if (definition.getRetryDisabledErrorCodes().isEmpty()) {
+ // if timeout codes are not defined, assume only HTTP timeout
and connection close
+ boolean isTimeout = SynapseConstants.NHTTP_CONNECTION_TIMEOUT
== errorCode;
+ boolean isClosed = SynapseConstants.NHTTP_CONNECTION_CLOSED ==
errorCode;
+
+ if (isTimeout || isClosed) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Encountered a HTTP connection " + (isClosed
? "close" :
+ "timeout") + " error : " + errorCode + ", for
which retries are " +
+ "disabled by default");
+ }
+ return true;
+ }
+ } else {
+ if
(definition.getRetryDisabledErrorCodes().contains(errorCode)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Encountered a retry disabled error : " +
errorCode
+ + ", defined retry disabled error codes are : "
+ + definition.getRetryDisabledErrorCodes());
+ }
+ return true;
+ }
+ }
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Encountered an error sending to endpoint : " +
endpointName +
+ ", with error code : " + errorCode + ", but not a retry
disabled error");
+ }
+ return false;
+ }
+
/**
* Is this a fault that should put the endpoint on SUSPEND? or is this a
fault to ignore?
* @param synCtx the current fault message
@@ -431,12 +468,7 @@ public abstract class AbstractEndpoint e
}
protected void logOnChildEndpointFail(Endpoint endpoint, MessageContext
synMessageContext) {
- if (log.isDebugEnabled()) {
- log.debug(this.toString() + " detected a failure in a child
endpoint : " + endpoint);
- log.debug(this.toString() + " retrying request [[Message ID : "
- + synMessageContext.getMessageID() + "], [To : "
- + synMessageContext.getTo() + "]]");
- }
+ log.warn(this + " Detect a Failure in a child endpoint : " + endpoint);
}
protected void informFailure(MessageContext synCtx, int errorCode, String
errorMsg) {
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/EndpointDefinition.java
Wed Jun 23 06:18:50 2010
@@ -148,6 +148,9 @@ public class EndpointDefinition implemen
*/
private int traceState = SynapseConstants.TRACING_UNSET;
+ /** A list of error codes which permit the retries */
+ private final List<Integer> retryDisabledErrorCodes = new
ArrayList<Integer>();
+
/**
* This should return the absolute EPR address referenced by the named
endpoint. This may be
* possibly computed.
@@ -491,6 +494,10 @@ public class EndpointDefinition implemen
return timeoutErrorCodes;
}
+ public List<Integer> getRetryDisabledErrorCodes() {
+ return retryDisabledErrorCodes;
+ }
+
public void addSuspendErrorCode(int code) {
suspendErrorCodes.add(code);
}
@@ -499,6 +506,10 @@ public class EndpointDefinition implemen
timeoutErrorCodes.add(code);
}
+ public void addRetryDisabledErrorCode(int code) {
+ retryDisabledErrorCodes.add(code);
+ }
+
public String toString() {
if (leafEndpoint != null) {
return leafEndpoint.toString();
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/FailoverEndpoint.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/FailoverEndpoint.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/FailoverEndpoint.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/FailoverEndpoint.java
Wed Jun 23 06:18:50 2010
@@ -86,16 +86,32 @@ public class FailoverEndpoint extends Ab
}
if (!foundEndpoint) {
- informFailure(synCtx, SynapseConstants.ENDPOINT_FO_NONE_READY,
"Failover endpoint : " + getName()
- + " - no ready child endpoints");
+ String msg = "Failover endpoint : " +
+ (getName() != null ? getName() :
SynapseConstants.ANONYMOUS_ENDPOINT) +
+ " - no ready child endpoints";
+ log.warn(msg);
+ informFailure(synCtx, SynapseConstants.ENDPOINT_FO_NONE_READY,
msg);
}
}
}
public void onChildEndpointFail(Endpoint endpoint, MessageContext
synMessageContext) {
-
logOnChildEndpointFail(endpoint, synMessageContext);
- send(synMessageContext);
+ if (!((AbstractEndpoint)endpoint).isRetryDisabled(synMessageContext)) {
+ if (log.isDebugEnabled()) {
+ log.debug(this + " Retry Attempt for Request with [Message ID
: " +
+ synMessageContext.getMessageID() + "], [To : " +
+ synMessageContext.getTo() + "]");
+ }
+ send(synMessageContext);
+ } else {
+ String msg = "Failover endpoint : " +
+ (getName() != null ? getName() :
SynapseConstants.ANONYMOUS_ENDPOINT) +
+ " - one of the child endpoints encounterd a non-retry
error, " +
+ "not sending message to another endpoint";
+ log.warn(msg);
+ informFailure(synMessageContext,
SynapseConstants.ENDPOINT_FO_NONE_READY, msg);
+ }
}
public boolean readyToSend() {
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java
Wed Jun 23 06:18:50 2010
@@ -132,9 +132,12 @@ public class LoadbalanceEndpoint extends
}
sendToApplicationMember(synCtx, to, faultHandler);
} else {
+ String msg = "Loadbalance endpoint : " +
+ (getName() != null ? getName() :
SynapseConstants.ANONYMOUS_ENDPOINT) +
+ " - no ready child endpoints";
+ log.warn(msg);
// if this is not a retry
- informFailure(synCtx, SynapseConstants.ENDPOINT_LB_NONE_READY,
- "Load-balance " + this.toString() + " - no child endpoints
at ready state");
+ informFailure(synCtx, SynapseConstants.ENDPOINT_LB_NONE_READY,
msg);
}
}
@@ -219,7 +222,21 @@ public class LoadbalanceEndpoint extends
logOnChildEndpointFail(endpoint, synMessageContext);
// resend (to a different endpoint) only if we support failover
if (failover) {
- send(synMessageContext);
+ if
(!((AbstractEndpoint)endpoint).isRetryDisabled(synMessageContext)) {
+ if (log.isDebugEnabled()) {
+ log.debug(this + " Retry Attempt for Request with [Message
ID : " +
+ synMessageContext.getMessageID() + "], [To : " +
+ synMessageContext.getTo() + "]");
+ }
+ send(synMessageContext);
+ } else {
+ String msg = "Loadbalance endpoint : " +
+ (getName() != null ? getName() :
SynapseConstants.ANONYMOUS_ENDPOINT) +
+ " - one of the child endpoints encounterd a non-retry
error, " +
+ "not sending message to another endpoint";
+ log.warn(msg);
+ informFailure(synMessageContext,
SynapseConstants.ENDPOINT_LB_NONE_READY, msg);
+ }
} else {
// we are not informing this to the parent endpoint as the failure
of this loadbalance
// endpoint. there can be more active endpoints under this, and
current request has
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/SALoadbalanceEndpoint.java
URL:
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/SALoadbalanceEndpoint.java?rev=957118&r1=957117&r2=957118&view=diff
==============================================================================
---
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/SALoadbalanceEndpoint.java
(original)
+++
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/SALoadbalanceEndpoint.java
Wed Jun 23 06:18:50 2010
@@ -158,15 +158,15 @@ public class SALoadbalanceEndpoint exten
Object o = synCtx.getProperty(
SynapseConstants.PROP_SAL_ENDPOINT_FIRST_MESSAGE_IN_SESSION);
- if (o != null && Boolean.TRUE.equals(o)) {
-
+ if (o != null && Boolean.TRUE.equals(o) &&
+ !((AbstractEndpoint) endpoint).isRetryDisabled(synCtx)) {
// this is the first message. so unbind the session with failed
endpoint and start
// new one by resending.
-
+
dispatcher.unbind(synCtx);
-
- // As going to be happened retry , we have to remove states
related to the previous try
-
+
+ // As going to be happened retry , we have to remove states
related to the previous try
+
Object epListObj =
synCtx.getProperty(SynapseConstants.PROP_SAL_ENDPOINT_ENDPOINT_LIST);
if (epListObj instanceof List) {
List<Endpoint> endpointList = (List<Endpoint>) epListObj;
@@ -176,20 +176,20 @@ public class SALoadbalanceEndpoint exten
} else {
if (endpointList.contains(this)) {
int lastIndex = endpointList.indexOf(this);
- List<Endpoint> head =
- endpointList.subList(lastIndex ,
endpointList.size());
+ List<Endpoint> head =
+ endpointList.subList(lastIndex,
endpointList.size());
head.clear();
}
}
}
}
-
+
send(synCtx);
} else {
// session has already started. we can't failover.
informFailure(synCtx, SynapseConstants.ENDPOINT_SAL_FAILED_SESSION,
- "Failure an endpoint " + endpoint + " in the current
session");
+ "Failure an endpoint " + endpoint + " in the current
session");
}
}