use of org.apache.qpid.proton.amqp.messaging.Rejected in project activemq-artemis by apache.
the class AmqpReceiver method reject.
/**
* Reject a message that was dispatched under the given Delivery instance.
*
* @param delivery
* the Delivery instance to reject.
* @throws IOException
* if an error occurs while sending the release.
*/
public void reject(final Delivery delivery) throws IOException {
checkClosed();
if (delivery == null) {
throw new IllegalArgumentException("Delivery to release cannot be null");
}
final ClientFuture request = new ClientFuture();
session.getScheduler().execute(new Runnable() {
@Override
public void run() {
checkClosed();
try {
if (!delivery.isSettled()) {
delivery.disposition(new Rejected());
delivery.settle();
session.pumpToProtonTransport(request);
}
request.onSuccess();
} catch (Exception e) {
request.onFailure(e);
}
}
});
request.sync();
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project activemq-artemis by apache.
the class AmqpSecurityTest method testSendMessageFailsOnAnonymousRelayWhenNotAuthorizedToSendToAddress.
@Test(timeout = 60000)
public void testSendMessageFailsOnAnonymousRelayWhenNotAuthorizedToSendToAddress() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
AmqpClient client = createAmqpClient(guestUser, guestPass);
client.setValidator(new AmqpValidator() {
@Override
public void inspectDeliveryUpdate(Sender sender, Delivery delivery) {
DeliveryState state = delivery.getRemoteState();
if (!delivery.remotelySettled()) {
markAsInvalid("delivery is not remotely settled");
}
if (state instanceof Rejected) {
Rejected rejected = (Rejected) state;
if (rejected.getError() == null || rejected.getError().getCondition() == null) {
markAsInvalid("Delivery should have been Rejected with an error condition");
} else {
ErrorCondition error = rejected.getError();
if (!error.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) {
markAsInvalid("Should have been tagged with unauthorized access error");
}
}
} else {
markAsInvalid("Delivery should have been Rejected");
}
latch.countDown();
}
});
AmqpConnection connection = client.connect();
try {
AmqpSession session = connection.createSession();
AmqpSender sender = session.createAnonymousSender();
AmqpMessage message = new AmqpMessage();
message.setAddress(getQueueName());
message.setMessageId("msg" + 1);
message.setText("Test-Message");
try {
sender.send(message);
fail("Should not be able to send, message should be rejected");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
sender.close();
}
assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
connection.getStateInspector().assertValid();
} finally {
connection.close();
}
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project azure-iot-sdk-java by Azure.
the class AmqpsIotHubConnection method sendQueuedAcknowledgements.
private void sendQueuedAcknowledgements() {
while (!queuedAcknowledgements.isEmpty()) {
IotHubTransportMessage queuedAcknowledgement = queuedAcknowledgements.keySet().iterator().next();
IotHubMessageResult result = queuedAcknowledgements.get(queuedAcknowledgement);
queuedAcknowledgements.remove(queuedAcknowledgement);
DeliveryState ackType;
// Complete/Abandon/Reject is an IoTHub concept. For AMQP, they map to Accepted/Released/Rejected.
if (result == IotHubMessageResult.ABANDON) {
ackType = Released.getInstance();
} else if (result == IotHubMessageResult.REJECT) {
ackType = new Rejected();
} else if (result == IotHubMessageResult.COMPLETE) {
ackType = Accepted.getInstance();
} else {
log.warn("Invalid IoT Hub message result {}", result.name());
continue;
}
AmqpsSessionHandler sessionHandler = sessionHandlers.get(queuedAcknowledgement.getConnectionDeviceId());
if (sessionHandler != null && sessionHandler.acknowledgeReceivedMessage(queuedAcknowledgement, ackType)) {
continue;
}
log.warn("No sessions could acknowledge the message ({})", queuedAcknowledgement);
}
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project hono by eclipse.
the class TelemetryAndEventCli method printDelivery.
private void printDelivery(final ProtonDelivery delivery) {
final DeliveryState state = delivery.getRemoteState();
writer.printf("[Delivery State: %s] %n", state.getType()).flush();
switch(state.getType()) {
case Rejected:
final Rejected rejected = (Rejected) state;
if (rejected.getError() != null) {
writer.printf("Message rejected: [Error Condition: %s, Error Description: %s] %n", rejected.getError().getCondition(), rejected.getError().getDescription());
writer.flush();
}
break;
default:
break;
}
}
use of org.apache.qpid.proton.amqp.messaging.Rejected in project hono by eclipse.
the class CommandAndControlAmqpIT method testSendCommandFailsForCommandRejectedByDevice.
/**
* Verifies that the adapter forwards the <em>rejected</em> disposition, received from a device, back to the
* application.
* <p>
* If Kafka is used, this means a corresponding error command response is published.
*
* @param endpointConfig The endpoints to use for sending/receiving commands.
* @param ctx The vert.x test context.
* @throws InterruptedException if not all commands and responses are exchanged in time.
*/
@ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("allCombinations")
@Timeout(timeUnit = TimeUnit.SECONDS, value = 10)
public void testSendCommandFailsForCommandRejectedByDevice(final AmqpCommandEndpointConfiguration endpointConfig, final VertxTestContext ctx) throws InterruptedException {
final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId;
final int totalNoOfCommandsToSend = 3;
connectAndSubscribe(ctx, commandTargetDeviceId, endpointConfig, (cmdReceiver, cmdResponseSender) -> createRejectingCommandConsumer(ctx, cmdReceiver), totalNoOfCommandsToSend);
if (ctx.failed()) {
return;
}
final String replyId = "reply-id";
final CountDownLatch commandsFailed = new CountDownLatch(totalNoOfCommandsToSend);
final AtomicInteger commandsSent = new AtomicInteger(0);
final AtomicLong lastReceivedTimestamp = new AtomicLong();
final long start = System.currentTimeMillis();
final long commandTimeout = IntegrationTestSupport.getSendCommandTimeout();
final Handler<Void> failureNotificationReceivedHandler = v -> {
lastReceivedTimestamp.set(System.currentTimeMillis());
commandsFailed.countDown();
};
final VertxTestContext setup = new VertxTestContext();
final Future<MessageConsumer> kafkaAsyncErrorResponseConsumer = IntegrationTestSupport.isUsingKafkaMessaging() ? helper.createDeliveryFailureCommandResponseConsumer(ctx, tenantId, HttpURLConnection.HTTP_BAD_REQUEST, response -> {
ctx.verify(() -> {
DownstreamMessageAssertions.assertMessageContainsTimeToLive(response, TTL_COMMAND_RESPONSE);
});
failureNotificationReceivedHandler.handle(null);
}, REJECTED_COMMAND_ERROR_MESSAGE::equals) : Future.succeededFuture(null);
kafkaAsyncErrorResponseConsumer.onComplete(setup.succeedingThenComplete());
assertWithMessage("setup of command response consumer finished within %s seconds", IntegrationTestSupport.getTestSetupTimeout()).that(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
if (setup.failed()) {
ctx.failNow(setup.causeOfFailure());
return;
}
while (commandsSent.get() < totalNoOfCommandsToSend) {
final CountDownLatch commandSent = new CountDownLatch(1);
context.runOnContext(go -> {
final String correlationId = String.valueOf(commandsSent.getAndIncrement());
final Buffer msg = Buffer.buffer("value: " + commandsSent.get());
helper.applicationClient.sendAsyncCommand(tenantId, commandTargetDeviceId, "setValue", "text/plain", msg, correlationId, replyId, null).onComplete(sendAttempt -> {
if (IntegrationTestSupport.isUsingAmqpMessaging()) {
if (sendAttempt.succeeded()) {
log.info("sending command {} via AMQP succeeded unexpectedly", commandsSent.get());
} else {
if (sendAttempt.cause() instanceof ClientErrorException && ((ClientErrorException) sendAttempt.cause()).getErrorCode() == HttpURLConnection.HTTP_BAD_REQUEST && REJECTED_COMMAND_ERROR_MESSAGE.equals(sendAttempt.cause().getMessage())) {
log.debug("sending command {} failed as expected: {}", commandsSent.get(), sendAttempt.cause().toString());
failureNotificationReceivedHandler.handle(null);
} else {
log.info("sending command {} failed with an unexpected error", commandsSent.get(), sendAttempt.cause());
}
}
} else if (sendAttempt.failed()) {
log.debug("sending command {} via Kafka failed unexpectedly", commandsSent.get(), sendAttempt.cause());
}
commandSent.countDown();
});
});
commandSent.await();
}
final long timeToWait = 300 + (totalNoOfCommandsToSend * commandTimeout);
if (!commandsFailed.await(timeToWait, TimeUnit.MILLISECONDS)) {
log.info("Timeout of {} milliseconds reached, stop waiting for commands", timeToWait);
}
final long commandsCompleted = totalNoOfCommandsToSend - commandsFailed.getCount();
log.info("commands sent: {}, commands failed: {} after {} milliseconds", commandsSent.get(), commandsCompleted, lastReceivedTimestamp.get() - start);
Optional.ofNullable(kafkaAsyncErrorResponseConsumer.result()).map(MessageConsumer::close).orElseGet(Future::succeededFuture).onComplete(ar -> {
if (commandsCompleted == commandsSent.get()) {
ctx.completeNow();
} else {
ctx.failNow(new IllegalStateException("did not complete all commands sent"));
}
});
}
Aggregations