/**
   * Cancel a previous subscription.
   *
   * @param destinationType The destination type (TOPIC or QUEUE).
   * @param destinationName The destination name (e.g., /topic/.*).
   * @param acceptRequest An AcceptRequest object used handling Accept messages.
   */
  public void unsubscribe(
      NetAction.DestinationType destinationType,
      String destinationName,
      AcceptRequest acceptRequest)
      throws Throwable {
    if ((StringUtils.isNotBlank(destinationName)) && (destinationType != null)) {
      NetUnsubscribe unsubs = new NetUnsubscribe(destinationName, destinationType);
      if (acceptRequest != null) {
        unsubs.setActionId(acceptRequest.getActionId());
        PendingAcceptRequestsManager.addAcceptRequest(acceptRequest);
      }
      NetAction action = new NetAction(ActionType.UNSUBSCRIBE);
      action.setUnsbuscribeMessage(unsubs);

      NetMessage message = buildMessage(action);

      getNetHandler().sendMessage(message);

      Map<String, BrokerAsyncConsumer> subscriptions =
          _consumerList.get(
              destinationType.equals(DestinationType.TOPIC)
                  ? DestinationType.TOPIC
                  : DestinationType.QUEUE);
      subscriptions.remove(destinationName);
    } else {
      throw new IllegalArgumentException("Mal-formed Unsubscribe request");
    }
  }
  /**
   * Publish a message to a topic.
   *
   * @param brokerMessage The Broker message containing the payload.
   * @param destination The destination name (e.g. /topic/foo).
   * @param acceptRequest An AcceptRequest object used handling Accept messages.
   */
  public void publishMessage(
      NetBrokerMessage brokerMessage, String destination, AcceptRequest acceptRequest) {
    if ((brokerMessage != null) && (StringUtils.isNotBlank(destination))) {
      NetPublish publish =
          new NetPublish(
              destination, pt.com.broker.types.NetAction.DestinationType.TOPIC, brokerMessage);
      if (acceptRequest != null) {
        publish.setActionId(acceptRequest.getActionId());
        PendingAcceptRequestsManager.addAcceptRequest(acceptRequest);
      }
      NetAction action = new NetAction(ActionType.PUBLISH);
      action.setPublishMessage(publish);

      NetMessage msg = buildMessage(action, brokerMessage.getHeaders());

      try {
        getNetHandler().sendMessage(msg);
      } catch (Throwable e) {
        log.error("Could not publish message, messageId:");
        log.error(e.getMessage(), e);
      }
    } else {
      throw new IllegalArgumentException("Mal-formed Publish request");
    }
  }
  /**
   * Publishes a message to a queue.
   *
   * @param brokerMessage The Broker message containing the payload.
   * @param destinationName The destination name (e.g. /queue/foo).
   * @param acceptRequest An AcceptRequest object used handling Accept messages.
   */
  public void enqueueMessage(
      NetBrokerMessage brokerMessage, String destinationName, AcceptRequest acceptRequest) {

    if ((brokerMessage != null) && (StringUtils.isNotBlank(destinationName))) {
      NetPublish publish =
          new NetPublish(
              destinationName, pt.com.broker.types.NetAction.DestinationType.QUEUE, brokerMessage);
      if (acceptRequest != null) {
        publish.setActionId(acceptRequest.getActionId());
        PendingAcceptRequestsManager.addAcceptRequest(acceptRequest);
      }

      NetAction action = new NetAction(ActionType.PUBLISH);
      action.setPublishMessage(publish);

      NetMessage msg = buildMessage(action, brokerMessage.getHeaders());

      try {
        getNetHandler().sendMessage(msg);
      } catch (Throwable t) {
        log.error("Failed to deliver message.", t);
      }
    } else {
      throw new IllegalArgumentException("Mal-formed Enqueue request");
    }
  }
  /**
   * Acknowledges a received message.
   *
   * @param notification The received notification message
   * @param acceptRequest An AcceptRequest object used handling Accept messages.
   */
  public void acknowledge(NetNotification notification, AcceptRequest acceptRequest)
      throws Throwable {

    if ((notification != null)
        && (notification.getMessage() != null)
        && (StringUtils.isNotBlank(notification.getMessage().getMessageId()))) {
      NetBrokerMessage brkMsg = notification.getMessage();

      if (notification.getDestinationType() == DestinationType.TOPIC) {
        return;
      }

      String ackDestination = notification.getSubscription();

      NetAcknowledge ackMsg = new NetAcknowledge(ackDestination, brkMsg.getMessageId());
      if (acceptRequest != null) {
        ackMsg.setActionId(acceptRequest.getActionId());
        PendingAcceptRequestsManager.addAcceptRequest(acceptRequest);
      }

      NetAction action = new NetAction(ActionType.ACKNOWLEDGE);
      action.setAcknowledgeMessage(ackMsg);
      NetMessage msg = buildMessage(action);

      getNetHandler().sendMessage(msg);

    } else {
      throw new IllegalArgumentException("Can't acknowledge invalid message.");
    }
  }
  /**
   * Create a new asynchronous subscription.
   *
   * @param subscribe A subscription message.
   * @param listener A BrokerListener instance.
   * @param acceptRequest An AcceptRequest object used handling Accept messages.
   */
  public void addAsyncConsumer(
      NetSubscribe subscribe, BrokerListener listener, AcceptRequest acceptRequest)
      throws Throwable {
    if ((subscribe != null) && (StringUtils.isNotBlank(subscribe.getDestination()))) {

      Map<String, BrokerAsyncConsumer> subscriptions =
          _consumerList.get(
              subscribe.getDestinationType().equals(DestinationType.TOPIC)
                  ? DestinationType.TOPIC
                  : DestinationType.QUEUE);

      BrokerAsyncConsumer previous =
          subscriptions.put(
              subscribe.getDestination(), new BrokerAsyncConsumer(subscribe, listener));

      if (previous != null) {
        // A subscription for the given destination already existed. Set it again and
        subscriptions.put(subscribe.getDestination(), previous);

        throw new IllegalStateException("A listener for that Destination already exists");
      }

      if (acceptRequest != null) {
        subscribe.setActionId(acceptRequest.getActionId());
        PendingAcceptRequestsManager.addAcceptRequest(acceptRequest);
      }

      NetAction netAction = new NetAction(ActionType.SUBSCRIBE);
      netAction.setSubscribeMessage(subscribe);

      NetMessage msg = buildMessage(netAction, subscribe.getHeaders());

      getNetHandler().sendMessage(msg);

      log.info("Created new async consumer for '{}'", subscribe.getDestination());
    } else {
      throw new IllegalArgumentException("Mal-formed Notification request");
    }
  }