Axis2:在AxisFault之后重试Web服务调用

时间:2017-04-19 16:47:41

标签: java axis2

环境:Ubuntu x86_64,JDK 1.7.0_80,Tomcat 7.0.64

我正在处理一些Axis2 Web服务,我希望能够在Web服务调用后捕获AxisFault异常(例如,当抛出HTTP 404,500或SSL错误时),执行一些任务(为了尝试自动解决任何配置问题)并重试一次相同的Web服务请求。我知道Axis2阶段和处理程序以及我们如何在InFault或OutFaultFlow阶段触发处理程序,但我认为它不符合目的,因为我想只执行一次重试,例如,如果我在重试时收到另一个AxisFault,我希望它升级并让整个请求失败(这意味着系统在第一次失败后自行配置的努力不足以解决问题因此需要系统管理员干预)。我认为使用处理程序会将请求带入无限循环,以防自我配置无法解决问题。尽管如此,我尝试过但无法找到执行重试的方法。因此,我试图在触发请求的代码中执行通常的try / catch。

在我的Stub类中,我使用其选项,必要的头文件创建ServiceClient,然后我执行请求。这是代码的相关部分:

public class RespondingGateway_ServiceStub extends org.apache.axis2.client.Stub {


       private void populateAxisService() {

        // creating the Service with a unique name
        _service = new org.apache.axis2.description.AxisService("RespondingGateway_Service" + getUniqueSuffix());
        addAnonymousOperations();

        // creating the operations
        org.apache.axis2.description.AxisOperation __operation;
        _operations = new org.apache.axis2.description.AxisOperation[1];
        __operation = new org.apache.axis2.description.OutInAxisOperation();
        __operation.setName(new javax.xml.namespace.QName(XCPDConstants.SOAP_HEADERS.NAMESPACE_URI, XCPDConstants.SOAP_HEADERS.NAMESPACE_REQUEST_LOCAL_PART));
        _service.addOperation(__operation);
        _operations[0] = __operation;

        }

        // populates the faults
        private void populateFaults() {
        }

        /**
         * Constructor that takes in a configContext
         */
        public RespondingGateway_ServiceStub(org.apache.axis2.context.ConfigurationContext configurationContext, String targetEndpoint) {
            this(configurationContext, targetEndpoint, false);
        }

        /**
         * Constructor that takes in a configContext and useseperate listner
         */
        public RespondingGateway_ServiceStub(org.apache.axis2.context.ConfigurationContext configurationContext, String targetEndpoint, boolean useSeparateListener) {
            // To populate AxisService
            populateAxisService();
            populateFaults();
            try {
                _serviceClient = new org.apache.axis2.client.ServiceClient(configurationContext, _service);
            } catch (AxisFault ex) {
                throw new RuntimeException(ex);
            }

            _serviceClient.getOptions().setTo(new org.apache.axis2.addressing.EndpointReference(targetEndpoint));
            _serviceClient.getOptions().setUseSeparateListener(useSeparateListener);

            _serviceClient.getOptions().setTimeOutInMilliSeconds(180000); //Wait time after which a client times out in a blocking scenario: 3 minutes

            // Set the soap version
            _serviceClient.getOptions().setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);

            MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager = new MultiThreadedHttpConnectionManager();

            HttpConnectionManagerParams params = new HttpConnectionManagerParams();
            params.setDefaultMaxConnectionsPerHost(20);
            multiThreadedHttpConnectionManager.setParams(params);
            HttpClient httpClient = new HttpClient(multiThreadedHttpConnectionManager);

            this._getServiceClient().getServiceContext().getConfigurationContext().setProperty(HTTPConstants.REUSE_HTTP_CLIENT, false);
            this._getServiceClient().getServiceContext().getConfigurationContext().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
            this._getServiceClient().getServiceContext().getConfigurationContext().setProperty(HTTPConstants.AUTO_RELEASE_CONNECTION, false);
        }

    public org.hl7.v3.PRPAIN201306UV02 respondingGateway_PRPA_IN201305UV02(PRPAIN201305UV02 pRPA_IN201305UV02, Assertion idAssertion) {

        org.apache.axis2.client.OperationClient operationClient = _serviceClient.createClient(_operations[0].getName());

        /* set the message context with that soap envelope */
        org.apache.axis2.context.MessageContext messageContext = new org.apache.axis2.context.MessageContext();
        messageContext.setEnvelope(env);

        /* add the message contxt to the operation client */
        operationClient.addMessageContext(messageContext);

        try {
            operationClient.execute(true);
        } catch (AxisFault e) {
        // perform internal tasks
        // retry the request
        // if we get another AxisFault we just let it escalate
        }
    }

使用此代码,我能够捕获AxisFault并执行内部任务。但后来我不知道如何进行重试。我尝试使用Axis2 API,包括再次调用operationClient.execute(true)块内的catch,但没有成功:

try {
        operationClient.execute(true);
    } catch (AxisFault e) {
       operationClient.complete(messageContext);
       LOG.debug("Adding message context again");
       messageContext.resetExecutedPhases();
       operationClient.addMessageContext(messageContext);
       LOG.debug("Executing");
       operationClient.execute(true);
       LOG.debug("Successfully retried the operation!");

我收到以下错误:

ERROR 2017-04-19 12:59:03,832 eu.epsos.pt.cc.ClientConnectorServiceMessageReceiverInOut invokeBusinessLogic.385  - A message was added that is not valid. However, the operation context was complete.
java.lang.RuntimeException: A message was added that is not valid. However, the operation context was complete.
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_ServiceStub.respondingGateway_PRPA_IN201305UV02(RespondingGateway_ServiceStub.java:445)
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_RequestSender.sendRequest(RespondingGateway_RequestSender.java:80)
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_RequestSender.respondingGateway_PRPA_IN201305UV02(RespondingGateway_RequestSender.java:69)
    at eu.epsos.pt.ws.client.xcpd.XcpdInitGateway.patientDiscovery(XcpdInitGateway.java:59)
    at eu.epsos.pt.cc.stub.IdentificationService.findIdentityByTraits(IdentificationService.java:72)
    at eu.epsos.pt.cc.ClientConnectorServiceSkeleton.queryPatient(ClientConnectorServiceSkeleton.java:107)
    at eu.epsos.pt.cc.ClientConnectorServiceMessageReceiverInOut.invokeBusinessLogic(ClientConnectorServiceMessageReceiverInOut.java:215)
    at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
    at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
    at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
    at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.axis2.AxisFault: A message was added that is not valid. However, the operation context was complete.
    at org.apache.axis2.description.OutInAxisOperation.addMessageContext(OutInAxisOperation.java:78)
    at org.apache.axis2.context.OperationContext.addMessageContext(OperationContext.java:218)
    at org.apache.axis2.description.AxisOperation.registerOperationContext(AxisOperation.java:286)
    at org.apache.axis2.description.OutInAxisOperationClient.addMessageContext(OutInAxisOperation.java:132)
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_ServiceStub.respondingGateway_PRPA_IN201305UV02(RespondingGateway_ServiceStub.java:302)
    ... 33 more

我试图寻找解决方案,但没有成功。我认为应该重新设置Axis2内部Web服务状态和阶段,但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。基本上,我要创建一个新的OperationClient,SOAPEnvelope和MessageContext并再次执行请求:

try {
    operationClient.execute(true);
} catch (AxisFault e) {
    LOG.error("Axis Fault error: " + e.getMessage());

    /* we need a new OperationClient, otherwise we'll face the error "A message was added that is not valid. However, the operation context was complete." */
    OperationClient newOperationClient = _serviceClient.createClient(_operations[0].getName());
    newOperationClient.getOptions().setAction(XCPDConstants.SOAP_HEADERS.REQUEST_ACTION);
    newOperationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);
    addPropertyToOperationClient(newOperationClient, org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR, "&");

    SOAPFactory newSoapFactory = getFactory(newOperationClient.getOptions().getSoapVersionURI());

    org.apache.axiom.soap.SOAPEnvelope newEnv;
    newEnv = toEnvelope(newSoapFactory,
                pRPA_IN201305UV02,
                optimizeContent(new javax.xml.namespace.QName(XCPDConstants.SOAP_HEADERS.NAMESPACE_URI, XCPDConstants.SOAP_HEADERS.NAMESPACE_REQUEST_LOCAL_PART)));

    _serviceClient.addHeadersToEnvelope(newEnv);

    /* we create a new Message Context with the new SOAP envelope */
    org.apache.axis2.context.MessageContext newMessageContext = new org.apache.axis2.context.MessageContext();
    newMessageContext.setEnvelope(newEnv);

    /* add the new message contxt to the new operation client */
    newOperationClient.addMessageContext(newMessageContext);
    /* we retry the request */
    newOperationClient.execute(true);
}