protected void handleAction()

in uimaj-as-core/src/main/java/org/apache/uima/aae/controller/BaseAnalysisEngineController.java [1179:1371]


  protected void handleAction(String anAction, String anEndpoint, final ErrorContext anErrorContext)
          throws Exception {

    String casReferenceId = null;
    if (anErrorContext != null) {
      casReferenceId = (String) anErrorContext.get(AsynchAEMessage.CasReference);
    }

    if (ErrorHandler.TERMINATE.equalsIgnoreCase(anAction)) {
    	String parentCasReferenceId = null;
      if ( casReferenceId != null ) {
        CasStateEntry stateEntry = null;
        
        try {
            stopInputChannels(InputChannel.CloseAllChannels, true);
        } catch( Exception e) {
        }
        
        try {
          stateEntry = getLocalCache().lookupEntry(casReferenceId);
          if (stateEntry != null && stateEntry.isSubordinate()) {
            CasStateEntry topParentEntry = getLocalCache().getTopCasAncestor(casReferenceId);
            parentCasReferenceId = topParentEntry.getCasReferenceId();
          }
          if (!isStopped()) {
            Endpoint endpoint = (Endpoint) anErrorContext.get(AsynchAEMessage.Endpoint);
            if ( endpoint != null && !"WarmupDelegate".equals(endpoint.getDelegateKey() ) ) {
              getOutputChannel().sendReply((Throwable) anErrorContext.get(ErrorContext.THROWABLE_ERROR), 
                      casReferenceId, parentCasReferenceId,
                      endpoint, AsynchAEMessage.Process);
            }
          }
        } catch (Exception e) {
        }

      }
      UimaEEAdminContext ctx = getUimaEEAdminContext();
      if ( ctx != null ) {
    	  ctx.onTerminate("ExceededErrorThreshold",EventTrigger.ExceededErrorThreshold );
      }
      //  Extended tests cant be killed, so skip this if dontKill is defined
      //  in System properties.
      if ( System.getProperty("dontKill") == null) {
        // The UIMA AS service error handling says to terminate. Try to terminate
        // cleanly. If the process is not down after 40 secs, take it down via
        // System.exit.  
//        Thread reaperThread = new Thread( new Runnable() {
//          public void run() {
//            System.out.println("++++++++++++++++++++++++ Starting Reaper thread");
//            Object sleepLock = new Object();
//            try {
//              synchronized( sleepLock ) {
//                sleepLock.wait(40000); // allow up to 40 sec minute for a clean shutdown.
//              }
//            } catch( Exception exx) {
//              exx.printStackTrace();
//            }
//             
//            // **********************************************************************
//            // **********************************************************************
//            // **********************************************************************
//            // **********************************************************************
//            // **********************************************************************
//            // Per discussion with Eddie on 4/11/12, exit process via System.exit() 
//            UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, CLASS_NAME.getName(),
//                    "handleAction", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE,
//                    "UIMAEE_killing_process__INFO", new Object[] { getComponentName() });
//            System.exit(1);
//            // **********************************************************************
//            // **********************************************************************
//            // **********************************************************************
//            // **********************************************************************
//            // **********************************************************************
//          }
//        }
//        );
//        reaperThread.start();        
        
      }

      // Propagate terminate event to the top controller and begin shutdown of this service along
      // with all collocated delegates (if any)
      if (anErrorContext != null && anErrorContext.containsKey(ErrorContext.THROWABLE_ERROR)
              && anErrorContext.containsKey(AsynchAEMessage.CasReference)) {
        terminate((Throwable) anErrorContext.get(ErrorContext.THROWABLE_ERROR),
                (String) anErrorContext.get(AsynchAEMessage.CasReference));
      } else {
        terminate();
      }
      //  Extended tests cant be killed, so skip this if dontKill is defined
      //  in System properties.
      if ( System.getProperty("dontKill") == null) {
    	  UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, CLASS_NAME.getName(),
                  "handleAction", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE,
                  "UIMAEE_killing_process__INFO", new Object[] { getComponentName() });
          System.exit(0);
      }

    } else if (ErrorHandler.DISABLE.equalsIgnoreCase(anAction)) {

      if (anEndpoint != null) {
        Endpoint endpoint = null;
        List list = new ArrayList();
        String key = "";
        if ((endpoint = ((AggregateAnalysisEngineController) this)
                .lookUpEndpoint(anEndpoint, false)) == null) {
          key = ((AggregateAnalysisEngineController) this).lookUpDelegateKey(anEndpoint);
          endpoint = ((AggregateAnalysisEngineController) this).lookUpEndpoint(key, false);
          list.add(key);
        } else {
          key = anEndpoint;
          list.add(anEndpoint);
        }
        ((AggregateAnalysisEngineController_impl) this).disableDelegates(list, casReferenceId);

        if (key != null && key.trim().length() > 0) {
          // Delegate has been disabled. Cleanup Delegate's lists. Each Delegate
          // maintains a list of CASes pending reply and a different list of CASes
          // pending dispatch. The first list contains CASes sent to the delegate.
          // When a reply is received from the delegate, the CAS is removed from
          // the list. The second list contains CASes that have been delayed
          // while the service was in the TIMEDOUT state. These CASes were to
          // be dispatched to the delegate once its state is reset to OK. It is
          // reset to OK state when the delegate responds to the client PING
          // request. Since we have disabled the delegate, remove ALL CASes from
          // both lists and send them through the ErrorHandler one at a time
          // as if these CASes timed out.

          Delegate delegate = ((AggregateAnalysisEngineController) this).lookupDelegate(key);
          // Cancel the delegate timer. No more responses are expected
          delegate.cancelDelegateTimer();
          // Check if we should force timeout on all CASes in a pending state. If this
          // method is called from ProcessCasErrorHandler we will skip this since we
          // want to first completely handle the CAS exception. Once that CAS exception
          // is handled, the ProcessCasErrorHandler will call forceTimeoutOnPendingCases
          // to time out CASes in pending lists
          if (anErrorContext.containsKey(AsynchAEMessage.SkipPendingLists) == false) {
            // If the delegate has CASes pending reply still, send each CAS
            // from the pending list through the error handler with
            // MessageTimeoutException as a cause of error
            forceTimeoutOnPendingCases(key);
          }
        }
        if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.INFO)) {
          UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, CLASS_NAME.getName(),
                  "handleAction", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE,
                  "UIMAEE_disabled_delegate_INFO", new Object[] { getComponentName(), key });
        }
      }
    } else if (ErrorHandler.CONTINUE.equalsIgnoreCase(anAction)) {
      if (anEndpoint != null) {
        String key = anEndpoint;
        //  check if we already have a valid key. If is not, the caller supplied the 
        //  delegates queue name which we use to lookup the delegates key.
        if ( ((AggregateAnalysisEngineController) this).lookupDelegate(key) == null) {
          //  the key is the queue name. Use it to look up the delegate's key
          key = ((AggregateAnalysisEngineController) this).lookUpDelegateKey(anEndpoint);
        }
        Exception ex = (Exception) anErrorContext.get(ErrorContext.THROWABLE_ERROR);
        boolean continueOnError = ((AggregateAnalysisEngineController) this).continueOnError(
                casReferenceId, key, ex);
        if (continueOnError) {
          CacheEntry entry = null;
          try {
            entry = getInProcessCache().getCacheEntryForCAS(casReferenceId);
          } catch (AsynchAEException e) {
            if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.INFO)) {
                UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, CLASS_NAME.getName(),
                        "handleAction", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE,
                        "UIMAEE_parent_cas_notin_cache__INFO", new Object[] { getComponentName(), casReferenceId});
              }
            
            
          }
          CAS cas = null;
          // Make sure that the ErrorHandler did not drop the cache entry and the CAS
          if (entry != null && ((cas = entry.getCas()) != null)) {
            //  Add a flag to the ErrorContext to indicate that the CAS exception was handled
            //  and the CAS was allowed to continue. The ErrorHandler who called this method
            //  will simply return after the completion of this method.
            anErrorContext.add(ErrorContext.ERROR_HANDLED, Boolean.valueOf(true));
            //  Continue processing the CAS
            ((AggregateAnalysisEngineController) this).process(cas, casReferenceId);
          }
        }
      }
    } else if (ErrorHandler.DROPCAS.equalsIgnoreCase(anAction)) {
      if (casReferenceId != null) {
        dropCAS(casReferenceId, true);
      }
    }

  }