Search in sources :

Example 6 with Rejected

use of org.apache.qpid.proton.amqp.messaging.Rejected in project hono by eclipse.

the class TelemetrySenderImplTest method testSendMessageDoesNotWaitForAcceptedOutcome.

/**
 * Verifies that the sender does not wait for the peer to settle and
 * accept a message before succeeding.
 *
 * @param ctx The vert.x test context.
 */
@SuppressWarnings({ "unchecked" })
@Test
public void testSendMessageDoesNotWaitForAcceptedOutcome(final TestContext ctx) {
    // GIVEN a sender that has credit
    when(sender.sendQueueFull()).thenReturn(Boolean.FALSE);
    MessageSender messageSender = new TelemetrySenderImpl(config, sender, "tenant", "telemetry/tenant", context);
    final AtomicReference<Handler<ProtonDelivery>> handlerRef = new AtomicReference<>();
    doAnswer(invocation -> {
        handlerRef.set(invocation.getArgument(1));
        return mock(ProtonDelivery.class);
    }).when(sender).send(any(Message.class), any(Handler.class));
    // WHEN trying to send a message
    final Future<ProtonDelivery> result = messageSender.send("device", "some payload", "application/text", "token");
    // which gets rejected by the peer
    ProtonDelivery rejected = mock(ProtonDelivery.class);
    when(rejected.remotelySettled()).thenReturn(Boolean.TRUE);
    when(rejected.getRemoteState()).thenReturn(new Rejected());
    handlerRef.get().handle(rejected);
    // THEN the resulting future is succeeded nevertheless
    assertTrue(result.succeeded());
    // and the message has been sent
    verify(sender).send(any(Message.class), eq(handlerRef.get()));
}
Also used : Message(org.apache.qpid.proton.message.Message) ProtonDelivery(io.vertx.proton.ProtonDelivery) MessageSender(org.eclipse.hono.client.MessageSender) Handler(io.vertx.core.Handler) AtomicReference(java.util.concurrent.atomic.AtomicReference) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) Test(org.junit.Test)

Example 7 with Rejected

use of org.apache.qpid.proton.amqp.messaging.Rejected in project azure-service-bus-java by Azure.

the class CoreMessageReceiver method onReceiveComplete.

@Override
public void onReceiveComplete(Delivery delivery) {
    this.underlyingFactory.getRetryPolicy().resetRetryCount(this.getClientId());
    byte[] deliveryTag = delivery.getTag();
    String deliveryTagAsString = StringUtil.convertBytesToString(delivery.getTag());
    TRACE_LOGGER.debug("Received a delivery '{}' from '{}'", deliveryTagAsString, this.receivePath);
    if (deliveryTag == null || deliveryTag.length == 0 || !this.tagsToDeliveriesMap.containsKey(deliveryTagAsString)) {
        TRACE_LOGGER.debug("Received a message from '{}'. Adding to prefecthed messages.", this.receivePath);
        try {
            Message message = Util.readMessageFromDelivery(receiveLink, delivery);
            if (this.settleModePair.getSenderSettleMode() == SenderSettleMode.SETTLED) {
                // No op. Delivery comes settled from the sender
                delivery.disposition(Accepted.getInstance());
                delivery.settle();
            } else {
                this.tagsToDeliveriesMap.put(StringUtil.convertBytesToString(delivery.getTag()), delivery);
                receiveLink.advance();
            }
            // Accuracy of count is not that important. So not making those two operations atomic
            this.currentPrefetechedMessagesCount.incrementAndGet();
            this.prefetchedMessages.add(new MessageWithDeliveryTag(message, delivery.getTag()));
        } catch (Exception e) {
            TRACE_LOGGER.warn("Reading message from delivery '{}' from '{}', session '{}' failed with unexpected exception.", deliveryTagAsString, this.receivePath, this.sessionId, e);
            delivery.disposition(Released.getInstance());
            delivery.settle();
            return;
        }
    } else {
        DeliveryState remoteState = delivery.getRemoteState();
        TRACE_LOGGER.debug("Received a delivery '{}' with state '{}' from '{}'", deliveryTagAsString, remoteState, this.receivePath);
        if (remoteState instanceof Outcome) {
            Outcome remoteOutcome = (Outcome) remoteState;
            UpdateStateWorkItem matchingUpdateStateWorkItem = this.pendingUpdateStateRequests.get(deliveryTagAsString);
            if (matchingUpdateStateWorkItem != null) {
                // This comparison is ugly. Using it for the lack of equals operation on Outcome classes
                if (remoteOutcome.getClass().getName().equals(matchingUpdateStateWorkItem.outcome.getClass().getName())) {
                    TRACE_LOGGER.debug("Completing a pending updateState operation for delivery '{}' from '{}'", deliveryTagAsString, this.receivePath);
                    this.completePendingUpdateStateWorkItem(delivery, deliveryTagAsString, matchingUpdateStateWorkItem, null);
                } else {
                    // if(matchingUpdateStateWorkItem.expectedOutcome instanceof Accepted)
                    // {
                    TRACE_LOGGER.warn("Received delivery '{}' state '{}' doesn't match expected state '{}'", deliveryTagAsString, remoteState, matchingUpdateStateWorkItem.outcome);
                    // Complete requests
                    if (remoteOutcome instanceof Rejected) {
                        Rejected rejected = (Rejected) remoteOutcome;
                        ErrorCondition error = rejected.getError();
                        Exception exception = ExceptionUtil.toException(error);
                        if (ExceptionUtil.isGeneralError(error.getCondition())) {
                            this.lastKnownLinkError = exception;
                            this.lastKnownErrorReportedAt = Instant.now();
                        }
                        Duration retryInterval = this.retryPolicy.getNextRetryInterval(this.getClientId(), exception, matchingUpdateStateWorkItem.getTimeoutTracker().remaining());
                        if (retryInterval == null) {
                            TRACE_LOGGER.error("Completing pending updateState operation for delivery '{}' with exception", deliveryTagAsString, exception);
                            this.completePendingUpdateStateWorkItem(delivery, deliveryTagAsString, matchingUpdateStateWorkItem, exception);
                        } else {
                            matchingUpdateStateWorkItem.setLastKnownException(exception);
                            // Retry after retry interval
                            TRACE_LOGGER.debug("Pending updateState operation for delivery '{}' will be retried after '{}'", deliveryTagAsString, retryInterval);
                            try {
                                this.underlyingFactory.scheduleOnReactorThread((int) retryInterval.toMillis(), new DispatchHandler() {

                                    @Override
                                    public void onEvent() {
                                        delivery.disposition((DeliveryState) matchingUpdateStateWorkItem.getOutcome());
                                    }
                                });
                            } catch (IOException ioException) {
                                this.completePendingUpdateStateWorkItem(delivery, deliveryTagAsString, matchingUpdateStateWorkItem, new ServiceBusException(false, "Operation failed while scheduling a retry on Reactor, see cause for more details.", ioException));
                            }
                        }
                    } else if (remoteOutcome instanceof Released) {
                        Exception exception = new OperationCancelledException(remoteOutcome.toString());
                        TRACE_LOGGER.error("Completing pending updateState operation for delivery '{}' with exception", deliveryTagAsString, exception);
                        this.completePendingUpdateStateWorkItem(delivery, deliveryTagAsString, matchingUpdateStateWorkItem, exception);
                    } else {
                        Exception exception = new ServiceBusException(false, remoteOutcome.toString());
                        TRACE_LOGGER.error("Completing pending updateState operation for delivery '{}' with exception", deliveryTagAsString, exception);
                        this.completePendingUpdateStateWorkItem(delivery, deliveryTagAsString, matchingUpdateStateWorkItem, exception);
                    }
                // }
                }
            } else {
            // Should not happen. Ignore it
            }
        } else {
        // Ignore it. we are only interested in terminal delivery states
        }
    }
}
Also used : Released(org.apache.qpid.proton.amqp.messaging.Released) Message(org.apache.qpid.proton.message.Message) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) Duration(java.time.Duration) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) IOException(java.io.IOException) IOException(java.io.IOException) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Outcome(org.apache.qpid.proton.amqp.messaging.Outcome)

Example 8 with Rejected

use of org.apache.qpid.proton.amqp.messaging.Rejected in project azure-service-bus-java by Azure.

the class CoreMessageReceiver method deadLetterMessageAsync.

public CompletableFuture<Void> deadLetterMessageAsync(byte[] deliveryTag, String deadLetterReason, String deadLetterErrorDescription, Map<String, Object> propertiesToModify) {
    Rejected outcome = new Rejected();
    ErrorCondition error = new ErrorCondition(ClientConstants.DEADLETTERNAME, null);
    Map<String, Object> errorInfo = new HashMap<String, Object>();
    if (!StringUtil.isNullOrEmpty(deadLetterReason)) {
        errorInfo.put(ClientConstants.DEADLETTER_REASON_HEADER, deadLetterReason);
    }
    if (!StringUtil.isNullOrEmpty(deadLetterErrorDescription)) {
        errorInfo.put(ClientConstants.DEADLETTER_ERROR_DESCRIPTION_HEADER, deadLetterErrorDescription);
    }
    if (propertiesToModify != null) {
        errorInfo.putAll(propertiesToModify);
    }
    error.setInfo(errorInfo);
    outcome.setError(error);
    return this.updateMessageStateAsync(deliveryTag, outcome);
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected)

Example 9 with Rejected

use of org.apache.qpid.proton.amqp.messaging.Rejected in project activemq-artemis by apache.

the class AMQPSessionCallback method rejectMessage.

private void rejectMessage(Delivery delivery, Symbol errorCondition, String errorMessage) {
    ErrorCondition condition = new ErrorCondition();
    condition.setCondition(errorCondition);
    condition.setDescription(errorMessage);
    Rejected rejected = new Rejected();
    rejected.setError(condition);
    afterIO(new IOCallback() {

        @Override
        public void done() {
            connection.lock();
            try {
                delivery.disposition(rejected);
                delivery.settle();
            } finally {
                connection.unlock();
            }
            connection.flush();
        }

        @Override
        public void onError(int errorCode, String errorMessage) {
        }
    });
}
Also used : ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) IOCallback(org.apache.activemq.artemis.core.io.IOCallback)

Example 10 with Rejected

use of org.apache.qpid.proton.amqp.messaging.Rejected in project activemq-artemis by apache.

the class ProtonServerReceiverContext method onMessage.

/*
   * called when Proton receives a message to be delivered via a Delivery.
   *
   * This may be called more than once per deliver so we have to cache the buffer until we have received it all.
   *
   * */
@Override
public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
    Receiver receiver;
    try {
        if (!delivery.isReadable()) {
            return;
        }
        if (delivery.isPartial()) {
            return;
        }
        receiver = ((Receiver) delivery.getLink());
        Transaction tx = null;
        byte[] data;
        data = new byte[delivery.available()];
        receiver.recv(data, 0, data.length);
        receiver.advance();
        if (delivery.getRemoteState() instanceof TransactionalState) {
            TransactionalState txState = (TransactionalState) delivery.getRemoteState();
            tx = this.sessionSPI.getTransaction(txState.getTxnId(), false);
        }
        sessionSPI.serverSend(this, tx, receiver, delivery, address, delivery.getMessageFormat(), data);
        flow(amqpCredits, minCreditRefresh);
    } catch (Exception e) {
        log.warn(e.getMessage(), e);
        Rejected rejected = new Rejected();
        ErrorCondition condition = new ErrorCondition();
        if (e instanceof ActiveMQSecurityException) {
            condition.setCondition(AmqpError.UNAUTHORIZED_ACCESS);
        } else {
            condition.setCondition(Symbol.valueOf("failed"));
        }
        condition.setDescription(e.getMessage());
        rejected.setError(condition);
        connection.lock();
        try {
            delivery.disposition(rejected);
            delivery.settle();
        } finally {
            connection.unlock();
        }
    }
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Receiver(org.apache.qpid.proton.engine.Receiver) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) ActiveMQSecurityException(org.apache.activemq.artemis.api.core.ActiveMQSecurityException) ActiveMQAMQPInternalErrorException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException) ActiveMQAMQPNotFoundException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException) ActiveMQAMQPException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException) ActiveMQSecurityException(org.apache.activemq.artemis.api.core.ActiveMQSecurityException) TransactionalState(org.apache.qpid.proton.amqp.transaction.TransactionalState)

Aggregations

Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)59 Message (org.apache.qpid.proton.message.Message)32 ProtonDelivery (io.vertx.proton.ProtonDelivery)28 Handler (io.vertx.core.Handler)27 DeliveryState (org.apache.qpid.proton.amqp.transport.DeliveryState)23 ErrorCondition (org.apache.qpid.proton.amqp.transport.ErrorCondition)23 Accepted (org.apache.qpid.proton.amqp.messaging.Accepted)21 Span (io.opentracing.Span)19 Test (org.junit.jupiter.api.Test)19 ProtonHelper (io.vertx.proton.ProtonHelper)18 ProtonSender (io.vertx.proton.ProtonSender)18 Released (org.apache.qpid.proton.amqp.messaging.Released)18 Future (io.vertx.core.Future)17 HttpURLConnection (java.net.HttpURLConnection)17 MessageHelper (org.eclipse.hono.util.MessageHelper)17 ProtonQoS (io.vertx.proton.ProtonQoS)16 ClientErrorException (org.eclipse.hono.client.ClientErrorException)16 ProtonReceiver (io.vertx.proton.ProtonReceiver)15 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)15 Truth.assertThat (com.google.common.truth.Truth.assertThat)14