/** * Closes an AMQP link and frees up its allocated resources. * <p> * This method simply invokes {@link #closeAndFree(Context, ProtonLink, long, Handler)} with * the {@linkplain #DEFAULT_FREE_LINK_AFTER_CLOSE_INTERVAL_MILLIS default time-out value}. * * @param context The vert.x context to run on. * @param link The link to close. If {@code null}, the given handler is invoked immediately. * @param closeHandler The handler to notify once the link has been closed. * @throws NullPointerException if context or close handler are {@code null}. */ public static void closeAndFree( final Context context, final ProtonLink<?> link, final Handler<Void> closeHandler) { closeAndFree(context, link, DEFAULT_FREE_LINK_AFTER_CLOSE_INTERVAL_MILLIS, closeHandler); }
/** * Executes some code on the vert.x Context that has been used to establish the * connection to the peer. * * @param <T> The type of the result that the code produces. * @param codeToRun The code to execute. The code is required to either complete or * fail the future that is passed into the handler. * @return The future passed into the handler for executing the code. The future * thus indicates the outcome of executing the code. */ protected final <T> Future<T> executeOrRunOnContext( final Handler<Future<T>> codeToRun) { return HonoProtonHelper.executeOrRunOnContext(context, codeToRun); }
Objects.requireNonNull(messageHandler); return HonoProtonHelper.executeOrRunOnContext(ctx, result -> { final ProtonReceiver receiver = con.createReceiver(sourceAddress); receiver.setAutoAccept(true); result.tryFail(StatusCodeMapper.from(error)); } else if (HonoProtonHelper.isLinkEstablished(receiver)) { LOG.debug("receiver open [source: {}]", sourceAddress); result.tryComplete(recvOpen.result()); HonoProtonHelper.setDetachHandler(receiver, remoteDetached -> onRemoteDetach(receiver, con.getRemoteContainer(), false, remoteCloseHook)); HonoProtonHelper.setCloseHandler(receiver, remoteClosed -> onRemoteDetach(receiver, con.getRemoteContainer(), true, remoteCloseHook)); receiver.open(); ctx.owner().setTimer(clientConfig.getLinkEstablishmentTimeout(), tid -> onTimeOut(receiver, clientConfig, result));
private Future<MessageConsumer> openCommandSenderLink( final ProtonSender sender, final ResourceIdentifier address, final Device authenticatedDevice, final Span span) { return createCommandConsumer(sender, address).map(consumer -> { final String tenantId = address.getTenantId(); final String deviceId = address.getResourceId(); sender.setSource(sender.getRemoteSource()); sender.setTarget(sender.getRemoteTarget()); sender.setQoS(ProtonQoS.AT_LEAST_ONCE); final Handler<AsyncResult<ProtonSender>> detachHandler = link -> { final Span detachHandlerSpan = newSpan("detach Command receiver", authenticatedDevice); sendDisconnectedTtdEvent(tenantId, deviceId, authenticatedDevice, detachHandlerSpan.context()); consumer.close(null); onLinkDetach(sender); detachHandlerSpan.finish(); }; HonoProtonHelper.setCloseHandler(sender, detachHandler); HonoProtonHelper.setDetachHandler(sender, detachHandler); sender.open(); // At this point, the remote peer's receiver link is successfully opened and is ready to receive // commands. Send "device ready for command" notification downstream. LOG.debug("established link [address: {}] for sending commands to device", address); sendConnectedTtdEvent(tenantId, deviceId, authenticatedDevice, span.context()); return consumer; }).otherwise(t -> { throw new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "cannot create command consumer"); }); }
handleMessage(con, receiver, targetAddress, delivery, message); }); HonoProtonHelper.setCloseHandler(receiver, clientDetached -> onLinkDetach(receiver));
HonoProtonHelper.setDefaultCloseHandler(session); handleSessionOpen(connection, session); }); connection.receiverOpenHandler(receiver -> { HonoProtonHelper.setDefaultCloseHandler(receiver); handleReceiverOpen(connection, receiver); }); connection.senderOpenHandler(sender -> { HonoProtonHelper.setDefaultCloseHandler(sender); handleSenderOpen(connection, sender); });
private static void onTimeOut( final ProtonLink<?> link, final ClientConfigProperties clientConfig, final Future<?> result) { if (link.isOpen() && !HonoProtonHelper.isLinkEstablished(link)) { LOG.debug("link establishment timed out after {}ms", clientConfig.getLinkEstablishmentTimeout()); link.close(); link.free(); result.tryFail(new ServerErrorException(HttpsURLConnection.HTTP_UNAVAILABLE)); } }
Objects.requireNonNull(qos); return HonoProtonHelper.executeOrRunOnContext(ctx, result -> { } else if (HonoProtonHelper.isLinkEstablished(sender)) { HonoProtonHelper.setDetachHandler(sender, remoteDetached -> onRemoteDetach(sender, con.getRemoteContainer(), false, closeHook)); HonoProtonHelper.setCloseHandler(sender, remoteClosed -> onRemoteDetach(sender, con.getRemoteContainer(), true, closeHook)); sender.open(); ctx.owner().setTimer(clientConfig.getLinkEstablishmentTimeout(), tid -> onTimeOut(sender, clientConfig, result));
HonoProtonHelper.setCloseHandler(receiver, remoteDetach -> onLinkDetach(receiver)); HonoProtonHelper.setDetachHandler(receiver, remoteDetach -> onLinkDetach(receiver)); receiver.handler((delivery, message) -> {
handleMessage(con, receiver, targetAddress, delivery, message); }); HonoProtonHelper.setCloseHandler(receiver, clientDetached -> onLinkDetach(receiver));
HonoProtonHelper.setDefaultCloseHandler(session); handleSessionOpen(connection, session); }); connection.receiverOpenHandler(receiver -> { HonoProtonHelper.setDefaultCloseHandler(receiver); handleReceiverOpen(connection, receiver); }); connection.senderOpenHandler(sender -> { HonoProtonHelper.setDefaultCloseHandler(sender); handleSenderOpen(connection, sender); });
private static void onRemoteDetach( final ProtonLink<?> link, final String remoteContainer, final boolean closed, final Handler<String> closeHook) { final ErrorCondition error = link.getRemoteCondition(); final String type = link instanceof ProtonSender ? "sender" : "receiver"; final String address = link instanceof ProtonSender ? link.getTarget().getAddress() : link.getSource().getAddress(); if (error == null) { LOG.debug("{} [{}] detached (with closed={}) by peer [{}]", type, address, closed, remoteContainer); } else { LOG.debug("{} [{}] detached (with closed={}) by peer [{}]: {} - {}", type, address, closed, remoteContainer, error.getCondition(), error.getDescription()); } link.close(); if (HonoProtonHelper.isLinkEstablished(link) && closeHook != null) { closeHook.handle(address); } } }
HonoProtonHelper.setCloseHandler(sender, senderClosed -> { logger.debug("client [{}] closed sender link, removing associated event bus consumer [{}]", sender.getName(), replyConsumer.address());
/** * Executes some code on the vert.x Context that has been used to establish the * connection to the peer. * * @param <T> The type of the result that the code produces. * @param codeToRun The code to execute. The code is required to either complete or * fail the future that is passed into the handler. * @return The future passed into the handler for executing the code. The future * thus indicates the outcome of executing the code. The future will * be failed with a {@link ServerErrorException} if the <em>context</em> * property is {@code null}. */ protected final <T> Future<T> executeOrRunOnContext(final Handler<Future<T>> codeToRun) { if (context == null) { // this means that the connection to the peer is not established (yet) return Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "not connected")); } else { return HonoProtonHelper.executeOrRunOnContext(context, codeToRun); } }
/** * Closes an AMQP link and frees up its allocated resources. * <p> * This method simply invokes {@link #closeAndFree(Context, ProtonLink, long, Handler)} with * the {@linkplain #DEFAULT_FREE_LINK_AFTER_CLOSE_INTERVAL_MILLIS default time-out value}. * * @param context The vert.x context to run on. * @param link The link to close. If {@code null}, the given handler is invoked immediately. * @param closeHandler The handler to notify once the link has been closed. * @throws NullPointerException if context or close handler are {@code null}. */ public static void closeAndFree( final Context context, final ProtonLink<?> link, final Handler<Void> closeHandler) { closeAndFree(context, link, DEFAULT_FREE_LINK_AFTER_CLOSE_INTERVAL_MILLIS, closeHandler); }
HonoProtonHelper.setDefaultCloseHandler(session); handleSessionOpen(con, session); }); HonoProtonHelper.setDefaultCloseHandler(receiver); receiver.setMaxMessageSize(UnsignedLong.valueOf(getConfig().getMaxPayloadSize())); handleRemoteReceiverOpen(con, receiver);
HonoProtonHelper.setCloseHandler(sender, senderClosed -> { logger.debug("client [{}] closed sender link, removing associated event bus consumer [{}]", sender.getName(), replyConsumer.address());
executeOrRunOnContext(context, result -> {
/** * Closes this client's sender and receiver links to Hono. * Link resources will be freed after the links are closed. * * @param closeHandler The handler to notify once the link has been closed. * @throws NullPointerException if the given handler is {@code null}. */ protected final void closeLinks(final Handler<Void> closeHandler) { Objects.requireNonNull(closeHandler); if (sender != null) { LOG.debug("locally closing sender link [{}]", sender.getTarget().getAddress()); } HonoProtonHelper.closeAndFree(context, sender, senderClosed -> { if (receiver != null) { LOG.debug("locally closing receiver link [{}]", receiver.getSource().getAddress()); } HonoProtonHelper.closeAndFree(context, receiver, receiverClosed -> closeHandler.handle(null)); }); }
executeOrRunOnContext(context, result -> {