Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add expression support to endpoint definition attributes for handling endpoints in the HTTP connector. #2238

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9f36f1d
add expression for suspend initial duration attribute without create …
chathuranga-jayanath-99 Oct 3, 2024
261b0f4
add expression for suspend maximum duration attribute without set sus…
chathuranga-jayanath-99 Oct 4, 2024
704a8da
add expression for suspend progression factor
chathuranga-jayanath-99 Oct 4, 2024
26ff0b4
add expression for retries on timeout before suspend without set time…
chathuranga-jayanath-99 Oct 4, 2024
64aab6c
add expression for retry duration on timeout
chathuranga-jayanath-99 Oct 4, 2024
1ba5ad2
add tests to check added expressions
chathuranga-jayanath-99 Oct 5, 2024
ea622f3
add expression for timeout action
chathuranga-jayanath-99 Oct 5, 2024
9e371ab
fix expression check pattern
chathuranga-jayanath-99 Oct 5, 2024
7178623
add expression for suspend error codes without setSuspendStateProperties
chathuranga-jayanath-99 Oct 7, 2024
67e5592
add expression for timeout error codes without setTimeoutStateProperties
chathuranga-jayanath-99 Oct 7, 2024
65fd4d2
add tests for error codes
chathuranga-jayanath-99 Oct 7, 2024
e19e5d4
parse message context for createJsonRepresentation
chathuranga-jayanath-99 Oct 8, 2024
81b9899
handle timeout action value "never"
chathuranga-jayanath-99 Nov 25, 2024
e27203b
remove log warns where unnecessary
chathuranga-jayanath-99 Nov 25, 2024
2a5cb16
add new tests handling value not defined scenarios
chathuranga-jayanath-99 Nov 25, 2024
5d0d62f
Merge branch 'refs/heads/add-expression' into integrate-new-expressions
chathuranga-jayanath-99 Nov 25, 2024
1b00df2
remove handling timeout action value "never"
chathuranga-jayanath-99 Nov 26, 2024
2df1a58
add synapse expression support
chathuranga-jayanath-99 Nov 26, 2024
3c782b1
Revert "parse message context for createJsonRepresentation"
chathuranga-jayanath-99 Nov 28, 2024
4a99054
introduce value to handle endpoint definition attributes
chathuranga-jayanath-99 Nov 28, 2024
4383df8
add 'never' as default value of timeoutAction
chathuranga-jayanath-99 Dec 6, 2024
80a2d64
change delimiter ", " to ","
chathuranga-jayanath-99 Dec 6, 2024
b1367aa
add tests to check endpoint definition
chathuranga-jayanath-99 Dec 7, 2024
9d29be9
address reviewed changes
chathuranga-jayanath-99 Dec 8, 2024
c88988f
add serializer tests
chathuranga-jayanath-99 Dec 8, 2024
68cf96d
add method overload for onSuccess, onFault, onTimeout
chathuranga-jayanath-99 Dec 9, 2024
213b9ec
update print endpoint address
chathuranga-jayanath-99 Dec 9, 2024
e79f395
address reviewed changes
chathuranga-jayanath-99 Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.aspects.AspectConfiguration;
Expand All @@ -53,12 +54,10 @@
import org.xml.sax.InputSource;

import javax.activation.DataHandler;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.xml.stream.XMLInputFactory;
Expand Down Expand Up @@ -86,7 +85,8 @@
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressWarnings({"UnusedDeclaration"})
public class SynapseConfigUtils {
Expand Down Expand Up @@ -895,6 +895,32 @@ public static boolean isFailSafeEnabled(String componentName) {
return false;
}

/**
* Replaces occurrences of a pattern in the input string with corresponding property values from the
* message context.
*
* @param input the input string containing patterns to be replaced
* @param pattern the pattern to be matched in the input string
* @param messageContext the message context containing property values
* @return the resulting string with patterns replaced by property values
*/
public static String replacePatternWithProperties(String input, Pattern pattern, MessageContext messageContext) {
Matcher matcher = pattern.matcher(input);
StringBuilder result = new StringBuilder();

int s = 0;
while (matcher.find()) {
String propertyName = matcher.group(1);
Object propertyValue = messageContext.getProperty(propertyName);
if (propertyValue != null) {
result.append(input.substring(s, matcher.start()));
result.append(propertyValue.toString());
s = matcher.end();
}
}
result.append(input.substring(s));
return result.toString();
}

public static SynapseConfiguration getSynapseConfiguration(String tenantDomain){
return lastRegisteredSynapseConfigurationMap.get(tenantDomain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.aspects.AspectConfiguration;
import org.apache.synapse.config.xml.ValueFactory;
import org.apache.synapse.config.xml.XMLConfigConstants;
import org.apache.synapse.endpoints.EPConstants;
import org.apache.synapse.endpoints.EndpointDefinition;
import org.apache.synapse.mediators.Value;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.jaxen.JaxenException;

Expand All @@ -46,6 +49,7 @@ public class EndpointDefinitionFactory implements DefinitionFactory{
*/
public EndpointDefinition createDefinition(OMElement elem) {
EndpointDefinition definition = new EndpointDefinition();
ValueFactory valueFactory = new ValueFactory();

OMAttribute optimize
= elem.getAttribute(new QName(XMLConfigConstants.NULL_NAMESPACE, "optimize"));
Expand Down Expand Up @@ -159,36 +163,31 @@ public EndpointDefinition createDefinition(OMElement elem) {
String d = duration.getText();
if (d != null) {
try {
Pattern pattern = Pattern.compile("\\{.*\\}");
if (pattern.matcher(d).matches()) {
d = d.trim().substring(1, d.length() - 1);
SynapseXPath xpath = new SynapseXPath(d);
definition.setDynamicTimeoutExpression(xpath);
} else {
long timeoutMilliSeconds = Long.parseLong(d.trim());
definition.setTimeoutDuration(timeoutMilliSeconds);
Value timeoutDurationValue = valueFactory.createTextValue(duration);
if (timeoutDurationValue.getKeyValue() != null) {
Long.parseLong(timeoutDurationValue.getKeyValue());
}
definition.setTimeoutDuration(timeoutDurationValue);
} catch (NumberFormatException e) {
handleException("Endpoint timeout duration expected as a " +
"number but was not a number");
} catch (JaxenException e) {
handleException("Couldn't assign dynamic endpoint timeout as Synapse expression");
}
}
}

OMElement action = timeout.getFirstChildWithName(
new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "responseAction"));
if (action != null && action.getText() != null) {
String actionString = action.getText();
if ("discard".equalsIgnoreCase(actionString.trim())) {
definition.setTimeoutAction(SynapseConstants.DISCARD);
} else if ("fault".equalsIgnoreCase(actionString.trim())) {
definition.setTimeoutAction(SynapseConstants.DISCARD_AND_FAULT);
} else {
handleException("Invalid timeout action, action : "
+ actionString + " is not supported");
Value timeoutActionValue = valueFactory.createTextValue(action);

if (timeoutActionValue.getKeyValue() != null &&
!timeoutActionValue.getKeyValue().equalsIgnoreCase(EPConstants.NEVER) &&
!timeoutActionValue.getKeyValue().equalsIgnoreCase(EPConstants.DISCARD) &&
!timeoutActionValue.getKeyValue().equalsIgnoreCase(EPConstants.FAULT)) {
handleException("Invalid timeout action, action : " + timeoutActionValue.getKeyValue() +
" is not supported");
}
definition.setTimeoutAction(timeoutActionValue);
}
}

Expand All @@ -202,25 +201,32 @@ public EndpointDefinition createDefinition(OMElement elem) {
SynapseConstants.SYNAPSE_NAMESPACE,
XMLConfigConstants.ERROR_CODES));
if (timeoutCodes != null && timeoutCodes.getText() != null) {
StringTokenizer st = new StringTokenizer(timeoutCodes.getText().trim(), ", ");
while (st.hasMoreTokens()) {
String s = st.nextToken();
try {
definition.addTimeoutErrorCode(Integer.parseInt(s));
} catch (NumberFormatException e) {
handleException("The timeout error codes should be specified " +
"as valid numbers separated by commas : " + timeoutCodes.getText(), e);
Value timeoutErrorCodesValue = valueFactory.createTextValue(timeoutCodes);
if (timeoutErrorCodesValue.getKeyValue() != null) {
StringTokenizer st = new StringTokenizer(timeoutCodes.getText().trim(), ",");
while (st.hasMoreTokens()) {
String s = st.nextToken();
try {
Integer.parseInt(s);
} catch (NumberFormatException e) {
handleException("The timeout error codes should be specified " +
"as valid numbers separated by commas : " + timeoutCodes.getText(), e);
}
}
}
definition.setTimeoutErrorCodes(timeoutErrorCodesValue);
}

OMElement retriesBeforeSuspend = markAsTimedOut.getFirstChildWithName(new QName(
SynapseConstants.SYNAPSE_NAMESPACE,
XMLConfigConstants.RETRIES_BEFORE_SUSPENSION));
if (retriesBeforeSuspend != null && retriesBeforeSuspend.getText() != null) {
try {
definition.setRetriesOnTimeoutBeforeSuspend(
Integer.parseInt(retriesBeforeSuspend.getText().trim()));
Value retriesBeforeSuspendValue = valueFactory.createTextValue(retriesBeforeSuspend);
if (retriesBeforeSuspendValue.getKeyValue() != null) {
Integer.parseInt(retriesBeforeSuspendValue.getKeyValue());
}
definition.setRetriesOnTimeoutBeforeSuspend(retriesBeforeSuspendValue);
} catch (NumberFormatException e) {
handleException("The retries before suspend [for timeouts] should be " +
"specified as a valid number : " + retriesBeforeSuspend.getText(), e);
Expand All @@ -232,8 +238,11 @@ public EndpointDefinition createDefinition(OMElement elem) {
XMLConfigConstants.RETRY_DELAY));
if (retryDelay != null && retryDelay.getText() != null) {
try {
definition.setRetryDurationOnTimeout(
Integer.parseInt(retryDelay.getText().trim()));
Value retryDelayValue = valueFactory.createTextValue(retryDelay);
if (retryDelayValue.getKeyValue() != null) {
Integer.parseInt(retryDelayValue.getKeyValue());
}
definition.setRetryDurationOnTimeout(retryDelayValue);
} catch (NumberFormatException e) {
handleException("The retry delay for timeouts should be specified " +
"as a valid number : " + retryDelay.getText(), e);
Expand All @@ -248,9 +257,9 @@ public EndpointDefinition createDefinition(OMElement elem) {

log.warn("Configuration uses deprecated style for endpoint 'suspendDurationOnFailure'");
try {
definition.setInitialSuspendDuration(
1000 * Long.parseLong(suspendDurationOnFailure.getText().trim()));
definition.setSuspendProgressionFactor((float) 1.0);
long suspendDurationValue = 1000 * Long.parseLong(suspendDurationOnFailure.getText().trim());
definition.setInitialSuspendDuration(new Value(String.valueOf(suspendDurationValue)));
definition.setSuspendProgressionFactor(new Value(String.valueOf((float) 1.0)));
} catch (NumberFormatException e) {
handleException("The initial suspend duration should be specified " +
"as a valid number : " + suspendDurationOnFailure.getText(), e);
Expand All @@ -267,26 +276,32 @@ public EndpointDefinition createDefinition(OMElement elem) {
SynapseConstants.SYNAPSE_NAMESPACE,
XMLConfigConstants.ERROR_CODES));
if (suspendCodes != null && suspendCodes.getText() != null) {

StringTokenizer st = new StringTokenizer(suspendCodes.getText().trim(), ", ");
while (st.hasMoreTokens()) {
String s = st.nextToken();
try {
definition.addSuspendErrorCode(Integer.parseInt(s));
} catch (NumberFormatException e) {
handleException("The suspend error codes should be specified " +
"as valid numbers separated by commas : " + suspendCodes.getText(), e);
Value suspendErrorCodesValue = valueFactory.createTextValue(suspendCodes);
if (suspendErrorCodesValue.getKeyValue() != null) {
chathuranga-jayanath-99 marked this conversation as resolved.
Show resolved Hide resolved
StringTokenizer st = new StringTokenizer(suspendCodes.getText().trim(), ",");
while (st.hasMoreTokens()) {
String s = st.nextToken();
try {
Integer.parseInt(s);
} catch (NumberFormatException e) {
handleException("The suspend error codes should be specified " +
"as valid numbers separated by commas : " + suspendCodes.getText(), e);
}
}
}
definition.setSuspendErrorCodes(suspendErrorCodesValue);
}

OMElement initialDuration = suspendOnFailure.getFirstChildWithName(new QName(
SynapseConstants.SYNAPSE_NAMESPACE,
XMLConfigConstants.SUSPEND_INITIAL_DURATION));
if (initialDuration != null && initialDuration.getText() != null) {
try {
definition.setInitialSuspendDuration(
Integer.parseInt(initialDuration.getText().trim()));
Value initialSuspendDurationValue = valueFactory.createTextValue(initialDuration);
if (initialSuspendDurationValue.getKeyValue() != null) {
Integer.parseInt(initialSuspendDurationValue.getKeyValue());
}
definition.setInitialSuspendDuration(initialSuspendDurationValue);
} catch (NumberFormatException e) {
handleException("The initial suspend duration should be specified " +
"as a valid number : " + initialDuration.getText(), e);
Expand All @@ -298,8 +313,11 @@ public EndpointDefinition createDefinition(OMElement elem) {
XMLConfigConstants.SUSPEND_PROGRESSION_FACTOR));
if (progressionFactor != null && progressionFactor.getText() != null) {
try {
definition.setSuspendProgressionFactor(
Float.parseFloat(progressionFactor.getText().trim()));
Value progressionFactorValue = valueFactory.createTextValue(progressionFactor);
if (progressionFactorValue.getKeyValue() != null) {
Float.parseFloat(progressionFactorValue.getKeyValue());
}
definition.setSuspendProgressionFactor(progressionFactorValue);
} catch (NumberFormatException e) {
handleException("The suspend duration progression factor should be specified " +
"as a valid float : " + progressionFactor.getText(), e);
Expand All @@ -311,8 +329,11 @@ public EndpointDefinition createDefinition(OMElement elem) {
XMLConfigConstants.SUSPEND_MAXIMUM_DURATION));
if (maximumDuration != null && maximumDuration.getText() != null) {
try {
definition.setSuspendMaximumDuration(
Long.parseLong(maximumDuration.getText().trim()));
Value suspendMaximumDurationValue = valueFactory.createTextValue(maximumDuration);
if (suspendMaximumDurationValue.getKeyValue() != null) {
Long.parseLong(suspendMaximumDurationValue.getKeyValue());
}
definition.setSuspendMaximumDuration(suspendMaximumDurationValue);
} catch (NumberFormatException e) {
handleException("The maximum suspend duration should be specified " +
"as a valid number : " + maximumDuration.getText(), e);
Expand All @@ -330,7 +351,7 @@ public EndpointDefinition createDefinition(OMElement elem) {
if (retryDisabledErrorCodes != null && retryDisabledErrorCodes.getText() != null) {

StringTokenizer st = new StringTokenizer(
retryDisabledErrorCodes.getText().trim(), ", ");
retryDisabledErrorCodes.getText().trim(), ",");
while (st.hasMoreTokens()) {
String s = st.nextToken();
try {
Expand Down
Loading
Loading