示例#1
0
        async Task NonexistentEntity()
        {
            // Rebuild connection string with a nonexistent entity.
            var csb = new EventHubsConnectionStringBuilder(TestUtility.EventHubsConnectionString);

            csb.EntityPath = Guid.NewGuid().ToString();
            var ehClient = EventHubClient.CreateFromConnectionString(csb.ToString());

            // GetRuntimeInformationAsync on a nonexistent entity.
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                TestUtility.Log("Getting entity information from a nonexistent entity.");
                await ehClient.GetRuntimeInformationAsync();
                throw new InvalidOperationException("GetRuntimeInformation call should have failed");
            });

            // GetPartitionRuntimeInformationAsync on a nonexistent entity.
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                TestUtility.Log("Getting partition information from a nonexistent entity.");
                await ehClient.GetPartitionRuntimeInformationAsync("0");
                throw new InvalidOperationException("GetPartitionRuntimeInformation call should have failed");
            });

            // Try sending.
            PartitionSender sender = null;
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                TestUtility.Log("Sending an event to nonexistent entity.");
                sender = ehClient.CreatePartitionSender("0");
                await sender.SendAsync(new EventData(Encoding.UTF8.GetBytes("this send should fail.")));
                throw new InvalidOperationException("Send call should have failed");
            });

            await sender.CloseAsync();

            // Try receiving.
            PartitionReceiver receiver = null;
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                TestUtility.Log("Receiving from nonexistent entity.");
                receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromStart());
                await receiver.ReceiveAsync(1);
                throw new InvalidOperationException("Receive call should have failed");
            });

            await receiver.CloseAsync();

            // Try receiving on an nonexistent consumer group.
            ehClient = EventHubClient.CreateFromConnectionString(TestUtility.EventHubsConnectionString);
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                TestUtility.Log("Receiving from nonexistent consumer group.");
                receiver = ehClient.CreateReceiver(Guid.NewGuid().ToString(), "0", EventPosition.FromStart());
                await receiver.ReceiveAsync(1);
                throw new InvalidOperationException("Receive call should have failed");
            });

            await receiver.CloseAsync();
        }
        public async Task ReceiveFromInvalidPartition()
        {
            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString       = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient               = EventHubClient.CreateFromConnectionString(connectionString);
                PartitionReceiver receiver = null;

                try
                {
                    // Some invalid partition values. These will fail on the service side.
                    var invalidPartitions = new List <string>()
                    {
                        "XYZ", "-1", "1000", "-"
                    };
                    foreach (var invalidPartitionId in invalidPartitions)
                    {
                        await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() =>
                        {
                            TestUtility.Log($"Receiving from invalid partition {invalidPartitionId}");
                            receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, invalidPartitionId, EventPosition.FromStart());
                            await receiver.ReceiveAsync(1);
                        });

                        await receiver.CloseAsync();
                    }

                    // Some invalid partition values. These will fail on the client side.
                    invalidPartitions = new List <string>()
                    {
                        " ", null, ""
                    };
                    foreach (var invalidPartitionId in invalidPartitions)
                    {
                        await Assert.ThrowsAsync <InvalidOperationException>(async() =>
                        {
                            TestUtility.Log($"Receiving from invalid partition {invalidPartitionId}");
                            receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, invalidPartitionId, EventPosition.FromStart());
                            await receiver.ReceiveAsync(1);
                        });

                        await receiver.CloseAsync();
                    }
                }
                finally
                {
                    await ehClient.CloseAsync();
                }
            }
        }
示例#3
0
文件: IotHub.cs 项目: v-jush/iotedge
        public async Task ReceiveEventsAsync(
            string deviceId,
            Func <EventData, bool> onEventReceived,
            CancellationToken token)
        {
            EventHubClient    client    = this.EventHubClient;
            int               count     = (await client.GetRuntimeInformationAsync()).PartitionCount;
            string            partition = EventHubPartitionKeyResolver.ResolveToPartition(deviceId, count);
            PartitionReceiver receiver  = client.CreateReceiver("$Default", partition, EventPosition.FromEnd());

            var result = new TaskCompletionSource <bool>();

            using (token.Register(() => result.TrySetCanceled()))
            {
                receiver.SetReceiveHandler(
                    new PartitionReceiveHandler(
                        data =>
                {
                    bool done = onEventReceived(data);
                    if (done)
                    {
                        result.TrySetResult(true);
                    }

                    return(done);
                }));

                await result.Task;
            }

            await receiver.CloseAsync();
        }
示例#4
0
        public async Task <List <EventData> > GetMessagesForDevice(string deviceId, DateTime startTime, int maxPerPartition = 100, int waitTimeSecs = 5)
        {
            var messages = new List <EventData>();

            EventHubClient    eventHubClient    = EventHubClient.CreateFromConnectionString(this.eventHubConnectionString);
            PartitionReceiver partitionReceiver = eventHubClient.CreateReceiver(
                EventHubConsumerGroup,
                EventHubPartitionKeyResolver.ResolveToPartition(deviceId, (await eventHubClient.GetRuntimeInformationAsync()).PartitionCount),
                EventPosition.FromEnqueuedTime(startTime));

            // Retry a few times due to weird behavior with ReceiveAsync() not returning all messages available
            for (int i = 0; i < 3; i++)
            {
                IEnumerable <EventData> events = await partitionReceiver.ReceiveAsync(maxPerPartition, TimeSpan.FromSeconds(waitTimeSecs));

                if (events != null)
                {
                    messages.AddRange(events);
                }

                if (i < 3)
                {
                    await Task.Delay(TimeSpan.FromSeconds(5));
                }
            }

            await partitionReceiver.CloseAsync();

            await eventHubClient.CloseAsync();

            return(messages);
        }
        async Task ReceiveTimeout()
        {
            var testValues = new[] { 10, 30, 120 };

            PartitionReceiver receiver = null;

            try
            {
                foreach (var receiveTimeoutInSeconds in testValues)
                {
                    Log($"Testing with {receiveTimeoutInSeconds} seconds.");

                    // Start receiving from a future time so that Receive call won't be able to fetch any events.
                    receiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", DateTime.UtcNow.AddMinutes(1));

                    var startTime = DateTime.Now;
                    await receiver.ReceiveAsync(1, TimeSpan.FromSeconds(receiveTimeoutInSeconds));

                    // Receive call should have waited more than receive timeout.
                    // Give 100 milliseconds of buffer.
                    var diff = DateTime.Now.Subtract(startTime).TotalSeconds;
                    Assert.True(diff >= receiveTimeoutInSeconds - 0.1, $"Hit timeout {diff} seconds into Receive call while testing {receiveTimeoutInSeconds} seconds timeout.");

                    // Timeout should not be late more than 5 seconds.
                    // This is just a logical buffer for timeout behavior validation.
                    Assert.True(diff < receiveTimeoutInSeconds + 5, $"Hit timeout {diff} seconds into Receive call while testing {receiveTimeoutInSeconds} seconds timeout.");
                }
            }
            finally
            {
                await receiver.CloseAsync();
            }
        }
示例#6
0
        public async Task <IList <EventData> > GetMessagesFromAllPartitions(DateTime startTime, int maxPerPartition = 10, int waitTimeSecs = 5)
        {
            var messages = new List <EventData>();
            EventHubRuntimeInformation rtInfo = await this.eventHubClient.GetRuntimeInformationAsync();

            foreach (string partition in rtInfo.PartitionIds)
            {
                PartitionReceiver partitionReceiver = this.eventHubClient.CreateReceiver(
                    PartitionReceiver.DefaultConsumerGroupName,
                    partition,
                    startTime);

                // Retry a few times to make sure we get all expected messages.
                for (int i = 0; i < 3; i++)
                {
                    IEnumerable <EventData> events = await partitionReceiver.ReceiveAsync(maxPerPartition, TimeSpan.FromSeconds(waitTimeSecs));

                    if (events != null)
                    {
                        messages.AddRange(events);
                    }

                    if (i < 3)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(5));
                    }
                }
                await partitionReceiver.CloseAsync();
            }
            return(messages);
        }
        async Task InvokeOnNull()
        {
            PartitionReceiver partitionReceiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromEnd());

            try
            {
                EventWaitHandle nullReceivedEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
                var             handler           = new TestPartitionReceiveHandler();

                handler.EventsReceived += (s, eventDatas) =>
                {
                    if (eventDatas == null)
                    {
                        TestUtility.Log("Received null.");
                        nullReceivedEvent.Set();
                    }
                };

                partitionReceiver.SetReceiveHandler(handler, true);

                if (!nullReceivedEvent.WaitOne(TimeSpan.FromSeconds(120)))
                {
                    throw new InvalidOperationException("Did not receive null.");
                }
            }
            finally
            {
                // Unregister handler.
                partitionReceiver.SetReceiveHandler(null);

                // Close clients.
                await partitionReceiver.CloseAsync();
            }
        }
        public async Task ReadPartitionWithReceiver()
        {
            #region Snippet:EventHubs_Sample05_ReadPartitionWithReceiver

            var connectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName     = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup    = EventHubConsumerClient.DefaultConsumerGroupName;
            /*@@*/
            /*@@*/ connectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            /*@@*/ eventHubName     = _scope.EventHubName;
            /*@@*/ consumerGroup    = _availableConsumerGroups.Dequeue();

            using CancellationTokenSource cancellationSource = new CancellationTokenSource();
            cancellationSource.CancelAfter(TimeSpan.FromSeconds(30));

            string firstPartition;

            await using (var producer = new EventHubProducerClient(connectionString, eventHubName))
            {
                firstPartition = (await producer.GetPartitionIdsAsync()).First();
            }

            var receiver = new PartitionReceiver(
                consumerGroup,
                firstPartition,
                EventPosition.Earliest,
                connectionString,
                eventHubName);

            try
            {
                while (!cancellationSource.IsCancellationRequested)
                {
                    int      batchSize = 50;
                    TimeSpan waitTime  = TimeSpan.FromSeconds(1);

                    IEnumerable <EventData> eventBatch = await receiver.ReceiveBatchAsync(
                        batchSize,
                        waitTime,
                        cancellationSource.Token);

                    foreach (EventData eventData in eventBatch)
                    {
                        byte[] eventBodyBytes = eventData.EventBody.ToArray();
                        Debug.WriteLine($"Read event of length { eventBodyBytes.Length } from { firstPartition }");
                    }
                }
            }
            catch (TaskCanceledException)
            {
                // This is expected if the cancellation token is
                // signaled.
            }
            finally
            {
                await receiver.CloseAsync();
            }

            #endregion
        }
示例#9
0
        public async Task SmallReceiveTimeout()
        {
            var maxClients = 4;

            // Issue receives with 1 second so that some of the Receive calls will timeout while creating AMQP link.
            // Even those Receive calls should return NULL instead of bubbling the exception up.
            var receiveTimeoutInSeconds = 1;

            var tasks = Enumerable.Range(0, maxClients)
                        .Select(async i =>
            {
                PartitionReceiver receiver = null;

                try
                {
                    TestUtility.Log($"Testing with {receiveTimeoutInSeconds} seconds on client {i}.");

                    // Start receiving from a future time so that Receive call won't be able to fetch any events.
                    var ehClient = EventHubClient.CreateFromConnectionString(TestUtility.EventHubsConnectionString);
                    receiver     = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromEnqueuedTime(DateTime.UtcNow.AddMinutes(1)));
                    var ed       = await receiver.ReceiveAsync(1, TimeSpan.FromSeconds(receiveTimeoutInSeconds));
                    if (ed == null)
                    {
                        TestUtility.Log($"Received NULL from client {i}");
                    }
                }
                finally
                {
                    await receiver.CloseAsync();
                }
            });

            await Task.WhenAll(tasks);
        }
示例#10
0
        protected async Task VerifyDataOnIoTHub(string moduleId)
        {
            Console.WriteLine($"Verifying data on IoTHub from {moduleId}");

            // First Verify if module is already running.
            await this.bootstrapper.VerifyModuleIsRunning(moduleId);

            var builder = new EventHubsConnectionStringBuilder(this.eventhubCompatibleEndpointWithEntityPath)
            {
                TransportType = this.eventHubClientTransportType
            };

            Console.WriteLine($"Receiving events from device '{this.context.DeviceId}' on Event Hub '{builder.EntityPath}'");

            EventHubClient eventHubClient =
                EventHubClient.CreateFromConnectionString(builder.ToString());

            this.proxy.ForEach(p => eventHubClient.WebProxy = p);

            PartitionReceiver eventHubReceiver = eventHubClient.CreateReceiver(
                "$Default",
                EventHubPartitionKeyResolver.ResolveToPartition(
                    this.context.DeviceId,
                    (await eventHubClient.GetRuntimeInformationAsync()).PartitionCount),
                EventPosition.FromEnd());

            // TODO: [Improvement] should verify test results without using event hub, which introduce latency.
            var result = new TaskCompletionSource <bool>();

            using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(20))) // This long timeout is needed in case event hub is slow to process messages
            {
                using (cts.Token.Register(() => result.TrySetCanceled()))
                {
                    eventHubReceiver.SetReceiveHandler(
                        new PartitionReceiveHandler(
                            eventData =>
                    {
                        eventData.SystemProperties.TryGetValue("iothub-connection-device-id", out object devId);
                        eventData.SystemProperties.TryGetValue("iothub-connection-module-id", out object modId);

                        if (devId != null && devId.ToString().Equals(this.context.DeviceId) &&
                            modId != null && modId.ToString().Equals(moduleId))
                        {
                            result.TrySetResult(true);
                            return(true);
                        }

                        return(false);
                    }));

                    await result.Task;
                }
            }

            Console.WriteLine("VerifyDataOnIoTHub completed.");
            await eventHubReceiver.CloseAsync();

            await eventHubClient.CloseAsync();
        }
示例#11
0
        /// <summary>
        ///   Performs the tasks needed to clean up the environment for an instance
        ///   of the test scenario.  When multiple instances are run in parallel, cleanup
        ///   will be run once for each after execution has completed.
        /// </summary>
        ///
        public async override Task CleanupAsync()
        {
            await _client.CloseAsync().ConfigureAwait(false);

            await _receiver.CloseAsync().ConfigureAwait(false);

            await base.CleanupAsync().ConfigureAwait(false);
        }
示例#12
0
        private async Task ReceiverPumpAsync(PartitionReceiver receiver, Func <IReadOnlyCollection <QueueMessage>, Task> onMessage, int maxBatchSize, CancellationToken cancellationToken)
        {
            while (true)
            {
                try
                {
                    IEnumerable <EventData> events = await receiver.ReceiveAsync(maxBatchSize, _waitTime);

                    if (events != null && !cancellationToken.IsCancellationRequested)
                    {
                        List <QueueMessage> qms = events.Select(ed => Converter.ToQueueMessage(ed, receiver.PartitionId)).ToList();
                        await onMessage(qms);

                        QueueMessage lastMessage = qms.LastOrDefault();

                        //save state
                        if (lastMessage != null)
                        {
                            const string sequenceNumberPropertyName = "x-opt-sequence-number";

                            if (lastMessage.Properties.TryGetValue(sequenceNumberPropertyName, out string sequenceNumber))
                            {
                                long?sequenceNumberLong = null;
                                if (long.TryParse(sequenceNumber, out long seqenceNumberNonNullable))
                                {
                                    sequenceNumberLong = seqenceNumberNonNullable;
                                }

                                await _state.SetPartitionStateAsync(receiver.PartitionId, sequenceNumberLong);
                            }
                        }
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        await receiver.CloseAsync();

                        return;
                    }
                }
                catch (ArgumentException ex)
                {
                    Console.WriteLine("failed with message: '{0}', clearing partition state.", ex);

                    await _state.SetPartitionStateAsync(receiver.PartitionId, EventPosition.FromStart().SequenceNumber);
                }
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("receiver stopped: {0}", ex);

                    return;
                }
            }
        }
示例#13
0
        public async Task CloseAsyncClosesTheTransportConsumer()
        {
            var transportConsumer = new ObservableTransportConsumerMock();
            var receiver          = new PartitionReceiver("group", "0", "hub", true, TimeSpan.Zero, transportConsumer);

            await receiver.CloseAsync();

            Assert.That(transportConsumer.WasCloseCalled, Is.True);
        }
示例#14
0
文件: Details.cs 项目: nlcamp/iotedge
        protected async Task VerifyDataOnIoTHubAsync()
        {
            // Leaf device without parent not expected to send messages
            if (!this.edgeDeviceId.HasValue)
            {
                return;
            }

            var builder = new EventHubsConnectionStringBuilder(this.eventhubCompatibleEndpointWithEntityPath)
            {
                TransportType = this.eventHubClientTransportType
            };

            Console.WriteLine($"Receiving events from device '{this.context.Device.Id}' on Event Hub '{builder.EntityPath}'");

            EventHubClient eventHubClient =
                EventHubClient.CreateFromConnectionString(builder.ToString());

            this.proxy.ForEach(p => eventHubClient.WebProxy = p);

            PartitionReceiver eventHubReceiver = eventHubClient.CreateReceiver(
                "$Default",
                EventHubPartitionKeyResolver.ResolveToPartition(
                    this.context.Device.Id,
                    (await eventHubClient.GetRuntimeInformationAsync()).PartitionCount),
                EventPosition.FromEnqueuedTime(DateTime.Now.AddMinutes(-5)));

            var result = new TaskCompletionSource <bool>();

            using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3)))
            {
                using (cts.Token.Register(() => result.TrySetCanceled()))
                {
                    eventHubReceiver.SetReceiveHandler(
                        new PartitionReceiveHandler(
                            eventData =>
                    {
                        eventData.SystemProperties.TryGetValue("iothub-connection-device-id", out var devId);

                        if (devId != null && devId.ToString().Equals(this.context.Device.Id, StringComparison.Ordinal) &&
                            Encoding.UTF8.GetString(eventData.Body).Contains(this.context.MessageGuid, StringComparison.Ordinal))
                        {
                            result.TrySetResult(true);
                            return(true);
                        }

                        return(false);
                    }));

                    await result.Task;
                }
            }

            await eventHubReceiver.CloseAsync();

            await eventHubClient.CloseAsync();
        }
示例#15
0
        async Task PartitionReceiverSetReceiveHandler()
        {
            Log("Receiving Events via PartitionReceiver.SetReceiveHandler()");
            string            partitionId       = "1";
            PartitionReceiver partitionReceiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, partitionId, DateTime.UtcNow.AddMinutes(-10));
            PartitionSender   partitionSender   = this.EventHubClient.CreatePartitionSender(partitionId);

            try
            {
                string uniqueEventId = Guid.NewGuid().ToString();
                Log($"Sending an event to Partition {partitionId} with custom property EventId {uniqueEventId}");
                var sendEvent = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!"));
                sendEvent.Properties = new Dictionary <string, object> {
                    ["EventId"] = uniqueEventId
                };
                await partitionSender.SendAsync(sendEvent);

                EventWaitHandle dataReceivedEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
                var             handler           = new TestPartitionReceiveHandler();
                handler.ErrorReceived  += (s, e) => Log($"TestPartitionReceiveHandler.ProcessError {e.GetType().Name}: {e.Message}");
                handler.EventsReceived += (s, eventDatas) =>
                {
                    int count = eventDatas != null?eventDatas.Count() : 0;

                    Log($"Received {count} event(s):");

                    foreach (var eventData in eventDatas)
                    {
                        object objectValue;
                        if (eventData.Properties != null && eventData.Properties.TryGetValue("EventId", out objectValue))
                        {
                            Log($"Received message with EventId {objectValue}");
                            string receivedId = objectValue.ToString();
                            if (receivedId == uniqueEventId)
                            {
                                Log("Success");
                                dataReceivedEvent.Set();
                                break;
                            }
                        }
                    }
                };

                partitionReceiver.SetReceiveHandler(handler);

                if (!dataReceivedEvent.WaitOne(TimeSpan.FromSeconds(20)))
                {
                    throw new InvalidOperationException("Data Received Event was not signaled.");
                }
            }
            finally
            {
                await partitionSender.CloseAsync();

                await partitionReceiver.CloseAsync();
            }
        }
        async Task SendReceiveNonexistentEntity()
        {
            // Rebuild connection string with a nonexistent entity.
            var csb = new EventHubsConnectionStringBuilder(this.connectionString);

            csb.EntityPath = Guid.NewGuid().ToString();
            var ehClient = EventHubClient.CreateFromConnectionString(csb.ToString());

            // Try sending.
            PartitionSender sender = null;
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                Log("Sending an event to nonexistent entity.");
                sender = ehClient.CreatePartitionSender("0");
                await sender.SendAsync(new EventData(Encoding.UTF8.GetBytes("this send should fail.")));
                throw new InvalidOperationException("Send should have failed");
            });

            await sender.CloseAsync();

            // Try receiving.
            PartitionReceiver receiver = null;
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                Log("Receiving from nonexistent entity.");
                receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", PartitionReceiver.StartOfStream);
                await receiver.ReceiveAsync(1);
                throw new InvalidOperationException("Receive should have failed");
            });

            await receiver.CloseAsync();

            // Try receiving on an nonexistent consumer group.
            ehClient = EventHubClient.CreateFromConnectionString(this.connectionString);
            await Assert.ThrowsAsync <MessagingEntityNotFoundException>(async() =>
            {
                Log("Receiving from nonexistent consumer group.");
                receiver = ehClient.CreateReceiver(Guid.NewGuid().ToString(), "0", PartitionReceiver.StartOfStream);
                await receiver.ReceiveAsync(1);
                throw new InvalidOperationException("Receive should have failed");
            });

            await receiver.CloseAsync();
        }
        private static async Task Stop(EventHubClient client, PartitionReceiver receiver)
        {
            _receive = false;
            Console.WriteLine("Stoping...");
            await receiver.CloseAsync();

            await client.CloseAsync();

            Console.WriteLine("The end");
        }
示例#18
0
        // Send and receive given event on given partition.
        protected async Task <EventData> SendAndReceiveEventAsync(string partitionId, EventData sendEvent, EventHubClient client)
        {
            PartitionSender   partitionSender   = client.CreatePartitionSender(partitionId);
            PartitionReceiver partitionReceiver = client.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, partitionId, EventPosition.FromEnqueuedTime(DateTime.UtcNow.AddMinutes(-10)));

            EventData receivedEvent = null;

            try
            {
                string uniqueEventId = Guid.NewGuid().ToString();
                TestUtility.Log($"Sending event to Partition {partitionId} with custom property EventId {uniqueEventId}");
                sendEvent.Properties["EventId"] = uniqueEventId;
                await partitionSender.SendAsync(sendEvent);

                bool expectedEventReceived = false;
                do
                {
                    IEnumerable <EventData> eventDatas = await partitionReceiver.ReceiveAsync(10);

                    if (eventDatas == null)
                    {
                        break;
                    }

                    TestUtility.Log($"Received a batch of {eventDatas.Count()} events:");
                    foreach (var eventData in eventDatas)
                    {
                        object objectValue;

                        if (eventData.Properties != null && eventData.Properties.TryGetValue("EventId", out objectValue))
                        {
                            TestUtility.Log($"Received message with EventId {objectValue}");
                            string receivedId = objectValue.ToString();
                            if (receivedId == uniqueEventId)
                            {
                                TestUtility.Log("Success");
                                receivedEvent         = eventData;
                                expectedEventReceived = true;
                                break;
                            }
                        }
                    }
                }while (!expectedEventReceived);

                Assert.True(expectedEventReceived, $"Did not receive expected event with EventId {uniqueEventId}");
            }
            finally
            {
                await Task.WhenAll(
                    partitionReceiver.CloseAsync(),
                    partitionSender.CloseAsync());
            }

            return(receivedEvent);
        }
示例#19
0
        async Task PartitionReceiverReceive()
        {
            Log("Receiving Events via PartitionReceiver.ReceiveAsync");
            const string      partitionId       = "1";
            PartitionSender   partitionSender   = this.EventHubClient.CreatePartitionSender(partitionId);
            PartitionReceiver partitionReceiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, partitionId, DateTime.UtcNow.AddMinutes(-10));

            try
            {
                string uniqueEventId = Guid.NewGuid().ToString();
                Log($"Sending an event to Partition {partitionId} with custom property EventId {uniqueEventId}");
                var sendEvent = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!"));
                sendEvent.Properties = new Dictionary <string, object> {
                    ["EventId"] = uniqueEventId
                };
                await partitionSender.SendAsync(sendEvent);

                bool expectedEventReceived = false;
                do
                {
                    IEnumerable <EventData> eventDatas = await partitionReceiver.ReceiveAsync(10);

                    if (eventDatas == null)
                    {
                        break;
                    }

                    Log($"Received a batch of {eventDatas.Count()} events:");
                    foreach (var eventData in eventDatas)
                    {
                        object objectValue;
                        if (eventData.Properties != null && eventData.Properties.TryGetValue("EventId", out objectValue))
                        {
                            Log($"Received message with EventId {objectValue}");
                            string receivedId = objectValue.ToString();
                            if (receivedId == uniqueEventId)
                            {
                                Log("Success");
                                expectedEventReceived = true;
                                break;
                            }
                        }
                    }
                }while (!expectedEventReceived);

                Assert.True(expectedEventReceived, $"Did not receive expected event with EventId {uniqueEventId}");
            }
            finally
            {
                await Task.WhenAll(
                    partitionReceiver.CloseAsync(),
                    partitionSender.CloseAsync());
            }
        }
示例#20
0
        async Task ReceiveFromInvalidPartition()
        {
            PartitionReceiver receiver = null;

            // Some invalid partition values. These will fail on the service side.
            var invalidPartitions = new List <string>()
            {
                "XYZ", "-1", "1000", "-"
            };

            foreach (var invalidPartitionId in invalidPartitions)
            {
                await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() =>
                {
                    TestUtility.Log($"Receiving from invalid partition {invalidPartitionId}");
                    receiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, invalidPartitionId, EventPosition.FromStart());
                    await receiver.ReceiveAsync(1);
                    throw new InvalidOperationException("Receive call should have failed");
                });

                await receiver.CloseAsync();
            }

            // Some invalid partition values. These will fail on the client side.
            invalidPartitions = new List <string>()
            {
                " ", null, ""
            };
            foreach (var invalidPartitionId in invalidPartitions)
            {
                await Assert.ThrowsAsync <InvalidOperationException>(async() =>
                {
                    TestUtility.Log($"Receiving from invalid partition {invalidPartitionId}");
                    receiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, invalidPartitionId, EventPosition.FromStart());
                    await receiver.ReceiveAsync(1);
                    throw new InvalidOperationException("Receive call should have failed");
                });

                await receiver.CloseAsync();
            }
        }
示例#21
0
        /// <inheritdoc />
        public BoolResult SuspendProcessing(OperationContext context)
        {
            // In unit tests, hangs sometimes occur for this when running multiple tests in sequence.
            // Adding a timeout to detect when this occurs
            if (_partitionReceiver != null)
            {
                _partitionReceiver.CloseAsync().WithTimeoutAsync(TimeSpan.FromMinutes(1)).GetAwaiter().GetResult();
                _partitionReceiver = null;
            }

            return(BoolResult.Success);
        }
        public async Task UseSharedAccessSignature()
        {
            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var csb           = new EventHubsConnectionStringBuilder(connectionString);
                var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(csb.SasKeyName, csb.SasKey);
                var token         = await tokenProvider.GetTokenAsync(csb.Endpoint.ToString(), TimeSpan.FromSeconds(120));

                var sas = token.TokenValue.ToString();

                // Update connection string builder to use shared access signature instead.
                csb.SasKey                = "";
                csb.SasKeyName            = "";
                csb.SharedAccessSignature = sas;

                // Create new client with updated connection string.
                var ehClient = EventHubClient.CreateFromConnectionString(csb.ToString());

                // Send one event
                TestUtility.Log($"Sending one message.");
                var ehSender  = ehClient.CreatePartitionSender("0");
                var eventData = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!"));
                await ehSender.SendAsync(eventData);

                // Receive event.
                PartitionReceiver ehReceiver = null;
                try
                {
                    TestUtility.Log($"Receiving one message.");
                    ehReceiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromStart());
                    var msg = await ehReceiver.ReceiveAsync(1);

                    Assert.True(msg != null, "Failed to receive message.");
                }
                finally
                {
                    await ehReceiver?.CloseAsync();
                }

                // Get EH runtime information.
                TestUtility.Log($"Getting Event Hub runtime information.");
                var ehInfo = await ehClient.GetRuntimeInformationAsync();

                Assert.True(ehInfo != null, "Failed to get runtime information.");

                // Get EH partition runtime information.
                TestUtility.Log($"Getting Event Hub partition '0' runtime information.");
                var partitionInfo = await ehClient.GetPartitionRuntimeInformationAsync("0");

                Assert.True(ehInfo != null, "Failed to get runtime partition information.");
            }
        }
        //// This function create a device with x509 cert and send a message to the iothub on the transport specified.
        //// It then verifies the message is received at the eventHubClient.
        internal async Task SendSingleMessageX509(Client.TransportType transport)
        {
            // TODO: Update Jenkins Config
            string endpoint = Configuration.IoTHub.EventHubString;

            if (endpoint.IsNullOrWhiteSpace())
            {
                return;
            }

            Tuple <string, string> deviceInfo = TestUtil.CreateDeviceWithX509(DevicePrefix, hostName, registryManager);

            EventHubClient    eventHubClient;
            PartitionReceiver eventHubReceiver = await CreateEventHubReceiver(deviceInfo.Item1).ConfigureAwait(false);

            X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey();

            var auth         = new DeviceAuthenticationWithX509Certificate(deviceInfo.Item1, cert);
            var deviceClient = DeviceClient.Create(deviceInfo.Item2, auth, transport);

            try
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);

                string         payload;
                string         p1Value;
                Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
                await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

                bool      isReceived = false;
                Stopwatch sw         = new Stopwatch();
                sw.Start();
                while (!isReceived && sw.Elapsed.Minutes < 1)
                {
                    var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)).ConfigureAwait(false);

                    isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);
                }

                sw.Stop();

                Assert.IsTrue(isReceived, "Message is not received.");
            }
            finally
            {
                await deviceClient.CloseAsync().ConfigureAwait(false);

                await eventHubReceiver.CloseAsync().ConfigureAwait(false);

                await TestUtil.RemoveDeviceAsync(deviceInfo.Item1, registryManager).ConfigureAwait(false);
            }
        }
        // Sends single message to given partition and returns it after receiving.
        async Task <EventData> SendAndReceiveSingleEvent(string partitionId)
        {
            var eDataToSend = new EventData(new byte[1]);

            // Stamp this message so we can recognize it when received.
            var stampValue = Guid.NewGuid().ToString();
            var sendEvent  = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!"));

            eDataToSend.Properties = new Dictionary <string, object>
            {
                { "stamp", stampValue }
            };
            PartitionSender partitionSender = this.EventHubClient.CreatePartitionSender(partitionId);

            Log($"Sending single event to partition {partitionId} with stamp {stampValue}");
            await partitionSender.SendAsync(eDataToSend);

            Log($"Receiving all messages from partition {partitionId}");
            PartitionReceiver receiver = null;

            try
            {
                receiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName,
                                                              partitionId, PartitionReceiver.StartOfStream);
                while (true)
                {
                    var receivedEvents = await receiver.ReceiveAsync(100);

                    if (receivedEvents == null || receivedEvents.Count() == 0)
                    {
                        throw new Exception("Not able to receive stamped message!");
                    }

                    Log($"Received {receivedEvents.Count()} event(s) in batch where last event is sent on {receivedEvents.Last().SystemProperties.EnqueuedTimeUtc}");

                    // Continue until we locate stamped message.
                    foreach (var receivedEvent in receivedEvents)
                    {
                        if (receivedEvent.Properties != null &&
                            receivedEvent.Properties.ContainsKey("stamp") &&
                            receivedEvent.Properties["stamp"].ToString() == eDataToSend.Properties["stamp"].ToString())
                        {
                            return(receivedEvent);
                        }
                    }
                }
            }
            finally
            {
                await receiver.CloseAsync();
            }
        }
        internal async Task SendMessageThrottledForHttp()
        {
            // TODO: Update Jenkins Config
            if (Configuration.IoTHub.EventHubString.IsNullOrWhiteSpace())
            {
                return;
            }
            await sequentialTestSemaphore.WaitAsync();

            Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager);

            EventHubClient    eventHubClient;
            PartitionReceiver eventHubReceiver = await CreateEventHubReceiver(deviceInfo.Item1);

            var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, Client.TransportType.Http1);

            try
            {
                deviceClient.OperationTimeoutInMilliseconds = (uint)TestUtil.ShortRetryInMilliSec;
                await deviceClient.OpenAsync();

                string         payload, p1Value;
                Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
                await deviceClient.SendEventAsync(testMessage);

                bool      isReceived = false;
                Stopwatch sw         = new Stopwatch();
                sw.Start();
                while (!isReceived && sw.Elapsed.Minutes < 1)
                {
                    var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

                    isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);
                }
                sw.Stop();

                // Implementation of error injection of throttling on http is that it will throttle the
                // fault injection message itself only.  The duration of fault has no effect on http throttle.
                // Client is supposed to retry sending the throttling fault message until operation timeout.
                await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(TestUtil.FaultType_Throttle,
                                                                                           TestUtil.FaultCloseReason_Boom, TestUtil.DefaultDelayInSec, TestUtil.DefaultDurationInSec));
            }
            finally
            {
                await deviceClient.CloseAsync();

                await eventHubReceiver.CloseAsync();

                sequentialTestSemaphore.Release(1);
            }
        }
示例#26
0
        private async Task RunEndlessStreamAnalysesAsync(CancellationToken cancellationToken)
        {
            string info1 = $"RouterService RunEndlessStreamAnalysesAsync is starting at partition ={Context.PartitionId} at {DateTimeOffset.UtcNow}.";

            ServiceEventSource.Current.ServiceMessage(this.Context, info1);

            // this Reliable Dictionary is used to keep track of our position in Event Hub.
            // If this service fails over, this will allow it to pick up where it left off in the event stream.
            IReliableDictionary <string, string> streamOffsetDictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <string, string> >(Names.EventHubOffsetDictionaryName);

            PartitionReceiver partitionReceiver = null;

            try
            {
                partitionReceiver = await ConnectToEventHubAsync(_settings.EventHubConnectionString, _settings.EventHubName, streamOffsetDictionary);

                //using (HttpClient httpClient = new HttpClient(new HttpServiceClientHandler()))
                //{
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    await MicroProcessEventHubPartitionStreamAsync(cancellationToken, partitionReceiver);
                }
                //}
            }
            catch (Exception exception)
            {
                string err = $"RouterService RunEndlessStreamAnalysesAsync met exception, event hub partition={_eventHubPartitionId}, " +
                             $"exception type={exception.GetType().Name}, exception= {exception.Message}, at partition ={Context.PartitionId}.";

                //ServiceEventSource.Current.CriticalError("RouterService", err);

                //ReportHealthError(cancellationToken, err);

                throw;
            }
            finally
            {
                if (partitionReceiver != null)
                {
                    await partitionReceiver.CloseAsync();
                }

                string info = $"RouterService RunEndlessStreamAnalysesAsync stopped when event hub partition={_eventHubPartitionId}," +
                              $" partition ={Context.PartitionId} at {DateTimeOffset.UtcNow}.";

                //ServiceEventSource.Current.CriticalError("RouterService", info);
            }
        }
示例#27
0
        protected async Task VerifyDataOnIoTHub(string moduleId)
        {
            var builder = new EventHubsConnectionStringBuilder(this.eventhubCompatibleEndpointWithEntityPath);

            builder.TransportType = this.eventHubClientTransportType;

            Console.WriteLine($"Receiving events from device '{this.context.Device.Id}' on Event Hub '{builder.EntityPath}'");

            EventHubClient eventHubClient =
                EventHubClient.CreateFromConnectionString(builder.ToString());

            PartitionReceiver eventHubReceiver = eventHubClient.CreateReceiver(
                "$Default",
                EventHubPartitionKeyResolver.ResolveToPartition(
                    this.context.Device.Id,
                    (await eventHubClient.GetRuntimeInformationAsync()).PartitionCount),
                EventPosition.FromEnd());

            var result = new TaskCompletionSource <bool>();

            using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10)))
            {
                using (cts.Token.Register(() => result.TrySetCanceled()))
                {
                    eventHubReceiver.SetReceiveHandler(
                        new PartitionReceiveHandler(
                            eventData =>
                    {
                        eventData.SystemProperties.TryGetValue("iothub-connection-device-id", out object devId);
                        eventData.SystemProperties.TryGetValue("iothub-connection-module-id", out object modId);

                        if (devId != null && devId.ToString().Equals(this.context.Device.Id) &&
                            modId != null && modId.ToString().Equals(moduleId))
                        {
                            result.TrySetResult(true);
                            return(true);
                        }

                        return(false);
                    }));

                    await result.Task;
                }
            }

            Console.WriteLine("VerifyDataOnIoTHub completed.");
            await eventHubReceiver.CloseAsync();

            await eventHubClient.CloseAsync();
        }
        async Task DefaultBehaviorNoInvokeOnNull()
        {
            PartitionReceiver partitionReceiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromEnd());

            try
            {
                EventWaitHandle nullReceivedEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
                EventWaitHandle dataReceivedEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
                var             handler           = new TestPartitionReceiveHandler();

                handler.EventsReceived += (s, eventDatas) =>
                {
                    if (eventDatas == null)
                    {
                        TestUtility.Log("Received null.");
                        nullReceivedEvent.Set();
                    }
                    else
                    {
                        TestUtility.Log("Received message.");
                        dataReceivedEvent.Set();
                    }
                };

                partitionReceiver.SetReceiveHandler(handler);

                if (nullReceivedEvent.WaitOne(TimeSpan.FromSeconds(120)))
                {
                    throw new InvalidOperationException("Received null.");
                }

                // Send one message. Pump should receive this.
                await TestUtility.SendToPartitionAsync(this.EventHubClient, "0", "new event");

                if (!dataReceivedEvent.WaitOne(TimeSpan.FromSeconds(60)))
                {
                    throw new InvalidOperationException("Data Received Event was not signaled.");
                }
            }
            finally
            {
                // Unregister handler.
                partitionReceiver.SetReceiveHandler(null);

                // Close clients.
                await partitionReceiver.CloseAsync();
            }
        }
        public async Task UseITokenProviderWithAad()
        {
            var appAuthority = "";
            var aadAppId     = "";
            var aadAppSecret = "";

            AzureActiveDirectoryTokenProvider.AuthenticationCallback authCallback =
                async(audience, authority, state) =>
            {
                var authContext = new AuthenticationContext(authority);
                var cc          = new ClientCredential(aadAppId, aadAppSecret);
                var authResult  = await authContext.AcquireTokenAsync(audience, cc);

                return(authResult.AccessToken);
            };

            var tokenProvider = TokenProvider.CreateAzureActiveDirectoryTokenProvider(authCallback, appAuthority);

            // Create new client with updated connection string.
            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var csb      = new EventHubsConnectionStringBuilder(connectionString);
                var ehClient = EventHubClient.CreateWithTokenProvider(csb.Endpoint, csb.EntityPath, tokenProvider);

                // Send one event
                TestUtility.Log($"Sending one message.");
                var ehSender  = ehClient.CreatePartitionSender("0");
                var eventData = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!"));
                await ehSender.SendAsync(eventData);

                // Receive event.
                PartitionReceiver ehReceiver = null;
                try
                {
                    TestUtility.Log($"Receiving one message.");
                    ehReceiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromStart());
                    var msg = await ehReceiver.ReceiveAsync(1);

                    Assert.True(msg != null, "Failed to receive message.");
                }
                finally
                {
                    await ehReceiver?.CloseAsync();
                }
            }
        }
示例#30
0
        async Task PartitionReceiverReceiveBatch()
        {
            const int MaxBatchSize = 5;

            TestUtility.Log("Receiving Events via PartitionReceiver.ReceiveAsync(BatchSize)");
            const string      partitionId       = "0";
            PartitionSender   partitionSender   = this.EventHubClient.CreatePartitionSender(partitionId);
            PartitionReceiver partitionReceiver = this.EventHubClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, partitionId, DateTime.UtcNow.AddMinutes(-10));

            try
            {
                int eventCount = 20;
                TestUtility.Log($"Sending {eventCount} events to Partition {partitionId}");
                var sendEvents = new List <EventData>(eventCount);
                for (int i = 0; i < eventCount; i++)
                {
                    sendEvents.Add(new EventData(Encoding.UTF8.GetBytes($"Hello EventHub! Message {i}")));
                }
                await partitionSender.SendAsync(sendEvents);

                int maxReceivedBatchSize = 0;
                while (true)
                {
                    IEnumerable <EventData> partition1Events = await partitionReceiver.ReceiveAsync(MaxBatchSize);

                    int receivedEventCount = partition1Events != null?partition1Events.Count() : 0;

                    TestUtility.Log($"Received {receivedEventCount} event(s)");

                    if (partition1Events == null)
                    {
                        break;
                    }

                    maxReceivedBatchSize = Math.Max(maxReceivedBatchSize, receivedEventCount);
                }

                Assert.True(maxReceivedBatchSize == MaxBatchSize, $"A max batch size of {MaxBatchSize} events was not honored! Actual {maxReceivedBatchSize}.");
            }
            finally
            {
                await partitionReceiver.CloseAsync();

                await partitionSender.CloseAsync();
            }
        }