Search in sources :

Example 6 with DispatchHandler

use of com.microsoft.azure.servicebus.amqp.DispatchHandler in project azure-service-bus-java by Azure.

the class RequestResponseLink method recreateInternalLinks.

private CompletableFuture<Void> recreateInternalLinks() {
    TRACE_LOGGER.info("RequestResponseLink - recreating internal send and receive links to {}", this.linkPath);
    this.amqpSender.closeInternals(false);
    this.amqpReceiver.closeInternals(false);
    this.cancelSASTokenRenewTimer();
    // Create new internal sender and receiver objects, as old ones are closed
    this.amqpSender = new InternalSender(this.getClientId() + ":internalSender", this, this.amqpSender);
    this.amqpReceiver = new InternalReceiver(this.getClientId() + ":interalReceiver", this);
    CompletableFuture<Void> recreateInternalLinksFuture = new CompletableFuture<Void>();
    this.sendTokenAndSetRenewTimer(false).handleAsync((v, sasTokenEx) -> {
        if (sasTokenEx != null) {
            Throwable cause = ExceptionUtil.extractAsyncCompletionCause(sasTokenEx);
            TRACE_LOGGER.error("Sending SAS Token failed. RequestResponseLink path:{}", this.linkPath, cause);
            recreateInternalLinksFuture.completeExceptionally(cause);
        } else {
            try {
                this.underlyingFactory.scheduleOnReactorThread(new DispatchHandler() {

                    @Override
                    public void onEvent() {
                        RequestResponseLink.this.createInternalLinks();
                    }
                });
            } catch (IOException ioException) {
                this.cancelSASTokenRenewTimer();
                recreateInternalLinksFuture.completeExceptionally(new ServiceBusException(false, "Failed to create internal links, see cause for more details.", ioException));
            }
        }
        return null;
    });
    CompletableFuture.allOf(this.amqpSender.openFuture, this.amqpReceiver.openFuture).handleAsync((v, ex) -> {
        if (ex == null) {
            TRACE_LOGGER.info("Recreated internal links to {}", this.linkPath);
            recreateInternalLinksFuture.complete(null);
        } else {
            this.cancelSASTokenRenewTimer();
            recreateInternalLinksFuture.completeExceptionally(ex);
        }
        return null;
    });
    Timer.schedule(new Runnable() {

        public void run() {
            if (!recreateInternalLinksFuture.isDone()) {
                Exception operationTimedout = new TimeoutException(String.format(Locale.US, "Recreating internal links of requestresponselink to %s.", RequestResponseLink.this.linkPath));
                TRACE_LOGGER.warn("Recreating internal links of requestresponselink timed out.", operationTimedout);
                RequestResponseLink.this.cancelSASTokenRenewTimer();
                recreateInternalLinksFuture.completeExceptionally(operationTimedout);
            }
        }
    }, this.underlyingFactory.getOperationTimeout(), TimerType.OneTimeRun);
    return recreateInternalLinksFuture;
}
Also used : DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) IOException(java.io.IOException) IOException(java.io.IOException) CompletableFuture(java.util.concurrent.CompletableFuture)

Example 7 with DispatchHandler

use of com.microsoft.azure.servicebus.amqp.DispatchHandler in project azure-service-bus-java by Azure.

the class CoreMessageReceiver method setPrefetchCount.

public void setPrefetchCount(final int value) throws ServiceBusException {
    if (value < 0) {
        throw new IllegalArgumentException("Prefetch count cannot be negative.");
    }
    this.throwIfInUnusableState();
    final int deltaPrefetchCount;
    synchronized (this.prefetchCountSync) {
        deltaPrefetchCount = value - this.prefetchCount;
        this.prefetchCount = value;
        TRACE_LOGGER.info("Setting prefetch count to '{}' on recieve link to '{}'", value, this.receivePath);
    }
    if (deltaPrefetchCount > 0) {
        try {
            this.underlyingFactory.scheduleOnReactorThread(new DispatchHandler() {

                @Override
                public void onEvent() {
                    sendFlow(deltaPrefetchCount);
                }
            });
        } catch (IOException ioException) {
            throw new ServiceBusException(false, "Setting prefetch count failed, see cause for more details", ioException);
        }
    }
}
Also used : DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) IOException(java.io.IOException)

Example 8 with DispatchHandler

use of com.microsoft.azure.servicebus.amqp.DispatchHandler in project azure-service-bus-java by Azure.

the class CoreMessageReceiver method ensureLinkIsOpen.

private synchronized CompletableFuture<Void> ensureLinkIsOpen() {
    // Send SAS token before opening a link as connection might have been closed and reopened
    if (this.receiveLink.getLocalState() == EndpointState.CLOSED || this.receiveLink.getRemoteState() == EndpointState.CLOSED) {
        if (this.receiveLinkReopenFuture == null) {
            TRACE_LOGGER.info("Recreating receive link to '{}'", this.receivePath);
            this.retryPolicy.incrementRetryCount(this.getClientId());
            this.receiveLinkReopenFuture = new CompletableFuture<Void>();
            // Variable just to be closed over by the scheduled runnable. The runnable should cancel only the closed over future, not the parent's instance variable which can change
            final CompletableFuture<Void> linkReopenFutureThatCanBeCancelled = this.receiveLinkReopenFuture;
            Timer.schedule(() -> {
                if (!linkReopenFutureThatCanBeCancelled.isDone()) {
                    CoreMessageReceiver.this.cancelSASTokenRenewTimer();
                    Exception operationTimedout = new TimeoutException(String.format(Locale.US, "%s operation on ReceiveLink(%s) to path(%s) timed out at %s.", "Open", CoreMessageReceiver.this.receiveLink.getName(), CoreMessageReceiver.this.receivePath, ZonedDateTime.now()));
                    TRACE_LOGGER.warn(operationTimedout.getMessage());
                    linkReopenFutureThatCanBeCancelled.completeExceptionally(operationTimedout);
                }
            }, CoreMessageReceiver.LINK_REOPEN_TIMEOUT, TimerType.OneTimeRun);
            this.cancelSASTokenRenewTimer();
            this.sendTokenAndSetRenewTimer(false).handleAsync((v, sendTokenEx) -> {
                if (sendTokenEx != null) {
                    this.receiveLinkReopenFuture.completeExceptionally(sendTokenEx);
                } else {
                    try {
                        this.underlyingFactory.scheduleOnReactorThread(new DispatchHandler() {

                            @Override
                            public void onEvent() {
                                CoreMessageReceiver.this.createReceiveLink();
                            }
                        });
                    } catch (IOException ioEx) {
                        this.receiveLinkReopenFuture.completeExceptionally(ioEx);
                    }
                }
                return null;
            });
        }
        return this.receiveLinkReopenFuture;
    } else {
        return CompletableFuture.completedFuture(null);
    }
}
Also used : DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) IOException(java.io.IOException) IOException(java.io.IOException)

Example 9 with DispatchHandler

use of com.microsoft.azure.servicebus.amqp.DispatchHandler in project azure-service-bus-java by Azure.

the class CoreMessageReceiver method updateMessageStateAsync.

private CompletableFuture<Void> updateMessageStateAsync(byte[] deliveryTag, Outcome outcome) {
    this.throwIfInUnusableState();
    CompletableFuture<Void> completeMessageFuture = new CompletableFuture<Void>();
    String deliveryTagAsString = StringUtil.convertBytesToString(deliveryTag);
    TRACE_LOGGER.debug("Updating message state of delivery '{}' to '{}'", deliveryTagAsString, outcome);
    Delivery delivery = CoreMessageReceiver.this.tagsToDeliveriesMap.get(deliveryTagAsString);
    if (delivery == null) {
        TRACE_LOGGER.error("Delivery not found for delivery tag '{}'. Either receive link to '{}' closed with a transient error and reopened or the delivery was already settled by complete/abandon/defer/deadletter.", deliveryTagAsString, this.receivePath);
        AsyncUtil.completeFutureExceptionally(completeMessageFuture, generateDeliveryNotFoundException());
    } else {
        final UpdateStateWorkItem workItem = new UpdateStateWorkItem(completeMessageFuture, outcome, CoreMessageReceiver.this.factoryRceiveTimeout);
        CoreMessageReceiver.this.pendingUpdateStateRequests.put(deliveryTagAsString, workItem);
        CoreMessageReceiver.this.ensureLinkIsOpen().thenRunAsync(() -> {
            try {
                this.underlyingFactory.scheduleOnReactorThread(new DispatchHandler() {

                    @Override
                    public void onEvent() {
                        delivery.disposition((DeliveryState) outcome);
                    }
                });
            } catch (IOException ioException) {
                completeMessageFuture.completeExceptionally(generateDispatacherSchedulingFailedException("completeMessage", ioException));
            }
        });
    }
    return completeMessageFuture;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) Delivery(org.apache.qpid.proton.engine.Delivery) IOException(java.io.IOException)

Example 10 with DispatchHandler

use of com.microsoft.azure.servicebus.amqp.DispatchHandler in project azure-service-bus-java by Azure.

the class CoreMessageSender method ensureLinkIsOpen.

private synchronized CompletableFuture<Void> ensureLinkIsOpen() {
    // Send SAS token before opening a link as connection might have been closed and reopened
    if (this.sendLink.getLocalState() == EndpointState.CLOSED || this.sendLink.getRemoteState() == EndpointState.CLOSED) {
        if (this.sendLinkReopenFuture == null) {
            TRACE_LOGGER.info("Recreating send link to '{}'", this.sendPath);
            this.retryPolicy.incrementRetryCount(CoreMessageSender.this.getClientId());
            this.sendLinkReopenFuture = new CompletableFuture<Void>();
            // Variable just to closed over by the scheduled runnable. The runnable should cancel only the closed over future, not the parent's instance variable which can change
            final CompletableFuture<Void> linkReopenFutureThatCanBeCancelled = this.sendLinkReopenFuture;
            Timer.schedule(() -> {
                if (!linkReopenFutureThatCanBeCancelled.isDone()) {
                    CoreMessageSender.this.cancelSASTokenRenewTimer();
                    Exception operationTimedout = new TimeoutException(String.format(Locale.US, "%s operation on SendLink(%s) to path(%s) timed out at %s.", "Open", CoreMessageSender.this.sendLink.getName(), CoreMessageSender.this.sendPath, ZonedDateTime.now()));
                    TRACE_LOGGER.warn(operationTimedout.getMessage());
                    linkReopenFutureThatCanBeCancelled.completeExceptionally(operationTimedout);
                }
            }, CoreMessageSender.LINK_REOPEN_TIMEOUT, TimerType.OneTimeRun);
            this.cancelSASTokenRenewTimer();
            this.sendTokenAndSetRenewTimer(false).handleAsync((v, sendTokenEx) -> {
                if (sendTokenEx != null) {
                    this.sendLinkReopenFuture.completeExceptionally(sendTokenEx);
                } else {
                    try {
                        this.underlyingFactory.scheduleOnReactorThread(new DispatchHandler() {

                            @Override
                            public void onEvent() {
                                CoreMessageSender.this.createSendLink();
                            }
                        });
                    } catch (IOException ioEx) {
                        this.sendLinkReopenFuture.completeExceptionally(ioEx);
                    }
                }
                return null;
            });
        }
        return this.sendLinkReopenFuture;
    } else {
        return CompletableFuture.completedFuture(null);
    }
}
Also used : DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) IOException(java.io.IOException) IOException(java.io.IOException)

Aggregations

DispatchHandler (com.microsoft.azure.servicebus.amqp.DispatchHandler)13 IOException (java.io.IOException)13 CompletableFuture (java.util.concurrent.CompletableFuture)3 Duration (java.time.Duration)2 DeliveryState (org.apache.qpid.proton.amqp.transport.DeliveryState)2 UnresolvedAddressException (java.nio.channels.UnresolvedAddressException)1 ExecutionException (java.util.concurrent.ExecutionException)1 Outcome (org.apache.qpid.proton.amqp.messaging.Outcome)1 Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)1 Released (org.apache.qpid.proton.amqp.messaging.Released)1 ErrorCondition (org.apache.qpid.proton.amqp.transport.ErrorCondition)1 Delivery (org.apache.qpid.proton.engine.Delivery)1 HandlerException (org.apache.qpid.proton.engine.HandlerException)1 Message (org.apache.qpid.proton.message.Message)1