简体   繁体   中英

Issue on : Call Mediator with blocking option on 404

I'm facing an issue with "blocking=true" on a call mediator. When the called backend endpoint returned a 404 (because no data can be found on REST get), a stacktrace is returned and the sequence fails with this stack trace:

[2016-04-18 12:49:20,303]  INFO - HTTPSender Unable to sendViaGet to url[http://api.vidal.fr:80/rest/imd/package/412849-1862-2/lppr?app_id=0c117950&app_key=f6657d21b96e5e86ff1758be84618459]
org.apache.axis2.AxisFault: Transport error: 404 Error: Introuvable
    at org.apache.axis2.transport.http.HTTPSender.handleResponse(HTTPSender.java:331)
    at org.apache.axis2.transport.http.HTTPSender.sendViaGet(HTTPSender.java:105)
    at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:63)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:451)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:278)
    at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
    at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:430)
    at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:225)
    at org.apache.axis2.client.OperationClient.execute(OperationClient.java:149)
    at org.apache.synapse.message.senders.blocking.BlockingMsgSender.sendReceive(BlockingMsgSender.java:254)
    at org.apache.synapse.message.senders.blocking.BlockingMsgSender.send(BlockingMsgSender.java:175)
    at org.apache.synapse.mediators.builtin.CallMediator.handleBlockingCall(CallMediator.java:113)
    at org.apache.synapse.mediators.builtin.CallMediator.mediate(CallMediator.java:85)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:214)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
    at org.apache.synapse.mediators.eip.Target.mediate(Target.java:106)
    at org.apache.synapse.mediators.eip.splitter.IterateMediator.mediate(IterateMediator.java:163)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:261)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.mediateFromContinuationStateStack(Axis2SynapseEnvironment.java:679)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:244)
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:529)
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:172)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:247)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Even if, I try to pass that parameter: because it fails on a cast from a String to a Set (!!) in HttpSender:

Set<Integer>nonErrorCodes = (Set<Integer>) msgContext.getProperty(HTTPConstants.NON_ERROR_HTTP_STATUS_CODES);

Here is my call mediator that throws exception when the endpoint respond a 404:

<property value="404" name="non.error.http.status.codes" scope="axis2" type="STRING" />

<call blocking="true">
    <endpoint key="xxxx" />
</call>

So, how can we properly handle 404 response code on a blocking call ?

Thanks

You can use a faultsequence to handle the mentioned error in the wso2 ESB. The falut sequence also same like the other sequences.If some error occurs during the mediation process or Forwarding the message, faultsequence will execute. In your scenario, you are using REST api in ESB and you can specify a faultsequenc in the API configuration. If some error occurred while invoking that API, the message that triggered the error is delegated to the specified fault sequence. First, you need to create a faultsequnce and then you can specify that faultsequnce in your API configuration. See following sample configurations.

FaultSequence

<sequence name="sampleFaultSequence">
    <makefault version="pox">
        <reason expression="get-property('ERROR_MESSAGE')"/>
    </makefault>
    <send/>
</sequence>

API configuration

<api xmlns="http://ws.apache.org/ns/synapse" name="testapi" context="/abcd">
   <resource methods="POST GET" uri-template="/*" faultSequence="sampleFaultSequence">
      <inSequence>
         <call blocking="true">
            <endpoint key="conf:/ep1"/>
         </call>
         <respond/>
      </inSequence>
   </resource>
</api>

You can refer document [1],[2] for getting more information about the error handling in the Wso2 ESB . [1] - https://docs.wso2.com/display/ESB490/Error+Handling [2] - https://docs.wso2.com/display/ESB490/Sample+4%3A+Specifying+a+Fault+Sequence+with+a+Regular+Mediation+Sequence

Thanks.

It can be done by simple mediator

import java.util.HashSet;
import java.util.Set;

import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;

public class ConfigureErrorResponseCodes extends AbstractMediator {

    private static final String ERROR_HTTP_STATUS_CODES     = "error.http.status.codes";
    private static final String NON_ERROR_HTTP_STATUS_CODES = "non.error.http.status.codes";

    // error.http.status.codes
    private String errorHttpStatusCodes;

    // non.error.http.status.codes
    private String nonErrorHttpStatusCodes;

    @Override
    public boolean mediate(MessageContext context) {
        org.apache.axis2.context.MessageContext axisInMsgCtx = ((Axis2MessageContext)context).getAxis2MessageContext();
        axisInMsgCtx.setProperty(ERROR_HTTP_STATUS_CODES, errorHttpStatusCodes);
        axisInMsgCtx.setProperty(NON_ERROR_HTTP_STATUS_CODES, getCodes(nonErrorHttpStatusCodes));
        return true;
    }

    private Set<Integer> getCodes(String codes) {
        Set<Integer> set = new HashSet<Integer>();

        if ( codes != null ) {
            String [] codes$ = codes.split(",");
            for ( String code : codes$ ) {
                set.add(Integer.parseInt(code));
            }
        }

        return set;
    }

    public String getErrorHttpStatusCodes() {
        return errorHttpStatusCodes;
    }

    public void setErrorHttpStatusCodes(String errorHttpStatusCodes) {
        this.errorHttpStatusCodes = errorHttpStatusCodes;
    }

    public String getNonErrorHttpStatusCodes() {
        return nonErrorHttpStatusCodes;
    }

    public void setNonErrorHttpStatusCodes(String nonErrorHttpStatusCodes) {
        this.nonErrorHttpStatusCodes = nonErrorHttpStatusCodes;
    }

}

called by:

<class name="ConfigureErrorResponseCodes">
     <property name="nonErrorHttpStatusCodes" value="404"/>
</class>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM