protected void handleRequestDispatchException(BaseMessageContextImpl ctx, Throwable e) {
   Object soapFault = ctx.getProperty(BaseSOAPProtocolProcessor.SOAP_FAULT_OBJECT);
   if (soapFault != null) {
     ctx.addError(new Exception("Received Soap Fault: " + soapFault));
   }
   ctx.addError(e);
 }
  /**
   * Invoke handlers, protocol processor and dispatchers for the given context NOTE: async
   * processing logic has been removed for SOA 2.0. Async processing logic will be reintroduced post
   * SOA 2.0.
   */
  @SuppressWarnings("unchecked")
  public final void processMessageInternal(BaseMessageContextImpl ctx, boolean useAsync) {
    MessageContextAccessorImpl.blockPreviousContext();
    try {
      long processingStartTime = System.nanoTime();
      // Pass the start time into ctx for later reference
      recordMessageProcessingStartTime(ctx, processingStartTime);

      // run request pipeline
      runRequestSequence(ctx);

      // give it to request dispatcher
      if (!ctx.hasErrors() && !ctx.hasResponseResidentErrors()) {
        try {
          dispatchInternal(ctx, useAsync);
        } catch (Throwable e) {
          handleRequestDispatchException(ctx, e);
          handleAbortedRequestDispatch(ctx);
        }
      } else {
        handleAbortedRequestDispatch(ctx);
      }

      if (!useAsync) {
        // run response pipeline in case of sync executions or pipeline
        // errors
        runResponseSequence(ctx);
        updateMonitoringAfterProcessing(ctx, processingStartTime);
      }
    } finally {
      MessageContextAccessorImpl.resetContext();
    }
  }
  void updateMonitoringAfterProcessing(BaseMessageContextImpl ctx, long processingStartTime) {
    long duration = System.nanoTime() - processingStartTime;
    ctx.updateSvcAndOpMetric(SystemMetricDefs.OP_TIME_TOTAL, duration);

    if (shouldCountAsFailedRequest(ctx)) {
      ctx.incrementSvcAndOpMetric(SystemMetricDefs.OP_ERR_FAILED_CALLS);
    }
  }
  protected boolean shouldCountAsFailedRequest(BaseMessageContextImpl ctx) {

    if (ctx.hasErrors()) return true;
    if (!ctx.hasResponseResidentErrors()) return false;

    /** RRE's only count as failed requests if the severity was severe enough */
    List<ErrorData> errorDataList = ctx.getResponseResidentErrorList();
    for (ErrorData errorData : errorDataList) if (isError(errorData)) return true;

    return false;
  }
 private void recordMessageProcessingStartTime(
     BaseMessageContextImpl ctx, long processingStartTime) {
   try {
     ctx.setProperty(
         SystemMetricDefs.CTX_KEY_MSG_PROCESSING_STARTED, new Long(processingStartTime));
   } catch (ServiceException e) {
     handleRequestProcessingException(ctx, e);
   }
 }
  public final void processResponseInternal(BaseMessageContextImpl ctx) {
    MessageContextAccessorImpl.blockPreviousContext();
    try {
      ServiceDesc serviceDesc = ctx.getServiceDesc();
      try {
        Dispatcher requestDispatcher = serviceDesc.getRequestDispatcher();
        requestDispatcher.retrieve(ctx, ctx.getFutureResponse());

      } catch (Throwable e) {
        handleRequestDispatchException(ctx, e);
        handleAbortedRequestDispatch(ctx);
      }

      runResponseSequence(ctx);
      Long processingStartTime =
          (Long) ctx.getProperty(SystemMetricDefs.CTX_KEY_MSG_PROCESSING_STARTED);
      updateMonitoringAfterProcessing(ctx, processingStartTime.longValue());
    } finally {
      MessageContextAccessorImpl.resetContext();
    }
  }
  private void runRequestSequence(BaseMessageContextImpl ctx) {
    ServiceDesc serviceDesc = ctx.getServiceDesc();

    // flip the processing stage
    ctx.changeProcessingStage(MessageProcessingStage.REQUEST_PIPELINE);

    // first set up logging handler
    ctx.runLoggingHandlerStage(LoggingHandlerStage.REQUEST_STARTED);

    long startTime = System.nanoTime();

    // run the protocol processor
    try {
      ProtocolProcessor protocol = ctx.getProtocolProcessor();
      protocol.beforeRequestPipeline(ctx);
    } catch (Throwable e) {
      handleRequestProtocolProcessingException(ctx, e);
    }

    // run any logic that has to run before pipeline (e.g. version checks)
    try {
      beforeRequestPipeline(ctx);
    } catch (Throwable e) {
      handleRequestProcessingException(ctx, e);
    }

    // run the pipeline
    try {
      Pipeline requestPipeline = serviceDesc.getRequestPipeline();
      requestPipeline.invoke(ctx);
    } catch (Throwable e) {
      handleRequestProcessingException(ctx, e);
    }

    // run the protocol processor
    try {
      ProtocolProcessor protocol = ctx.getProtocolProcessor();
      protocol.beforeRequestDispatch(ctx);
    } catch (Throwable e) {
      handleRequestProtocolProcessingException(ctx, e);
    }

    // flip the processing stage
    ctx.changeProcessingStage(MessageProcessingStage.REQUEST_DISPATCH);

    ctx.runLoggingHandlerStage(LoggingHandlerStage.BEFORE_REQUEST_DISPATCH);

    long duration = System.nanoTime() - startTime;
    ctx.updateSvcAndOpMetric(SystemMetricDefs.OP_TIME_PIPELINE_REQUEST, startTime, duration);
  }
 protected void handlePostResponseDispatchException(BaseMessageContextImpl ctx, Throwable e) {
   ctx.addError(e);
 }
 protected void handleResponseProcessingException(BaseMessageContextImpl ctx, Throwable e) {
   ctx.addError(e);
 }
  void runResponseSequence(BaseMessageContextImpl ctx) {
    ServiceDesc serviceDesc = ctx.getServiceDesc();

    long startTime = System.nanoTime();

    // flip the processing stage
    ctx.changeProcessingStage(MessageProcessingStage.RESPONSE_PIPELINE);

    ctx.runLoggingHandlerStage(LoggingHandlerStage.RESPONSE_STARTED);

    // run the protocol processor
    try {
      ProtocolProcessor protocol = ctx.getProtocolProcessor();
      protocol.beforeResponsePipeline(ctx);
    } catch (Throwable e) {
      handleResponseProtocolProcessingException(ctx, e);
    }

    // run the pipeline
    try {
      Pipeline responsePipeline = serviceDesc.getResponsePipeline();
      responsePipeline.invoke(ctx);
    } catch (Throwable e) {
      handleResponseProcessingException(ctx, e);
    }

    // run the protocol processor
    try {
      ProtocolProcessor protocol = ctx.getProtocolProcessor();
      protocol.beforeResponseDispatch(ctx);
    } catch (Throwable e) {
      handleResponseProtocolProcessingException(ctx, e);
    }

    // flip the processing stage
    ctx.changeProcessingStage(MessageProcessingStage.RESPONSE_DISPATCH);

    boolean canProcessResponse = true;
    try {
      processPreResponseDispatchErrors(ctx);
    } catch (Throwable e) {
      // cannot do anything if errors are not processed
      canProcessResponse = false;
      handlePostResponseDispatchException(ctx, e);
    }

    long duration = System.nanoTime() - startTime;
    ctx.updateSvcAndOpMetric(SystemMetricDefs.OP_TIME_PIPELINE_RESPONSE, startTime, duration);

    if (canProcessResponse) {
      /*
       * Returning response is a seperate step. It is also abstracted out
       * through a dispatcher. In the case of a servlet, the
       * responseDispatcher is simply writing the data to the
       * HTTPResponse's outputstream. In the case of a Loaclbinding and
       * client cases, the response dispatcher simply returns and does
       * nothing. In the case of an asynchronous model, the response
       * dispatcher may use a connection and send the response back.
       */

      // TODO: add timing for response dispatcher on server (both sync and
      // async cases)
      // TO DO: fix async case - we should use callback and uplink here as
      // we cannot call logger yet
      try {
        // run through the response dispatcher.
        Dispatcher responseDispatcher = serviceDesc.getResponseDispatcher();
        responseDispatcher.dispatchSynchronously(ctx);
      } catch (Throwable e) {
        handlePostResponseDispatchException(ctx, e);
      }
    }

    ctx.changeProcessingStage(MessageProcessingStage.RESPONSE_COMPLETE);

    ctx.runLoggingHandlerStage(LoggingHandlerStage.RESPONSE_COMPLETE);
  }