if(!sender.sendQueueFull()) { final int msgNum = sent.incrementAndGet(); Message message = message("Hello " + msgNum);
/** * Settles and accepts the delivery by applying the ACCEPTED disposition state. * * @return The proton delivery. */ ProtonDelivery accept() { return ProtonHelper.accepted(delivery, true); }
/** * Create an ErrorCondition with the given error condition value (which will be converted to the required Symbol type) * and error description string. * * See {@link #condition(Symbol, String)} for more details. * * @param condition * the error condition value, to be converted to a Symbol * @param description * String description of the error, may be null * @return the condition */ public static ErrorCondition condition(String condition, String description) { return condition(Symbol.valueOf(condition), description); }
@Override public final void onLinkAttach(final ProtonConnection con, final ProtonSender sender, final ResourceIdentifier targetResource) { if (ProtonQoS.AT_LEAST_ONCE.equals(sender.getRemoteQoS())) { final HonoUser user = Constants.getClientPrincipal(con); sender.setQoS(ProtonQoS.AT_LEAST_ONCE).open(); logger.debug("transferring token to client..."); final Message tokenMsg = ProtonHelper.message(user.getToken()); MessageHelper.addProperty(tokenMsg, AuthenticationConstants.APPLICATION_PROPERTY_TYPE, AuthenticationConstants.TYPE_AMQP_JWT); sender.send(tokenMsg, disposition -> { if (disposition.remotelySettled()) { logger.debug("successfully transferred auth token to client"); } else { logger.debug("failed to transfer auth token to client"); } sender.close(); }); } else { onLinkDetach(sender, ProtonHelper.condition(AmqpError.INVALID_FIELD, "supports AT_LEAST_ONCE delivery mode only")); } }
try { processRequest(message, targetAddress, clientPrincipal); ProtonHelper.accepted(delivery, true); return Future.succeededFuture(); } catch (final DecodeException e) { message.getSubject(), t.getMessage()); MessageHelper.rejected(delivery, ProtonHelper.condition(AmqpError.INTERNAL_ERROR, "internal error"));
LOG.debug("discarding unexpected response [reply-to: {}, correlation ID: {}]", replyToAddress, message.getCorrelationId()); ProtonHelper.rejected(delivery, true); } else { final R response = getRequestResponseResult(message); replyToAddress, message.getCorrelationId()); TracingHelper.logError(span, "response from peer released (no status code)"); ProtonHelper.released(delivery, true); } else { LOG.debug("received response [reply-to: {}, subject: {}, correlation ID: {}, status: {}]", ProtonHelper.accepted(delivery, true);
private void createReceiver(Vertx vertx, String address, CompletableFuture<Void> promise, int retries) { receiver = connection.createReceiver(address); Source source = new Source(); source.setDynamic(true); receiver.setSource(source); receiver.openHandler(h -> { if (h.succeeded()) { context = vertx.getOrCreateContext(); replyTo = receiver.getRemoteSource().getAddress(); promise.complete(null); } else { if (retries > maxRetries) { promise.completeExceptionally(h.cause()); } else { log.info("Error creating receiver, retries = {}", retries); vertx.setTimer(1000, id -> createReceiver(vertx, address, promise, retries + 1)); } } }); receiver.handler(((protonDelivery, message) -> { try { replies.put(message); ProtonHelper.accepted(protonDelivery, true); } catch (Exception e) { ProtonHelper.rejected(protonDelivery, true); } })); receiver.open(); }
/** * Sets an AMQP 1.0 message delivery state to either RELEASED in the case of a <em>ServerErrorException</em> or REJECTED in the * case of a <em>ClientErrorException</em>. In the REJECTED case, the supplied exception will provide * the error condition value and description as reason for rejection. * * @param t The service invocation exception. * @throws NullPointerException if error is {@code null}. */ void handleFailure(final Throwable t) { Objects.requireNonNull(t); final ErrorCondition condition = getErrorCondition(t); if (ServiceInvocationException.class.isInstance(t)) { final ServiceInvocationException error = (ServiceInvocationException) t; if (ServerErrorException.class.isInstance(error)) { ProtonHelper.released(delivery, true); } else { MessageHelper.rejected(delivery, condition); } } else { MessageHelper.rejected(delivery, condition); } }
/** * Creates an ErrorCondition using the given throwable to provide an error condition value and * description. All throwables that are not service invocation exceptions will be mapped to {@link AmqpError#PRECONDITION_FAILED}. * * @param t The throwable to map to an error condition. * @return The ErrorCondition. */ static ErrorCondition getErrorCondition(final Throwable t) { if (ServiceInvocationException.class.isInstance(t)) { final ServiceInvocationException error = (ServiceInvocationException) t; switch (error.getErrorCode()) { case HttpURLConnection.HTTP_BAD_REQUEST: return ProtonHelper.condition(Constants.AMQP_BAD_REQUEST, error.getMessage()); case HttpURLConnection.HTTP_FORBIDDEN: return ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS, error.getMessage()); default: return ProtonHelper.condition(AmqpError.PRECONDITION_FAILED, error.getMessage()); } } else { return ProtonHelper.condition(AmqpError.PRECONDITION_FAILED, t.getMessage()); } } }
try { processRequest(message, targetAddress, clientPrincipal); ProtonHelper.accepted(delivery, true); return Future.succeededFuture(); } catch (final DecodeException e) { message.getSubject(), t.getMessage()); MessageHelper.rejected(delivery, ProtonHelper.condition(AmqpError.INTERNAL_ERROR, "internal error"));
/** * Settles the command message with the <em>released</em> outcome * and flows credit to the peer. * <p> * This method also finishes the OpenTracing span returned by * {@link #getCurrentSpan()}. * * @param credit The number of credits to flow to the peer. * @throws IllegalArgumentException if credit is negative. */ public void release(final int credit) { if (credit < 0) { throw new IllegalArgumentException("credit must be >= 0"); } ProtonHelper.released(delivery, true); currentSpan.log("released command for device"); currentSpan.log(Tags.ERROR.getKey()); if (credit > 0) { flow(credit); } currentSpan.finish(); }
int msgNum = sent.incrementAndGet(); System.out.println("Sending message " + msgNum + " to client, for address: " + remoteSource.getAddress()); Message m = message("Hello " + msgNum + " from Server!"); sender.send(m, delivery -> { System.out.println("Message " + msgNum + " was received by the client.");
/** * Gets an AMQP {@link ErrorCondition} based on this exception's error and description. * * @return The condition. */ public ErrorCondition asErrorCondition() { return ProtonHelper.condition(error.toString(), getMessage()); } }
protected void forwardMessage(final ProtonSender sender, final Message msg, final ProtonDelivery delivery) { ProtonHelper.accepted(delivery, true); sender.send(msg); }
/** * Creates a Message object with the given String contained as an AmqpValue body, and the 'to' address set as given. * * @param address * the 'to' address to set * @param body * the string to set as an AmqpValue body * @return the message */ public static Message message(String address, String body) { Message value = message(body); value.setAddress(address); return value; }
@Override protected void handleReceiverOpen(final ProtonConnection con, final ProtonReceiver receiver) { receiver.setCondition(ProtonHelper.condition(AmqpError.NOT_ALLOWED, "cannot write to node")); receiver.close(); }
/** * Settles the command message with the <em>accepted</em> outcome * and flows credit to the peer. * <p> * This method also finishes the OpenTracing span returned by * {@link #getCurrentSpan()}. * * @param credit The number of credits to flow to the peer. * @throws IllegalArgumentException if credit is negative. */ public void accept(final int credit) { if (credit < 0) { throw new IllegalArgumentException("credit must be >= 0"); } LOG.trace("accepting command message [{}]", getCommand()); ProtonHelper.accepted(delivery, true); currentSpan.log("accepted command for device"); if (credit > 0) { flow(credit); } currentSpan.finish(); }
/** * Return a raw AMQP message * * @return */ public Message toAmqp() { Message message = ProtonHelper.message(); message.setSubject(AMQP_SUBJECT); message.setCorrelationId(String.format(AmqpHelper.AMQP_CLIENT_PUBLISH_ADDRESS_TEMPLATE, this.clientId)); return message; }