diff --git a/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java b/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java index edcdbeb1b0..be73b0d127 100644 --- a/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java +++ b/modules/core/src/main/java/org/apache/synapse/SynapseConstants.java @@ -628,4 +628,6 @@ public enum ENDPOINT_TIMEOUT_TYPE { ENDPOINT_TIMEOUT, GLOBAL_TIMEOUT, HTTP_CONNE public static final String SCATTER_MESSAGES = "SCATTER_MESSAGES"; public static final String CONTINUE_FLOW_TRIGGERED_FROM_MEDIATOR_WORKER = "CONTINUE_FLOW_TRIGGERED_FROM_MEDIATOR_WORKER"; + + public static final String DEFAULT_ERROR_TYPE = "ANY"; } diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java b/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java index cda214f563..ea3c352b65 100644 --- a/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactoryFinder.java @@ -104,7 +104,8 @@ public class MediatorFactoryFinder implements XMLToObjectMapper { JSONTransformMediatorFactory.class, NTLMMediatorFactory.class, VariableMediatorFactory.class, - ScatterGatherMediatorFactory.class + ScatterGatherMediatorFactory.class, + ThrowErrorMediatorFactory.class }; private final static MediatorFactoryFinder instance = new MediatorFactoryFinder(); diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java b/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java index eb12240762..8ccd913b0d 100644 --- a/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializerFinder.java @@ -78,7 +78,8 @@ public class MediatorSerializerFinder { JSONTransformMediatorSerializer.class, NTLMMediatorSerializer.class, VariableMediatorSerializer.class, - ScatterGatherMediatorSerializer.class + ScatterGatherMediatorSerializer.class, + ThrowErrorMediatorSerializer.class }; private final static MediatorSerializerFinder instance = new MediatorSerializerFinder(); diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java b/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java index e2d52acf7d..67b30b497b 100644 --- a/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/SynapsePathSerializer.java @@ -71,6 +71,14 @@ public static OMElement serializePath(SynapsePath path, String expression, } else if(path.getPathType() == SynapsePath.X_PATH) { elem.addAttribute(elem.getOMFactory().createOMAttribute( attribName, nullNS, expression)); + } else if (path.getPathType() == SynapsePath.SYNAPSE_EXPRESSIONS_PATH) { + if (expression.startsWith("{") && expression.endsWith("}")) { + elem.addAttribute(elem.getOMFactory().createOMAttribute( + attribName, nullNS, expression)); + } else { + elem.addAttribute(elem.getOMFactory().createOMAttribute( + attribName, nullNS, "{" + expression + "}")); + } } serializeNamespaces(elem, path); diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/ThrowErrorMediatorFactory.java b/modules/core/src/main/java/org/apache/synapse/config/xml/ThrowErrorMediatorFactory.java new file mode 100644 index 0000000000..86d5171b15 --- /dev/null +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/ThrowErrorMediatorFactory.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024, 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.OMAttribute; +import org.apache.axiom.om.OMElement; +import org.apache.synapse.Mediator; +import org.apache.synapse.SynapseConstants; +import org.apache.synapse.mediators.Value; +import org.apache.synapse.mediators.v2.ThrowError; + +import javax.xml.namespace.QName; +import java.util.Properties; + +/** + * Creates a throw error mediator through the supplied XML configuration + *
+ *+ * <throwError (type="string") (errorMessage=("string" | expression))/> + *+ */ +public class ThrowErrorMediatorFactory extends AbstractMediatorFactory { + + private static final String ERROR_MESSAGE = "errorMessage"; + private static final String THROW_ERROR = "throwError"; + private static final QName ATT_ERROR_MSG = new QName(ERROR_MESSAGE); + private static final QName ATT_TYPE = new QName("type"); + private static final QName THROW_ERROR_Q + = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, THROW_ERROR); + + @Override + protected Mediator createSpecificMediator(OMElement elem, Properties properties) { + ThrowError throwErrorMediator = new ThrowError(); + OMAttribute type = elem.getAttribute(ATT_TYPE); + OMAttribute errorMsg = elem.getAttribute(ATT_ERROR_MSG); + + if (type == null || type.getAttributeValue().isEmpty()) { + throwErrorMediator.setType(SynapseConstants.DEFAULT_ERROR_TYPE); + } else { + throwErrorMediator.setType(type.getAttributeValue()); + } + if (errorMsg == null || errorMsg.getAttributeValue().isEmpty()) { + throwErrorMediator.setErrorMsg(new Value("Error occurred in the mediation flow")); + } else { + ValueFactory msgFactory = new ValueFactory(); + Value generatedMsg = msgFactory.createValue(ERROR_MESSAGE, elem); + throwErrorMediator.setErrorMsg(generatedMsg); + } + return throwErrorMediator; + } + + @Override + public QName getTagQName() { + return THROW_ERROR_Q; + } +} diff --git a/modules/core/src/main/java/org/apache/synapse/config/xml/ThrowErrorMediatorSerializer.java b/modules/core/src/main/java/org/apache/synapse/config/xml/ThrowErrorMediatorSerializer.java new file mode 100644 index 0000000000..1cd5790c03 --- /dev/null +++ b/modules/core/src/main/java/org/apache/synapse/config/xml/ThrowErrorMediatorSerializer.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024, 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.OMElement; +import org.apache.synapse.Mediator; +import org.apache.synapse.mediators.v2.ThrowError; + +/** + *
+ * <throwError (type="string") (errorMessage=("string" | expression))/> + *+ */ +public class ThrowErrorMediatorSerializer extends AbstractMediatorSerializer{ + + @Override + protected OMElement serializeSpecificMediator(Mediator m) { + if (!(m instanceof ThrowError)) { + handleException("Unsupported mediator passed in for serialization : " + m.getType()); + } + + ThrowError mediator = (ThrowError) m; + OMElement throwError = fac.createOMElement("throwError", synNS); + saveTracingState(throwError, mediator); + + if (mediator.getType() != null) { + throwError.addAttribute(fac.createOMAttribute("type", nullNS, mediator.getType())); + } + if (mediator.getErrorMsg() != null) { + ValueSerializer valueSerializer = new ValueSerializer(); + valueSerializer.serializeValue(mediator.getErrorMsg(), "errorMessage", throwError); + } + + serializeComments(throwError, mediator.getCommentsList()); + return throwError; + } + + @Override + public String getMediatorClassName() { + return ThrowError.class.getName(); + } +} diff --git a/modules/core/src/main/java/org/apache/synapse/mediators/v2/ThrowError.java b/modules/core/src/main/java/org/apache/synapse/mediators/v2/ThrowError.java new file mode 100644 index 0000000000..62969dcd86 --- /dev/null +++ b/modules/core/src/main/java/org/apache/synapse/mediators/v2/ThrowError.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024, 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.mediators.v2; + +import org.apache.synapse.MessageContext; +import org.apache.synapse.SynapseConstants; +import org.apache.synapse.SynapseException; +import org.apache.synapse.SynapseLog; +import org.apache.synapse.mediators.AbstractMediator; +import org.apache.synapse.mediators.Value; + +/** + * This mediator is used to throw an error from the mediation flow. + */ +public class ThrowError extends AbstractMediator { + private String type = null; + private Value errorMsg = null; + + @Override + public boolean mediate(MessageContext synCtx) { + if (synCtx.getEnvironment().isDebuggerEnabled()) { + if (super.divertMediationRoute(synCtx)) { + return true; + } + } + + SynapseLog synLog = getLog(synCtx); + if (synLog.isTraceOrDebugEnabled()) { + synLog.traceOrDebug("Start : ThrowError mediator"); + if (synLog.isTraceTraceEnabled()) { + synLog.traceTrace("Message : " + synCtx.getEnvelope()); + } + } + + String error = errorMsg.evaluateValue(synCtx); + + synLog.traceOrDebug("End : ThrowError mediator"); + synCtx.setProperty(SynapseConstants.ERROR_CODE, type); + synCtx.setProperty(SynapseConstants.ERROR_MESSAGE, error); + throw new SynapseException(error, new Throwable(type)); + } + + @Override + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Value getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(Value errorMsg) { + this.errorMsg = errorMsg; + } +} diff --git a/modules/core/src/test/java/org/apache/synapse/config/xml/ThrowErrorMediatorFactoryTest.java b/modules/core/src/test/java/org/apache/synapse/config/xml/ThrowErrorMediatorFactoryTest.java new file mode 100644 index 0000000000..3a2595310e --- /dev/null +++ b/modules/core/src/test/java/org/apache/synapse/config/xml/ThrowErrorMediatorFactoryTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024, 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.OMElement; +import org.apache.axiom.om.util.AXIOMUtil; +import org.apache.synapse.mediators.v2.ThrowError; +import org.junit.Assert; +import org.junit.Test; + +import javax.xml.stream.XMLStreamException; + +/** + * This is the test class for ThrowErrorMediatorFactory class. + */ +public class ThrowErrorMediatorFactoryTest { + + /** + * Test create TriggerError with given XML configuration and asserting it is created. + * + * @throws XMLStreamException - XMLStreamException + */ + @Test + public void testThrowErrorExp() throws XMLStreamException { + String inputXML = "