Search in sources :

Example 11 with DispatchHandler

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

the class MessagingFactory method onClose.

@Override
protected CompletableFuture<Void> onClose() {
    if (!this.getIsClosed()) {
        TRACE_LOGGER.info("Closing messaging factory");
        CompletableFuture<Void> cbsLinkCloseFuture;
        if (this.cbsLink == null) {
            cbsLinkCloseFuture = CompletableFuture.completedFuture(null);
        } else {
            TRACE_LOGGER.info("Closing CBS link");
            cbsLinkCloseFuture = this.cbsLink.closeAsync();
        }
        cbsLinkCloseFuture.thenRun(() -> this.managementLinksCache.freeAsync()).thenRun(() -> {
            if (this.cbsLinkCreationFuture != null && !this.cbsLinkCreationFuture.isDone()) {
                this.cbsLinkCreationFuture.completeExceptionally(new Exception("Connection closed."));
            }
            if (this.connection != null && this.connection.getRemoteState() != EndpointState.CLOSED) {
                try {
                    this.scheduleOnReactorThread(new DispatchHandler() {

                        @Override
                        public void onEvent() {
                            if (MessagingFactory.this.connection != null && MessagingFactory.this.connection.getLocalState() != EndpointState.CLOSED) {
                                TRACE_LOGGER.info("Closing connection to host");
                                MessagingFactory.this.connection.close();
                            }
                        }
                    });
                } catch (IOException e) {
                    AsyncUtil.completeFutureExceptionally(this.connetionCloseFuture, e);
                }
                Timer.schedule(new Runnable() {

                    @Override
                    public void run() {
                        if (!MessagingFactory.this.connetionCloseFuture.isDone()) {
                            String errorMessage = "Closing MessagingFactory timed out.";
                            TRACE_LOGGER.warn(errorMessage);
                            MessagingFactory.this.connetionCloseFuture.completeExceptionally(new TimeoutException(errorMessage));
                        }
                    }
                }, this.clientSettings.getOperationTimeout(), TimerType.OneTimeRun);
            } else {
                this.connetionCloseFuture.complete(null);
                Timer.unregister(this.getClientId());
            }
        });
        return this.connetionCloseFuture;
    } else {
        return CompletableFuture.completedFuture(null);
    }
}
Also used : DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) IOException(java.io.IOException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) HandlerException(org.apache.qpid.proton.engine.HandlerException) UnresolvedAddressException(java.nio.channels.UnresolvedAddressException)

Example 12 with DispatchHandler

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

the class RequestResponseLink method completeRequestWithResponse.

private RequestResponseWorkItem completeRequestWithResponse(String requestId, Message responseMessage) {
    RequestResponseWorkItem workItem = this.pendingRequests.get(requestId);
    if (workItem != null) {
        int statusCode = RequestResponseUtils.getResponseStatusCode(responseMessage);
        TRACE_LOGGER.debug("Response for request with id:{} has status code:{}", requestId, statusCode);
        // Retry on server busy and other retry-able status codes (what are other codes??)
        if (statusCode == ClientConstants.REQUEST_RESPONSE_SERVER_BUSY_STATUS_CODE) {
            TRACE_LOGGER.warn("Request with id:{} received ServerBusy response from '{}'", requestId, this.linkPath);
            // error response
            Exception responseException = RequestResponseUtils.genereateExceptionFromResponse(responseMessage);
            this.underlyingFactory.getRetryPolicy().incrementRetryCount(this.getClientId());
            Duration retryInterval = this.underlyingFactory.getRetryPolicy().getNextRetryInterval(this.getClientId(), responseException, workItem.getTimeoutTracker().remaining());
            if (retryInterval == null) {
                // Either not retry-able or not enough time to retry
                TRACE_LOGGER.error("Request with id:{} cannot be retried. So completing with excetion.", requestId, responseException);
                this.exceptionallyCompleteRequest(requestId, responseException, false);
            } else {
                // Retry
                TRACE_LOGGER.info("Request with id:{} will be retried after {}.", requestId, retryInterval);
                workItem.setLastKnownException(responseException);
                try {
                    this.underlyingFactory.scheduleOnReactorThread((int) retryInterval.toMillis(), new DispatchHandler() {

                        @Override
                        public void onEvent() {
                            RequestResponseLink.this.amqpSender.sendRequest(workItem.getRequest(), true);
                        }
                    });
                } catch (IOException e) {
                    this.exceptionallyCompleteRequest(requestId, responseException, false);
                }
            }
        } else {
            TRACE_LOGGER.debug("Completing request with id:{}", requestId);
            this.underlyingFactory.getRetryPolicy().resetRetryCount(this.getClientId());
            this.pendingRequests.remove(requestId);
            workItem.getWork().complete(responseMessage);
            workItem.cancelTimeoutTask(true);
        }
    } else {
        TRACE_LOGGER.warn("Request with id:{} not found in the requestresponse link.", requestId);
    }
    return workItem;
}
Also used : DispatchHandler(com.microsoft.azure.servicebus.amqp.DispatchHandler) Duration(java.time.Duration) IOException(java.io.IOException) IOException(java.io.IOException)

Example 13 with DispatchHandler

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

the class RequestResponseLink method createAsync.

public static CompletableFuture<RequestResponseLink> createAsync(MessagingFactory messagingFactory, String linkName, String linkPath, String sasTokenAudienceURI) {
    final RequestResponseLink requestReponseLink = new RequestResponseLink(messagingFactory, linkName, linkPath, sasTokenAudienceURI);
    Timer.schedule(new Runnable() {

        public void run() {
            if (!requestReponseLink.createFuture.isDone()) {
                requestReponseLink.amqpSender.closeInternals(false);
                requestReponseLink.amqpReceiver.closeInternals(false);
                requestReponseLink.cancelSASTokenRenewTimer();
                Exception operationTimedout = new TimeoutException(String.format(Locale.US, "Open operation on RequestResponseLink(%s) on Entity(%s) timed out at %s.", requestReponseLink.getClientId(), requestReponseLink.linkPath, ZonedDateTime.now().toString()));
                TRACE_LOGGER.error("RequestResponseLink open timed out.", operationTimedout);
                requestReponseLink.createFuture.completeExceptionally(operationTimedout);
            }
        }
    }, messagingFactory.getOperationTimeout(), TimerType.OneTimeRun);
    requestReponseLink.sendTokenAndSetRenewTimer(false).handleAsync((v, sasTokenEx) -> {
        if (sasTokenEx != null) {
            Throwable cause = ExceptionUtil.extractAsyncCompletionCause(sasTokenEx);
            TRACE_LOGGER.error("Sending SAS Token failed. RequestResponseLink path:{}", requestReponseLink.linkPath, cause);
            requestReponseLink.createFuture.completeExceptionally(cause);
        } else {
            try {
                messagingFactory.scheduleOnReactorThread(new DispatchHandler() {

                    @Override
                    public void onEvent() {
                        requestReponseLink.createInternalLinks();
                    }
                });
            } catch (IOException ioException) {
                requestReponseLink.cancelSASTokenRenewTimer();
                requestReponseLink.createFuture.completeExceptionally(new ServiceBusException(false, "Failed to create internal links, see cause for more details.", ioException));
            }
        }
        return null;
    });
    CompletableFuture.allOf(requestReponseLink.amqpSender.openFuture, requestReponseLink.amqpReceiver.openFuture).handleAsync((v, ex) -> {
        if (ex == null) {
            TRACE_LOGGER.info("Opened requestresponselink to {}", requestReponseLink.linkPath);
            requestReponseLink.createFuture.complete(requestReponseLink);
        } else {
            requestReponseLink.cancelSASTokenRenewTimer();
            requestReponseLink.createFuture.completeExceptionally(ex);
        }
        return null;
    });
    return requestReponseLink.createFuture;
}
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