public void ShouldRaiseFlushFailedOnFlushAsyncWhenHttpClientFails() { var httpClient = HttpClientTestHelper.Create(); httpClient.When(client => client.PostAsync(Arg.Any<string>(), Arg.Any<HttpContent>())).Do(action => { throw new Exception(); }); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) using (var collectErrorsListener = new MockEventListener()) { collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All); sink.OnNext(EventEntryTestHelper.Create()); try { sink.FlushAsync().Wait(); Assert.Fail("AggregateException should be thrown."); } catch (AggregateException ex) { Assert.IsInstanceOfType(ex.InnerException, typeof(FlushFailedException)); } Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1)); } }
public void ShouldRaiseFlushFailedOnFlushAsyncWhenHttpClientFails() { var httpClient = HttpClientTestHelper.Create(); httpClient.When(client => client.PostAsync(Arg.Any <string>(), Arg.Any <HttpContent>())).Do(action => { throw new Exception(); }); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) using (var collectErrorsListener = new MockEventListener()) { collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All); sink.OnNext(EventEntryTestHelper.Create()); try { sink.FlushAsync().Wait(); Assert.Fail("AggregateException should be thrown."); } catch (AggregateException ex) { Assert.IsInstanceOfType(ex.InnerException, typeof(FlushFailedException)); } Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1)); } }
public async Task ShouldWritePropertiesForBatchMessage() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any <string>(), Arg.Any <HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); var entry = EventEntryTestHelper.Create(); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) { sink.OnNext(entry); sink.OnNext(entry); await sink.FlushAsync(); } IList <EventEntry> entries = new List <EventEntry> { entry, entry }; var messages = entries.Select(c => c.ToBatchMessage()); var sendMessage = new ServiceBusHttpMessage { Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(messages)) }; var byteRepresentation = sendMessage.Body; await httpClient.Received().PostAsync(Arg.Any <string>(), Arg.Is <HttpContent>(c => byteRepresentation.SequenceEqual(c.ReadAsByteArrayAsync().Result))); }
public void ShouldNotStallOrThrowWhenHttpClientFails() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any<string>(), Arg.Any<HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.InternalServerError))); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) using (var collectErrorsListener = new MockEventListener()) { collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All); sink.OnNext(EventEntryTestHelper.Create()); Assert.IsTrue(Task.Run(() => sink.OnCompleted()).Wait(TimeSpan.FromSeconds(5))); Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1)); } }
public async Task ShouldWriteEntriesOnFlushAsync() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any <string>(), Arg.Any <HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) { sink.OnNext(EventEntryTestHelper.Create()); sink.OnNext(EventEntryTestHelper.Create()); await sink.FlushAsync(); } await httpClient.Received().PostAsync(Arg.Any <string>(), Arg.Any <HttpContent>()); }
/// <summary> /// Subscribes to an <see cref="IObservable{EventEntry}" /> using an <see cref="EventHubHttpSink" />. /// </summary> /// <param name="eventStream">The event stream. Typically this is an instance of <see cref="ObservableEventListener" />.</param> /// <param name="eventHubNamespace">The namespace of the eventhub.</param> /// <param name="eventHubName">The name of the eventhub.</param> /// <param name="publisherId">The id of the event publisher.</param> /// <param name="sasToken">The shared access signature token.</param> /// <param name="bufferingInterval">The buffering interval between each batch publishing.</param> /// <param name="bufferingCount">The number of entries that will trigger a batch publishing.</param> /// <param name="maxBufferSize">The maximum number of entries that can be buffered while it's sending to the store before the sink starts dropping entries.</param> /// <param name="onCompletedTimeout">Defines a timeout interval for when flushing the entries after an <see cref="OnCompleted"/> call is received and before disposing the sink. /// This means that if the timeout period elapses, some event entries will be dropped and not sent to the store. Normally, calling <see cref="IDisposable.Dispose"/> on /// the <see cref="System.Diagnostics.Tracing.EventListener"/> will block until all the entries are flushed or the interval elapses. /// If <see langword="null"/> is specified, then the call will block indefinitely until the flush operation finishes.</param> /// <returns> /// A subscription to the sink that can be disposed to unsubscribe the sink and dispose it, or to get access to the sink instance. /// </returns> public static SinkSubscription<EventHubHttpSink> LogToEventHubUsingHttp(this IObservable<EventEntry> eventStream, string eventHubNamespace, string eventHubName, string publisherId, string sasToken, TimeSpan? bufferingInterval = null, int bufferingCount = Buffering.DefaultBufferingCount, TimeSpan? onCompletedTimeout = null, int maxBufferSize = Buffering.DefaultMaxBufferSize) { var sink = new EventHubHttpSink( eventHubNamespace, eventHubName, publisherId, sasToken, bufferingInterval ?? Buffering.DefaultBufferingInterval, bufferingCount, maxBufferSize, onCompletedTimeout ?? Timeout.InfiniteTimeSpan ); var subscription = eventStream.Subscribe(sink); return new SinkSubscription<EventHubHttpSink>(subscription, sink); }
public void ShouldNotStallOrThrowWhenHttpClientFails() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any <string>(), Arg.Any <HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.InternalServerError))); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) using (var collectErrorsListener = new MockEventListener()) { collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All); sink.OnNext(EventEntryTestHelper.Create()); Assert.IsTrue(Task.Run(() => sink.OnCompleted()).Wait(TimeSpan.FromSeconds(5))); Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1)); } }
public async Task ShouldWritePropertiesForBatchMessageUsingAutoSizedBatch() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any <string>(), Arg.Any <HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); var entry = EventEntryTestHelper.Create(); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, 0, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) { foreach (var i in Enumerable.Range(0, 500)) { sink.OnNext(entry); } await sink.FlushAsync(); } await httpClient.Received(2).PostAsync(Arg.Any <string>(), Arg.Is <HttpContent>(c => c.Headers.ContentLength < 256 * 1024)); }
public async Task ShouldNotUseBatchMessagesWhenBatchCountSetToOne() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any <string>(), Arg.Any <HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); var entry = EventEntryTestHelper.Create(); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, 1, 500, TimeSpan.Zero)) { sink.OnNext(entry); sink.OnNext(entry); await sink.FlushAsync(); } var byteRepresentation = Encoding.Default.GetBytes(JsonConvert.SerializeObject(entry)); await httpClient.Received(2).PostAsync(Arg.Any <string>(), Arg.Is <HttpContent>(c => byteRepresentation.SequenceEqual(c.ReadAsByteArrayAsync().Result))); }
public async Task ShouldWriteEntriesOnFlushAsync() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any<string>(), Arg.Any<HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) { sink.OnNext(EventEntryTestHelper.Create()); sink.OnNext(EventEntryTestHelper.Create()); await sink.FlushAsync(); } await httpClient.Received().PostAsync(Arg.Any<string>(), Arg.Any<HttpContent>()); }
public async Task ShouldWritePropertiesForBatchMessage() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any<string>(), Arg.Any<HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); var entry = EventEntryTestHelper.Create(); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero)) { sink.OnNext(entry); sink.OnNext(entry); await sink.FlushAsync(); } IList<EventEntry> entries = new List<EventEntry> { entry, entry }; var messages = entries.Select(c => c.ToBatchMessage()); var sendMessage = new ServiceBusHttpMessage { Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(messages)) }; var byteRepresentation = sendMessage.Body; await httpClient.Received().PostAsync(Arg.Any<string>(), Arg.Is<HttpContent>(c => byteRepresentation.SequenceEqual(c.ReadAsByteArrayAsync().Result))); }
public async Task ShouldNotUseBatchMessagesWhenBatchCountSetToOne() { var httpClient = HttpClientTestHelper.Create(); httpClient.PostAsync(Arg.Any<string>(), Arg.Any<HttpContent>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); var entry = EventEntryTestHelper.Create(); using (var sink = new EventHubHttpSink(httpClient, "eventHubNameNs", "eventhubName", "pubId", "token", Buffering.DefaultBufferingInterval, 1, 500, TimeSpan.Zero)) { sink.OnNext(entry); sink.OnNext(entry); await sink.FlushAsync(); } var byteRepresentation = Encoding.Default.GetBytes(JsonConvert.SerializeObject(entry)); await httpClient.Received(2).PostAsync(Arg.Any<string>(), Arg.Is<HttpContent>(c => byteRepresentation.SequenceEqual(c.ReadAsByteArrayAsync().Result))); }