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;
}
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);
}
}
}
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);
}
}
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;
}
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);
}
}
Aggregations