@Override
 public JSONObject toJSON() throws JSONException {
   JSONObject obj = new JSONObject();
   obj.put(FeedConstants.MessageConstants.MESSAGE_TYPE, messageType.name());
   obj.put(FeedConstants.MessageConstants.DATAVERSE, connectionId.getFeedId().getDataverse());
   obj.put(FeedConstants.MessageConstants.FEED, connectionId.getFeedId().getFeedName());
   obj.put(FeedConstants.MessageConstants.DATASET, connectionId.getDatasetName());
   obj.put(FeedConstants.MessageConstants.AQL, aql);
   return obj;
 }
  private void handleFeedTupleCommitResponseMessage(
      FeedTupleCommitResponseMessage commitResponseMessage) {
    FeedConnectionId connectionId = commitResponseMessage.getConnectionId();
    FeedRuntimeManager runtimeManager =
        feedManager.getFeedConnectionManager().getFeedRuntimeManager(connectionId);
    Set<FeedRuntimeId> runtimes = runtimeManager.getFeedRuntimes();
    for (FeedRuntimeId runtimeId : runtimes) {
      FeedRuntime runtime = runtimeManager.getFeedRuntime(runtimeId);
      switch (runtimeId.getFeedRuntimeType()) {
        case COLLECT:
          FeedCollectRuntimeInputHandler inputHandler =
              (FeedCollectRuntimeInputHandler) runtime.getInputHandler();
          int maxBasePersisted = commitResponseMessage.getMaxWindowAcked();
          inputHandler.dropTill(IntakePartitionStatistics.ACK_WINDOW_SIZE * (maxBasePersisted + 1));
          break;
        case STORE:
          MonitoredBufferStorageTimerTask sTask =
              runtime.getInputHandler().getmBuffer().getStorageTimeTrackingRateTask();
          sTask.receiveCommitAckResponse(commitResponseMessage);
          break;
      }
    }

    commitResponseMessage.getIntakePartition();
    SubscribableFeedRuntimeId sid =
        new SubscribableFeedRuntimeId(connectionId.getFeedId(), FeedRuntimeType.INTAKE, partition);
    IngestionRuntime ingestionRuntime =
        (IngestionRuntime) feedManager.getFeedSubscriptionManager().getSubscribableRuntime(sid);
    if (ingestionRuntime != null) {
      IIntakeProgressTracker tracker =
          ingestionRuntime.getAdapterRuntimeManager().getProgressTracker();
      if (tracker != null) {
        tracker.notifyIngestedTupleTimestamp(System.currentTimeMillis());
      }
    }
  }
  private void hanldeDisconnectFeedTypeMessage(EndFeedMessage endFeedMessage) throws Exception {
    if (LOGGER.isLoggable(Level.INFO)) {
      LOGGER.info("Ending feed:" + endFeedMessage.getFeedConnectionId());
    }
    FeedRuntimeId runtimeId = null;
    FeedRuntimeType subscribableRuntimeType = ((EndFeedMessage) message).getSourceRuntimeType();
    if (endFeedMessage.isCompleteDisconnection()) {
      // subscribableRuntimeType represents the location at which the feed connection receives data
      FeedRuntimeType runtimeType = null;
      switch (subscribableRuntimeType) {
        case INTAKE:
          runtimeType = FeedRuntimeType.COLLECT;
          break;
        case COMPUTE:
          runtimeType = FeedRuntimeType.COMPUTE_COLLECT;
          break;
        default:
          throw new IllegalStateException(
              "Invalid subscribable runtime type " + subscribableRuntimeType);
      }

      runtimeId = new FeedRuntimeId(runtimeType, partition, FeedRuntimeId.DEFAULT_OPERAND_ID);
      CollectionRuntime feedRuntime =
          (CollectionRuntime)
              feedManager.getFeedConnectionManager().getFeedRuntime(connectionId, runtimeId);
      feedRuntime.getSourceRuntime().unsubscribeFeed(feedRuntime);
      if (LOGGER.isLoggable(Level.INFO)) {
        LOGGER.info("Complete Unsubscription of " + endFeedMessage.getFeedConnectionId());
      }
    } else {
      // subscribaleRuntimeType represents the location for data hand-off in presence of subscribers
      switch (subscribableRuntimeType) {
        case INTAKE:
          // illegal state as data hand-off from one feed to another does not happen at intake
          throw new IllegalStateException(
              "Illegal State, invalid runtime type  " + subscribableRuntimeType);
        case COMPUTE:
          // feed could be primary or secondary, doesn't matter
          SubscribableFeedRuntimeId feedSubscribableRuntimeId =
              new SubscribableFeedRuntimeId(
                  connectionId.getFeedId(), FeedRuntimeType.COMPUTE, partition);
          ISubscribableRuntime feedRuntime =
              feedManager
                  .getFeedSubscriptionManager()
                  .getSubscribableRuntime(feedSubscribableRuntimeId);
          DistributeFeedFrameWriter dWriter =
              (DistributeFeedFrameWriter) feedRuntime.getFeedFrameWriter();
          Map<IFrameWriter, FeedFrameCollector> registeredCollectors =
              dWriter.getRegisteredReaders();

          IFrameWriter unsubscribingWriter = null;
          for (Entry<IFrameWriter, FeedFrameCollector> entry : registeredCollectors.entrySet()) {
            IFrameWriter frameWriter = entry.getKey();
            FeedRuntimeInputHandler feedFrameWriter = (FeedRuntimeInputHandler) frameWriter;
            if (feedFrameWriter.getConnectionId().equals(endFeedMessage.getFeedConnectionId())) {
              unsubscribingWriter = feedFrameWriter;
              dWriter.unsubscribeFeed(unsubscribingWriter);
              if (LOGGER.isLoggable(Level.INFO)) {
                LOGGER.info("Partial Unsubscription of " + unsubscribingWriter);
              }
              break;
            }
          }
          break;
      }
    }

    if (LOGGER.isLoggable(Level.INFO)) {
      LOGGER.info("Unsubscribed from feed :" + connectionId);
    }
  }