示例#1
0
 public ReceiverManager(
     ServiceBusConnection connection,
     string fullyQualifiedNamespace,
     string entityPath,
     string identifier,
     ServiceBusProcessorOptions processorOptions,
     Func <ProcessMessageEventArgs, Task> messageHandler,
     Func <ProcessErrorEventArgs, Task> errorHandler,
     EntityScopeFactory scopeFactory,
     IList <ServiceBusPlugin> plugins)
 {
     _connection = connection;
     _fullyQualifiedNamespace = fullyQualifiedNamespace;
     _entityPath       = entityPath;
     _processorOptions = processorOptions;
     _receiverOptions  = new ServiceBusReceiverOptions
     {
         ReceiveMode   = _processorOptions.ReceiveMode,
         PrefetchCount = _processorOptions.PrefetchCount
     };
     _maxReceiveWaitTime = _processorOptions.MaxReceiveWaitTime;
     _identifier         = identifier;
     _plugins            = plugins;
     Receiver            = new ServiceBusReceiver(
         connection: _connection,
         entityPath: _entityPath,
         isSessionEntity: false,
         plugins: _plugins,
         options: _receiverOptions);
     _errorHandler   = errorHandler;
     _messageHandler = messageHandler;
     _scopeFactory   = scopeFactory;
 }
 public SessionReceiverManager(
     ServiceBusConnection connection,
     string fullyQualifiedNamespace,
     string entityPath,
     string identifier,
     string sessionId,
     ServiceBusProcessorOptions processorOptions,
     Func <ProcessSessionEventArgs, Task> sessionInitHandler,
     Func <ProcessSessionEventArgs, Task> sessionCloseHandler,
     Func <ProcessSessionMessageEventArgs, Task> messageHandler,
     Func <ProcessErrorEventArgs, Task> errorHandler,
     SemaphoreSlim concurrentAcceptSessionsSemaphore,
     EntityScopeFactory scopeFactory,
     IList <ServiceBusPlugin> plugins)
     : base(connection, fullyQualifiedNamespace, entityPath, identifier, processorOptions, default, errorHandler,
            scopeFactory, plugins)
 {
     _sessionInitHandler  = sessionInitHandler;
     _sessionCloseHandler = sessionCloseHandler;
     _messageHandler      = messageHandler;
     _concurrentAcceptSessionsSemaphore = concurrentAcceptSessionsSemaphore;
     _sessionReceiverOptions            = new ServiceBusSessionReceiverOptions
     {
         ReceiveMode   = _processorOptions.ReceiveMode,
         PrefetchCount = _processorOptions.PrefetchCount,
         SessionId     = sessionId
     };
 }
示例#3
0
 public ReceiverManager(
     ServiceBusProcessor processor,
     EntityScopeFactory scopeFactory,
     IList <ServiceBusPlugin> plugins)
 {
     Processor        = processor;
     ProcessorOptions = processor.Options;
     _receiverOptions = new ServiceBusReceiverOptions
     {
         ReceiveMode   = ProcessorOptions.ReceiveMode,
         PrefetchCount = ProcessorOptions.PrefetchCount,
         // Pass None for subqueue since the subqueue has already
         // been taken into account when computing the EntityPath of the processor.
         SubQueue = SubQueue.None
     };
     _maxReceiveWaitTime = ProcessorOptions.MaxReceiveWaitTime;
     _plugins            = plugins;
     Receiver            = new ServiceBusReceiver(
         connection: Processor.Connection,
         entityPath: Processor.EntityPath,
         isSessionEntity: false,
         isProcessor: true,
         plugins: _plugins,
         options: _receiverOptions);
     _scopeFactory = scopeFactory;
 }
        /// <summary>
        ///   Initializes a new instance of the <see cref="ServiceBusSender"/> class.
        /// </summary>
        /// <param name="entityPath">The entity path to send the message to.</param>
        /// <param name="options">The set of <see cref="ServiceBusSenderOptions"/> to use for configuring
        /// this <see cref="ServiceBusSender"/>.</param>
        /// <param name="connection">The connection for the sender.</param>
        ///
        internal ServiceBusSender(
            string entityPath,
            ServiceBusSenderOptions options,
            ServiceBusConnection connection)
        {
            Logger.ClientCreateStart(typeof(ServiceBusSender), connection?.FullyQualifiedNamespace, entityPath);
            try
            {
                Argument.AssertNotNull(connection, nameof(connection));
                Argument.AssertNotNull(connection.RetryOptions, nameof(connection.RetryOptions));
                Argument.AssertNotNullOrWhiteSpace(entityPath, nameof(entityPath));
                connection.ThrowIfClosed();

                options       = options?.Clone() ?? new ServiceBusSenderOptions();
                EntityPath    = entityPath;
                ViaEntityPath = options.ViaQueueOrTopicName;
                Identifier    = DiagnosticUtilities.GenerateIdentifier(EntityPath);
                _connection   = connection;
                _retryPolicy  = _connection.RetryOptions.ToRetryPolicy();
                _innerSender  = _connection.CreateTransportSender(
                    entityPath,
                    ViaEntityPath,
                    _retryPolicy,
                    Identifier);
                _scopeFactory = new EntityScopeFactory(EntityPath, FullyQualifiedNamespace);
            }
            catch (Exception ex)
            {
                Logger.ClientCreateException(typeof(ServiceBusSender), connection?.FullyQualifiedNamespace, entityPath, ex);
                throw;
            }
            Logger.ClientCreateComplete(typeof(ServiceBusSender), Identifier);
        }
示例#5
0
        public void ConstructorUpdatesState()
        {
            var mockBatch = new MockTransportBatch();
            var mockScope = new EntityScopeFactory("mock", "mock");

            var batch = new ServiceBusMessageBatch(mockBatch, mockScope);

            Assert.That(GetInnerBatch(batch), Is.SameAs(mockBatch), "The inner transport batch should have been set.");
        }
示例#6
0
        public void DisposeIsDelegatedToTheTransportClient()
        {
            var mockBatch = new MockTransportBatch();
            var mockScope = new EntityScopeFactory("mock", "mock");

            var batch = new ServiceBusMessageBatch(mockBatch, mockScope);

            batch.Dispose();
            Assert.That(mockBatch.DisposeInvoked, Is.True);
        }
示例#7
0
        public void AsReadOnlyIsDelegatedToTheTransportClient()
        {
            var mockBatch = new MockTransportBatch();
            var mockScope = new EntityScopeFactory("mock", "mock");

            var batch = new ServiceBusMessageBatch(mockBatch, mockScope);

            batch.AsReadOnly <string>();
            Assert.That(mockBatch.AsReadOnlyCalledWith, Is.EqualTo(typeof(string)), "The enumerable should delegated the requested type parameter.");
        }
示例#8
0
        public void PropertyAccessIsDelegatedToTheTransportClient()
        {
            var mockBatch = new MockTransportBatch();
            var mockScope = new EntityScopeFactory("mock", "mock");

            var batch = new ServiceBusMessageBatch(mockBatch, mockScope);

            Assert.That(batch.MaxSizeInBytes, Is.EqualTo(mockBatch.MaxSizeInBytes), "The maximum size should have been delegated.");
            Assert.That(batch.SizeInBytes, Is.EqualTo(mockBatch.SizeInBytes), "The size should have been delegated.");
            Assert.That(batch.Count, Is.EqualTo(mockBatch.Count), "The count should have been delegated.");
        }
示例#9
0
        public void TryAddIsDelegatedToTheTransportClient()
        {
            var mockBatch = new MockTransportBatch();
            var mockScope = new EntityScopeFactory("mock", "mock");

            var batch   = new ServiceBusMessageBatch(mockBatch, mockScope);
            var message = new ServiceBusMessage(new byte[] { 0x21 });

            Assert.That(batch.TryAddMessage(message), Is.True, "The message should have been accepted.");
            Assert.That(mockBatch.TryAddCalledWith, Is.SameAs(message), "The message should have been passed with delegation.");
        }
示例#10
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="ServiceBusProcessor"/> class.
        /// </summary>
        ///
        /// <param name="connection">The <see cref="ServiceBusConnection" /> connection to use for communication with the Service Bus service.</param>
        /// <param name="entityPath">The queue name or subscription path to process messages from.</param>
        /// <param name="isSessionEntity">Whether or not the processor is associated with a session entity.</param>
        /// <param name="plugins">The set of plugins to apply to incoming messages.</param>
        /// <param name="options">The set of options to use when configuring the processor.</param>
        /// <param name="sessionIds">An optional set of session Ids to limit processing to.
        /// Only applies if isSessionEntity is true.</param>
        /// <param name="maxConcurrentSessions">The max number of sessions that can be processed concurrently.
        /// Only applies if isSessionEntity is true.</param>
        /// <param name="maxConcurrentCallsPerSession">The max number of concurrent calls per session.
        /// Only applies if isSessionEntity is true.</param>
        internal ServiceBusProcessor(
            ServiceBusConnection connection,
            string entityPath,
            bool isSessionEntity,
            IList <ServiceBusPlugin> plugins,
            ServiceBusProcessorOptions options,
            string[] sessionIds              = default,
            int maxConcurrentSessions        = default,
            int maxConcurrentCallsPerSession = default)
        {
            Argument.AssertNotNullOrWhiteSpace(entityPath, nameof(entityPath));
            Argument.AssertNotNull(connection, nameof(connection));
            Argument.AssertNotNull(connection.RetryOptions, nameof(connection.RetryOptions));
            connection.ThrowIfClosed();

            _options    = options?.Clone() ?? new ServiceBusProcessorOptions();
            _connection = connection;
            EntityPath  = entityPath;
            Identifier  = DiagnosticUtilities.GenerateIdentifier(EntityPath);

            ReceiveMode   = _options.ReceiveMode;
            PrefetchCount = _options.PrefetchCount;
            MaxAutoLockRenewalDuration   = _options.MaxAutoLockRenewalDuration;
            MaxConcurrentCalls           = _options.MaxConcurrentCalls;
            MaxConcurrentSessions        = maxConcurrentSessions;
            MaxConcurrentCallsPerSession = maxConcurrentCallsPerSession;
            _sessionIds = sessionIds ?? Array.Empty <string>();

            int maxCalls = isSessionEntity ?
                           (_sessionIds.Length > 0 ?
                            Math.Min(_sessionIds.Length, MaxConcurrentSessions) :
                            MaxConcurrentSessions) * MaxConcurrentCallsPerSession :
                           MaxConcurrentCalls;

            MessageHandlerSemaphore = new SemaphoreSlim(
                maxCalls,
                maxCalls);
            var maxAcceptSessions = Math.Min(maxCalls, 2 * Environment.ProcessorCount);

            MaxConcurrentAcceptSessionsSemaphore = new SemaphoreSlim(
                maxAcceptSessions,
                maxAcceptSessions);

            MaxReceiveWaitTime = _options.MaxReceiveWaitTime;
            AutoComplete       = _options.AutoComplete;

            EntityPath         = entityPath;
            IsSessionProcessor = isSessionEntity;
            _scopeFactory      = new EntityScopeFactory(EntityPath, FullyQualifiedNamespace);
            _plugins           = plugins;
        }
        public async Task SendBatchManagesLockingTheBatch()
        {
            using var cancellationSource = new CancellationTokenSource();
            cancellationSource.CancelAfter(TimeSpan.FromSeconds(15));

            var completionSource   = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);
            var mockTransportBatch = new Mock <TransportMessageBatch>();
            var mockScope          = new EntityScopeFactory("mock", "mock");
            var batch = new ServiceBusMessageBatch(mockTransportBatch.Object, mockScope);
            var mockTransportSender = new Mock <TransportSender>();
            var mockConnection      = new Mock <ServiceBusConnection>();

            mockConnection
            .Setup(connection => connection.RetryOptions)
            .Returns(new ServiceBusRetryOptions());

            mockConnection
            .Setup(connection => connection.CreateTransportSender(It.IsAny <string>(), It.IsAny <ServiceBusRetryPolicy>(), It.IsAny <string>(), It.IsAny <string>()))
            .Returns(mockTransportSender.Object);

            mockConnection
            .Setup(connection => connection.ThrowIfClosed());

            mockTransportBatch
            .Setup(transport => transport.TryAddMessage(It.IsAny <ServiceBusMessage>()))
            .Returns(true);

            mockTransportBatch
            .Setup(transport => transport.Count)
            .Returns(1);

            mockTransportSender
            .Setup(transport => transport.SendBatchAsync(It.IsAny <ServiceBusMessageBatch>(), It.IsAny <CancellationToken>()))
            .Returns(async() => await Task.WhenAny(completionSource.Task, Task.Delay(Timeout.Infinite, cancellationSource.Token)));

            Assert.That(batch.TryAddMessage(new ServiceBusMessage(Array.Empty <byte>())), Is.True, "The batch should not be locked before sending.");

            var sender   = new ServiceBusSender("dummy", null, mockConnection.Object, new ServiceBusPlugin[] { });
            var sendTask = sender.SendMessagesAsync(batch);

            Assert.That(() => batch.TryAddMessage(new ServiceBusMessage(Array.Empty <byte>())), Throws.InstanceOf <InvalidOperationException>(), "The batch should be locked while sending.");
            completionSource.TrySetResult(true);

            await sendTask;

            Assert.That(cancellationSource.IsCancellationRequested, Is.False, "The cancellation token should not have been signaled.");
            Assert.That(batch.TryAddMessage(new ServiceBusMessage(Array.Empty <byte>())), Is.True, "The batch should not be locked after sending.");

            cancellationSource.Cancel();
        }
示例#12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceBusReceiver"/> class.
        /// </summary>
        ///
        /// <param name="connection">The <see cref="ServiceBusConnection" /> connection to use for communication with the Service Bus service.</param>
        /// <param name="entityPath"></param>
        /// <param name="isSessionEntity"></param>
        /// <param name="plugins">The plugins to apply to incoming messages.</param>
        /// <param name="options">A set of options to apply when configuring the consumer.</param>
        /// <param name="sessionId">An optional session Id to scope the receiver to. If not specified,
        /// the next available session returned from the service will be used.</param>
        ///
        internal ServiceBusReceiver(
            ServiceBusConnection connection,
            string entityPath,
            bool isSessionEntity,
            IList <ServiceBusPlugin> plugins,
            ServiceBusReceiverOptions options,
            string sessionId = default)
        {
            Type type = GetType();

            Logger.ClientCreateStart(type, connection?.FullyQualifiedNamespace, entityPath);
            try
            {
                Argument.AssertNotNull(connection, nameof(connection));
                Argument.AssertNotNull(connection.RetryOptions, nameof(connection.RetryOptions));
                Argument.AssertNotNullOrWhiteSpace(entityPath, nameof(entityPath));
                connection.ThrowIfClosed();
                options           = options?.Clone() ?? new ServiceBusReceiverOptions();
                Identifier        = DiagnosticUtilities.GenerateIdentifier(entityPath);
                _connection       = connection;
                _retryPolicy      = connection.RetryOptions.ToRetryPolicy();
                ReceiveMode       = options.ReceiveMode;
                PrefetchCount     = options.PrefetchCount;
                EntityPath        = entityPath;
                IsSessionReceiver = isSessionEntity;
                _innerReceiver    = _connection.CreateTransportReceiver(
                    entityPath: EntityPath,
                    retryPolicy: _retryPolicy,
                    receiveMode: ReceiveMode,
                    prefetchCount: (uint)PrefetchCount,
                    identifier: Identifier,
                    sessionId: sessionId,
                    isSessionReceiver: IsSessionReceiver);
                _scopeFactory = new EntityScopeFactory(EntityPath, FullyQualifiedNamespace);
                _plugins      = plugins;
                if (!isSessionEntity)
                {
                    // don't log client completion for session receiver here as it is not complete until
                    // the link is opened.
                    Logger.ClientCreateComplete(type, Identifier);
                }
            }
            catch (Exception ex)
            {
                Logger.ClientCreateException(type, connection?.FullyQualifiedNamespace, entityPath, ex);
                throw;
            }
        }
示例#13
0
        public void TryAddRespectsTheBatchLock()
        {
            var mockBatch = new MockTransportBatch();
            var mockScope = new EntityScopeFactory("mock", "mock");

            var batch   = new ServiceBusMessageBatch(mockBatch, mockScope);
            var message = new ServiceBusMessage(new byte[] { 0x21 });

            Assert.That(batch.TryAddMessage(new ServiceBusMessage(new byte[] { 0x21 })), Is.True, "The message should have been accepted before locking.");

            batch.Lock();
            Assert.That(() => batch.TryAddMessage(new ServiceBusMessage(Array.Empty <byte>())), Throws.InstanceOf <InvalidOperationException>(), "The batch should not accept messages when locked.");

            batch.Unlock();
            Assert.That(batch.TryAddMessage(new ServiceBusMessage(Array.Empty <byte>())), Is.True, "The message should have been accepted after unlocking.");
        }
示例#14
0
 public SessionReceiverManager(
     ServiceBusSessionProcessor sessionProcessor,
     string sessionId,
     SemaphoreSlim concurrentAcceptSessionsSemaphore,
     EntityScopeFactory scopeFactory,
     bool keepOpenOnReceiveTimeout)
     : base(sessionProcessor.InnerProcessor, scopeFactory)
 {
     _concurrentAcceptSessionsSemaphore = concurrentAcceptSessionsSemaphore;
     _sessionReceiverOptions            = new ServiceBusSessionReceiverOptions
     {
         ReceiveMode   = sessionProcessor.InnerProcessor.Options.ReceiveMode,
         PrefetchCount = sessionProcessor.InnerProcessor.Options.PrefetchCount,
     };
     _sessionId = sessionId;
     _keepOpenOnReceiveTimeout = keepOpenOnReceiveTimeout;
     _sessionProcessor         = sessionProcessor;
 }
 public SessionReceiverManager(
     ServiceBusProcessor processor,
     string sessionId,
     SemaphoreSlim concurrentAcceptSessionsSemaphore,
     EntityScopeFactory scopeFactory,
     IList <ServiceBusPlugin> plugins,
     int maxCallsPerSession,
     bool keepOpenOnReceiveTimeout)
     : base(processor, scopeFactory, plugins)
 {
     _concurrentAcceptSessionsSemaphore = concurrentAcceptSessionsSemaphore;
     _maxCallsPerSession     = maxCallsPerSession;
     _sessionReceiverOptions = new ServiceBusSessionReceiverOptions
     {
         ReceiveMode   = processor.Options.ReceiveMode,
         PrefetchCount = processor.Options.PrefetchCount,
     };
     _sessionId = sessionId;
     _keepOpenOnReceiveTimeout = keepOpenOnReceiveTimeout;
 }
 public SessionReceiverManager(
     ServiceBusConnection connection,
     string fullyQualifiedNamespace,
     string entityPath,
     string identifier,
     string sessionId,
     ServiceBusProcessorOptions processorOptions,
     Func <ProcessSessionEventArgs, Task> sessionInitHandler,
     Func <ProcessSessionEventArgs, Task> sessionCloseHandler,
     Func <ProcessSessionMessageEventArgs, Task> messageHandler,
     Func <ProcessErrorEventArgs, Task> errorHandler,
     SemaphoreSlim concurrentAcceptSessionsSemaphore,
     EntityScopeFactory scopeFactory)
     : base(connection, fullyQualifiedNamespace, entityPath, identifier, processorOptions, default, errorHandler,
            scopeFactory)
 {
     _sessionId           = sessionId;
     _sessionInitHandler  = sessionInitHandler;
     _sessionCloseHandler = sessionCloseHandler;
     _messageHandler      = messageHandler;
     _concurrentAcceptSessionsSemaphore = concurrentAcceptSessionsSemaphore;
 }
示例#17
0
 public ReceiverManager(
     ServiceBusProcessor processor,
     EntityScopeFactory scopeFactory,
     IList <ServiceBusPlugin> plugins)
 {
     Processor        = processor;
     ProcessorOptions = processor.Options;
     _receiverOptions = new ServiceBusReceiverOptions
     {
         ReceiveMode   = ProcessorOptions.ReceiveMode,
         PrefetchCount = ProcessorOptions.PrefetchCount,
     };
     _maxReceiveWaitTime = ProcessorOptions.MaxReceiveWaitTime;
     _plugins            = plugins;
     Receiver            = new ServiceBusReceiver(
         connection: Processor.Connection,
         entityPath: Processor.EntityPath,
         isSessionEntity: false,
         plugins: _plugins,
         options: _receiverOptions);
     _scopeFactory = scopeFactory;
 }
 public OrganizationTestContext(IExtern konturExtern, EntityScopeFactory <Organization> scopeFactory)
 {
     this.konturExtern = konturExtern;
     this.scopeFactory = scopeFactory;
 }
 /// <summary>
 ///   Initializes a new instance of the <see cref="ServiceBusMessageBatch"/> class.
 /// </summary>
 ///
 /// <param name="transportBatch">The  transport-specific batch responsible for performing the batch operations.</param>
 /// <param name="entityScope">The entity scope used for instrumentation.</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>
 ///
 internal ServiceBusMessageBatch(TransportMessageBatch transportBatch, EntityScopeFactory entityScope)
 {
     Argument.AssertNotNull(transportBatch, nameof(transportBatch));
     _innerBatch   = transportBatch;
     _scopeFactory = entityScope;
 }
示例#20
0
 public AccountTestContext(IExtern konturExtern, EntityScopeFactory <Account> scopeFactory)
 {
     this.konturExtern = konturExtern;
     this.scopeFactory = scopeFactory;
 }
示例#21
0
 public DraftsTestContext(IExtern konturExtern, EntityScopeFactory <Draft> scopeFactory)
 {
     this.konturExtern = konturExtern;
     this.scopeFactory = scopeFactory;
 }
 public DocflowsTestContext(IExtern konturExtern, EntityScopeFactory <IDocflowWithDocuments> scopeFactory)
 {
     this.konturExtern = konturExtern;
     this.scopeFactory = scopeFactory;
 }