@Override
 public void disconnect(ServerConsumer consumer, String queueName) {
   synchronized (connection.getLock()) {
     ((Link) consumer.getProtocolContext()).close();
     connection.flush();
   }
 }
  @Override
  public boolean hasCredits(ServerConsumer consumer) {
    ProtonPlugSender plugSender = (ProtonPlugSender) consumer.getProtocolContext();

    if (plugSender != null && plugSender.getSender().getCredit() > 0) {
      return true;
    } else {
      return false;
    }
  }
 @Override
 public void cancel(Object brokerConsumer, Object message, boolean updateCounts) throws Exception {
   recoverContext();
   try {
     ((ServerConsumer) brokerConsumer)
         .individualCancel(((ServerMessage) message).getMessageID(), updateCounts);
   } finally {
     resetContext();
   }
 }
 @Override
 public void ack(Object brokerConsumer, Object message) throws Exception {
   recoverContext();
   try {
     ((ServerConsumer) brokerConsumer)
         .individualAcknowledge(null, ((ServerMessage) message).getMessageID());
   } finally {
     resetContext();
   }
 }
  @Override
  public Object createSender(
      ProtonPlugSender protonSender, String queue, String filer, boolean browserOnly)
      throws Exception {
    long consumerID = consumerIDGenerator.generateID();

    ServerConsumer consumer =
        serverSession.createConsumer(
            consumerID,
            SimpleString.toSimpleString(queue),
            SimpleString.toSimpleString(filer),
            browserOnly);

    // AMQP handles its own flow control for when it's started
    consumer.setStarted(true);

    consumer.setProtocolContext(protonSender);

    return consumer;
  }
  @Override
  public String listConsumersAsJSON() throws Exception {
    checkStarted();

    clearIO();
    try {
      Collection<Consumer> consumers = queue.getConsumers();

      JSONArray jsonArray = new JSONArray();

      for (Consumer consumer : consumers) {

        if (consumer instanceof ServerConsumer) {
          ServerConsumer serverConsumer = (ServerConsumer) consumer;

          JSONObject obj = new JSONObject();
          obj.put("consumerID", serverConsumer.getID());
          obj.put("connectionID", serverConsumer.getConnectionID().toString());
          obj.put("sessionID", serverConsumer.getSessionID());
          obj.put("browseOnly", serverConsumer.isBrowseOnly());
          obj.put("creationTime", serverConsumer.getCreationTime());

          jsonArray.put(obj);
        }
      }

      return jsonArray.toString();
    } finally {
      blockOnIO();
    }
  }
  @Override
  public int sendMessage(ServerMessage message, ServerConsumer consumer, int deliveryCount) {

    ProtonPlugSender plugSender = (ProtonPlugSender) consumer.getProtocolContext();

    try {
      return plugSender.deliverMessage(message, deliveryCount);
    } catch (Exception e) {
      synchronized (connection.getLock()) {
        plugSender
            .getSender()
            .setCondition(new ErrorCondition(AmqpError.INTERNAL_ERROR, e.getMessage()));
        connection.flush();
      }
      throw new IllegalStateException("Can't deliver message " + e, e);
    }
  }
 @Override
 public void onFlowConsumer(Object consumer, int credits) {
   // We have our own flow control on AMQP, so we set activemq's flow control to 0
   ((ServerConsumer) consumer).receiveCredits(-1);
 }
 @Override
 public void resumeDelivery(Object consumer) {
   ((ServerConsumer) consumer).receiveCredits(-1);
 }
 @Override
 public void startSender(Object brokerConsumer) throws Exception {
   ServerConsumer serverConsumer = (ServerConsumer) brokerConsumer;
   // flow control is done at proton
   serverConsumer.receiveCredits(-1);
 }