Search in sources :

Example 31 with Rejected

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

the class RequestResponseEndpointTest method testHandleMessageRejectsUnauthorizedRequests.

/**
 * Verifies that the endpoint rejects request messages for operations the client
 * is not authorized to invoke.
 */
@Test
public void testHandleMessageRejectsUnauthorizedRequests() {
    Message msg = ProtonHelper.message();
    msg.setSubject("unauthorized");
    ProtonConnection con = mock(ProtonConnection.class);
    ProtonDelivery delivery = mock(ProtonDelivery.class);
    AuthorizationService authService = mock(AuthorizationService.class);
    when(authService.isAuthorized(any(HonoUser.class), any(ResourceIdentifier.class), anyString())).thenReturn(Future.succeededFuture(Boolean.FALSE));
    Future<Void> processingTracker = Future.future();
    RequestResponseEndpoint<ServiceConfigProperties> endpoint = getEndpoint(true, processingTracker);
    endpoint.setAuthorizationService(authService);
    // WHEN a request for an operation is received that the client is not authorized to invoke
    endpoint.handleMessage(con, receiver, resource, delivery, msg);
    // THEN the the message is rejected
    ArgumentCaptor<DeliveryState> deliveryState = ArgumentCaptor.forClass(DeliveryState.class);
    verify(delivery).disposition(deliveryState.capture(), booleanThat(is(Boolean.TRUE)));
    assertThat(deliveryState.getValue(), instanceOf(Rejected.class));
    verify(receiver, never()).close();
    verify(authService).isAuthorized(Constants.PRINCIPAL_ANONYMOUS, resource, "unauthorized");
    assertFalse(processingTracker.isComplete());
}
Also used : EventBusMessage(org.eclipse.hono.util.EventBusMessage) Message(org.apache.qpid.proton.message.Message) ProtonDelivery(io.vertx.proton.ProtonDelivery) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) ProtonConnection(io.vertx.proton.ProtonConnection) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) HonoUser(org.eclipse.hono.auth.HonoUser) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) AuthorizationService(org.eclipse.hono.service.auth.AuthorizationService) ServiceConfigProperties(org.eclipse.hono.config.ServiceConfigProperties) Test(org.junit.Test)

Example 32 with Rejected

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

the class AmqpSender method processDeliveryUpdates.

@Override
public void processDeliveryUpdates(AmqpConnection connection, Delivery updated) throws IOException {
    List<Delivery> toRemove = new ArrayList<>();
    for (Delivery delivery : pending) {
        DeliveryState state = delivery.getRemoteState();
        if (state == null) {
            continue;
        }
        doDeliveryUpdateInspection(delivery);
        Outcome outcome = null;
        if (state instanceof TransactionalState) {
            LOG.trace("State of delivery is Transactional, retrieving outcome: {}", state);
            outcome = ((TransactionalState) state).getOutcome();
        } else if (state instanceof Outcome) {
            outcome = (Outcome) state;
        } else {
            LOG.warn("Message send updated with unsupported state: {}", state);
            outcome = null;
        }
        AsyncResult request = (AsyncResult) delivery.getContext();
        Exception deliveryError = null;
        if (outcome instanceof Accepted) {
            LOG.trace("Outcome of delivery was accepted: {}", delivery);
            if (request != null && !request.isComplete()) {
                request.onSuccess();
            }
        } else if (outcome instanceof Rejected) {
            LOG.trace("Outcome of delivery was rejected: {}", delivery);
            ErrorCondition remoteError = ((Rejected) outcome).getError();
            if (remoteError == null) {
                remoteError = getEndpoint().getRemoteCondition();
            }
            deliveryError = AmqpSupport.convertToException(remoteError);
        } else if (outcome instanceof Released) {
            LOG.trace("Outcome of delivery was released: {}", delivery);
            deliveryError = new IOException("Delivery failed: released by receiver");
        } else if (outcome instanceof Modified) {
            LOG.trace("Outcome of delivery was modified: {}", delivery);
            deliveryError = new IOException("Delivery failed: failure at remote");
        }
        if (deliveryError != null) {
            if (request != null && !request.isComplete()) {
                request.onFailure(deliveryError);
            } else {
                connection.fireClientException(deliveryError);
            }
        }
        tagGenerator.returnTag(delivery.getTag());
        delivery.settle();
        toRemove.add(delivery);
    }
    pending.removeAll(toRemove);
}
Also used : Released(org.apache.qpid.proton.amqp.messaging.Released) Modified(org.apache.qpid.proton.amqp.messaging.Modified) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ArrayList(java.util.ArrayList) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) IOException(java.io.IOException) InvalidDestinationException(javax.jms.InvalidDestinationException) IOException(java.io.IOException) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) TransactionalState(org.apache.qpid.proton.amqp.transaction.TransactionalState) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Outcome(org.apache.qpid.proton.amqp.messaging.Outcome) Delivery(org.apache.qpid.proton.engine.Delivery) AsyncResult(org.apache.activemq.transport.amqp.client.util.AsyncResult)

Example 33 with Rejected

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

the class AmqpTransactionCoordinator method processDeliveryUpdates.

@Override
public void processDeliveryUpdates(AmqpConnection connection, Delivery delivery) throws IOException {
    try {
        Iterator<Delivery> deliveries = pendingDeliveries.iterator();
        while (deliveries.hasNext()) {
            Delivery pendingDelivery = deliveries.next();
            if (!pendingDelivery.remotelySettled()) {
                continue;
            }
            DeliveryState state = pendingDelivery.getRemoteState();
            AmqpTransactionId txId = (AmqpTransactionId) pendingDelivery.getContext();
            AsyncResult pendingRequest = pendingRequests.get(txId);
            if (pendingRequest == null) {
                throw new IllegalStateException("Pending tx operation with no pending request");
            }
            if (state instanceof Declared) {
                LOG.debug("New TX started: {}", txId.getTxId());
                Declared declared = (Declared) state;
                txId.setRemoteTxId(declared.getTxnId());
                pendingRequest.onSuccess();
            } else if (state instanceof Rejected) {
                LOG.debug("Last TX request failed: {}", txId.getTxId());
                Rejected rejected = (Rejected) state;
                Exception cause = AmqpSupport.convertToException(rejected.getError());
                JMSException failureCause = null;
                if (txId.isCommit()) {
                    failureCause = new TransactionRolledBackException(cause.getMessage());
                } else {
                    failureCause = new JMSException(cause.getMessage());
                }
                pendingRequest.onFailure(failureCause);
            } else {
                LOG.debug("Last TX request succeeded: {}", txId.getTxId());
                pendingRequest.onSuccess();
            }
            // Clear state data
            pendingDelivery.settle();
            pendingRequests.remove(txId);
            deliveries.remove();
        }
        super.processDeliveryUpdates(connection, delivery);
    } catch (Exception e) {
        throw IOExceptionSupport.create(e);
    }
}
Also used : IllegalStateException(javax.jms.IllegalStateException) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) JMSException(javax.jms.JMSException) TransactionRolledBackException(javax.jms.TransactionRolledBackException) Delivery(org.apache.qpid.proton.engine.Delivery) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) AsyncResult(org.apache.activemq.transport.amqp.client.util.AsyncResult) Declared(org.apache.qpid.proton.amqp.transaction.Declared) BufferOverflowException(java.nio.BufferOverflowException) IOException(java.io.IOException) IllegalStateException(javax.jms.IllegalStateException) JMSException(javax.jms.JMSException) TransactionRolledBackException(javax.jms.TransactionRolledBackException)

Example 34 with Rejected

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

the class ProtonServerSenderContext method onMessage.

@Override
public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
    if (closed) {
        return;
    }
    OperationContext oldContext = sessionSPI.recoverContext();
    try {
        Message message = ((MessageReference) delivery.getContext()).getMessage();
        boolean preSettle = sender.getRemoteSenderSettleMode() == SenderSettleMode.SETTLED;
        DeliveryState remoteState;
        connection.lock();
        try {
            remoteState = delivery.getRemoteState();
        } finally {
            connection.unlock();
        }
        boolean settleImmediate = true;
        if (remoteState instanceof Accepted) {
            // acking again would show an exception but would have no negative effect but best to handle anyway.
            if (delivery.isSettled()) {
                return;
            }
            // from dealer, a perf hit but a must
            try {
                sessionSPI.ack(null, brokerConsumer, message);
            } catch (Exception e) {
                log.warn(e.toString(), e);
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof TransactionalState) {
            // When the message arrives with a TransactionState disposition the ack should
            // enlist the message into the transaction associated with the given txn ID.
            TransactionalState txState = (TransactionalState) remoteState;
            ProtonTransactionImpl tx = (ProtonTransactionImpl) this.sessionSPI.getTransaction(txState.getTxnId(), false);
            if (txState.getOutcome() != null) {
                settleImmediate = false;
                Outcome outcome = txState.getOutcome();
                if (outcome instanceof Accepted) {
                    if (!delivery.remotelySettled()) {
                        TransactionalState txAccepted = new TransactionalState();
                        txAccepted.setOutcome(Accepted.getInstance());
                        txAccepted.setTxnId(txState.getTxnId());
                        connection.lock();
                        try {
                            delivery.disposition(txAccepted);
                        } finally {
                            connection.unlock();
                        }
                    }
                    // from dealer, a perf hit but a must
                    try {
                        sessionSPI.ack(tx, brokerConsumer, message);
                        tx.addDelivery(delivery, this);
                    } catch (Exception e) {
                        throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
                    }
                }
            }
        } else if (remoteState instanceof Released) {
            try {
                sessionSPI.cancel(brokerConsumer, message, false);
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof Rejected) {
            try {
                sessionSPI.reject(brokerConsumer, message);
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof Modified) {
            try {
                Modified modification = (Modified) remoteState;
                if (Boolean.TRUE.equals(modification.getUndeliverableHere())) {
                    message.rejectConsumer(brokerConsumer.sequentialID());
                }
                if (Boolean.TRUE.equals(modification.getDeliveryFailed())) {
                    sessionSPI.cancel(brokerConsumer, message, true);
                } else {
                    sessionSPI.cancel(brokerConsumer, message, false);
                }
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else {
            log.debug("Received null or unknown disposition for delivery update: " + remoteState);
            return;
        }
        if (!preSettle) {
            protonSession.replaceTag(delivery.getTag());
        }
        if (settleImmediate) {
            settle(delivery);
        }
    } finally {
        sessionSPI.afterIO(new IOCallback() {

            @Override
            public void done() {
                connection.flush();
            }

            @Override
            public void onError(int errorCode, String errorMessage) {
                connection.flush();
            }
        });
        sessionSPI.resetContext(oldContext);
    }
}
Also used : OperationContext(org.apache.activemq.artemis.core.persistence.OperationContext) Released(org.apache.qpid.proton.amqp.messaging.Released) Modified(org.apache.qpid.proton.amqp.messaging.Modified) AMQPMessage(org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage) Message(org.apache.activemq.artemis.api.core.Message) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) ActiveMQAMQPNotFoundException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException) ActiveMQAMQPException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException) FilterException(org.apache.activemq.artemis.selector.filter.FilterException) ActiveMQAMQPInternalErrorException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException) ActiveMQQueueExistsException(org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException) ActiveMQAMQPResourceLimitExceededException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPResourceLimitExceededException) ActiveMQAMQPIllegalStateException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPIllegalStateException) ActiveMQSecurityException(org.apache.activemq.artemis.api.core.ActiveMQSecurityException) TransactionalState(org.apache.qpid.proton.amqp.transaction.TransactionalState) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Outcome(org.apache.qpid.proton.amqp.messaging.Outcome) ProtonTransactionImpl(org.apache.activemq.artemis.protocol.amqp.proton.transaction.ProtonTransactionImpl)

Example 35 with Rejected

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

the class ProtonTransactionHandler method createRejected.

private Rejected createRejected(Symbol amqpError, String message) {
    Rejected rejected = new Rejected();
    ErrorCondition condition = new ErrorCondition();
    condition.setCondition(amqpError);
    condition.setDescription(message);
    rejected.setError(condition);
    return rejected;
}
Also used : ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected)

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