Package org.apache.uima.aae.handler.input

Source Code of org.apache.uima.aae.handler.input.ProcessResponseHandler

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF 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.uima.aae.handler.input;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.uima.UIMAFramework;
import org.apache.uima.aae.UIMAEE_Constants;
import org.apache.uima.aae.UimaSerializer;
import org.apache.uima.aae.InProcessCache.CacheEntry;
import org.apache.uima.aae.controller.AggregateAnalysisEngineController;
import org.apache.uima.aae.controller.AnalysisEngineController;
import org.apache.uima.aae.controller.Endpoint;
import org.apache.uima.aae.controller.PrimitiveAnalysisEngineController;
import org.apache.uima.aae.error.AsynchAEException;
import org.apache.uima.aae.error.ErrorContext;
import org.apache.uima.aae.error.ExpiredMessageException;
import org.apache.uima.aae.error.ServiceShutdownException;
import org.apache.uima.aae.error.UimaEEServiceException;
import org.apache.uima.aae.handler.HandlerBase;
import org.apache.uima.aae.jmx.ServicePerformance;
import org.apache.uima.aae.message.AsynchAEMessage;
import org.apache.uima.aae.message.MessageContext;
import org.apache.uima.aae.monitor.Monitor;
import org.apache.uima.aae.monitor.statistics.DelegateStats;
import org.apache.uima.aae.monitor.statistics.LongNumericStatistic;
import org.apache.uima.aae.monitor.statistics.TimerStats;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.impl.XmiSerializationSharedData;
import org.apache.uima.util.Level;

public class ProcessResponseHandler extends HandlerBase
{
  private static final Class CLASS_NAME = ProcessResponseHandler.class;

  private Object monitor = new Object();

  public ProcessResponseHandler(String aName)
  {
    super(aName);
  }

  private void aggregateDelegateStats(MessageContext aMessageContext, String aCasReferenceId) throws AsynchAEException
  {
    String delegateKey = "";
    try
    {
     
      delegateKey = ((AggregateAnalysisEngineController)getController()).lookUpDelegateKey(aMessageContext.getEndpoint().getEndpoint());
      CacheEntry entry = getController().getInProcessCache().getCacheEntryForCAS(aCasReferenceId);
      if ( entry == null )
      {
        throw new AsynchAEException("CasReferenceId:"+aCasReferenceId+" Not Found in the Cache.");
      }
      CacheEntry inputCasEntry = null;
      String inputCasReferenceId = entry.getInputCasReferenceId();
      ServicePerformance casStats =
        ((AggregateAnalysisEngineController)getController()).getCasStatistics(aCasReferenceId);
      if ( inputCasReferenceId != null &&
         getController().getInProcessCache().entryExists(inputCasReferenceId) )
      {
        String casProducerKey = entry.getCasProducerKey();
        if ( casProducerKey != null &&
          ((AggregateAnalysisEngineController)getController()).
            isDelegateKeyValid(casProducerKey) )
        {
          //  Get entry for the input CAS
          inputCasEntry = getController().
                getInProcessCache().
                  getCacheEntryForCAS(inputCasReferenceId);
        }
       
      }
      ServicePerformance delegateServicePerformance =
        ((AggregateAnalysisEngineController)getController()).getServicePerformance(delegateKey);

      if (aMessageContext.propertyExists(AsynchAEMessage.TimeToSerializeCAS))
      {
        long timeToSerializeCAS = ((Long) aMessageContext.getMessageLongProperty(AsynchAEMessage.TimeToSerializeCAS)).longValue();
        if ( timeToSerializeCAS > 0)
        {
          casStats.incrementCasSerializationTime(timeToSerializeCAS);
          if ( delegateServicePerformance != null )
          {
            delegateServicePerformance.
            incrementCasSerializationTime(timeToSerializeCAS);
          }
          getController().getServicePerformance().
            incrementCasSerializationTime(timeToSerializeCAS);
        }
      }
      if (aMessageContext.propertyExists(AsynchAEMessage.TimeToDeserializeCAS))
      {
        long timeToDeserializeCAS = ((Long) aMessageContext.getMessageLongProperty(AsynchAEMessage.TimeToDeserializeCAS)).longValue();
        if ( timeToDeserializeCAS > 0 )
        {
          casStats.incrementCasDeserializationTime(timeToDeserializeCAS);

          if ( delegateServicePerformance != null )
          {
            delegateServicePerformance.
              incrementCasDeserializationTime(timeToDeserializeCAS);
          }
          getController().getServicePerformance().
            incrementCasDeserializationTime(timeToDeserializeCAS);
        }
      }

      if (aMessageContext.propertyExists(AsynchAEMessage.IdleTime))
      {
        long idleTime = ((Long) aMessageContext.getMessageLongProperty(AsynchAEMessage.IdleTime)).longValue();
        if ( idleTime > 0 )
        {
          casStats.incrementIdleTime(idleTime);
          if ( delegateServicePerformance != null )
          {
            delegateServicePerformance.
              incrementIdleTime(idleTime);
          }
        }
      }
     
      if (aMessageContext.propertyExists(AsynchAEMessage.TimeWaitingForCAS))
      {
        long timeWaitingForCAS = ((Long) aMessageContext.getMessageLongProperty(AsynchAEMessage.TimeWaitingForCAS)).longValue();
        if ( aMessageContext.getEndpoint().isRemote())
        {
          entry.incrementTimeWaitingForCAS(timeWaitingForCAS);
          if ( inputCasEntry != null )
          {
            inputCasEntry.incrementTimeWaitingForCAS(timeWaitingForCAS);
          }
        }
      }
      if (aMessageContext.propertyExists(AsynchAEMessage.TimeInProcessCAS))
      {
        long timeInProcessCAS = ((Long) aMessageContext.getMessageLongProperty(AsynchAEMessage.TimeInProcessCAS)).longValue();
        casStats.incrementAnalysisTime(timeInProcessCAS);
        if ( delegateServicePerformance != null )
        {
          delegateServicePerformance.
            incrementAnalysisTime(timeInProcessCAS);
        }
        //  Accumulate processing time
        getController().getServicePerformance().
          incrementAnalysisTime(timeInProcessCAS);
        if ( inputCasReferenceId != null )
        {
          ServicePerformance inputCasStats =
            ((AggregateAnalysisEngineController)getController()).
              getCasStatistics(inputCasReferenceId);
          // Update processing time for this CAS
          if ( inputCasStats != null )
          {
            inputCasStats.incrementAnalysisTime(timeInProcessCAS);
          }
        }
      }
    }
    catch( AsynchAEException e)
    {
      throw e;
    }
    catch( Exception e)
    {
      throw new AsynchAEException(e);
    }
  }
  private void computeStats(MessageContext aMessageContext, String aCasReferenceId) throws AsynchAEException
  {
    if (aMessageContext.propertyExists(AsynchAEMessage.TimeInService))
    {
      long departureTime = getController().getTime(aCasReferenceId, aMessageContext.getEndpoint().getEndpoint());
      long currentTime = System.nanoTime();
      long roundTrip = currentTime - departureTime;
      long timeInService = aMessageContext.getMessageLongProperty(AsynchAEMessage.TimeInService);
      long totalTimeInComms = currentTime - (departureTime - timeInService);

     
      UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, CLASS_NAME.getName(),
                  "computeStats", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_show_roundtrip_time__FINE",
                  new Object[] { aCasReferenceId, aMessageContext.getEndpoint(),(double) roundTrip / (double) 1000000 });

      UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, CLASS_NAME.getName(),
                  "computeStats", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_show_time_spent_in_delegate__FINE",
                  new Object[] { aCasReferenceId, (double) timeInService / (double) 1000000, aMessageContext.getEndpoint() });

      UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, CLASS_NAME.getName(),
                  "computeStats", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_show_time_spent_in_comms__FINE",
                  new Object[] { aCasReferenceId, (double) totalTimeInComms / (double) 1000000, aMessageContext.getEndpoint() });
    }
   
      if ( getController() instanceof AggregateAnalysisEngineController )
      {
        aggregateDelegateStats( aMessageContext, aCasReferenceId );
      }     
  }

  private Endpoint lookupEndpoint(String anEndpointName, String aCasReferenceId)
  {
    return getController().getInProcessCache().getEndpoint(anEndpointName, aCasReferenceId);
  }

  private void cancelTimer(MessageContext aMessageContext, String aCasReferenceId, boolean removeEndpoint) throws AsynchAEException
  {
    if (aMessageContext != null && aMessageContext.getEndpoint() != null)
    {
      UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, CLASS_NAME.getName(),
                  "cancelTimer", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_cancel_timer__FINE",
                  new Object[] { aMessageContext.getEndpoint().getEndpoint(), aCasReferenceId });

      // Retrieve the endpoint from the cache using endpoint name
      // and casRefereceId
      if ( aCasReferenceId == null &&
         aMessageContext.propertyExists(AsynchAEMessage.Command) &&
         aMessageContext.getMessageIntProperty(AsynchAEMessage.Command) == AsynchAEMessage.CollectionProcessComplete
          )
      {
        aCasReferenceId = ":CpC";
      }
      if ( aMessageContext != null && aMessageContext.getEndpoint() != null )
      {
        Endpoint endpoint = lookupEndpoint(aMessageContext.getEndpoint().getEndpoint(), aCasReferenceId);

        if (endpoint != null)
        {
          // Received the response within timeout interval so
          // cancel the running timer
          endpoint.cancelTimer();
          if ( removeEndpoint )
          {
            getController().getInProcessCache().removeEndpoint(aMessageContext.getEndpoint().getEndpoint(), aCasReferenceId);
          }
        }
        else
        {
          UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, CLASS_NAME.getName(),
                      "cancelTimer", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_endpoint_not_found__INFO",
                      new Object[] { aMessageContext.getEndpoint().getEndpoint(), aCasReferenceId });
        }
      }
    }
  }

  private void cancelTimerAndProcess(MessageContext aMessageContext, String aCasReferenceId, CAS aCAS) throws AsynchAEException
  {
    computeStats(aMessageContext, aCasReferenceId);

    cancelTimer(aMessageContext, aCasReferenceId, true);
    super.invokeProcess(aCAS, aCasReferenceId, null, aMessageContext, null);

  }

  private boolean isMessageExpected(String aCasReferenceId, Endpoint anEndpointWithTimer)

  {
    if (getController().getInProcessCache().entryExists(aCasReferenceId) && anEndpointWithTimer.isWaitingForResponse())
    {
      return true;
    }
    return false;
  }

  private void handleUnexpectedMessage(String aCasReferenceId, Endpoint anEndpoint)
  {
    // Cas does not exist in the CAS Cache. This would be possible if the
    // CAS has been dropped due to timeout and the delegate
    // sends the response later. In asynch communication this scenario is
    // possible. The service may not be up when the client sends
    // the message. Messages accumulate in the service queue until the
    // service becomes available. When this happens, the service
    // will pickup messages from the queue, process them and send respones
    // to an appropriate response queue. Most likely such
    // respones should be thrown away. Well perhaps logged first.
    ErrorContext errorContext = new ErrorContext();
    errorContext.add(AsynchAEMessage.CasReference, aCasReferenceId);
    errorContext.add(AsynchAEMessage.Command, AsynchAEMessage.Process);
    errorContext.add(AsynchAEMessage.Endpoint, anEndpoint);
    AnalysisEngineController controller = getController();
    controller.getErrorHandlerChain().handle(new ExpiredMessageException(), errorContext, controller);

  }

  private void handleProcessResponseWithXMI(MessageContext aMessageContext, String aDelegateKey)
  {
    CAS cas = null;
    String casReferenceId = null;
    Endpoint endpointWithTimer = null;
    try
    {
      casReferenceId = aMessageContext.getMessageStringProperty(AsynchAEMessage.CasReference);
      endpointWithTimer = lookupEndpoint(aMessageContext.getEndpoint().getEndpoint(), casReferenceId);

      if ( endpointWithTimer == null )
      {
        UIMAFramework.getLogger(CLASS_NAME).logrb(Level.WARNING, CLASS_NAME.getName(),
                    "handleProcessResponseWithXMI", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_invalid_endpoint__WARNING",
                    new Object[] { aMessageContext.getEndpoint().getEndpoint(), casReferenceId});
        throw new AsynchAEException("Unable to lookup endpoint:"+aMessageContext.getEndpoint().getEndpoint()+ " Cas Reference Id:"+casReferenceId);
      }
     
      // Check if this reply message is expected. A message is expected
      // when it contains a reply for request
      // that has not been already received nor the timeout for the
      // request has been handled. This is done
      // to catch duplicate replies for the same request. If a cache entry
      // does not exist with a given CAS reference id
      // it means that the initial request has been canceled and the CAS
      // has either been processed or dropped. If a duplicate
      // reply arrives containing CAS that is still being processed in
      // this aggregate, the endpoint state will show that
      // it is not waiting for a response.
      if (!isMessageExpected(casReferenceId, endpointWithTimer))
      {
        handleUnexpectedMessage(casReferenceId, aMessageContext.getEndpoint());
        return;
      }
      //  Increment number of CASes processed by this delegate
      if ( aDelegateKey != null)
      {
        ServicePerformance delegateServicePerformance =
          ((AggregateAnalysisEngineController)getController()).
            getServicePerformance(aDelegateKey);
        if ( delegateServicePerformance != null )
        {
          delegateServicePerformance.incrementNumberOfCASesProcessed();
        }
      }
     
      String xmi = aMessageContext.getStringMessage();

      //  Fetch entry from the cache for a given Cas Id. The entry contains a CAS that will be used during deserialization
      CacheEntry cacheEntry = getController().getInProcessCache().getCacheEntryForCAS(casReferenceId);
      cacheEntry.setReplyReceived();
      cas = cacheEntry.getCas()
      int totalNumberOfParallelDelegatesProcessingCas = cacheEntry.getNumberOfParallelDelegates();
      UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, CLASS_NAME.getName(),
                  "handleProcessResponseWithXMI", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_number_parallel_delegates_FINE",
                  new Object[] { totalNumberOfParallelDelegatesProcessingCas});

      if (cas == null)
      {
        throw new AsynchAEException(Thread.currentThread().getName()+"-Cache Does not contain a CAS. Cas Reference Id::"+casReferenceId);
      }
      if ( UIMAFramework.getLogger().isLoggable(Level.FINEST) )
      {
        UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINEST, CLASS_NAME.getName(),
                    "handleProcessResponseWithXMI", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_rcvd_reply_FINEST",
                    new Object[] { aMessageContext.getEndpoint().getEndpoint(), casReferenceId, xmi });
      }
     
      long t1 = System.nanoTime();
     
      synchronized (monitor)
      {
        XmiSerializationSharedData deserSharedData;
        if (totalNumberOfParallelDelegatesProcessingCas > 1 && cacheEntry.howManyDelegatesResponded() > 0)
        {
          // process secondary reply from a parallel step
          UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINEST, CLASS_NAME.getName(),
                      "handleProcessResponseWithXMI", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_delegate_responded_count_FINEST",
                      new Object[] { cacheEntry.howManyDelegatesResponded(), casReferenceId});
         
          int highWaterMark = cacheEntry.getHighWaterMark();
          UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINEST, CLASS_NAME.getName(),
                      "handleProcessResponseWithXMI", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_high_water_mark_FINEST",
                      new Object[] { highWaterMark, casReferenceId });

          deserSharedData = getController().getInProcessCache().getCacheEntryForCAS(casReferenceId).getDeserSharedData();
          UimaSerializer.deserializeCasFromXmi(xmi, cas, deserSharedData, true, highWaterMark);
        }
        else // general case, or first reply from a parallel step
        {
          //  Processing the reply from a standard, non-parallel delegate
          deserSharedData = getController().getInProcessCache().getCacheEntryForCAS(casReferenceId).getDeserSharedData();
          if (deserSharedData == null) {
            deserSharedData = new XmiSerializationSharedData();
            getController().getInProcessCache().getCacheEntryForCAS(casReferenceId).setXmiSerializationData(deserSharedData);
          }
          UimaSerializer.deserializeCasFromXmi(xmi, cas, deserSharedData, true, -1);
        }
      }

     
      if ( cacheEntry != null && totalNumberOfParallelDelegatesProcessingCas > 1 )
      {
        synchronized( cacheEntry )
        {
          cacheEntry.incrementHowManyDelegatesResponded();
        }
      }
   
      long timeToDeserializeCAS = System.nanoTime() - t1;

            getController().
              getServicePerformance().
                incrementCasDeserializationTime(timeToDeserializeCAS);

            ServicePerformance casStats =
              getController().getCasStatistics(casReferenceId);
      casStats.incrementCasDeserializationTime(timeToDeserializeCAS);
      LongNumericStatistic statistic;
      if ( (statistic = getController().getMonitor().getLongNumericStatistic("",Monitor.TotalDeserializeTime)) != null )
      {
        statistic.increment(timeToDeserializeCAS);
      }

      computeStats(aMessageContext, casReferenceId);

      cancelTimer(aMessageContext, casReferenceId, true);

      // Send CAS for processing when all delegates reply
      // totalNumberOfParallelDelegatesProcessingCas indicates how many delegates are processing CAS in parallel. Default is 1, meaning only
      // one delegate processes the CAS at the same. Otherwise, check if all delegates responded before passing CAS on to the Flow Controller.
      // The idea is that all delegates processing one CAS concurrently must respond, before the CAS is allowed to move on to the next step.
      // HowManyDelegatesResponded is incremented every time a parallel delegate sends response.
      if (totalNumberOfParallelDelegatesProcessingCas == 1 || ( cacheEntry.howManyDelegatesResponded() == totalNumberOfParallelDelegatesProcessingCas) )
      {
        cacheEntry.resetDelegateResponded();
        super.invokeProcess(cas, casReferenceId, null, aMessageContext, null);
      }

    }
    catch ( Exception e)
    {
      e.printStackTrace();
      ErrorContext errorContext = new ErrorContext();
      errorContext.add(AsynchAEMessage.Command, AsynchAEMessage.Process);
      errorContext.add(AsynchAEMessage.CasReference, casReferenceId );
      errorContext.add(AsynchAEMessage.Endpoint, aMessageContext.getEndpoint());
      getController().getErrorHandlerChain().handle(e, errorContext, getController());
    }
    finally
    {
      incrementDelegateProcessCount(aMessageContext);
    }

  }
  private void handleProcessResponseWithCASReference(MessageContext aMessageContext )
  {
    String casReferenceId = null;
    CacheEntry cacheEntry = null;

    try
    {
      casReferenceId = aMessageContext.getMessageStringProperty(AsynchAEMessage.CasReference);
      cacheEntry = getController().getInProcessCache().getCacheEntryForCAS(casReferenceId);
      cacheEntry.setReplyReceived();
      CAS cas = cacheEntry.getCas();
      String endpointName = aMessageContext.getEndpoint().getEndpoint();
      String delegateKey = ((AggregateAnalysisEngineController)getController()).
                  lookUpDelegateKey(endpointName);
      ServicePerformance delegateServicePerformance =
        ((AggregateAnalysisEngineController)getController()).
          getServicePerformance(delegateKey);
      if ( delegateServicePerformance != null )
      {
        delegateServicePerformance.incrementNumberOfCASesProcessed();
      }

      //CAS cas = getController().getInProcessCache().getCasByReference(casReferenceId);
      if (cas != null)
      {
        cancelTimerAndProcess(aMessageContext, casReferenceId, cas);
      }
      else
      {
        UIMAFramework.getLogger(CLASS_NAME).logrb(Level.INFO, CLASS_NAME.getName(),
                    "handleProcessResponseWithCASReference", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_cas_not_in_cache__INFO",
                    new Object[] { getController().getName(), casReferenceId, aMessageContext.getEndpoint().getEndpoint() });
        throw new AsynchAEException("CAS with Reference Id:" + casReferenceId + " Not Found in CasManager's CAS Cache");
      }
    }
    catch ( Exception e)
    {
     
      e.printStackTrace();
      ErrorContext errorContext = new ErrorContext();
      errorContext.add(AsynchAEMessage.Command, AsynchAEMessage.Process);
      errorContext.add(AsynchAEMessage.CasReference, casReferenceId );
      errorContext.add(AsynchAEMessage.Endpoint, aMessageContext.getEndpoint());
      getController().getErrorHandlerChain().handle(e, errorContext, getController());
    }
    finally
    {
      incrementDelegateProcessCount(aMessageContext);
      if ( getController() instanceof AggregateAnalysisEngineController )
      {
        try
        {
          String endpointName = aMessageContext.getEndpoint().getEndpoint();
          String delegateKey =
            ((AggregateAnalysisEngineController)getController()).lookUpDelegateKey(endpointName);
          if ( delegateKey != null )
          {
            Endpoint endpoint =
              ((AggregateAnalysisEngineController)getController()).lookUpEndpoint(delegateKey, false);

            //  Check if the multiplier aborted during processing of this input CAS
            if ( endpoint != null && endpoint.isCasMultiplier() && cacheEntry.isAborted() )
            {
              if ( !getController().getInProcessCache().isEmpty() )
              {
                getController().getInProcessCache().registerCallbackWhenCacheEmpty(getController().getEventListener());
              }
              else
              {
                //  Callback to notify that the cache is empty
                getController().getEventListener().onCacheEmpty();
              }
            }
           
          }
        }
        catch( Exception e)
        {
          e.printStackTrace();
        }
      }
    }

  }
  private void incrementDelegateProcessCount(MessageContext aMessageContext)
  {
    Endpoint endpoint = aMessageContext.getEndpoint();
    if ( endpoint != null && getController() instanceof AggregateAnalysisEngineController)
    {
      try
      {
        String delegateKey = ((AggregateAnalysisEngineController)getController()).lookUpDelegateKey(endpoint.getEndpoint());
        LongNumericStatistic stat = getController().getMonitor().getLongNumericStatistic(delegateKey, Monitor.ProcessCount);
        stat.increment();
      }
      catch( Exception e) {}
    }
   
  }
 
  private boolean isException( Object object )
  {
    return (object instanceof Exception || object instanceof Throwable );
  }
 
  private boolean isShutdownException( Object object )
  {
    return ( object instanceof Exception &&
         object instanceof UimaEEServiceException &&
         ((UimaEEServiceException)object).getCause() != null &&
         ((UimaEEServiceException)object).getCause() instanceof ServiceShutdownException
            );
  }
  private boolean ignoreException(Object object)
  {
    if ( object != null && isException(object) && !isShutdownException(object) )
    {
      return false;
    }
    return true;
  }
  private void handleProcessResponseWithException(MessageContext aMessageContext)
  {
    UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, CLASS_NAME.getName(),
                "handleProcessResponseWithException", UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_handling_exception_from_delegate_FINE",
                new Object[] { getController().getName(), aMessageContext.getEndpoint().getEndpoint() });

    boolean isCpCError = false;
    String casReferenceId = null;


    try
    {
      //  If a Process Request, increment number of docs processed
      if ( aMessageContext.getMessageIntProperty(AsynchAEMessage.MessageType) == AsynchAEMessage.Response &&
         aMessageContext.getMessageIntProperty(AsynchAEMessage.Command)== AsynchAEMessage.Process )
      {
        //  Increment number of CASes processed by a delegate
        incrementDelegateProcessCount(aMessageContext);
      }

      Object object = aMessageContext.getObjectMessage();
      if ( object == null )
      {
        //   Could be a C++ exception. In this case the exception is just a String in the message cargo
        if ( aMessageContext.getStringMessage() != null )
        {
          object = new UimaEEServiceException(aMessageContext.getStringMessage());
        }
      }
      if ( ignoreException(object) )
      {
        return;
      }
     
      if ( getController() instanceof AggregateAnalysisEngineController &&
         aMessageContext.propertyExists(AsynchAEMessage.Command ) &&
         aMessageContext.getMessageIntProperty(AsynchAEMessage.Command) == AsynchAEMessage.CollectionProcessComplete
         )
      {
        isCpCError = true;
        ((AggregateAnalysisEngineController)getController()).
          processCollectionCompleteReplyFromDelegate(aMessageContext.getEndpoint().getEndpoint(), false);
      }
      else
      {
        casReferenceId = aMessageContext.getMessageStringProperty(AsynchAEMessage.CasReference);
        cancelTimer(aMessageContext, casReferenceId, false);
      }

      if ( object != null && (object instanceof Exception || object instanceof Throwable ))
      {
       
       
        Exception remoteException = (Exception) object;
        ErrorContext errorContext = new ErrorContext();
        errorContext.add(AsynchAEMessage.Command, aMessageContext.getMessageIntProperty(AsynchAEMessage.Command));
        errorContext.add(AsynchAEMessage.MessageType, aMessageContext.getMessageIntProperty(AsynchAEMessage.MessageType));
        if ( !isCpCError )
        {
          errorContext.add(AsynchAEMessage.CasReference, casReferenceId);
        }
        errorContext.add(AsynchAEMessage.Endpoint, aMessageContext.getEndpoint());
        getController().getErrorHandlerChain().handle(remoteException, errorContext, getController());
      }
    }
    catch ( Exception e)
    {
      e.printStackTrace();
      ErrorContext errorContext = new ErrorContext();
      errorContext.add(AsynchAEMessage.Command, AsynchAEMessage.Process);
      errorContext.add(AsynchAEMessage.CasReference, casReferenceId );
      errorContext.add(AsynchAEMessage.Endpoint, aMessageContext.getEndpoint());
      getController().getErrorHandlerChain().handle(e, errorContext, getController());
    }

  }

  private void handleCollectionProcessCompleteReply(MessageContext aMessageContext)
  {
    try
    {
      String delegateKey = ((Endpoint)aMessageContext.getEndpoint()).getEndpoint();
      if ( getController() instanceof AggregateAnalysisEngineController )
      {
        ((AggregateAnalysisEngineController) getController())
          .processCollectionCompleteReplyFromDelegate(delegateKey, true);
      }
    }
    catch ( Exception e)
    {
      e.printStackTrace();
      ErrorContext errorContext = new ErrorContext();
      errorContext.add(AsynchAEMessage.Command, AsynchAEMessage.CollectionProcessComplete);
      errorContext.add(AsynchAEMessage.Endpoint, aMessageContext.getEndpoint());
      getController().getErrorHandlerChain().handle(e, errorContext, getController());
    }

  }
  private void resetErrorCounts(String aDelegate)
  {
    getController().getMonitor().resetCountingStatistic(aDelegate, Monitor.ProcessErrorCount);
    getController().getMonitor().resetCountingStatistic(aDelegate, Monitor.ProcessErrorRetryCount);
  }
  public synchronized void handle(Object anObjectToHandle) throws AsynchAEException
  {
    super.validate(anObjectToHandle);
    MessageContext messageContext = (MessageContext) anObjectToHandle;
   
    if (isHandlerForMessage(messageContext, AsynchAEMessage.Response, AsynchAEMessage.Process) ||
      isHandlerForMessage(messageContext, AsynchAEMessage.Response, AsynchAEMessage.ACK ) ||
        isHandlerForMessage(messageContext, AsynchAEMessage.Response, AsynchAEMessage.CollectionProcessComplete) )
    {
      int payload = messageContext.getMessageIntProperty(AsynchAEMessage.Payload);
      int command = messageContext.getMessageIntProperty(AsynchAEMessage.Command);
      String delegate = ((Endpoint)messageContext.getEndpoint()).getEndpoint();
      String key = null;
      if ( getController() instanceof AggregateAnalysisEngineController )
      {
        key = ((AggregateAnalysisEngineController)getController()).lookUpDelegateKey(delegate);
      }
      if (AsynchAEMessage.CASRefID == payload)
      {
       
        handleProcessResponseWithCASReference(messageContext);
        if ( key != null )
        {
          resetErrorCounts(key);
        }
      }
      else if (AsynchAEMessage.XMIPayload == payload)
      {
        handleProcessResponseWithXMI(messageContext, key);
        if ( key != null )
        {
          resetErrorCounts(key);
        }
      }
      else if (AsynchAEMessage.Exception == payload)
      {
        handleProcessResponseWithException(messageContext);
      }
      else if (AsynchAEMessage.None == payload && AsynchAEMessage.CollectionProcessComplete == command)
      {
        handleCollectionProcessCompleteReply(messageContext);
      }
      else if (AsynchAEMessage.None == payload && AsynchAEMessage.ACK == command)
      {
        handleACK(messageContext);
      }

      else
      {
        throw new AsynchAEException("Invalid Payload. Expected XMI or CasReferenceId Instead Got::" + payload);
      }
     
     
      // Handled Request to Process with A given Payload
      return;
    }
    // Not a Request nor Command. Delegate to the next handler in the chain
    super.delegate(messageContext);

  }
  private void handleACK(MessageContext aMessageContext)
  throws AsynchAEException
  {
    if ( getController() instanceof PrimitiveAnalysisEngineController )
    {
//      ((PrimitiveAnalysisEngineController) getController()).throttleNext();
    }
  }

}
TOP

Related Classes of org.apache.uima.aae.handler.input.ProcessResponseHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.