/// <summary> /// Adds a rule to the current subscription to filter the messages reaching from topic to the subscription. /// </summary> /// /// <param name="description">The rule description that provides the rule to add.</param> /// <param name="timeout">The per-try timeout specified in the RetryOptions.</param> /// /// <returns>A task instance that represents the asynchronous add rule operation.</returns> private async Task AddRuleInternalAsync( RuleProperties description, TimeSpan timeout) { // Create an AmqpRequest Message to add rule var amqpRequestMessage = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.AddRuleOperation, timeout, null); amqpRequestMessage.Map[ManagementConstants.Properties.RuleName] = description.Name; amqpRequestMessage.Map[ManagementConstants.Properties.RuleDescription] = AmqpMessageConverter.GetRuleDescriptionMap(description); AmqpResponseMessage response = await ManagementUtilities.ExecuteRequestResponseAsync( _connectionScope, _managementLink, amqpRequestMessage, null, timeout).ConfigureAwait(false); if (response.StatusCode != AmqpResponseStatusCode.OK) { throw response.ToMessagingContractException(); } }
/// <summary> /// /// </summary> /// <param name="sequenceNumber"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task CancelScheduledMessageInternalAsync( long sequenceNumber, TimeSpan timeout, CancellationToken cancellationToken = default) { var stopWatch = Stopwatch.StartNew(); var request = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.CancelScheduledMessageOperation, timeout, null); if (_sendLink.TryGetOpenedObject(out SendingAmqpLink sendLink)) { request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name; } request.Map[ManagementConstants.Properties.SequenceNumbers] = new[] { sequenceNumber }; AmqpResponseMessage amqpResponseMessage = await ManagementUtilities.ExecuteRequestResponseAsync( _connectionScope, _managementLink, request, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); stopWatch.Stop(); if (amqpResponseMessage.StatusCode != AmqpResponseStatusCode.OK) { throw amqpResponseMessage.ToMessagingContractException(); } }
/// <summary> /// /// </summary> /// <param name="sequenceNumbers"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task CancelScheduledMessageInternalAsync( long[] sequenceNumbers, TimeSpan timeout, CancellationToken cancellationToken = default) { var sendLink = default(SendingAmqpLink); try { var request = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.CancelScheduledMessageOperation, timeout, null); if (_sendLink.TryGetOpenedObject(out sendLink)) { request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name; } request.Map[ManagementConstants.Properties.SequenceNumbers] = sequenceNumbers; AmqpResponseMessage amqpResponseMessage = await ManagementUtilities.ExecuteRequestResponseAsync( _connectionScope, _managementLink, request, _transactionGroup, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); if (amqpResponseMessage.StatusCode != AmqpResponseStatusCode.OK) { throw amqpResponseMessage.ToMessagingContractException(); } } catch (Exception exception) { ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException( exception, sendLink?.GetTrackingId(), null, HasLinkCommunicationError(sendLink))) .Throw(); throw; // will never be reached } }
/// <summary> /// Removes the rule on the subscription identified by <paramref name="ruleName" />. /// </summary> /// /// <param name="ruleName">Name of the rule</param> /// <param name="timeout">The per-try timeout specified in the RetryOptions.</param> /// /// <returns>A task instance that represents the asynchronous remove rule operation.</returns> private async Task RemoveRuleInternalAsync( string ruleName, TimeSpan timeout) { // Create an AmqpRequest Message to remove rule var amqpRequestMessage = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.RemoveRuleOperation, timeout, null); amqpRequestMessage.Map[ManagementConstants.Properties.RuleName] = ruleName; AmqpResponseMessage response = await ManagementUtilities.ExecuteRequestResponseAsync( _connectionScope, _managementLink, amqpRequestMessage, timeout).ConfigureAwait(false); if (response.StatusCode != AmqpResponseStatusCode.OK) { throw response.ToMessagingContractException(); } }
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task <long> ScheduleMessageInternalAsync( ServiceBusMessage message, TimeSpan timeout, CancellationToken cancellationToken = default) { var stopWatch = Stopwatch.StartNew(); using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message)) { var request = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.ScheduleMessageOperation, timeout, null); if (_sendLink.TryGetOpenedObject(out SendingAmqpLink sendLink)) { request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name; } ArraySegment <byte>[] payload = amqpMessage.GetPayload(); var buffer = new BufferListStream(payload); ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length); var entry = new AmqpMap(); { entry[ManagementConstants.Properties.Message] = value; entry[ManagementConstants.Properties.MessageId] = message.MessageId; if (!string.IsNullOrWhiteSpace(message.SessionId)) { entry[ManagementConstants.Properties.SessionId] = message.SessionId; } if (!string.IsNullOrWhiteSpace(message.PartitionKey)) { entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey; } if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey)) { entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey; } } request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> { entry }; RequestResponseAmqpLink mgmtLink = await _managementLink.GetOrCreateAsync( UseMinimum(_connectionScope.SessionTimeout, timeout.CalculateRemaining(stopWatch.Elapsed))) .ConfigureAwait(false); using AmqpMessage response = await mgmtLink.RequestAsync( request.AmqpMessage, timeout.CalculateRemaining(stopWatch.Elapsed)) .ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); stopWatch.Stop(); AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(response); if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK) { var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers); if (sequenceNumbers == null || sequenceNumbers.Length < 1) { throw new ServiceBusException(true, "Could not schedule message successfully."); } return(sequenceNumbers[0]); } else { throw amqpResponseMessage.ToMessagingContractException(); } } }
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task <long> ScheduleMessageInternalAsync( ServiceBusMessage message, TimeSpan timeout, CancellationToken cancellationToken = default) { var sendLink = default(SendingAmqpLink); try { using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message)) { var request = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.ScheduleMessageOperation, timeout, null); if (_sendLink.TryGetOpenedObject(out sendLink)) { request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name; } ArraySegment <byte>[] payload = amqpMessage.GetPayload(); var buffer = new BufferListStream(payload); ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length); var entry = new AmqpMap(); { entry[ManagementConstants.Properties.Message] = value; entry[ManagementConstants.Properties.MessageId] = message.MessageId; if (!string.IsNullOrWhiteSpace(message.SessionId)) { entry[ManagementConstants.Properties.SessionId] = message.SessionId; } if (!string.IsNullOrWhiteSpace(message.PartitionKey)) { entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey; } if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey)) { entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey; } } request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> { entry }; AmqpResponseMessage amqpResponseMessage = await ManagementUtilities.ExecuteRequestResponseAsync( _connectionScope, _managementLink, request, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK) { var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers); if (sequenceNumbers == null || sequenceNumbers.Length < 1) { throw new ServiceBusException(true, "Could not schedule message successfully."); } return(sequenceNumbers[0]); } else { throw amqpResponseMessage.ToMessagingContractException(); } } } catch (Exception exception) { ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException( exception, sendLink?.GetTrackingId(), null, HasLinkCommunicationError(sendLink))) .Throw(); throw; // will never be reached } }