public void TestFallback() { var endpoint1 = new NullEndpoint("id1"); var endpoint2 = new NullEndpoint("id2"); var allEndpoints = new HashSet <Endpoint> { endpoint1, endpoint2 }; var route1 = new Route("id1", "key1 = 'value1'", "hub", TelemetryMessageSource.Instance, new HashSet <Endpoint> { endpoint1 }); var fallback = new Route("$fallback", "true", "hub", InvalidMessageSource, new HashSet <Endpoint> { endpoint2 }); var routes = new HashSet <Route> { route1 }; var evaluator = new Evaluator(new RouterConfig(allEndpoints, routes, Option.Some(fallback))); ISet <Endpoint> result1 = evaluator.Evaluate(Message1); Assert.Equal(1, result1.Count); Assert.Contains(endpoint1, result1); ISet <Endpoint> result2 = evaluator.Evaluate(Message4); Assert.Equal(1, result2.Count); Assert.Contains(endpoint2, result2); // non-telemetry messages should not send to the fallback ISet <Endpoint> result3 = evaluator.Evaluate(InvalidMessage); Assert.Equal(0, result3.Count); }
public void TestMessageSource() { var endpoint1 = new NullEndpoint("id1"); var endpoint3 = new NullEndpoint("id3"); var allEndpoints = new HashSet <Endpoint> { endpoint1, endpoint3 }; var route1 = new Route("id1", "true", "hub", TelemetryMessageSource.Instance, new HashSet <Endpoint> { endpoint1 }); var route3 = new Route("id3", "true", "hub", InvalidMessageSource, new HashSet <Endpoint> { endpoint3 }); var routes = new HashSet <Route> { route1, route3 }; var evaluator = new Evaluator(new RouterConfig(allEndpoints, routes)); NullEndpoint[] expected = new[] { endpoint1, endpoint3 }; IMessage[] messages = new[] { Message1, InvalidMessage }; foreach (Tuple <NullEndpoint, IMessage> pair in expected.Zip(messages, Tuple.Create)) { ISet <Endpoint> result = evaluator.Evaluate(pair.Item2); Assert.Equal(1, result.Count); Assert.Contains(pair.Item1, result); } }
public async Task TestSetEndpoint() { var endpoint1 = new TestEndpoint("id"); var endpoint2 = new NullEndpoint("id"); var endpoint3 = new TestEndpoint("id1"); ICheckpointer checkpointer = await Checkpointer.CreateAsync("cid", new CheckpointStore()); var endpointExecutorConfig = new EndpointExecutorConfig(TimeSpan.FromHours(1), RetryStrategy.NoRetry, TimeSpan.FromHours(1)); var asyncEndpointExecutorOptions = new AsyncEndpointExecutorOptions(1, TimeSpan.FromSeconds(1)); var messageStore = new TestMessageStore(); var executor = new StoringAsyncEndpointExecutor(endpoint1, checkpointer, endpointExecutorConfig, asyncEndpointExecutorOptions, messageStore); Assert.Equal(endpoint1, executor.Endpoint); await Assert.ThrowsAsync <ArgumentNullException>(() => executor.SetEndpoint(null)); await Assert.ThrowsAsync <ArgumentException>(() => executor.SetEndpoint(endpoint3)); await executor.SetEndpoint(endpoint2); Assert.Equal(endpoint2, executor.Endpoint); await executor.CloseAsync(); await Assert.ThrowsAsync <InvalidOperationException>(() => executor.SetEndpoint(endpoint1)); }
public async Task SmokeTest() { var store1 = new RouteStore(); RouterConfig config = await store1.GetRouterConfigAsync("hub", CancellationToken.None); Assert.Equal(0, config.Routes.Count); Endpoint endpoint1 = new NullEndpoint("endpoint1"); Endpoint endpoint2 = new NullEndpoint("endpoint2"); IEnumerable <Endpoint> allEndpoints = new List <Endpoint> { endpoint1, endpoint2 }; var route1 = new Route("id1", "true", "hub", TelemetryMessageSource.Instance, endpoint1, 0, 0); var route2 = new Route("id2", "false", "hub", TelemetryMessageSource.Instance, endpoint2, 0, 0); IEnumerable <Route> allRoutes = new List <Route> { route1, route2 }; var store2 = new RouteStore( new Dictionary <string, RouterConfig> { { "hub", new RouterConfig(allEndpoints, allRoutes) } }); RouterConfig config2 = await store2.GetRouterConfigAsync("hub", CancellationToken.None); Assert.True(config2.Routes.SetEquals(new HashSet <Route> { route1, route2 })); RouterConfig config3 = await store2.GetRouterConfigAsync("hub2", CancellationToken.None); Assert.Equal(0, config3.Routes.Count); }
public async Task TestCheckpoint() { var endpoint1 = new TestEndpoint("id1"); var checkpointer = new Mock <ICheckpointer>(); checkpointer.Setup(c => c.Admit(It.IsAny <IMessage>())).Returns(true); checkpointer.Setup(c => c.CommitAsync(It.IsAny <IMessage[]>(), It.IsAny <IMessage[]>(), It.IsAny <Option <DateTime> >(), It.IsAny <Option <DateTime> >(), It.IsAny <CancellationToken>())).Returns(TaskEx.Done); checkpointer.Setup(c => c.CommitAsync(It.IsAny <IMessage[]>(), It.IsAny <IMessage[]>(), It.IsAny <Option <DateTime> >(), It.IsAny <Option <DateTime> >(), It.IsAny <CancellationToken>())).Returns(TaskEx.Done); IEndpointExecutor executor1 = new SyncEndpointExecutor(endpoint1, checkpointer.Object); await executor1.Invoke(Message1, 0, 0); checkpointer.Verify(c => c.CommitAsync(new[] { Message1 }, new IMessage[0], It.IsAny <Option <DateTime> >(), It.IsAny <Option <DateTime> >(), It.IsAny <CancellationToken>()), Times.Exactly(1)); var endpoint2 = new NullEndpoint("id2"); var checkpointer2 = new Mock <ICheckpointer>(); checkpointer2.Setup(c => c.Admit(It.IsAny <IMessage>())).Returns(false); checkpointer2.Setup(c => c.CommitAsync(It.IsAny <IMessage[]>(), It.IsAny <IMessage[]>(), It.IsAny <Option <DateTime> >(), It.IsAny <Option <DateTime> >(), It.IsAny <CancellationToken>())).Returns(TaskEx.Done); checkpointer2.Setup(c => c.CommitAsync(It.IsAny <IMessage[]>(), It.IsAny <IMessage[]>(), It.IsAny <Option <DateTime> >(), It.IsAny <Option <DateTime> >(), It.IsAny <CancellationToken>())).Returns(TaskEx.Done); IEndpointExecutor executor2 = new SyncEndpointExecutor(endpoint2, checkpointer2.Object); await executor2.Invoke(Message1, 0, 0); checkpointer2.Verify(c => c.CommitAsync(It.IsAny <IMessage[]>(), It.IsAny <IMessage[]>(), It.IsAny <Option <DateTime> >(), It.IsAny <Option <DateTime> >(), It.IsAny <CancellationToken>()), Times.Never); await executor1.CloseAsync(); await executor2.CloseAsync(); }
public async Task InvokeTest() { // Arrange const int MessagesCount = 10; const string EndpointId = "endpoint1"; var endpoint = new NullEndpoint(EndpointId); var priorities = new List <uint>() { 0, 1, 2, 100, 101, 102 }; var checkpointer = new NullCheckpointer(); var endpointExecutorConfig = new EndpointExecutorConfig(TimeSpan.FromHours(1), RetryStrategy.NoRetry, TimeSpan.FromHours(1)); var asyncEndpointExecutorOptions = new AsyncEndpointExecutorOptions(10); var messageStore = new TestMessageStore(); var storingAsyncEndpointExecutor = new StoringAsyncEndpointExecutor(endpoint, priorities, checkpointer, endpointExecutorConfig, asyncEndpointExecutorOptions, messageStore); IEnumerable <IMessage> messages = GetNewMessages(MessagesCount, 0); // Act - Send messages to invoke foreach (IMessage message in messages) { await storingAsyncEndpointExecutor.Invoke(message, 0, 3600); } // Assert - Check that the message store received the messages sent to invoke. List <IMessage> storeMessages = messageStore.GetReceivedMessagesForEndpoint(EndpointId); Assert.NotNull(storeMessages); Assert.Equal(MessagesCount, storeMessages.Count); for (int i = 0; i < MessagesCount; i++) { IMessage message = storeMessages[i]; Assert.True(message.Properties.ContainsKey($"key{i}")); Assert.Equal($"value{i}", message.Properties[$"key{i}"]); } // Assert - Make sure no additional / duplicate messages were sent. storeMessages = messageStore.GetReceivedMessagesForEndpoint(EndpointId); Assert.NotNull(storeMessages); Assert.Equal(10, storeMessages.Count); // Act - Send messages again to Invoke. messages = GetNewMessages(MessagesCount, MessagesCount); foreach (IMessage message in messages) { await storingAsyncEndpointExecutor.Invoke(message, 0, 3600); } // Assert - Make sure the store now has the old and the new messages. storeMessages = messageStore.GetReceivedMessagesForEndpoint(EndpointId); Assert.NotNull(storeMessages); Assert.Equal(MessagesCount * 2, storeMessages.Count); for (int i = 0; i < MessagesCount * 2; i++) { IMessage message = storeMessages[i]; Assert.True(message.Properties.ContainsKey($"key{i}")); Assert.Equal($"value{i}", message.Properties[$"key{i}"]); } }
public async Task TestSetEndpoint() { var endpoint1 = new TestEndpoint("id"); var endpoint2 = new NullEndpoint("id"); var endpoint3 = new TestEndpoint("id1"); IEndpointExecutor executor = await Factory.CreateAsync(endpoint1, null); Assert.Equal(endpoint1, executor.Endpoint); await Assert.ThrowsAsync <ArgumentNullException>(() => executor.SetEndpoint(null, null)); await Assert.ThrowsAsync <ArgumentException>(() => executor.SetEndpoint(endpoint3, null)); await executor.SetEndpoint(endpoint2, null); Assert.Equal(endpoint2, executor.Endpoint); await executor.CloseAsync(); await Assert.ThrowsAsync <InvalidOperationException>(() => executor.SetEndpoint(endpoint1, null)); }
public async Task <IPushChannel> FindEndpoint(CancellationToken ct, string locationId) { var endpoints = _endpoints; if (endpoints == null) { // endpoints was erased, we are in an invalid state (too much exceptions) return(null); } if (endpoints.TryGetValue(locationId, out var endpoint) && IsValid(endpoint)) { return(endpoint); } ct = _token.Token; // Do not abort a load operation (and keep the lock locked) using (await _endpointsGate.LockAsync(ct)) { if (endpoints.TryGetValue(locationId, out endpoint) && IsValid(endpoint)) { return(endpoint); } endpoints = _endpoints = await LoadEndpoints(ct); if (endpoints.TryGetValue(locationId, out endpoint)) // No needs to check if 'endpoint' is valid here { return(endpoint); } else { endpoint = new NullEndpoint(locationId, _timeProvider); _endpoints = endpoints.Add(locationId, endpoint); return(endpoint); } } }
public void TestNoFallback() { var endpoint1 = new NullEndpoint("id1"); var allEndpoints = new HashSet <Endpoint> { endpoint1 }; var route1 = new Route("id1", "key1 = 'value1'", "hub", TelemetryMessageSource.Instance, endpoint1, 0, 0); var routes = new HashSet <Route> { route1 }; var evaluator = new Evaluator(new RouterConfig(allEndpoints, routes)); ISet <RouteResult> result1 = evaluator.Evaluate(Message1); Assert.Equal(1, result1.Count); Assert.Equal(endpoint1, result1.First().Endpoint); ISet <RouteResult> result2 = evaluator.Evaluate(Message4); Assert.Equal(0, result2.Count); }
public async Task TestSetEndpoint() { var endpoint1 = new TestEndpoint("id"); var endpoint2 = new NullEndpoint("id"); var endpoint3 = new TestEndpoint("id1"); var priorities = new List <uint>() { 100, 101, 102, 0, 1, 2 }; var checkpointerFactory = new NullCheckpointerFactory(); var endpointExecutorConfig = new EndpointExecutorConfig(TimeSpan.FromHours(1), RetryStrategy.NoRetry, TimeSpan.FromHours(1)); var asyncEndpointExecutorOptions = new AsyncEndpointExecutorOptions(1, TimeSpan.FromSeconds(1)); var messageStore = new TestMessageStore(); var executor = new StoringAsyncEndpointExecutor(endpoint1, checkpointerFactory, endpointExecutorConfig, asyncEndpointExecutorOptions, messageStore); await executor.UpdatePriorities(priorities, Option.None <Endpoint>()); Assert.Equal(endpoint1, executor.Endpoint); await Assert.ThrowsAsync <ArgumentNullException>(() => executor.SetEndpoint(null, new List <uint>() { 0 })); await Assert.ThrowsAsync <ArgumentNullException>(() => executor.SetEndpoint(endpoint1, null)); await Assert.ThrowsAsync <ArgumentException>(() => executor.SetEndpoint(endpoint3, new List <uint>() { 0 })); await executor.SetEndpoint(endpoint2, new List <uint>() { 103, 104, 105, 0, 1, 2, 2 }); Assert.Equal(endpoint2, executor.Endpoint); await executor.CloseAsync(); await Assert.ThrowsAsync <InvalidOperationException>(() => executor.SetEndpoint(endpoint1, new List <uint>() { 0 })); }
public async Task SmokeTest() { var endpoint = new NullEndpoint("endpoint1"); IProcessor processor = endpoint.CreateProcessor(); Assert.True(processor.ErrorDetectionStrategy.IsTransient(new Exception())); Assert.Equal(endpoint, processor.Endpoint); ISinkResult <IMessage> result = await processor.ProcessAsync(new IMessage[] { }, CancellationToken.None); Assert.Equal(new IMessage[0], result.Succeeded); ISinkResult <IMessage> result2 = await processor.ProcessAsync(new[] { Message1, Message2, Message3 }, CancellationToken.None); Assert.Equal(new[] { Message1, Message2, Message3 }, result2.Succeeded); var endpoint2 = new NullEndpoint("id2", "name2", "hub2"); Assert.Equal("id2", endpoint2.Id); Assert.Equal("name2", endpoint2.Name); Assert.Equal("hub2", endpoint2.IotHubName); }
public void TestPriorities() { var endpoint1 = new NullEndpoint("endpoint1"); var endpoint2 = new NullEndpoint("endpoint2"); var allEndpoints = new HashSet <Endpoint> { endpoint1, endpoint2 }; var route1 = new Route("id1", "key1 = 'value1'", "hub", TelemetryMessageSource.Instance, endpoint1, 1, 3600); var route2 = new Route("id2", "key1 = 'value1'", "hub", TelemetryMessageSource.Instance, endpoint1, 0, 7200); var route3 = new Route("id3", "key1 = 'value1'", "hub", TelemetryMessageSource.Instance, endpoint1, 2, 60); var route4 = new Route("id4", "key1 = 'value1'", "hub", TelemetryMessageSource.Instance, endpoint2, 0, 120); var routes = new HashSet <Route> { route1, route2, route3, route4 }; var evaluator = new Evaluator(new RouterConfig(allEndpoints, routes)); // Verify multiple routes to the same endpoint with different priorities, // the route with highest priority should win ISet <RouteResult> results = evaluator.Evaluate(Message1); Assert.Equal(2, results.Count); Assert.Contains(new RouteResult(endpoint1, 0, 7200), results); Assert.Contains(new RouteResult(endpoint2, 0, 120), results); }