Skip to content

Commit

Permalink
Introduce new JSON type to property
Browse files Browse the repository at this point in the history
Introduce JSON type to property and json-eval evaluation against
properties
Fixes wso2/product-ei/issues/5266
  • Loading branch information
GDLMadushanka committed Oct 2, 2020
1 parent fabb6fb commit 8711709
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class XMLConfigConstants {

/** The set of supported data types */
public static enum DATA_TYPES {
STRING, BOOLEAN, INTEGER, LONG, SHORT, FLOAT, DOUBLE, OM
STRING, BOOLEAN, INTEGER, LONG, SHORT, FLOAT, DOUBLE, OM, JSON
}

//-- WS-RM sequence mediator --
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

package org.apache.synapse.mediators.builtin;

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import org.apache.axis2.context.OperationContext;
import org.apache.commons.lang.StringUtils;
import org.apache.synapse.MessageContext;
Expand Down Expand Up @@ -427,6 +430,7 @@ private Object convertValue(String value, String type) {
case LONG : return Long.parseLong(value);
case OM : return buildOMElement(value);
case SHORT : return Short.parseShort(value);
case JSON : return buildJSONElement(value);
default : return value;
}
} catch (IllegalArgumentException e) {
Expand Down Expand Up @@ -515,6 +519,16 @@ private OMElement buildOMElement(String xml) {
return result;
}

private JsonElement buildJSONElement(String jsonPayload) {
JsonParser jsonParser = new JsonParser();
try {
return jsonParser.parse(jsonPayload);
} catch (JsonSyntaxException ex) {
log.error("Malformed JSON payload : " + jsonPayload, ex);
return null;
}
}

@Override public String getMediatorName() {
return super.getMediatorName() + ":" + name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ public boolean mediate(MessageContext synCtx) {
*/
boolean isSourcePropertyXML = false;
Object sourceProperty = synCtx.getProperty(source.getProperty());
if (sourceProperty instanceof OMElement) {
if (sourceProperty instanceof JsonElement) {
// Handle JSON type property values
sourcePropertyJson = (JsonElement) sourceProperty;
isSourcePropertyXML = false;
} else if (sourceProperty instanceof OMElement) {
isSourcePropertyXML = true;
} else if (sourceProperty instanceof ArrayList) {
for (Object node : (ArrayList) sourceProperty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ public void insertJson(MessageContext synCtx, Object sourceJsonElement, SynapseL
JsonElement jsonElement = jsonParser.parse(sourceJsonElement.toString());
if (action.equalsIgnoreCase(ACTION_REPLACE)) {
// replacing the property with new value
synCtx.setProperty(property, sourceJsonElement.toString());
synCtx.setProperty(property, sourceJsonElement);
} else if (action.equalsIgnoreCase(ACTION_ADD_CHILD)) {
Object propertyObj = synCtx.getProperty(property);
if (propertyObj != null) {
Expand All @@ -441,7 +441,7 @@ public void insertJson(MessageContext synCtx, Object sourceJsonElement, SynapseL
// Add as a new element if the value contains in the property is an array.
if (sourceElement.isJsonArray()) {
sourceElement.getAsJsonArray().add(jsonElement);
synCtx.setProperty(property, sourceElement.toString());
synCtx.setProperty(property, sourceElement);
} else {
synLog.error("Cannot add child, since the target " + sourceElement.toString() + " is " +
"not an JSON array");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,18 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SynapseJsonPath extends SynapsePath {

private static final Log log = LogFactory.getLog(SynapseJsonPath.class);

private static final String JSON_PATH_WITH_PROP_REGEX = "^(\\$ctx|\\$trp|\\$axis2):([a-zA-Z0-9]+)\\.(.*?)$";
private static final String EXTRACT_PROP_REGEX = "^(\\$ctx|\\$trp|\\$axis2):([a-zA-Z0-9]+)";

private String propertyExpression;

private String enableStreamingJsonPath = SynapsePropertiesLoader.loadSynapseProperties().
getProperty(SynapseConstants.STREAMING_JSONPATH_PROCESSING);

Expand Down Expand Up @@ -91,7 +98,22 @@ public SynapseJsonPath(String jsonPathExpression) throws JaxenException {
EIPUtils.setJsonPathConfiguration();

this.contentAware = true;
this.expression = jsonPathExpression;
// supporting evaluation against a property
// Ex: json-eval($ctx:prop1.student.name)
Pattern fullPattern = Pattern.compile(JSON_PATH_WITH_PROP_REGEX);
Matcher fullMatcher = fullPattern.matcher(jsonPathExpression);
if (fullMatcher.matches()) {
// pattern to extract the property
Pattern extractProp = Pattern.compile(EXTRACT_PROP_REGEX);
Matcher extractPropMatcher = extractProp.matcher(jsonPathExpression);
if (extractPropMatcher.find()) {
propertyExpression = extractPropMatcher.group(0);
expression = "$" + jsonPathExpression.substring(propertyExpression.length());
}
} else {
this.expression = jsonPathExpression;
}

// Though SynapseJsonPath support "$.", the JSONPath implementation does not support it
if (expression.endsWith(".")) {
expression = expression.substring(0, expression.length() - 1);
Expand Down Expand Up @@ -125,6 +147,20 @@ public String stringValueOf(MessageContext synCtx) {
// Create new JSON path by replacing dynamic values with content.
jsonPath = JsonPath.compile(InlineExpressionUtil.replaceDynamicValues(synCtx, expression));
}

// evaluating the jsonPath against a property
if (propertyExpression != null) {
try {
SynapseXPath xPath = new SynapseXPath(propertyExpression);
String result = xPath.stringValueOf(synCtx);
return stringValueOf(result);
} catch (JaxenException e) {
log.error("Xpath evaluation failed", e);
return "";
}
}

// else evaluate against the body
org.apache.axis2.context.MessageContext amc = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
InputStream stream;
if (!JsonUtil.hasAJsonPayload(amc) || "true".equals(enableStreamingJsonPath)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.apache.synapse.util.xpath;

import com.google.gson.JsonElement;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
Expand Down Expand Up @@ -453,6 +454,10 @@ public String stringValueOf(MessageContext synCtx) {
} else if (o instanceof SynapseXPath) {
textValue.append(
((SynapseXPath) o).stringValueOf(synCtx));
} else if (o instanceof JsonElement) {
// Xpath evaluation can return a JSON Elements since property mediator
// can store JSON payloads
textValue.append(o.toString());
}
}

Expand Down

0 comments on commit 8711709

Please sign in to comment.