diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorFactory.java b/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorFactory.java index 4a50a1bb29..b9db3d7c46 100644 --- a/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorFactory.java +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorFactory.java @@ -32,6 +32,7 @@ * *
  * <log [level="simple|headers|full|custom"]>
+ *      <message>String template</message>
  *      <property> *
  * </log>
  * 
@@ -52,6 +53,8 @@ public class LogMediatorFactory extends AbstractMediatorFactory { private static final QName ATT_LEVEL = new QName("level"); private static final QName ATT_SEPERATOR = new QName("separator"); private static final QName ATT_CATEGORY = new QName("category"); + protected static final QName ELEMENT_MESSAGE_Q + = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "message"); public QName getTagQName() { return LOG_Q; @@ -64,7 +67,13 @@ public Mediator createSpecificMediator(OMElement elem, Properties properties) { // after successfully creating the mediator // set its common attributes such as tracing etc processAuditStatus(logMediator,elem); - + + OMElement messageElement = elem.getFirstChildWithName(ELEMENT_MESSAGE_Q); + if (messageElement != null && messageElement.getText() != null) { + logMediator.setMessageTemplate(messageElement.getText()); + logMediator.setLogLevel(LogMediator.MESSAGE_TEMPLATE); + } + // Set the high level set of properties to be logged (i.e. log level) OMAttribute level = elem.getAttribute(ATT_LEVEL); if (level != null) { diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorSerializer.java b/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorSerializer.java index af8dec95b4..08e7fc1856 100644 --- a/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorSerializer.java +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/LogMediatorSerializer.java @@ -20,12 +20,14 @@ package org.apache.synapse.config.xml; import org.apache.axiom.om.OMElement; +import org.apache.commons.lang3.StringUtils; import org.apache.synapse.Mediator; import org.apache.synapse.mediators.builtin.LogMediator; /** *
  * <log [level="simple|headers|full|custom"] [separator="string"] [category="INFO|TRACE|DEBUG|WARN|ERROR|FATAL"]>
+ *      <message>String template</message>
  *      <property> *
  * </log>
  * 
@@ -42,7 +44,7 @@ public OMElement serializeSpecificMediator(Mediator m) { OMElement log = fac.createOMElement("log", synNS); saveTracingState(log,mediator); - if (mediator.getLogLevel() != LogMediator.SIMPLE) { + if (StringUtils.isBlank(mediator.getMessageTemplate()) && mediator.getLogLevel() != LogMediator.SIMPLE) { log.addAttribute(fac.createOMAttribute( "level", nullNS, mediator.getLogLevel() == LogMediator.HEADERS ? "headers" : @@ -73,6 +75,12 @@ public OMElement serializeSpecificMediator(Mediator m) { "separator", nullNS, mediator.getSeparator())); } + if (StringUtils.isNotBlank(mediator.getMessageTemplate())) { + OMElement onCompleteElem = fac.createOMElement("message", synNS); + onCompleteElem.setText(mediator.getMessageTemplate()); + log.addChild(onCompleteElem); + } + super.serializeProperties(log, mediator.getProperties()); serializeComments(log, mediator.getCommentsList()); diff --git a/modules/core/src/main/java/org/apache/synapse/mediators/builtin/LogMediator.java b/modules/core/src/main/java/org/apache/synapse/mediators/builtin/LogMediator.java index ee0dc49250..671c26be0b 100644 --- a/modules/core/src/main/java/org/apache/synapse/mediators/builtin/LogMediator.java +++ b/modules/core/src/main/java/org/apache/synapse/mediators/builtin/LogMediator.java @@ -29,14 +29,17 @@ import org.apache.synapse.SynapseLog; import org.apache.synapse.commons.json.JsonUtil; import org.apache.synapse.commons.CorrelationConstants; +import org.apache.synapse.config.xml.SynapsePath; import org.apache.synapse.core.axis2.Axis2MessageContext; import org.apache.synapse.mediators.AbstractMediator; import org.apache.synapse.mediators.MediatorProperty; +import org.apache.synapse.util.InlineExpressionUtil; import java.util.ArrayList; import java.util.Iterator; import java.util.List; - +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Logs the specified message into the configured logger. The log levels specify @@ -56,6 +59,9 @@ public class LogMediator extends AbstractMediator { /** all attributes of level 'simple' and the SOAP envelope and any properties */ public static final int FULL = 3; + /** The message template and the additional properties specified to the Log mediator */ + public static final int MESSAGE_TEMPLATE = 4; + public static final int CATEGORY_INFO = 0; public static final int CATEGORY_DEBUG = 1; public static final int CATEGORY_TRACE = 2; @@ -74,6 +80,8 @@ public class LogMediator extends AbstractMediator { /** The holder for the custom properties */ private final List properties = new ArrayList(); + private String messageTemplate; + /** * Logs the current message according to the supplied semantics * @@ -143,6 +151,8 @@ private String getLogMessage(MessageContext synCtx) { return getHeadersLogMessage(synCtx); case FULL: return getFullLogMessage(synCtx); + case MESSAGE_TEMPLATE: + return processMessageTemplate(synCtx, messageTemplate); default: return "Invalid log level specified"; } @@ -288,6 +298,16 @@ public void setCategory(int category) { } } + public String getMessageTemplate() { + + return messageTemplate; + } + + public void setMessageTemplate(String messageTemplate) { + + this.messageTemplate = messageTemplate; + } + private String trimLeadingSeparator(StringBuffer sb) { String retStr = sb.toString(); if (retStr.startsWith(separator)) { @@ -297,8 +317,16 @@ private String trimLeadingSeparator(StringBuffer sb) { } } + private String processMessageTemplate(MessageContext synCtx, String template) { + StringBuffer result = new StringBuffer(); + result.append(InlineExpressionUtil.processInLineTemplate(synCtx, template)); + setCustomProperties(result, synCtx); + return result.toString(); + } + @Override public boolean isContentAware() { + // TODO Use the new simplified expression model to check if the log mediator is content aware if (logLevel == CUSTOM) { for (MediatorProperty property : properties) { if (property.getExpression() != null && property.getExpression().isContentAware()) { diff --git a/modules/core/src/main/java/org/apache/synapse/util/InlineExpressionUtil.java b/modules/core/src/main/java/org/apache/synapse/util/InlineExpressionUtil.java index e362b54557..c7a7548482 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/InlineExpressionUtil.java +++ b/modules/core/src/main/java/org/apache/synapse/util/InlineExpressionUtil.java @@ -49,6 +49,9 @@ public final class InlineExpressionUtil { // Regex to identify expressions in inline text private static final Pattern EXPRESSION_PATTERN = Pattern.compile("(\\{[^\\s\",<>}\\]]+})"); + // Regex to identify synapse expressions #[expression] in inline text + private static final Pattern EXPRESSION_PLACEHOLDER_PATTERN = Pattern.compile("#\\[(.+?)\\]"); + private InlineExpressionUtil() { } @@ -197,4 +200,37 @@ private static boolean isValidXML(String stringToValidate) { } return false; } + + /** + * Process the inline template and replace the synapse expressions with the resolved values + * + * @param synCtx Message Context + * @param template Inline template + * @return Processed inline template + */ + public static String processInLineTemplate(MessageContext synCtx, String template) { + + Matcher matcher = EXPRESSION_PLACEHOLDER_PATTERN.matcher(template); + StringBuffer result = new StringBuffer(); + while (matcher.find()) { + // Extract the expression inside #[...] + String placeholder = matcher.group(1); + // Dummy resolver for expressions to test the Log mediator + // TODO update the #getDynamicValue method with synapse expressions and replace this + String replacement = ExpressionResolver.resolve(placeholder, synCtx); + matcher.appendReplacement(result, Matcher.quoteReplacement(replacement)); + } + matcher.appendTail(result); + return result.toString(); + } + + static class ExpressionResolver { + public static String resolve(String expression, MessageContext synCtx) { + String variableName = expression.substring(5); + if (synCtx.getVariable(variableName) != null) { + return synCtx.getVariable(variableName).toString(); + } + return expression; + } + } } diff --git a/modules/core/src/test/java/org/apache/synapse/config/xml/LogMediatorSerializationTest.java b/modules/core/src/test/java/org/apache/synapse/config/xml/LogMediatorSerializationTest.java index 8ef2be2b8c..f135a5f2ea 100644 --- a/modules/core/src/test/java/org/apache/synapse/config/xml/LogMediatorSerializationTest.java +++ b/modules/core/src/test/java/org/apache/synapse/config/xml/LogMediatorSerializationTest.java @@ -51,6 +51,12 @@ public LogMediatorSerializationTest() { logMediatorSerializer = new LogMediatorSerializer(); } + public void testLogMediatorSerializationWithTemplate() throws Exception { + + assertTrue(serialization(getXmlOfLogMediatorWithTemplate(), logMediatorFactory, logMediatorSerializer)); + assertTrue(serialization(getXmlOfLogMediatorWithTemplateAndProps(), logMediatorFactory, logMediatorSerializer)); + } + public void testLogMediatorSerializationSenarioOne() throws Exception { // assertTrue(serialization(getXmlOfMediatorScenarioOne(SIMPLE), logMediatorFactory, logMediatorSerializer)); @@ -130,6 +136,17 @@ private String getXmlOfMediatorScenarioOne(String level) { } + private String getXmlOfLogMediatorWithTemplate() { + return "" + + "Processing message with ID: 123"; + } + + private String getXmlOfLogMediatorWithTemplateAndProps() { + return "" + + "Processing message with ID: 123" + + ""; + } + private String getXmlOfMediatorScenarioOneA(String level) { return "";