/** {@inheritDoc} */
  @Override
  public boolean sendMessageToSubscriber(ProtocolMessage protocolMessage, AndesContent content)
      throws AndesException {

    boolean sendSuccess;

    DeliverableAndesMetadata messageMetadata = protocolMessage.getMessage();

    if (messageMetadata.isRetain()) {
      recordRetainedMessage(messageMetadata.getMessageID());
    }

    // Should get the message from the list
    ByteBuffer message = MQTTUtils.getContentFromMetaInformation(content);
    // Will publish the message to the respective queue
    if (null != mqqtServerChannel) {
      try {

        // TODO:review - instead of getSubscribedDestination() used message destination
        mqqtServerChannel.distributeMessageToSubscriber(
            wildcardDestination,
            message,
            messageMetadata.getMessageID(),
            messageMetadata.getQosLevel(),
            messageMetadata.isPersistent(),
            getMqttSubscriptionID(),
            getSubscriberQOS(),
            messageMetadata);

        // We will indicate the ack to the kernel at this stage
        // For MQTT QOS 0 we do not get ack from subscriber, hence will be implicitly creating an
        // ack
        if (QOSLevel.AT_MOST_ONCE.getValue() == getSubscriberQOS()
            || QOSLevel.AT_MOST_ONCE.getValue() == messageMetadata.getQosLevel()) {
          mqqtServerChannel.implicitAck(messageMetadata.getMessageID(), getChannelID());
        }
        sendSuccess = true;
      } catch (MQTTException e) {
        final String error =
            "Error occurred while delivering message to the subscriber for message :"
                + messageMetadata.getMessageID();
        log.error(error, e);
        throw new AndesException(error, e);
      }
    } else {
      sendSuccess = false;
    }

    return sendSuccess;
  }
示例#2
0
  /**
   * write message to channel
   *
   * @param queueEntry message to send
   * @throws AndesException
   */
  private void sendMessage(QueueEntry queueEntry) throws AndesException {

    String msgHeaderStringID = (String) queueEntry.getMessageHeader().getHeader("msgID");
    Long messageID = queueEntry.getMessage().getMessageNumber();

    try {

      if (amqpSubscription instanceof SubscriptionImpl.AckSubscription) {

        MessageTracer.trace(
            messageID,
            "",
            "Sending message "
                + msgHeaderStringID
                + " messageID-"
                + messageID
                + "-to channel "
                + getChannelID());

        amqpSubscription.send(queueEntry);
      } else if (amqpSubscription instanceof SubscriptionImpl.NoAckSubscription) {
        MessageTracer.trace(
            messageID,
            "",
            "Sending message "
                + msgHeaderStringID
                + " messageID-"
                + messageID
                + "-to channel "
                + getChannelID());

        amqpSubscription.send(queueEntry);

        // After sending message we simulate acknowledgment for NoAckSubscription
        UUID channelID =
            ((SubscriptionImpl.NoAckSubscription) amqpSubscription).getChannel().getId();
        AndesAckData andesAckData = AndesUtils.generateAndesAckMessage(channelID, messageID);

        Andes.getInstance().ackReceived(andesAckData);
      } else {
        throw new AndesException(
            "Error occurred while delivering message. Unexpected Subscription type for "
                + "message with ID : "
                + msgHeaderStringID);
      }
    } catch (AMQException e) {
      // The error is not logged here since this will be caught safely higher up in the execution
      // plan :
      // MessageFlusher.deliverAsynchronously. If we have more context, its better to log here too,
      // but since this is a general explanation of many possible errors, no point in logging at
      // this state.
      ProtocolMessage protocolMessage =
          ((AMQMessage) queueEntry.getMessage()).getAndesMetadataReference();
      log.error(
          "AMQP Protocol Error while delivering message to the subscriber subID= "
              + amqpSubscription.getSubscriptionID()
              + " message id= "
              + messageID
              + " slot= "
              + protocolMessage.getMessage().getSlot().getId(),
          e);
      throw new ProtocolDeliveryFailureException(
          "Error occurred while delivering message with ID : " + msgHeaderStringID, e);
    }
  }