From ce97244a91de6433dc2ab291f5bd230e67bfbe54 Mon Sep 17 00:00:00 2001 From: GDLMadushanka Date: Mon, 9 Dec 2024 08:41:03 +0530 Subject: [PATCH] Improve logging in Synapse Expressions Improve logging Add synapse expression support to validate mediator --- .../mediators/builtin/ValidateMediator.java | 6 +- .../expression/ast/SignedExpressionNode.java | 4 - .../expression/visitor/ExpressionVisitor.java | 80 ++++++++++++++++++- .../synapse/util/xpath/SynapseExpression.java | 12 ++- 4 files changed, 91 insertions(+), 11 deletions(-) diff --git a/modules/core/src/main/java/org/apache/synapse/mediators/builtin/ValidateMediator.java b/modules/core/src/main/java/org/apache/synapse/mediators/builtin/ValidateMediator.java index 135b0a4e98..34f20e3655 100644 --- a/modules/core/src/main/java/org/apache/synapse/mediators/builtin/ValidateMediator.java +++ b/modules/core/src/main/java/org/apache/synapse/mediators/builtin/ValidateMediator.java @@ -57,6 +57,7 @@ import org.apache.synapse.util.resolver.ResourceMap; import org.apache.synapse.util.resolver.UserDefinedXmlSchemaURIResolver; import org.apache.synapse.util.xpath.SourceXPathSupport; +import org.apache.synapse.util.xpath.SynapseExpression; import org.apache.synapse.util.xpath.SynapseJsonPath; import org.apache.synapse.util.xpath.SynapseXPath; import org.xml.sax.SAXException; @@ -279,10 +280,11 @@ public boolean mediate(MessageContext synCtx) { String jsonPayload = null; if (sourcePath != null) { //evaluating - if (sourcePath instanceof SynapseJsonPath) { + if (sourcePath instanceof SynapseJsonPath || sourcePath instanceof SynapseExpression) { jsonPayload = sourcePath.stringValueOf(synCtx); } else { - handleException("Could not find the JSONPath evaluator for Source", synCtx); + handleException("Could not find JSONPath or Synapse Expression to extract the message " + + "to validate from the payload", synCtx); } } else { jsonPayload = JsonUtil.jsonPayloadToString(a2mc); diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/SignedExpressionNode.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/SignedExpressionNode.java index 9792729407..7f2aaabea9 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/SignedExpressionNode.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/SignedExpressionNode.java @@ -17,16 +17,12 @@ */ package org.apache.synapse.util.synapse.expression.ast; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.synapse.util.synapse.expression.context.EvaluationContext; /** * Represents a node in the AST that holds a signed expression. ex: ( -var.num1 ) */ public class SignedExpressionNode implements ExpressionNode { - private static final Log log = LogFactory.getLog(SignedExpressionNode.class); private final ExpressionNode expression; private final boolean signed; diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/visitor/ExpressionVisitor.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/visitor/ExpressionVisitor.java index 2ae0bdf1cc..788c043a94 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/visitor/ExpressionVisitor.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/visitor/ExpressionVisitor.java @@ -17,6 +17,8 @@ */ package org.apache.synapse.util.synapse.expression.visitor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.synapse.SynapseConstants; import org.apache.synapse.util.synapse.expression.ast.*; import org.apache.synapse.util.synapse.expression.constants.ExpressionConstants; @@ -35,8 +37,13 @@ public class ExpressionVisitor extends ExpressionParserBaseVisitor implements ExpressionParserVisitor { + private static final Log log = LogFactory.getLog(ExpressionVisitor.class); + @Override public ExpressionNode visitExpression(ExpressionParser.ExpressionContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting expression: " + ctx.getText()); + } if (ctx.comparisonExpression() != null) { return visitComparisonExpression(ctx.comparisonExpression()); } else if (ctx.conditionalExpression() != null) { @@ -47,6 +54,9 @@ public ExpressionNode visitExpression(ExpressionParser.ExpressionContext ctx) { @Override public ExpressionNode visitComparisonExpression(ExpressionParser.ComparisonExpressionContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting comparison expression: " + ctx.getText()); + } if (ctx.logicalExpression() != null) { if (ctx.logicalExpression().size() == 1) { return visitLogicalExpression(ctx.logicalExpression().get(0)); @@ -64,6 +74,9 @@ public ExpressionNode visitComparisonExpression(ExpressionParser.ComparisonExpre @Override public ExpressionNode visitLogicalExpression(ExpressionParser.LogicalExpressionContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting logical expression: " + ctx.getText()); + } if (ctx.arithmeticExpression() != null) { ExpressionNode left = visit(ctx.arithmeticExpression()); if (ctx.logicalExpression() != null && ctx.getChild(1) != null) { @@ -77,6 +90,9 @@ public ExpressionNode visitLogicalExpression(ExpressionParser.LogicalExpressionC @Override public ExpressionNode visitArithmeticExpression(ExpressionParser.ArithmeticExpressionContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting arithmetic expression: " + ctx.getText()); + } if (ctx.term() != null) { if (ctx.term().size() == 1) { return visit(ctx.term().get(0)); @@ -94,6 +110,9 @@ public ExpressionNode visitArithmeticExpression(ExpressionParser.ArithmeticExpre @Override public ExpressionNode visitTerm(ExpressionParser.TermContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting term: " + ctx.getText()); + } if (ctx.factor() != null) { if (ctx.factor().size() == 1) { return visit(ctx.factor().get(0)); @@ -111,6 +130,9 @@ public ExpressionNode visitTerm(ExpressionParser.TermContext ctx) { @Override public ExpressionNode visitFactor(ExpressionParser.FactorContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting factor: " + ctx.getText()); + } if (ctx.literal() != null) { return visit(ctx.literal()); } else if (ctx.functionCall() != null) { @@ -135,6 +157,9 @@ public ExpressionNode visitFactor(ExpressionParser.FactorContext ctx) { @Override public ExpressionNode visitFunctionCall(ExpressionParser.FunctionCallContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting function call: " + ctx.getText()); + } ArgumentListNode parameterList = new ArgumentListNode(); if (ctx.expression() != null) { for (ExpressionParser.ExpressionContext expressionContext : ctx.expression()) { @@ -263,6 +288,9 @@ public ExpressionNode visitFunctionCall(ExpressionParser.FunctionCallContext ctx @Override public ExpressionNode visitLiteral(ExpressionParser.LiteralContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting literal: " + ctx.getText()); + } if (ctx.NUMBER() != null) { return new LiteralNode(ctx.NUMBER().getText(), LiteralNode.Type.NUMBER); } else if (ctx.BOOLEAN_LITERAL() != null) { @@ -279,6 +307,9 @@ public ExpressionNode visitLiteral(ExpressionParser.LiteralContext ctx) { @Override public ExpressionNode visitArrayLiteral(ExpressionParser.ArrayLiteralContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting array literal: " + ctx.getText()); + } if (ctx.expression() != null) { ArgumentListNode parameterList = new ArgumentListNode(); for (ExpressionParser.ExpressionContext expressionContext : ctx.expression()) { @@ -291,6 +322,9 @@ public ExpressionNode visitArrayLiteral(ExpressionParser.ArrayLiteralContext ctx @Override public ExpressionNode visitVariableAccess(ExpressionParser.VariableAccessContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting variable access: " + ctx.getText()); + } Map expressionNodeMap = new HashMap<>(); if (ctx.jsonPathExpression() != null) { expressionNodeMap = visitJsonPath(ctx.jsonPathExpression()); @@ -300,6 +334,9 @@ public ExpressionNode visitVariableAccess(ExpressionParser.VariableAccessContext @Override public ExpressionNode visitPayloadAccess(ExpressionParser.PayloadAccessContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting payload access: " + ctx.getText()); + } Map expressionNodeMap = new HashMap<>(); if (ctx.jsonPathExpression() != null) { expressionNodeMap = visitJsonPath(ctx.jsonPathExpression()); @@ -308,6 +345,9 @@ public ExpressionNode visitPayloadAccess(ExpressionParser.PayloadAccessContext c } public Map visitJsonPath(ExpressionParser.JsonPathExpressionContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting json path: " + ctx.getText()); + } Map expressionNodeMap = new HashMap<>(); if (ctx.arrayIndex() != null) { for (ExpressionParser.ArrayIndexContext expressionContext : ctx.arrayIndex()) { @@ -319,6 +359,9 @@ public Map visitJsonPath(ExpressionParser.JsonPathExpres public ExpressionNode visitJsonPathAfterPayload(ExpressionParser.JsonPathExpressionContext ctx, PredefinedFunctionNode functionNode, PayloadAccessNode.Type type) { + if (log.isDebugEnabled()) { + log.debug("Visiting json path after payload: " + ctx.getText()); + } Map expressionNodeMap = new HashMap<>(); if (ctx.arrayIndex() != null) { for (ExpressionParser.ArrayIndexContext expressionContext : ctx.arrayIndex()) { @@ -330,6 +373,9 @@ public ExpressionNode visitJsonPathAfterPayload(ExpressionParser.JsonPathExpress @Override public ExpressionNode visitArrayIndex(ExpressionParser.ArrayIndexContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting array index: " + ctx.getText()); + } if (ctx.NUMBER() != null) { return new LiteralNode(ctx.NUMBER().getText(), LiteralNode.Type.NUMBER); } else if (ctx.STRING_LITERAL() != null) { @@ -352,6 +398,9 @@ public ExpressionNode visitArrayIndex(ExpressionParser.ArrayIndexContext ctx) { @Override public ExpressionNode visitMultipleArrayIndices(ExpressionParser.MultipleArrayIndicesContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting multiple array indices: " + ctx.getText()); + } if (ctx.expression() != null) { ArgumentListNode expressionNodes = new ArgumentListNode(); for (ExpressionParser.ExpressionContext expressionContext : ctx.expression()) { @@ -364,6 +413,9 @@ public ExpressionNode visitMultipleArrayIndices(ExpressionParser.MultipleArrayIn @Override public ExpressionNode visitSliceArrayIndex(ExpressionParser.SliceArrayIndexContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting slice array index: " + ctx.getText()); + } if (ctx.signedExpressions() != null) { ArgumentListNode expressionNodes = new ArgumentListNode(); if (ctx.getChildCount() == 2 && ctx.getChild(0).getText().equals(":")) { @@ -382,6 +434,9 @@ public ExpressionNode visitSliceArrayIndex(ExpressionParser.SliceArrayIndexConte @Override public ExpressionNode visitSignedExpressions(ExpressionParser.SignedExpressionsContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting signed expressions: " + ctx.getText()); + } if (ctx.expression() != null) { if (ctx.MINUS() != null) { return new SignedExpressionNode(visit(ctx.expression()), true); @@ -394,6 +449,9 @@ public ExpressionNode visitSignedExpressions(ExpressionParser.SignedExpressionsC @Override public ExpressionNode visitFilterExpression(ExpressionParser.FilterExpressionContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting filter expression: " + ctx.getText()); + } Map expressionNodeMap = new HashMap<>(); if (ctx.filterComponent() != null) { for (ExpressionParser.FilterComponentContext filterExpressionContext : ctx.filterComponent()) { @@ -405,6 +463,9 @@ public ExpressionNode visitFilterExpression(ExpressionParser.FilterExpressionCon @Override public ExpressionNode visitFilterComponent(ExpressionParser.FilterComponentContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting filter component: " + ctx.getText()); + } if (ctx.payloadAccess() != null) { return visit(ctx.payloadAccess()); } else if (ctx.stringOrOperator() != null) { @@ -427,6 +488,9 @@ public ExpressionNode visitFilterComponent(ExpressionParser.FilterComponentConte @Override public ExpressionNode visitHeaderAccess(ExpressionParser.HeaderAccessContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting header access: " + ctx.getText()); + } if (ctx.propertyName() != null) { return new HeadersAndPropertiesAccessNode(visit(ctx.propertyName()), HeadersAndPropertiesAccessNode.Type.HEADER); @@ -436,6 +500,9 @@ public ExpressionNode visitHeaderAccess(ExpressionParser.HeaderAccessContext ctx @Override public ExpressionNode visitPropertyName(ExpressionParser.PropertyNameContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting property name: " + ctx.getText()); + } if (ctx.ID() != null) { return new LiteralNode(ctx.ID().getText(), LiteralNode.Type.STRING); } else if (ctx.STRING_LITERAL() != null) { @@ -446,6 +513,9 @@ public ExpressionNode visitPropertyName(ExpressionParser.PropertyNameContext ctx @Override public ExpressionNode visitConfigAccess(ExpressionParser.ConfigAccessContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting config access: " + ctx.getText()); + } if (ctx.propertyName() != null) { return new HeadersAndPropertiesAccessNode(visit(ctx.propertyName()), HeadersAndPropertiesAccessNode.Type.CONFIG); @@ -455,6 +525,9 @@ public ExpressionNode visitConfigAccess(ExpressionParser.ConfigAccessContext ctx @Override public ExpressionNode visitPropertyAccess(ExpressionParser.PropertyAccessContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting property access: " + ctx.getText()); + } if (ctx.propertyName() != null) { if (ctx.ID() != null) { String scope = ctx.ID().getText(); @@ -471,6 +544,9 @@ public ExpressionNode visitPropertyAccess(ExpressionParser.PropertyAccessContext @Override public ExpressionNode visitParameterAccess(ExpressionParser.ParameterAccessContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting parameter access: " + ctx.getText()); + } if (ctx.propertyName() != null) { if (ctx.ID() != null) { String scope = ctx.ID().getText(); @@ -489,9 +565,11 @@ public ExpressionNode visitParameterAccess(ExpressionParser.ParameterAccessConte return null; } - @Override public ExpressionNode visitConditionalExpression(ExpressionParser.ConditionalExpressionContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Visiting conditional expression: " + ctx.getText()); + } ExpressionNode condition = null; if (ctx.comparisonExpression() != null) { condition = visit(ctx.comparisonExpression()); diff --git a/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java b/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java index 20a5ba3ede..8ee16b8dc0 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java +++ b/modules/core/src/main/java/org/apache/synapse/util/xpath/SynapseExpression.java @@ -40,8 +40,6 @@ import java.util.HashMap; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Represents a Synapse Expression @@ -51,7 +49,7 @@ public class SynapseExpression extends SynapsePath { private static final Log log = LogFactory.getLog(SynapseExpression.class); private final ExpressionNode expressionNode; private final Map namespaceMap = new HashMap<>(); - private boolean isContentAware = false; + private final boolean isContentAware; public SynapseExpression(String synapseExpression) throws JaxenException { super(synapseExpression, org.apache.synapse.config.xml.SynapsePath.JSON_PATH, log); @@ -79,6 +77,9 @@ public SynapseExpression(String synapseExpression) throws JaxenException { @Override public String stringValueOf(MessageContext synCtx) { + if (log.isDebugEnabled()) { + log.debug("Evaluating expression (stringValueOf): " + expression); + } EvaluationContext context = new EvaluationContext(); context.setNamespaceMap(namespaceMap); context.setSynCtx(synCtx); @@ -88,11 +89,14 @@ public String stringValueOf(MessageContext synCtx) { @Override public Object objectValueOf(MessageContext synCtx) { + if (log.isDebugEnabled()) { + log.debug("Evaluating expression (objectValueOf): " + expression); + } EvaluationContext context = new EvaluationContext(); context.setNamespaceMap(namespaceMap); context.setSynCtx(synCtx); ExpressionResult result = evaluateExpression(context, true); - return result != null ? result.getValue() : null; + return result != null ? result.getValue() : ""; } private ExpressionResult evaluateExpression(EvaluationContext context, boolean isObjectValue) {