public override TransportReceiver CreateReceiver(string entityPath, ServiceBusRetryPolicy retryPolicy, ServiceBusReceiveMode receiveMode, uint prefetchCount, string identifier, string sessionId, bool isSessionReceiver, bool isProcessor, CancellationToken cancellationToken) { throw new NotImplementedException(); }
/// <summary> /// Initializes a new instance of the <see cref="AmqpSender"/> class. /// </summary> /// /// <param name="entityPath">The name of the entity to which messages will be sent.</param> /// <param name="connectionScope">The AMQP connection context for operations.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpSender( string entityPath, AmqpConnectionScope connectionScope, ServiceBusRetryPolicy retryPolicy) { Argument.AssertNotNullOrEmpty(entityPath, nameof(entityPath)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); _entityPath = entityPath; _retryPolicy = retryPolicy; _connectionScope = connectionScope; _sendLink = new FaultTolerantAmqpObject <SendingAmqpLink>( timeout => CreateLinkAndEnsureSenderStateAsync(timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); }); _managementLink = new FaultTolerantAmqpObject <RequestResponseAmqpLink>( timeout => _connectionScope.OpenManagementLinkAsync( _entityPath, timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); }); }
/// <summary> /// Creates a receiver strongly aligned with the active protocol and transport, responsible /// for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity. /// </summary> /// <param name="entityPath">The entity path to receive from.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="receiveMode">The <see cref="ServiceBusReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="identifier">The identifier for the sender.</param> /// <param name="sessionId">The session ID to receive messages for.</param> /// <param name="isSessionReceiver">Whether or not this is a sessionful receiver link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the /// open link operation. Only applicable for session receivers.</param> /// /// <returns>A <see cref="TransportReceiver" /> configured in the requested manner.</returns> public override TransportReceiver CreateReceiver( string entityPath, ServiceBusRetryPolicy retryPolicy, ServiceBusReceiveMode receiveMode, uint prefetchCount, string identifier, string sessionId, bool isSessionReceiver, CancellationToken cancellationToken) { Argument.AssertNotDisposed(_closed, nameof(AmqpClient)); return(new AmqpReceiver ( entityPath, receiveMode, prefetchCount, ConnectionScope, retryPolicy, identifier, sessionId, isSessionReceiver, cancellationToken )); }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity. /// </summary> /// <param name="entityName"></param> /// /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="sessionId"></param> /// <param name="isSessionReceiver"></param> /// /// <returns>A <see cref="TransportReceiver" /> configured in the requested manner.</returns> /// public abstract TransportReceiver CreateReceiver( string entityName, ServiceBusRetryPolicy retryPolicy, ReceiveMode receiveMode, uint prefetchCount, string sessionId, bool isSessionReceiver);
/// <summary> /// /// </summary> /// <param name="retryPolicy"></param> /// <param name="fromSequenceNumber"></param> /// <param name="messageCount"></param> /// <param name="sessionId"></param> /// <param name="receiveLinkName"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override async Task <IEnumerable <ServiceBusMessage> > PeekAsync( ServiceBusRetryPolicy retryPolicy, long?fromSequenceNumber, int messageCount = 1, string sessionId = null, string receiveLinkName = null, CancellationToken cancellationToken = default) { IEnumerable <ServiceBusMessage> messages = null; Task peekTask = retryPolicy.RunOperation(async(timeout) => { messages = await PeekInternal( retryPolicy, fromSequenceNumber, messageCount, sessionId, receiveLinkName, timeout, cancellationToken).ConfigureAwait(false); }, EntityName, ConnectionScope, cancellationToken); await peekTask.ConfigureAwait(false); return(messages); }
///// <summary> ///// The converter to use for translating between AMQP messages and client library ///// types. ///// </summary> //private AmqpMessageConverter MessageConverter { get; } ///// <summary> ///// The AMQP connection scope responsible for managing transport constructs for this instance. ///// </summary> ///// //internal AmqpConnectionScope ConnectionScope { get; } ///// <summary> ///// The AMQP link intended for use with receiving operations. ///// </summary> ///// //internal FaultTolerantAmqpObject<ReceivingAmqpLink> ReceiveLink { get; } /// <summary> /// Initializes a new instance of the <see cref="AmqpConsumer"/> class. /// </summary> /// /// <param name="entityName">The name of the Service Bus entity from which events will be consumed.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="connectionScope">The AMQP connection context for operations .</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// <param name="sessionId"></param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpConsumer( string entityName, long?ownerLevel, uint?prefetchCount, AmqpConnectionScope connectionScope, ServiceBusRetryPolicy retryPolicy, string sessionId) { Argument.AssertNotNullOrEmpty(entityName, nameof(entityName)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); EntityName = entityName; ConnectionScope = connectionScope; RetryPolicy = retryPolicy; ReceiveLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>( timeout => ConnectionScope.OpenConsumerLinkAsync( //consumerGroup, //partitionId, timeout, prefetchCount ?? DefaultPrefetchCount, ownerLevel, sessionId, CancellationToken.None), link => { CloseLink(link); }); }
/// <summary> /// Initializes a new instance of the <see cref="AmqpConsumer"/> class. /// </summary> /// /// <param name="entityName">The name of the Service Bus entity from which events will be consumed.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param> /// <param name="connectionScope">The AMQP connection context for operations .</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// <param name="sessionId"></param> /// <param name="isSessionReceiver"></param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpConsumer( string entityName, ReceiveMode receiveMode, uint?prefetchCount, AmqpConnectionScope connectionScope, ServiceBusRetryPolicy retryPolicy, string sessionId, bool isSessionReceiver) { Argument.AssertNotNullOrEmpty(entityName, nameof(entityName)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); EntityName = entityName; _connectionScope = connectionScope; _retryPolicy = retryPolicy; _isSessionReceiver = isSessionReceiver; _receiveMode = receiveMode; ReceiveLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>( timeout => _connectionScope.OpenConsumerLinkAsync( timeout: timeout, prefetchCount: prefetchCount ?? DefaultPrefetchCount, receiveMode: receiveMode, sessionId: sessionId, isSessionReceiver: isSessionReceiver, cancellationToken: CancellationToken.None), link => { CloseLink(link); }); }
/// <summary> /// /// </summary> /// <param name="retryPolicy"></param> /// <param name="fromSequenceNumber"></param> /// <param name="messageCount"></param> /// <param name="sessionId"></param> /// <param name="receiveLinkName"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override async Task <IEnumerable <ServiceBusMessage> > PeekAsync( ServiceBusRetryPolicy retryPolicy, long?fromSequenceNumber, int messageCount = 1, string sessionId = null, string receiveLinkName = null, CancellationToken cancellationToken = default) { RetriableContext context = new RetriableContext( ConnectionScope, new Stopwatch(), retryPolicy, EntityName, cancellationToken); return(await context.RunOperation( async() => await PeekInternal( context, fromSequenceNumber, messageCount, sessionId, receiveLinkName) .ConfigureAwait(false)) .ConfigureAwait(false)); }
/// <summary> /// /// </summary> /// <param name="retryPolicy"></param> /// <param name="fromSequenceNumber"></param> /// <param name="messageCount"></param> /// <param name="sessionId"></param> /// <param name="receiveLinkName"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public abstract Task <IEnumerable <ServiceBusMessage> > PeekAsync( ServiceBusRetryPolicy retryPolicy, long?fromSequenceNumber, int messageCount = 1, string sessionId = null, string receiveLinkName = null, CancellationToken cancellationToken = default);
/// <summary> /// Initializes a new instance of the <see cref="AmqpRuleManager"/> class. /// </summary> /// /// <param name="subscriptionPath">The path of the Service Bus subscription to which the rule manager is bound.</param> /// <param name="connectionScope">The AMQP connection context for operations.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// <param name="identifier">The identifier for the rule manager.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> public AmqpRuleManager( string subscriptionPath, AmqpConnectionScope connectionScope, ServiceBusRetryPolicy retryPolicy, string identifier) { Argument.AssertNotNullOrEmpty(subscriptionPath, nameof(subscriptionPath)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); _subscriptionPath = subscriptionPath; _connectionScope = connectionScope; _retryPolicy = retryPolicy; _identifier = identifier; _managementLink = new FaultTolerantAmqpObject <RequestResponseAmqpLink>( timeout => _connectionScope.OpenManagementLinkAsync( _subscriptionPath, _identifier, timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); }); }
public abstract TransportReceiver CreateReceiver( string entityPath, ServiceBusRetryPolicy retryPolicy, ServiceBusReceiveMode receiveMode, uint prefetchCount, string identifier, string sessionId, bool isSessionReceiver, string transactionGroup);
public abstract TransportReceiver CreateReceiver(string entityPath, ServiceBusRetryPolicy retryPolicy, ServiceBusReceiveMode receiveMode, uint prefetchCount, string identifier, string sessionId, bool isSessionReceiver, bool isProcessor, CancellationToken cancellationToken);
/// <summary> /// Creates a producer strongly aligned with the active protocol and transport, /// responsible for publishing <see cref="ServiceBusMessage" /> to the Service Bus entity. /// </summary> /// /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns> /// public override TransportSender CreateSender(ServiceBusRetryPolicy retryPolicy) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpSender ( EntityName, ConnectionScope, retryPolicy )); }
/// <summary> /// Creates a rule manager strongly aligned with the active protocol and transport, /// responsible for adding, removing and getting rules from the Service Bus subscription. /// </summary> /// /// <param name="subscriptionPath">The path of the Service Bus subscription to which the rule manager is bound.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportRuleManager"/> configured in the requested manner.</returns> public override TransportRuleManager CreateRuleManager( string subscriptionPath, ServiceBusRetryPolicy retryPolicy) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpRuleManager ( subscriptionPath, ConnectionScope, retryPolicy )); }
public RetriableContext( AmqpConnectionScope scope, Stopwatch stopwatch, ServiceBusRetryPolicy retryPolicy, string entityName, CancellationToken cancellationToken) { Scope = scope; Stopwatch = stopwatch; RetryPolicy = retryPolicy; TimeSpan = retryPolicy.CalculateTryTimeout(0); CancellationToken = cancellationToken; EntityName = entityName; }
/// <summary> /// Creates a producer strongly aligned with the active protocol and transport, /// responsible for publishing <see cref="ServiceBusMessage" /> to the Service Bus entity. /// </summary> /// /// <param name="entityPath">The entity path to send the message to.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="identifier">The identifier for the sender.</param> /// /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns> public override TransportSender CreateSender( string entityPath, ServiceBusRetryPolicy retryPolicy, string identifier) { Argument.AssertNotDisposed(_closed, nameof(AmqpClient)); return(new AmqpSender ( entityPath, ConnectionScope, retryPolicy, identifier )); }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity partition, in the context /// of a specific consumer group. /// /// A consumer may be exclusive, which asserts ownership over the partition for the consumer /// group to ensure that only one consumer from that group is reading the from the partition. /// These exclusive consumers are sometimes referred to as "Epoch Consumers." /// /// A consumer may also be non-exclusive, allowing multiple consumers from the same consumer /// group to be actively reading events from the partition. These non-exclusive consumers are /// sometimes referred to as "Non-epoch Consumers." /// /// Designating a consumer as exclusive may be specified by setting the <paramref name="ownerLevel" />. /// When <c>null</c>, consumers are created as non-exclusive. /// </summary> /// /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="sessionId"></param> /// /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns> /// public override TransportConsumer CreateConsumer(ServiceBusRetryPolicy retryPolicy, long?ownerLevel, uint?prefetchCount, string sessionId = default) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpConsumer ( EntityName, ownerLevel, prefetchCount, ConnectionScope, retryPolicy, sessionId )); }
/// <summary> /// /// </summary> /// <param name="sequenceNumber"></param> /// <param name="retryPolicy"></param> /// <param name="receiveLinkName"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task CancelScheduledMessageInternal( long sequenceNumber, ServiceBusRetryPolicy retryPolicy, string receiveLinkName, TimeSpan timeout, CancellationToken cancellationToken = default) { var stopWatch = Stopwatch.StartNew(); var request = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.CancelScheduledMessageOperation, timeout, null); if (receiveLinkName != null) { request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = receiveLinkName; } request.Map[ManagementConstants.Properties.SequenceNumbers] = new[] { sequenceNumber }; RequestResponseAmqpLink link = await ManagementLink.GetOrCreateAsync( UseMinimum(ConnectionScope.SessionTimeout, timeout.CalculateRemaining(stopWatch.Elapsed))) .ConfigureAwait(false); using AmqpMessage response = await link.RequestAsync( request.AmqpMessage, timeout.CalculateRemaining(stopWatch.Elapsed)) .ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); stopWatch.Stop(); AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(response); if (amqpResponseMessage.StatusCode != AmqpResponseStatusCode.OK) { throw new Exception(); //throw response.ToMessagingContractException(); } return; }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity. /// </summary> /// /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="sessionId"></param> /// <param name="isSessionReceiver"></param> /// /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns> /// public override TransportConsumer CreateConsumer(ServiceBusRetryPolicy retryPolicy, ReceiveMode receiveMode, uint?prefetchCount, string sessionId, bool isSessionReceiver) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpConsumer ( EntityName, receiveMode, prefetchCount, ConnectionScope, retryPolicy, sessionId, isSessionReceiver )); }
/// <summary> /// /// </summary> /// <param name="sequenceNumber"></param> /// <param name="retryPolicy"></param> /// <param name="receiveLinkName"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override async Task CancelScheduledMessageAsync( long sequenceNumber, ServiceBusRetryPolicy retryPolicy, string receiveLinkName = null, CancellationToken cancellationToken = default) { Task cancelMessageTask = retryPolicy.RunOperation(async(timeout) => { await CancelScheduledMessageInternal( sequenceNumber, retryPolicy, receiveLinkName, timeout, cancellationToken).ConfigureAwait(false); }, EntityName, ConnectionScope, cancellationToken); await cancelMessageTask.ConfigureAwait(false); }
/// <summary> /// Initializes a new instance of the <see cref="AmqpSender"/> class. /// </summary> /// /// <param name="entityName">The name of the entity to which messages will be sent.</param> /// <param name="connectionScope">The AMQP connection context for operations.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpSender( string entityName, AmqpConnectionScope connectionScope, ServiceBusRetryPolicy retryPolicy) { Argument.AssertNotNullOrEmpty(entityName, nameof(entityName)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); EntityName = entityName; RetryPolicy = retryPolicy; ConnectionScope = connectionScope; SendLink = new FaultTolerantAmqpObject <SendingAmqpLink>( timeout => CreateLinkAndEnsureProducerStateAsync(timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); }); }
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="retryPolicy"></param> /// <param name="receiveLinkName"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override async Task <long> ScheduleMessageAsync( ServiceBusMessage message, ServiceBusRetryPolicy retryPolicy, string receiveLinkName = null, CancellationToken cancellationToken = default) { long sequenceNumber = 0; Task scheduleTask = retryPolicy.RunOperation(async(timeout) => { sequenceNumber = await ScheduleMessageInternal( message, retryPolicy, receiveLinkName, timeout, cancellationToken).ConfigureAwait(false); }, EntityName, ConnectionScope, cancellationToken); await scheduleTask.ConfigureAwait(false); return(sequenceNumber); }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity. /// </summary> /// /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="sessionId"></param> /// <param name="isSessionReceiver"></param> /// /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns> /// public abstract TransportConsumer CreateConsumer( ServiceBusRetryPolicy retryPolicy, ReceiveMode receiveMode, uint?prefetchCount, string sessionId, bool isSessionReceiver);
/// <summary> /// Creates a rule manager strongly aligned with the active protocol and transport, /// responsible for adding, removing and getting rules from the Service Bus subscription. /// </summary> /// /// <param name="subscriptionPath">The path of the Service Bus subscription to which the rule manager is bound.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="identifier">The identifier for the rule manager.</param> /// /// <returns>A <see cref="TransportRuleManager"/> configured in the requested manner.</returns> /// public abstract TransportRuleManager CreateRuleManager( string subscriptionPath, ServiceBusRetryPolicy retryPolicy, string identifier);
/// <summary> /// Creates a sender strongly aligned with the active protocol and transport, /// responsible for sending <see cref="ServiceBusMessage" /> to the entity. /// </summary> /// <param name="entityPath">The entity path to send the message to.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="identifier">The identifier for the sender.</param> /// /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns> /// public abstract TransportSender CreateSender(string entityPath, ServiceBusRetryPolicy retryPolicy, string identifier);
/// <summary> /// Creates a sender strongly aligned with the active protocol and transport, /// responsible for sending <see cref="ServiceBusMessage" /> to the entity. /// </summary> /// <param name="entityPath">The entity path to send the message to.</param> /// <param name="viaEntityPath">The entity path to route the message through. Useful when using transactions.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns> /// public abstract TransportSender CreateSender(string entityPath, string viaEntityPath, ServiceBusRetryPolicy retryPolicy);
/// <summary> /// Creates a producer strongly aligned with the active protocol and transport, /// responsible for publishing <see cref="ServiceBusMessage" /> to the entity. /// </summary> /// /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns> /// public abstract TransportSender CreateSender(ServiceBusRetryPolicy retryPolicy);
/// <summary> /// /// </summary> /// <param name="sequenceNumber"></param> /// <param name="retryPolicy"></param> /// <param name="receiveLinkName"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public abstract Task CancelScheduledMessageAsync( long sequenceNumber, ServiceBusRetryPolicy retryPolicy, string receiveLinkName = null, CancellationToken cancellationToken = default);
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="retryPolicy"></param> /// <param name="receiveLinkName"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public abstract Task <long> ScheduleMessageAsync( ServiceBusMessage message, ServiceBusRetryPolicy retryPolicy, string receiveLinkName = null, CancellationToken cancellationToken = default);
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="retryPolicy"></param> /// <param name="receiveLinkName"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task <long> ScheduleMessageInternal( ServiceBusMessage message, ServiceBusRetryPolicy retryPolicy, string receiveLinkName, 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 (receiveLinkName != null) { request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = receiveLinkName; } 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 link = await ManagementLink.GetOrCreateAsync( UseMinimum(ConnectionScope.SessionTimeout, timeout.CalculateRemaining(stopWatch.Elapsed))) .ConfigureAwait(false); using AmqpMessage response = await link.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 new Exception(); //throw response.ToMessagingContractException(); } } }