Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update input and output parameters of Class, Script, Scatter gather and ForEach V2 #2310

Merged
merged 3 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,8 @@
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 All @@ -61,7 +58,7 @@ public abstract class AbstractMediatorFactory implements MediatorFactory {
protected static final QName ATT_EXPRN = new QName("expression");
protected static final QName ATT_KEY = new QName("key");
protected static final QName ATT_SOURCE = new QName("source");
protected static final QName ATT_TARGET = new QName("target");
public static final QName ATT_TARGET = new QName("target");
protected static final QName ATT_ONERROR = new QName("onError");
protected static final QName ATT_EVAL = new QName("evaluator");
protected static final QName ATT_STATS
Expand All @@ -79,7 +76,9 @@ 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");
public static final QName ATT_TARGET_VARIABLE = new QName("target-variable");
protected static final QName ATT_ROOT_ELEMENT = new QName("result-enclosing-element");
protected static final QName RESULT_TYPE_Q = new QName("result-content-type");
protected static final QName ATT_TYPE = new QName("type");
protected static final QName ATT_ARGUMENT = new QName("argument");
protected static final QName INPUTS
Expand Down Expand Up @@ -247,37 +246,4 @@ 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 @@ -26,15 +26,18 @@
import org.apache.synapse.SynapseException;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.mediators.ext.ClassMediator;
import org.apache.synapse.mediators.v2.Utils;
import org.apache.synapse.mediators.v2.ext.AbstractClassMediator;
import org.apache.synapse.mediators.v2.ext.InputArgument;
import org.jaxen.JaxenException;

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

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

String targetAtt = elem.getAttributeValue(RESULT_TARGET_Q);
String targetAtt = elem.getAttributeValue(ATT_TARGET);
if (StringUtils.isNotBlank(targetAtt)) {
// This a V2 class mediator. Set the result target and input arguments
if (Utils.isTargetBody(targetAtt)) {
classMediator.setResultTarget(Utils.TARGET_BODY);
} else if (Utils.isTargetVariable(targetAtt)) {
String variableNameAttr = elem.getAttributeValue(ATT_TARGET_VARIABLE);
if (StringUtils.isBlank(variableNameAttr)) {
String msg = "The '" + AbstractMediatorFactory.ATT_TARGET_VARIABLE + "' attribute is required for the configuration of a " +
"Class mediator when the '" + AbstractMediatorFactory.ATT_TARGET + "' is 'variable'";
throw new SynapseException(msg);
}
classMediator.setResultTarget(Utils.TARGET_VARIABLE);
classMediator.setVariableName(variableNameAttr);
} else if (Utils.isTargetNone(targetAtt)) {
classMediator.setResultTarget(Utils.TARGET_NONE);
} else {
throw new SynapseException("Invalid '" + AbstractMediatorFactory.ATT_TARGET + "' attribute value for " +
"class mediator : " + targetAtt + ". It should be either 'body', 'variable' or 'none'");
}
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);
methodAtt = "mediate";
}
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<>();
Map<String, AbstractClassMediator.Arg> arguments = new LinkedHashMap<>();
for (Parameter parameter : method.getParameters()) {
if (parameter.isAnnotationPresent(AbstractClassMediator.Arg.class)) {
AbstractClassMediator.Arg arg = parameter.getAnnotation(AbstractClassMediator.Arg.class);
arguments.add(arg);
arguments.put(arg.name(), arg);
}
}
classMediator.setArguments(new ArrayList<>(arguments.values()));
if (!arguments.isEmpty()) {
OMElement inputArgsElement = elem.getFirstChildWithName(INPUTS);
if (inputArgsElement != null) {
Map<String, InputArgument> inputArgsMap = getInputArguments(arguments, inputArgsElement,
clazz.getName() + " class");
classMediator.setInputArguments(inputArgsMap);
} else {
String msg = "The 'inputs' element is required for the configuration of a " +
"Class mediator.";
throw new SynapseException(msg);
}
}
classMediator.setArguments(arguments);
break;
}
}
Expand All @@ -169,4 +193,45 @@ public Mediator createSpecificMediator(OMElement elem, Properties properties) {
public QName getTagQName() {
return CLASS_Q;
}


/**
* This method is used to get the input arguments of the V2 class mediator.
*
* @param inputArgsElement input arguments element
* @return Map of input arguments
*/
private Map<String, InputArgument> getInputArguments(Map<String, AbstractClassMediator.Arg> args,
OMElement inputArgsElement, String mediator) {

Map<String, InputArgument> inputArgsMap = new LinkedHashMap<>();
Iterator inputIterator = inputArgsElement.getChildrenWithName(ATT_ARGUMENT);
while (inputIterator.hasNext()) {
OMElement inputElement = (OMElement) inputIterator.next();
String nameAttribute = inputElement.getAttributeValue(ATT_NAME);
if (args.containsKey(nameAttribute)) {
String type = args.get(nameAttribute).type().getTypeName();
String valueAttribute = inputElement.getAttributeValue(ATT_VALUE);
String expressionAttribute = inputElement.getAttributeValue(ATT_EXPRN);
InputArgument argument = new InputArgument(nameAttribute);
if (valueAttribute != null) {
argument.setValue(valueAttribute, type);
} else if (expressionAttribute != null) {
try {
argument.setExpression(SynapsePathFactory.getSynapsePath(inputElement,
new QName("expression")), type);
} catch (JaxenException e) {
handleException("Error setting expression : " + expressionAttribute + " as an input argument to " +
mediator + " mediator. " + e.getMessage(), e);
}
}
inputArgsMap.put(nameAttribute, argument);
}
}
if (inputArgsMap.size() != args.size()) {
handleException("The input arguments provided in the configuration of the " + mediator +
" mediator does not match with the method signature. Please provide the correct input arguments.");
}
return inputArgsMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.synapse.Mediator;
import org.apache.synapse.mediators.ext.ClassMediator;
import org.apache.synapse.mediators.v2.Utils;

import java.util.Iterator;

Expand Down Expand Up @@ -54,8 +55,12 @@ public OMElement serializeSpecificMediator(Mediator m) {

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.addAttribute(fac.createOMAttribute(AbstractMediatorFactory.ATT_TARGET.getLocalPart(), nullNS,
mediator.getResultTarget()));
if (Utils.isTargetVariable(mediator.getResultTarget())) {
clazz.addAttribute(fac.createOMAttribute(AbstractMediatorFactory.ATT_TARGET_VARIABLE.getLocalPart(),
nullNS, mediator.getVariableName()));
}
clazz.addChild(InputArgumentSerializer.serializeInputArguments(mediator.getInputArguments()));
} else {
super.serializeProperties(clazz, mediator.getProperties());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.synapse.Mediator;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.mediators.base.SequenceMediator;
import org.apache.synapse.mediators.builtin.CallMediator;
import org.apache.synapse.mediators.builtin.CalloutMediator;
Expand Down Expand Up @@ -63,10 +64,9 @@ public class ForEachMediatorFactory extends AbstractMediatorFactory {
private static final QName ATT_COLLECTION = new QName("collection");
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 RESULT_TYPE_Q = new QName("result-type");
public static final QName ATT_UPDATE_ORIGINAL = new QName("update-original");
private static final QName ATT_COUNTER_VARIABLE = new QName("counter-variable");
private static final QName ATT_CONTINUE_WITHOUT_AGGREGATION = new QName("continue-without-aggregation");
public static final QName ATT_CONTINUE_WITHOUT_AGGREGATION = new QName("continue-without-aggregation");

public QName getTagQName() {
return FOREACH_Q;
Expand Down Expand Up @@ -161,20 +161,31 @@ public Mediator createForEachMediatorV2(OMElement elem, Properties properties) {
if ("true".equalsIgnoreCase(continueWithoutAggregationAttr)) {
mediator.setContinueWithoutAggregation(true);
} else {
OMAttribute resultTargetAttr = elem.getAttribute(RESULT_TARGET_Q);
if (resultTargetAttr != null && StringUtils.isNotBlank(resultTargetAttr.getAttributeValue())) {
OMAttribute contentTypeAttr = elem.getAttribute(RESULT_TYPE_Q);
if (contentTypeAttr == null || StringUtils.isBlank(contentTypeAttr.getAttributeValue())) {
handleException("The 'result-type' attribute is required when the 'result-target' attribute is present");
} else {
if ("JSON".equals(contentTypeAttr.getAttributeValue())) {
OMAttribute updateOriginalAttr = elem.getAttribute(ATT_UPDATE_ORIGINAL);
if (updateOriginalAttr != null && "false".equals(updateOriginalAttr.getAttributeValue())) {
mediator.setUpdateOriginal(false);
String contentTypeAttr = elem.getAttributeValue(RESULT_TYPE_Q);
String variableNameAttr = elem.getAttributeValue(ATT_TARGET_VARIABLE);
if (StringUtils.isNotBlank(contentTypeAttr) && StringUtils.isNotBlank(variableNameAttr)) {
mediator.setVariableName(variableNameAttr);
if ("JSON".equals(contentTypeAttr)) {
mediator.setContentType(ForEachMediatorV2.JSON_TYPE);
} else if ("XML".equals(contentTypeAttr.getAttributeValue())) {
mediator.setContentType(ForEachMediatorV2.XML_TYPE);
} else if ("XML".equals(contentTypeAttr)) {
String rootElementAttr = elem.getAttributeValue(ATT_ROOT_ELEMENT);
if (StringUtils.isNotBlank(rootElementAttr)) {
mediator.setRootElementName(rootElementAttr);
mediator.setContentType(ForEachMediatorV2.XML_TYPE);
} else {
String msg = "The '" + ATT_ROOT_ELEMENT + "' attribute is required for the configuration of a " +
"Foreach mediator when the '" + RESULT_TYPE_Q + "' is 'XML'";
throw new SynapseException(msg);
}
} else {
handleException("The 'result-type' attribute should be either 'JSON' or 'XML'");
handleException("The '" + RESULT_TYPE_Q + "' attribute should be either 'JSON' or 'XML'");
}
mediator.setResultTarget(resultTargetAttr.getAttributeValue());
} else {
handleException("The '" + RESULT_TYPE_Q + "' and '" + ATT_TARGET_VARIABLE + "' attributes are required when the " +
"'" + ATT_UPDATE_ORIGINAL + "' attribute is 'false'");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,19 @@ protected OMElement serializeSpecificMediator(Mediator m) {
"parallel-execution", nullNS, Boolean.toString(forEachMediatorV2.getParallelExecution())));
if (forEachMediatorV2.isContinueWithoutAggregation()) {
forEachElem.addAttribute(fac.createOMAttribute(
"continue-without-aggregation", nullNS, "true"));
ForEachMediatorFactory.ATT_CONTINUE_WITHOUT_AGGREGATION.getLocalPart(), nullNS, "true"));
} else {
if (forEachMediatorV2.getResultTarget() != null) {
forEachElem.addAttribute(fac.createOMAttribute(
ForEachMediatorFactory.ATT_UPDATE_ORIGINAL.getLocalPart(), nullNS, Boolean.toString(forEachMediatorV2.isUpdateOriginal())));
if (!forEachMediatorV2.isUpdateOriginal()) {
forEachElem.addAttribute(fac.createOMAttribute(
"result-target", nullNS, forEachMediatorV2.getResultTarget()));
AbstractMediatorFactory.ATT_TARGET_VARIABLE.getLocalPart(), nullNS, forEachMediatorV2.getVariableName()));
forEachElem.addAttribute(fac.createOMAttribute(
"result-type", nullNS, forEachMediatorV2.getContentType()));
AbstractMediatorFactory.RESULT_TYPE_Q.getLocalPart(), nullNS, forEachMediatorV2.getContentType()));
if ("XML".equalsIgnoreCase(forEachMediatorV2.getContentType())) {
forEachElem.addAttribute(fac.createOMAttribute(
AbstractMediatorFactory.ATT_ROOT_ELEMENT.getLocalPart(), nullNS, forEachMediatorV2.getRootElementName()));
}
}
}
if (forEachMediatorV2.getCounterVariable() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.mediators.v2.ext.InputArgument;

import java.util.List;
import java.util.Map;

/**
* Serializer for input arguments
Expand All @@ -41,13 +41,21 @@ public class InputArgumentSerializer {
private static final String EXPRESSION = "expression";
private static final String VALUE = "value";

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

return serializeInputArguments(inputArguments, false);
}

public static OMElement serializeInputArguments(Map<String, InputArgument> inputArguments, boolean includeType) {

OMElement inputElement = fac.createOMElement(INPUTS, SynapseConstants.SYNAPSE_OMNAMESPACE);
for (InputArgument inputArgument : inputArguments) {
for (Map.Entry<String, InputArgument> entry : inputArguments.entrySet()) {
InputArgument inputArgument = entry.getValue();
OMElement inputArgElement = fac.createOMElement(ARGUMENT, SynapseConstants.SYNAPSE_OMNAMESPACE);
if (includeType) {
inputArgElement.addAttribute(fac.createOMAttribute(TYPE, nullNS, inputArgument.getType()));
}
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);
Expand Down
Loading
Loading