Skip to content

Commit

Permalink
Merge pull request #2294 from SanojPunchihewa/script-mediator-v2
Browse files Browse the repository at this point in the history
Improve Script mediator and class mediator to support inputs and outputs
  • Loading branch information
arunans23 authored Jan 22, 2025
2 parents 24f830a + bbad753 commit cdbb695
Show file tree
Hide file tree
Showing 22 changed files with 833 additions and 284 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@
import org.apache.synapse.SynapseException;
import org.apache.synapse.aspects.AspectConfigurable;
import org.apache.synapse.aspects.AspectConfiguration;
import org.apache.synapse.mediators.v2.ext.InputArgument;
import org.jaxen.JaxenException;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
Expand Down Expand Up @@ -76,6 +79,12 @@ public abstract class AbstractMediatorFactory implements MediatorFactory {
protected static final QName DESCRIPTION_Q
= new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "description");

protected static final QName RESULT_TARGET_Q = new QName("result-target");
protected static final QName ATT_TYPE = new QName("type");
protected static final QName ATT_ARGUMENT = new QName("argument");
protected static final QName INPUTS
= new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "inputs");

/**
* A constructor that makes subclasses pick up the correct logger
*/
Expand Down Expand Up @@ -238,4 +247,37 @@ protected static void addAllCommentChildrenToList(OMElement el, List<String> com
}
}
}

/**
* This method is used to get the input arguments of the script mediator.
*
* @param inputArgsElement input arguments element
* @return List of input arguments
*/
protected List<InputArgument> getInputArguments(OMElement inputArgsElement, String mediator) {

List<InputArgument> inputArgsMap = new ArrayList<>();
Iterator inputIterator = inputArgsElement.getChildrenWithName(ATT_ARGUMENT);
while (inputIterator.hasNext()) {
OMElement inputElement = (OMElement) inputIterator.next();
String nameAttribute = inputElement.getAttributeValue(ATT_NAME);
String typeAttribute = inputElement.getAttributeValue(ATT_TYPE);
String valueAttribute = inputElement.getAttributeValue(ATT_VALUE);
String expressionAttribute = inputElement.getAttributeValue(ATT_EXPRN);
InputArgument argument = new InputArgument(nameAttribute);
if (valueAttribute != null) {
argument.setValue(valueAttribute, typeAttribute);
} else if (expressionAttribute != null) {
try {
argument.setExpression(SynapsePathFactory.getSynapsePath(inputElement,
new QName("expression")), typeAttribute);
} catch (JaxenException e) {
handleException("Error setting expression : " + expressionAttribute + " as an input argument to " +
mediator + " mediator. " + e.getMessage(), e);
}
}
inputArgsMap.add(argument);
}
return inputArgsMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
import org.apache.synapse.SynapseException;
import org.apache.synapse.aspects.AspectConfigurable;
import org.apache.synapse.aspects.statistics.StatisticsConfigurable;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.synapse.mediators.MediatorProperty;
import org.apache.synapse.mediators.builtin.CommentMediator;
import org.apache.synapse.mediators.v2.ext.InputArgument;

import javax.xml.namespace.QName;
import java.util.Collection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,20 @@

import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.commons.lang3.StringUtils;
import org.apache.synapse.Mediator;
import org.apache.synapse.SynapseException;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.mediators.ext.ClassMediator;
import org.apache.synapse.mediators.v2.ext.AbstractClassMediator;
import org.apache.synapse.mediators.v2.ext.InputArgument;

import javax.xml.namespace.QName;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

Expand Down Expand Up @@ -114,7 +121,40 @@ public Mediator createSpecificMediator(OMElement elem, Properties properties) {
throw new SynapseException(msg, e);
}

classMediator.addAllProperties(MediatorPropertyFactory.getMediatorProperties(elem, mediator));
String targetAtt = elem.getAttributeValue(RESULT_TARGET_Q);
if (StringUtils.isNotBlank(targetAtt)) {
// This a V2 class mediator. Set the result target and input arguments
String methodAtt = elem.getAttributeValue(new QName(XMLConfigConstants.NULL_NAMESPACE,
"method"));
if (StringUtils.isBlank(methodAtt)) {
String msg = "The 'method' attribute is required for the class mediator " + clazz.getName();
log.error(msg);
throw new SynapseException(msg);
}
classMediator.setResultTarget(targetAtt);
classMediator.setMethodName(methodAtt);
OMElement inputArgsElement = elem.getFirstChildWithName(INPUTS);
if (inputArgsElement != null) {
List<InputArgument> inputArgsMap = getInputArguments(inputArgsElement, clazz.getName() + " class");
classMediator.setInputArguments(inputArgsMap);
}
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getName().equals(methodAtt)) {
List<AbstractClassMediator.Arg> arguments = new ArrayList<>();
for (Parameter parameter : method.getParameters()) {
if (parameter.isAnnotationPresent(AbstractClassMediator.Arg.class)) {
AbstractClassMediator.Arg arg = parameter.getAnnotation(AbstractClassMediator.Arg.class);
arguments.add(arg);
}
}
classMediator.setArguments(arguments);
break;
}
}
} else {
classMediator.addAllProperties(MediatorPropertyFactory.getMediatorProperties(elem, mediator));
}

// after successfully creating the mediator
// set its common attributes such as tracing etc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.commons.lang3.StringUtils;
import org.apache.synapse.Mediator;
import org.apache.synapse.mediators.ext.ClassMediator;

Expand Down Expand Up @@ -51,7 +52,14 @@ public OMElement serializeSpecificMediator(Mediator m) {
handleException("Invalid class mediator. The class name is required");
}

super.serializeProperties(clazz, mediator.getProperties());
if (StringUtils.isNotBlank(mediator.getResultTarget())) {
// If result target is set, this is V2 class mediator
clazz.addAttribute(fac.createOMAttribute("result-target", nullNS, mediator.getResultTarget()));
clazz.addAttribute(fac.createOMAttribute("method", nullNS, mediator.getMethodName()));
clazz.addChild(InputArgumentSerializer.serializeInputArguments(mediator.getInputArguments()));
} else {
super.serializeProperties(clazz, mediator.getProperties());
}

serializeComments(clazz, mediator.getCommentsList());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2025, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.synapse.config.xml;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.mediators.v2.ext.InputArgument;

import java.util.List;

/**
* Serializer for input arguments
*/
public class InputArgumentSerializer {

private static final OMFactory fac = OMAbstractFactory.getOMFactory();
private static final OMNamespace nullNS = fac.createOMNamespace(XMLConfigConstants.NULL_NAMESPACE, "");
private static final String INPUTS = "inputs";
private static final String ARGUMENT = "argument";
private static final String NAME = "name";
private static final String TYPE = "type";
private static final String EXPRESSION = "expression";
private static final String VALUE = "value";

public static OMElement serializeInputArguments(List<InputArgument> inputArguments) {

OMElement inputElement = fac.createOMElement(INPUTS, SynapseConstants.SYNAPSE_OMNAMESPACE);
for (InputArgument inputArgument : inputArguments) {
OMElement inputArgElement = fac.createOMElement(ARGUMENT, SynapseConstants.SYNAPSE_OMNAMESPACE);
inputArgElement.addAttribute(fac.createOMAttribute(NAME, nullNS, inputArgument.getName()));
inputArgElement.addAttribute(fac.createOMAttribute(TYPE, nullNS, inputArgument.getType()));
if (inputArgument.getExpression() != null) {
SynapsePathSerializer.serializePath(inputArgument.getExpression(),
inputArgument.getExpression().getExpression(), inputArgElement, EXPRESSION);
} else {
inputArgElement.addAttribute(fac.createOMAttribute(VALUE, nullNS, inputArgument.getValue().toString()));
}
inputElement.addChild(inputArgElement);
}
return inputElement;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ public class ScatterGatherMediatorFactory extends AbstractMediatorFactory {
private static final QName ATT_MAX_MESSAGES = new QName("max-messages");
private static final QName SEQUENCE_Q = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "sequence");
private static final QName PARALLEL_EXEC_Q = new QName("parallel-execution");
private static final QName RESULT_TARGET_Q = new QName("result-target");
private static final QName ROOT_ELEMENT_Q = new QName("root-element");
private static final QName CONTENT_TYPE_Q = new QName("content-type");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public static OMElement serializePath(SynapsePath path, String expression,
attribName, nullNS, "{${" + expression.substring(1, expression.length() - 1) + "}}"));
} else {
elem.addAttribute(elem.getOMFactory().createOMAttribute(
attribName, nullNS, "{${" + expression + "}"));
attribName, nullNS, "${" + expression + "}"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.apache.synapse.continuation.SeqContinuationState;
import org.apache.synapse.debug.SynapseDebugManager;
import org.apache.synapse.mediators.base.SequenceMediator;
import org.apache.synapse.mediators.v2.ScatterGatherUtils;
import org.apache.synapse.mediators.v2.Utils;
import org.apache.synapse.util.logging.LoggingUtils;

/**
Expand Down Expand Up @@ -96,7 +96,7 @@ public void run() {

boolean result = seq.mediate(synCtx);
// If this is a scatter message, then we need to use the continuation state and continue the mediation
if (ScatterGatherUtils.isScatterMessage(synCtx) && result) {
if (Utils.isScatterMessage(synCtx) && result) {
SeqContinuationState seqContinuationState = (SeqContinuationState) ContinuationStackManager.peakContinuationStateStack(synCtx);
if (seqContinuationState == null) {
return;
Expand Down Expand Up @@ -143,7 +143,7 @@ public void run() {
debugManager.advertiseMediationFlowTerminatePoint(synCtx);
debugManager.releaseMediationFlowLock();
}
if (RuntimeStatisticCollector.isStatisticsEnabled() && !ScatterGatherUtils.isScatterMessage(synCtx)) {
if (RuntimeStatisticCollector.isStatisticsEnabled() && !Utils.isScatterMessage(synCtx)) {
this.statisticsCloseEventListener.invokeCloseEventEntry(synCtx);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.apache.synapse.aspects.flow.statistics.collectors.OpenEventCollector;
import org.apache.synapse.aspects.flow.statistics.collectors.RuntimeStatisticCollector;
import org.apache.synapse.aspects.flow.statistics.data.artifact.ArtifactHolder;
import org.apache.synapse.mediators.v2.ScatterGatherUtils;
import org.apache.synapse.mediators.v2.Utils;
import org.apache.synapse.transport.customlogsetter.CustomLogSetter;
import org.apache.synapse.aspects.ComponentType;
import org.apache.synapse.continuation.ContinuationStackManager;
Expand Down Expand Up @@ -158,7 +158,7 @@ public boolean mediate(MessageContext synCtx) {

boolean result = super.mediate(synCtx);

if (result && !skipAddition && !ScatterGatherUtils.isScatterMessage(synCtx)) {
if (result && !skipAddition && !Utils.isScatterMessage(synCtx)) {
// if flow completed remove the previously added SeqContinuationState
ContinuationStackManager.removeSeqContinuationState(synCtx, sequenceType);
}
Expand Down
Loading

0 comments on commit cdbb695

Please sign in to comment.