Skip to content

Commit

Permalink
Add registry support
Browse files Browse the repository at this point in the history
Add registry support and introduce objectValueof method to synapse path
  • Loading branch information
GDLMadushanka committed Nov 4, 2024
1 parent 0222047 commit ba89cda
Show file tree
Hide file tree
Showing 18 changed files with 367 additions and 60 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
target/

## various other file types we don't want to have in the repository:
.DS_Store
.DS_Store
/modules/core/src/main/antlr4/org/apache/synapse/util/synapse_path/gen/
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ VAR: 'var';
PAYLOAD: 'payload' | '$';
HEADERS: 'headers';
CONFIG: 'config';
ATTRIBUTES: 'attributes';
ATTRIBUTES: 'attributes' | 'attr';
AXIS2: 'axis2';
SYNAPSE: 'synapse';
REGISTRY: 'registry';
Expand All @@ -28,6 +28,8 @@ INTEGER: 'integer';
FLOAT: 'float';
STRING: 'string';
BOOLEAN: 'boolean';
OBJECT: 'object';
ARRAY: 'array';
ABS: 'abs';
FLOOR: 'floor';
CEIL: 'ceil';
Expand All @@ -41,6 +43,7 @@ SUBSTRING: 'subString';
STARTSWITH: 'startsWith';
ENDSWITH: 'endsWith';
CONTAINS: 'contains';
EXISTS: 'exists';
TRIM: 'trim';
REPLACE: 'replace';
SPLIT: 'split';
Expand Down Expand Up @@ -104,8 +107,8 @@ NULL_LITERAL
;
// Identifiers
ID: [a-zA-Z_][a-zA-Z_0-9]*;
GETPROPERTY: 'getProperty';
ID: [a-zA-Z_][a-zA-Z_0-9]*;
// Special symbols for JSONPath filter expressions
QUESTION: '?';
AT: '@';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ payloadAccess
| DOUBLE_DOT ID (LBRACKET arrayIndex RBRACKET)? )
;

registryAccess
: (DOUBLE_DOT ASTERISK
| DOUBLE_DOT ID
| DOT ID
| LBRACKET arrayIndex RBRACKET
| DOT LBRACKET arrayIndex RBRACKET
| DOT ASTERISK)*
;

arrayIndex
: NUMBER
| STRING_LITERAL
Expand Down Expand Up @@ -161,7 +170,7 @@ functionCall
| SQRT LPAREN expression RPAREN
| LOG LPAREN expression RPAREN
| POW LPAREN expression COMMA expression RPAREN
| REGISTRY LPAREN expression RPAREN (DOT GETPROPERTY LPAREN expression RPAREN)?
| REGISTRY LPAREN expression RPAREN ( (DOT GETPROPERTY LPAREN expression RPAREN) | registryAccess )?
| SECRET LPAREN expression RPAREN
| BASE64ENCODE LPAREN expression (COMMA expression)? RPAREN
| BASE64DECODE LPAREN expression RPAREN
Expand All @@ -179,4 +188,7 @@ functionCall
| FLOAT LPAREN expression RPAREN
| STRING LPAREN expression RPAREN
| BOOLEAN LPAREN expression RPAREN
| EXISTS LPAREN expression RPAREN
| OBJECT LPAREN expression RPAREN
| ARRAY LPAREN expression RPAREN
;
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,10 @@ public enum ENDPOINT_TIMEOUT_TYPE { ENDPOINT_TIMEOUT, GLOBAL_TIMEOUT, HTTP_CONNE
public static final String IS_STRING = "isString";
public static final String IS_ARRAY = "isArray";
public static final String IS_OBJECT = "isObject";
public static final String OBJECT = "object";
public static final String ARRAY = "array";
public static final String REGISTRY = "registry";
public static final String EXISTS = "exists";

public static final String ROUND = "round";
public static final String INTEGER = "integer";
Expand All @@ -669,16 +673,4 @@ public enum ENDPOINT_TIMEOUT_TYPE { ENDPOINT_TIMEOUT, GLOBAL_TIMEOUT, HTTP_CONNE
public static final String AXIS2 = "axis2";

public static final String UNKNOWN = "unknown";

public static final class SIELErrors {
public static final String IF_CONDITION_ERROR = "Condition is not a boolean value";
private static final String INVALID_ARGUMENT = "Invalid argument type provided for %s function";
private static final String INVALID_OPERATION = "Invalid argument type provided for %s operation";
public static String getInvalidArgumentMessage(String functionName) {
return String.format(INVALID_ARGUMENT, functionName);
}
public static String getInvalidOperationMessage(String functionName) {
return String.format(INVALID_OPERATION, functionName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.apache.synapse.mediators.builtin.PropertyMediator;
import org.apache.synapse.util.MediatorPropertyUtils;
import org.apache.synapse.util.xpath.SynapseJsonPath;
import org.apache.synapse.util.xpath.SynapsePath;
import org.apache.synapse.util.xpath.Synapse_Path;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.jaxen.JaxenException;

Expand Down Expand Up @@ -87,7 +87,7 @@ public Mediator createSpecificMediator(OMElement elem, Properties properties) {
new SynapseJsonPath(nameExpression.substring(10, nameExpression.length() - 1));
} else if (nameExpression.startsWith(SynapseConstants.SIEL_IDENTIFIER_START) &&
nameExpression.endsWith(SynapseConstants.SIEL_IDENTIFIER_END)) {
new SynapsePath(nameExpression.substring(2, nameExpression.length() - 1));
new Synapse_Path(nameExpression.substring(2, nameExpression.length() - 1));
} else {
new SynapseXPath(nameExpression);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ public String toString() {

public abstract String stringValueOf(MessageContext synCtx);

/**
* New method to get the object value of the expression in places where we can handle the Object result.
* @param synCtx MessageContext
* @return Object - can be String, Integer, Double, Boolean, OMNode, JSONElement or null.
*/
public abstract Object objectValueOf(MessageContext synCtx);

public void handleException(String msg, Throwable e) {
log.error(msg, e);
throw new SynapseException(msg, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.apache.synapse.SynapseException;
import org.apache.synapse.config.SynapsePropertiesLoader;
import org.apache.synapse.util.xpath.SynapseJsonPath;
import org.apache.synapse.util.xpath.SynapsePath;
import org.apache.synapse.util.xpath.Synapse_Path;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.jaxen.JaxenException;

Expand All @@ -52,7 +52,7 @@ public static org.apache.synapse.config.xml.SynapsePath getSynapsePath(OMElement
path = new SynapseJsonPath(pathAttrib.getAttributeValue().substring(10, pathAttrib.getAttributeValue().length() - 1));
} else if (pathAttrib.getAttributeValue().startsWith(SynapseConstants.SIEL_IDENTIFIER_START) &&
pathAttrib.getAttributeValue().endsWith(SynapseConstants.SIEL_IDENTIFIER_END)) {
path = new SynapsePath(pathAttrib.getAttributeValue().substring(2, pathAttrib.getAttributeValue().length() - 1));
path = new Synapse_Path(pathAttrib.getAttributeValue().substring(2, pathAttrib.getAttributeValue().length() - 1));
} else {
try {
path = new SynapseXPath(pathAttrib.getAttributeValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@

package org.apache.synapse.util.synapse_path.ast;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.internal.LazilyParsedNumber;
import org.apache.axiom.om.OMElement;
import org.apache.synapse.util.synapse_path.exception.EvaluationException;

/**
Expand All @@ -39,6 +44,14 @@ public ExpressionResult(String value) {
this.value = value;
}

public ExpressionResult(OMElement value) {
this.value = value;
}

public Object getValue() {
return value;
}

public ExpressionResult(Number value) {
this.value = value;
}
Expand Down Expand Up @@ -119,6 +132,24 @@ public JsonElement asJsonElement() {
throw new EvaluationException("Value is not a JsonElement");
}

public JsonObject asJsonObject() {
if (value instanceof JsonObject) {
return (JsonObject) value;
} else if (value instanceof String) {
return parseStringToJsonObject((String) value);
}
throw new EvaluationException("Value is not a JsonObject");
}

public JsonArray asJsonArray() {
if (value instanceof JsonArray) {
return (JsonArray) value;
} else if (value instanceof String) {
return parseStringToJsonArray((String) value);
}
throw new EvaluationException("Value is not a JsonArray");
}

// Method to check the actual type of the result
public Class<?> getType() {
if (value == null) {
Expand Down Expand Up @@ -148,11 +179,31 @@ public boolean isString() {
}

public boolean isObject() {
return value instanceof JsonElement && ((JsonElement) value).isJsonObject();
if (value instanceof JsonElement && ((JsonElement) value).isJsonObject()) {
return true;
} else if (value instanceof String) {
try {
parseStringToJsonObject((String) value);
return true;
} catch (EvaluationException e) {
return false;
}
}
return false;
}

public boolean isArray() {
return value instanceof JsonElement && ((JsonElement) value).isJsonArray();
if (value instanceof JsonElement && ((JsonElement) value).isJsonArray()) {
return true;
} else if (value instanceof String) {
try {
parseStringToJsonArray((String) value);
return true;
} catch (Exception e) {
return false;
}
}
return false;
}

public boolean isJsonPrimitive() {
Expand Down Expand Up @@ -197,4 +248,40 @@ private boolean isDouble(JsonPrimitive jsonPrimitive) {
}
return false; // Not a number, so it's not a double
}

public boolean isOMElement() {
return value instanceof OMElement;
}

private JsonObject parseStringToJsonObject(String value) throws EvaluationException {
String stringValue = value;
if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) {
stringValue = stringValue.substring(1, stringValue.length() - 1);
}
try {
JsonElement jsonElement = JsonParser.parseString(stringValue.replace("\\", ""));
if (jsonElement.isJsonObject()) {
return jsonElement.getAsJsonObject();
}
} catch (JsonSyntaxException e) {
throw new EvaluationException("Value is not a JsonObject");
}
throw new EvaluationException("Value is not a JsonObject");
}

private JsonArray parseStringToJsonArray(String value) throws EvaluationException {
String stringValue = value;
if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) {
stringValue = stringValue.substring(1, stringValue.length() - 1);
}
try {
JsonElement jsonElement = JsonParser.parseString(stringValue.replace("\\", ""));
if (jsonElement.isJsonArray()) {
return jsonElement.getAsJsonArray();
}
} catch (JsonSyntaxException e) {
throw new EvaluationException("Value is not a JsonArray");
}
throw new EvaluationException("Value is not a JsonArray");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,20 @@ public class PayloadAccessNode implements ExpressionNode {
private static final Log log = LogFactory.getLog(PayloadAccessNode.class);
private String expression;
private final Map<String, ExpressionNode> arguments;
public enum Type {
PAYLOAD,
VARIABLE,
REGISTRY,
}
private final Type type;
private ExpressionNode registryAccessNode = null;

private final boolean isVariable;

public PayloadAccessNode(String expression, Map<String, ExpressionNode> arguments, boolean isVariable) {
public PayloadAccessNode(String expression, Map<String, ExpressionNode> arguments, Type type,
ExpressionNode registryAccessNode) {
this.expression = expression;
this.arguments = arguments;
this.isVariable = isVariable;
this.type = type;
this.registryAccessNode = registryAccessNode;
Configuration.setDefaults(new Configuration.Defaults() {
private final JsonProvider jsonProvider = new GsonJsonProvider(new GsonBuilder().serializeNulls().create());
private final MappingProvider mappingProvider = new GsonMappingProvider();
Expand All @@ -80,7 +87,7 @@ public Set<Option> options() {

@Override
public ExpressionResult evaluate(EvaluationContext context) {
if (expression.startsWith(SynapseConstants.PAYLOAD) && !isVariable) {
if (expression.startsWith(SynapseConstants.PAYLOAD)) {
expression = SynapseConstants.PAYLOAD_$ + expression.substring(SynapseConstants.PAYLOAD.length());
}

Expand All @@ -90,8 +97,8 @@ public ExpressionResult evaluate(EvaluationContext context) {
.ifPresent(result -> processResult(entry, result));
}

Object result;
if (!isVariable) {
Object result = null;
if (type.equals(Type.PAYLOAD)) {
try {
result = context.getPayload();
if (result == null) {
Expand All @@ -104,7 +111,7 @@ public ExpressionResult evaluate(EvaluationContext context) {
} catch (IOException e) {
throw new EvaluationException("Error while parsing payload");
}
} else {
} else if (type.equals(Type.VARIABLE)) {
String[] variableAndExpression = ExpressionUtils.extractVariableAndJsonPath(expression);
Object variable = context.getVariable(variableAndExpression[0]);
if (variable == null) {
Expand All @@ -124,6 +131,21 @@ public ExpressionResult evaluate(EvaluationContext context) {
throw new EvaluationException(e.getMessage());
}
}
} else if (type.equals(Type.REGISTRY)) {
ExpressionResult registryValue = registryAccessNode.evaluate(context);
try {
if (registryValue == null) {
throw new EvaluationException("Could not find a JSON payload to evaluate the expression: " + expression);
} else if (!registryValue.isOMElement()) {
throw new EvaluationException("Could not evaluate JSONPath expression: " + expression
+ " on non-JSON registry value");
}
expression = expression.startsWith(".") ? "$" + expression : "$." + expression;
result = JsonPath.parse(registryValue.asString()).read(expression);
} catch (PathNotFoundException e) {
// convert jsonPath error to native one
throw new EvaluationException(e.getMessage());
}
}
if (result instanceof JsonPrimitive) {
return new ExpressionResult((JsonPrimitive) result);
Expand Down
Loading

0 comments on commit ba89cda

Please sign in to comment.