コード例 #1
0
ファイル: MessagingModule.cs プロジェクト: misterPaul0/Curt
 /// <summary>
 /// Composes a message to send to a user, then performs the message action.
 /// The test will also validate the username of the recipient.
 /// </summary>
 /// <param name="userName">The username of the recipient</param>
 /// <param name="subject">The subject for the message.</param>
 /// <param name="content">The body of the message.</param>
 /// <param name="msgAction">The action to perform after composing the message.
 /// The current options are: "Send", "Save", "Delete" and "Cancel".</param>
 public void ComposeMessage(string userName, string subject, string content, string msgAction)
 {
     ComposeLink.ClickNoWait();
     ToTextField.TypeText(userName);
     System.Threading.Thread.Sleep(1000);
     ValidateUserLink.ClickNoWait();
     System.Threading.Thread.Sleep(2000);
     Assert.IsTrue(ModuleMessageSpan.InnerHtml.Contains("Username '" + userName + "' is valid"), MessageSpan.InnerHtml);
     SubjectTextField.TypeText(subject);
     HTMLEditorModeSpan.ClickNoWait();
     System.Threading.Thread.Sleep(1000);
     htmlField.TypeText(content);
     if (msgAction.CompareTo("Send") == 0)
     {
         SendLink.Click();
     }
     else if (msgAction.CompareTo("Save") == 0)
     {
         SaveMsgLink.Click();
     }
     else if (msgAction.CompareTo("Delete") == 0)
     {
         DeleteMsgLink.Click();
     }
     else if (msgAction.CompareTo("Cancel") == 0)
     {
         CancelMsgLink.Click();
     }
 }
コード例 #2
0
        /// <summary>
        ///   Reads the set of partition publishing properties active for this producer at the time it was initialized.
        /// </summary>
        ///
        /// <param name="cancellationToken">The cancellation token to consider when creating the link.</param>
        ///
        /// <returns>The set of <see cref="PartitionPublishingProperties" /> observed when the producer was initialized.</returns>
        ///
        /// <remarks>
        ///   It is important to note that these properties are a snapshot of the service state at the time when the
        ///   producer was initialized; they do not necessarily represent the current state of the service.
        /// </remarks>
        ///
        public override async ValueTask <PartitionPublishingProperties> ReadInitializationPublishingPropertiesAsync(CancellationToken cancellationToken)
        {
            Argument.AssertNotClosed(_closed, nameof(AmqpProducer));
            Argument.AssertNotClosed(ConnectionScope.IsDisposed, nameof(EventHubConnection));

            // If the properties were already initialized, use them.

            if (InitializedPartitionProperties != null)
            {
                return(InitializedPartitionProperties);
            }

            // Initialize the properties by forcing the link to be opened.

            var failedAttemptCount = 0;
            var tryTimeout         = RetryPolicy.CalculateTryTimeout(0);

            while ((!cancellationToken.IsCancellationRequested) && (!_closed))
            {
                try
                {
                    if (!SendLink.TryGetOpenedObject(out _))
                    {
                        await SendLink.GetOrCreateAsync(UseMinimum(ConnectionScope.SessionTimeout, tryTimeout), cancellationToken).ConfigureAwait(false);
                    }

                    break;
                }
                catch (Exception ex)
                {
                    ++failedAttemptCount;

                    // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop.
                    // Otherwise, bubble the exception.

                    var activeEx   = ex.TranslateServiceException(EventHubName);
                    var retryDelay = RetryPolicy.CalculateRetryDelay(activeEx, failedAttemptCount);

                    if ((retryDelay.HasValue) && (!ConnectionScope.IsDisposed) && (!cancellationToken.IsCancellationRequested))
                    {
                        await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false);

                        tryTimeout = RetryPolicy.CalculateTryTimeout(failedAttemptCount);
                    }
                    else if (ex is AmqpException)
                    {
                        ExceptionDispatchInfo.Capture(activeEx).Throw();
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
            return(InitializedPartitionProperties);
        }
コード例 #3
0
ファイル: MessagingModule.cs プロジェクト: misterPaul0/Curt
        /// <summary>
        /// Sends a message to a user.
        /// The test will also validate the username of the recipient.
        /// </summary>
        /// <param name="userName">The username of the message recipient.</param>
        /// <param name="subject">The subject for the message.</param>
        /// <param name="body">The body of the message.</param>
        public void SendMsgToUser(string userName, string subject, string body)
        {
            System.Threading.Thread.Sleep(1000);
            ComposeLink.Click();
            System.Threading.Thread.Sleep(2000);
            //Setting textfield.value does not appear to work properly
            ToTextField.TypeText(userName);
            System.Threading.Thread.Sleep(3000);
            ValidateUserLink.Click();
            System.Threading.Thread.Sleep(1000);
            Assert.IsTrue(MessageSpan.InnerHtml.Contains("Username '" + userName + "' is valid"));
            SubjectTextField.TypeText(subject);

            HTMLEditorModeSpan.Click();
            System.Threading.Thread.Sleep(2000);
            htmlField.Value = body;
            SendLink.Click();
        }
コード例 #4
0
        /// <summary>
        ///   Creates a size-constraint batch to which <see cref="EventData" /> may be added using a try-based pattern.  If an event would
        ///   exceed the maximum allowable size of the batch, the batch will not allow adding the event and signal that scenario using its
        ///   return value.
        ///
        ///   Because events that would violate the size constraint cannot be added, publishing a batch will not trigger an exception when
        ///   attempting to send the events to the Event Hubs service.
        /// </summary>
        ///
        /// <param name="options">The set of options to consider when creating this batch.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        /// <returns>An <see cref="EventDataBatch" /> with the requested <paramref name="options"/>.</returns>
        ///
        public override async ValueTask <TransportEventBatch> CreateBatchAsync(CreateBatchOptions options,
                                                                               CancellationToken cancellationToken)
        {
            Argument.AssertNotNull(options, nameof(options));

            // Ensure that maximum message size has been determined; this depends on the underlying
            // AMQP link, so if not set, requesting the link will ensure that it is populated.

            if (!MaximumMessageSize.HasValue)
            {
                await SendLink.GetOrCreateAsync(RetryPolicy.CalculateTryTimeout(0)).ConfigureAwait(false);
            }

            // Ensure that there was a maximum size populated; if none was provided,
            // default to the maximum size allowed by the link.

            options.MaximumSizeInBytes ??= MaximumMessageSize;

            Argument.AssertInRange(options.MaximumSizeInBytes.Value, EventHubProducerClient.MinimumBatchSizeLimit, MaximumMessageSize.Value, nameof(options.MaximumSizeInBytes));
            return(new AmqpEventBatch(MessageConverter, options));
        }
コード例 #5
0
        /// <summary>
        ///   Closes the connection to the transport producer instance.
        /// </summary>
        ///
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        public override async Task CloseAsync(CancellationToken cancellationToken)
        {
            if (_closed)
            {
                return;
            }

            _closed = true;

            var clientId   = GetHashCode().ToString();
            var clientType = GetType();

            try
            {
                EventHubsEventSource.Log.ClientCloseStart(clientType, EventHubName, clientId);
                cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

                if (SendLink?.TryGetOpenedObject(out var _) == true)
                {
                    cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
                    await SendLink.CloseAsync().ConfigureAwait(false);
                }

                SendLink?.Dispose();
            }
            catch (Exception ex)
            {
                _closed = false;
                EventHubsEventSource.Log.ClientCloseError(clientType, EventHubName, clientId, ex.Message);

                throw;
            }
            finally
            {
                EventHubsEventSource.Log.ClientCloseComplete(clientType, EventHubName, clientId);
            }
        }
コード例 #6
0
        /// <summary>
        ///   Sends an AMQP message that contains a batch of events to the associated Event Hub. If the size of events exceed the
        ///   maximum size of a single batch, an exception will be triggered and the send will fail.
        /// </summary>
        ///
        /// <param name="messageFactory">A factory which can be used to produce an AMQP message containing the batch of events to be sent.</param>
        /// <param name="partitionKey">The hashing key to use for influencing the partition to which events should be routed.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        protected virtual async Task SendAsync(Func <AmqpMessage> messageFactory,
                                               string partitionKey,
                                               CancellationToken cancellationToken)
        {
            var failedAttemptCount = 0;
            var logPartition       = PartitionId ?? partitionKey;
            var retryDelay         = default(TimeSpan?);
            var messageHash        = default(string);
            var stopWatch          = Stopwatch.StartNew();

            SendingAmqpLink link;

            try
            {
                var tryTimeout = RetryPolicy.CalculateTryTimeout(0);

                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        using AmqpMessage batchMessage = messageFactory();
                        messageHash = batchMessage.GetHashCode().ToString();

                        EventHubsEventSource.Log.EventPublishStart(EventHubName, logPartition, messageHash);

                        link = await SendLink.GetOrCreateAsync(UseMinimum(ConnectionScope.SessionTimeout, tryTimeout)).ConfigureAwait(false);

                        cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

                        // Validate that the batch of messages is not too large to send.  This is done after the link is created to ensure
                        // that the maximum message size is known, as it is dictated by the service using the link.

                        if (batchMessage.SerializedMessageSize > MaximumMessageSize)
                        {
                            throw new EventHubsException(EventHubName, string.Format(Resources.MessageSizeExceeded, messageHash, batchMessage.SerializedMessageSize, MaximumMessageSize), EventHubsException.FailureReason.MessageSizeExceeded);
                        }

                        // Attempt to send the message batch.

                        var deliveryTag = new ArraySegment <byte>(BitConverter.GetBytes(Interlocked.Increment(ref _deliveryCount)));
                        var outcome     = await link.SendMessageAsync(batchMessage, deliveryTag, AmqpConstants.NullBinary, tryTimeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false);

                        cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

                        if (outcome.DescriptorCode != Accepted.Code)
                        {
                            throw AmqpError.CreateExceptionForError((outcome as Rejected)?.Error, EventHubName);
                        }

                        // The send operation should be considered successful; return to
                        // exit the retry loop.

                        return;
                    }
                    catch (Exception ex)
                    {
                        Exception activeEx = ex.TranslateServiceException(EventHubName);

                        // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop.
                        // Otherwise, bubble the exception.

                        ++failedAttemptCount;
                        retryDelay = RetryPolicy.CalculateRetryDelay(activeEx, failedAttemptCount);

                        if ((retryDelay.HasValue) && (!ConnectionScope.IsDisposed) && (!cancellationToken.IsCancellationRequested))
                        {
                            EventHubsEventSource.Log.EventPublishError(EventHubName, logPartition, messageHash, activeEx.Message);
                            await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false);

                            tryTimeout = RetryPolicy.CalculateTryTimeout(failedAttemptCount);
                            stopWatch.Reset();
                        }
                        else if (ex is AmqpException)
                        {
                            throw activeEx;
                        }
                        else
                        {
                            throw;
                        }
                    }
                }

                // If no value has been returned nor exception thrown by this point,
                // then cancellation has been requested.

                throw new TaskCanceledException();
            }
            catch (Exception ex)
            {
                EventHubsEventSource.Log.EventPublishError(EventHubName, logPartition, messageHash, ex.Message);
                throw;
            }
            finally
            {
                stopWatch.Stop();
                EventHubsEventSource.Log.EventPublishComplete(EventHubName, logPartition, messageHash);
            }
        }
コード例 #7
0
        /// <summary>
        ///   Creates a size-constraint batch to which <see cref="EventData" /> may be added using a try-based pattern.  If an event would
        ///   exceed the maximum allowable size of the batch, the batch will not allow adding the event and signal that scenario using its
        ///   return value.
        ///
        ///   Because events that would violate the size constraint cannot be added, publishing a batch will not trigger an exception when
        ///   attempting to send the events to the Event Hubs service.
        /// </summary>
        ///
        /// <param name="options">The set of options to consider when creating this batch.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        /// <returns>An <see cref="EventDataBatch" /> with the requested <paramref name="options"/>.</returns>
        ///
        public override async ValueTask <TransportEventBatch> CreateBatchAsync(CreateBatchOptions options,
                                                                               CancellationToken cancellationToken)
        {
            Argument.AssertNotNull(options, nameof(options));
            Argument.AssertNotClosed(_closed, nameof(AmqpProducer));

            cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

            // Ensure that maximum message size has been determined; this depends on the underlying
            // AMQP link, so if not set, requesting the link will ensure that it is populated.

            if (!MaximumMessageSize.HasValue)
            {
                var failedAttemptCount = 0;
                var retryDelay         = default(TimeSpan?);
                var tryTimeout         = RetryPolicy.CalculateTryTimeout(0);

                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        await SendLink.GetOrCreateAsync(UseMinimum(ConnectionScope.SessionTimeout, tryTimeout)).ConfigureAwait(false);

                        break;
                    }
                    catch (Exception ex)
                    {
                        Exception activeEx = ex.TranslateServiceException(EventHubName);

                        // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop.
                        // Otherwise, bubble the exception.

                        ++failedAttemptCount;
                        retryDelay = RetryPolicy.CalculateRetryDelay(activeEx, failedAttemptCount);

                        if ((retryDelay.HasValue) && (!ConnectionScope.IsDisposed) && (!cancellationToken.IsCancellationRequested))
                        {
                            await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false);

                            tryTimeout = RetryPolicy.CalculateTryTimeout(failedAttemptCount);
                        }
                        else if (ex is AmqpException)
                        {
                            throw activeEx;
                        }
                        else
                        {
                            throw;
                        }
                    }
                }

                // If MaximumMessageSize has not been populated nor exception thrown
                // by this point, then cancellation has been requested.

                if (!MaximumMessageSize.HasValue)
                {
                    throw new TaskCanceledException();
                }
            }

            // Ensure that there was a maximum size populated; if none was provided,
            // default to the maximum size allowed by the link.

            options.MaximumSizeInBytes ??= MaximumMessageSize;

            Argument.AssertInRange(options.MaximumSizeInBytes.Value, EventHubProducerClient.MinimumBatchSizeLimit, MaximumMessageSize.Value, nameof(options.MaximumSizeInBytes));
            return(new AmqpEventBatch(MessageConverter, options));
        }
コード例 #8
0
        /// <summary>
        ///   Sends an AMQP message that contains a batch of events to the associated Event Hub. If the size of events exceed the
        ///   maximum size of a single batch, an exception will be triggered and the send will fail.
        /// </summary>
        ///
        /// <param name="messages">The set of AMQP messages to packaged in a batch envelope and sent.</param>
        /// <param name="partitionKey">The hashing key to use for influencing the partition to which events should be routed.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        /// <remarks>
        ///   Callers retain ownership of the <paramref name="messages" /> passed and hold responsibility for
        ///   ensuring that they are disposed.
        /// </remarks>
        ///
        protected virtual async Task SendAsync(IReadOnlyCollection <AmqpMessage> messages,
                                               string partitionKey,
                                               CancellationToken cancellationToken)
        {
            var failedAttemptCount = 0;
            var logPartition       = PartitionId ?? partitionKey;
            var operationId        = Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture);

            TimeSpan?       retryDelay;
            SendingAmqpLink link;

            try
            {
                var tryTimeout = RetryPolicy.CalculateTryTimeout(0);

                while (!cancellationToken.IsCancellationRequested)
                {
                    EventHubsEventSource.Log.EventPublishStart(EventHubName, logPartition, operationId);

                    try
                    {
                        using AmqpMessage batchMessage = MessageConverter.CreateBatchFromMessages(messages);

                        if (!SendLink.TryGetOpenedObject(out link))
                        {
                            link = await SendLink.GetOrCreateAsync(UseMinimum(ConnectionScope.SessionTimeout, tryTimeout), cancellationToken).ConfigureAwait(false);
                        }

                        // Validate that the batch of messages is not too large to send.  This is done after the link is created to ensure
                        // that the maximum message size is known, as it is dictated by the service using the link.

                        if (batchMessage.SerializedMessageSize > MaximumMessageSize)
                        {
                            throw new EventHubsException(EventHubName, string.Format(CultureInfo.CurrentCulture, Resources.MessageSizeExceeded, operationId, batchMessage.SerializedMessageSize, MaximumMessageSize), EventHubsException.FailureReason.MessageSizeExceeded);
                        }

                        // Attempt to send the message batch.

                        var deliveryTag = new ArraySegment <byte>(BitConverter.GetBytes(Interlocked.Increment(ref _deliveryCount)));
                        var outcome     = await link.SendMessageAsync(batchMessage, deliveryTag, AmqpConstants.NullBinary, cancellationToken).ConfigureAwait(false);

                        if (outcome.DescriptorCode != Accepted.Code)
                        {
                            throw AmqpError.CreateExceptionForError((outcome as Rejected)?.Error, EventHubName);
                        }

                        // The send operation should be considered successful; return to
                        // exit the retry loop.

                        return;
                    }
                    catch (Exception ex)
                    {
                        Exception activeEx = ex.TranslateServiceException(EventHubName);

                        // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop.
                        // Otherwise, bubble the exception.

                        ++failedAttemptCount;
                        retryDelay = RetryPolicy.CalculateRetryDelay(activeEx, failedAttemptCount);

                        if ((retryDelay.HasValue) && (!ConnectionScope.IsDisposed) && (!_closed) && (!cancellationToken.IsCancellationRequested))
                        {
                            EventHubsEventSource.Log.EventPublishError(EventHubName, logPartition, operationId, activeEx.Message);
                            await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false);

                            tryTimeout = RetryPolicy.CalculateTryTimeout(failedAttemptCount);
                        }
                        else if (ex is AmqpException)
                        {
                            ExceptionDispatchInfo.Capture(activeEx).Throw();
                        }
                        else
                        {
                            throw;
                        }
                    }
                }

                // If no value has been returned nor exception thrown by this point,
                // then cancellation has been requested.

                throw new TaskCanceledException();
            }
            catch (TaskCanceledException)
            {
                throw;
            }
            catch (Exception ex)
            {
                EventHubsEventSource.Log.EventPublishError(EventHubName, logPartition, operationId, ex.Message);
                throw;
            }
            finally
            {
                EventHubsEventSource.Log.EventPublishComplete(EventHubName, logPartition, operationId, failedAttemptCount);
            }
        }