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 PumpMessagesTest()
        {
            // Arrange
            const int     MessagesCount = 10;
            const string  EndpointId    = "endpoint1";
            var           endpoint      = new TestEndpoint(EndpointId);
            ICheckpointer checkpointer  = await Checkpointer.CreateAsync(EndpointId, new CheckpointStore());

            var endpointExecutorConfig       = new EndpointExecutorConfig(TimeSpan.FromHours(1), RetryStrategy.NoRetry, TimeSpan.FromHours(1));
            var asyncEndpointExecutorOptions = new AsyncEndpointExecutorOptions(4, TimeSpan.FromSeconds(2));
            var messageStore = new TestMessageStore();
            var storingAsyncEndpointExecutor = new StoringAsyncEndpointExecutor(endpoint, checkpointer, endpointExecutorConfig, asyncEndpointExecutorOptions, messageStore);
            IEnumerable <IMessage> messages  = GetNewMessages(MessagesCount, 0);

            // Act - Send messages to invoke
            foreach (IMessage message in messages)
            {
                await storingAsyncEndpointExecutor.Invoke(message);
            }

            await Task.Delay(TimeSpan.FromSeconds(10));

            // Assert - Make sure the endpoint received all the messages.
            Assert.Equal(MessagesCount, endpoint.N);
            for (int i = 0; i < MessagesCount; i++)
            {
                IMessage message = endpoint.Processed[i];
                Assert.True(message.Properties.ContainsKey($"key{i}"));
                Assert.Equal($"value{i}", message.Properties[$"key{i}"]);
            }
        }
        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}"]);
            }
        }
예제 #4
0
        static async Task <(IEdgeHub, IConnectionManager)> SetupEdgeHub(IEnumerable <string> routes, IoTHub iotHub, string edgeDeviceId)
        {
            string iotHubName = "testHub";

            Routing.UserMetricLogger    = NullRoutingUserMetricLogger.Instance;
            Routing.PerfCounter         = NullRoutingPerfCounter.Instance;
            Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance;

            RetryStrategy defaultRetryStrategy   = new FixedInterval(0, TimeSpan.FromSeconds(1));
            TimeSpan      defaultRevivePeriod    = TimeSpan.FromHours(1);
            TimeSpan      defaultTimeout         = TimeSpan.FromSeconds(60);
            var           endpointExecutorConfig = new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true);

            var cloudProxy = new Mock <ICloudProxy>();

            cloudProxy.Setup(c => c.SendMessageAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask);
            cloudProxy.Setup(c => c.SendMessageBatchAsync(It.IsAny <IEnumerable <IMessage> >())).Callback <IEnumerable <IMessage> >(m => iotHub.ReceivedMessages.AddRange(m)).Returns(Task.CompletedTask);
            cloudProxy.Setup(c => c.UpdateReportedPropertiesAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask);
            cloudProxy.SetupGet(c => c.IsActive).Returns(true);
            var cloudConnection = Mock.Of <ICloudConnection>(c => c.IsActive && c.CloudProxy == Option.Some(cloudProxy.Object));

            var cloudConnectionProvider = new Mock <ICloudConnectionProvider>();

            cloudConnectionProvider.Setup(c => c.Connect(It.IsAny <IClientCredentials>(), It.IsAny <Action <string, CloudConnectionStatus> >())).ReturnsAsync(Try.Success(cloudConnection));

            var deviceConnectivityManager                    = Mock.Of <IDeviceConnectivityManager>();
            IConnectionManager connectionManager             = new ConnectionManager(cloudConnectionProvider.Object, Mock.Of <ICredentialsCache>(), new IdentityProvider(iotHubName), deviceConnectivityManager);
            var                      routingMessageConverter = new RoutingMessageConverter();
            RouteFactory             routeFactory            = new EdgeRouteFactory(new EndpointFactory(connectionManager, routingMessageConverter, edgeDeviceId, 10, 10));
            IEnumerable <Route>      routesList              = routeFactory.Create(routes).ToList();
            IEnumerable <Endpoint>   endpoints               = routesList.Select(r => r.Endpoint);
            var                      routerConfig            = new RouterConfig(endpoints, routesList);
            IDbStoreProvider         dbStoreProvider         = new InMemoryDbStoreProvider();
            IStoreProvider           storeProvider           = new StoreProvider(dbStoreProvider);
            IMessageStore            messageStore            = new MessageStore(storeProvider, CheckpointStore.Create(storeProvider), TimeSpan.MaxValue);
            IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(1, TimeSpan.FromMilliseconds(10)), messageStore);
            Router                   router                  = await Router.CreateAsync(Guid.NewGuid().ToString(), iotHubName, routerConfig, endpointExecutorFactory);

            ITwinManager twinManager           = new TwinManager(connectionManager, new TwinCollectionMessageConverter(), new TwinMessageConverter(), Option.None <IEntityStore <string, TwinInfo> >());
            var          invokeMethodHandler   = Mock.Of <IInvokeMethodHandler>();
            var          subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager);
            IEdgeHub     edgeHub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, edgeDeviceId, invokeMethodHandler, subscriptionProcessor);

            return(edgeHub, connectionManager);
        }
예제 #5
0
        public async Task TestFailedEndpoint()
        {
            var      retryStrategy = new FixedInterval(10, TimeSpan.FromSeconds(1));
            TimeSpan revivePeriod  = TimeSpan.FromHours(1);
            TimeSpan execTimeout   = TimeSpan.FromSeconds(60);
            var      config        = new EndpointExecutorConfig(execTimeout, retryStrategy, revivePeriod, true);
            var      factory       = new SyncEndpointExecutorFactory(config);

            var endpoint  = new FailedEndpoint("endpoint1");
            var endpoints = new Dictionary <Endpoint, IList <uint> > {
                { endpoint, new List <uint>()
                  {
                      0
                  } }
            };

            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)))
            {
                Dispatcher dispatcher = await Dispatcher.CreateAsync("dispatcher", "hub", endpoints, factory);

                // Because the buffer size is one and we are failing we should block on the dispatch
                Task dispatching = dispatcher.DispatchAsync(Message1, new HashSet <RouteResult> {
                    new RouteResult(endpoint, 0, 3600)
                });

                var  endpoint2 = new TestEndpoint("endpoint1");
                Task setting   = dispatcher.SetEndpoint(endpoint2, new List <uint>()
                {
                    0
                });

                Task timeout = Task.Delay(TimeSpan.FromSeconds(1), cts.Token);
                await Task.WhenAny(dispatching, setting, timeout);

                await dispatcher.CloseAsync(CancellationToken.None);

                var expected = new List <IMessage> {
                    Message1
                };
                Assert.Equal(expected, endpoint2.Processed);
            }
        }
예제 #6
0
        public async Task TestFailedEndpoint()
        {
            var message1 = new Message(TelemetryMessageSource.Instance, new byte[] { 1, 2, 3 }, new Dictionary <string, string> {
                { "key1", "value1" }, { "key2", "value2" }
            });
            var      retryStrategy = new FixedInterval(10, TimeSpan.FromSeconds(1));
            TimeSpan revivePeriod  = TimeSpan.FromHours(1);
            TimeSpan execTimeout   = TimeSpan.FromSeconds(60);
            var      config        = new EndpointExecutorConfig(execTimeout, retryStrategy, revivePeriod, true);
            var      factory       = new SyncEndpointExecutorFactory(config);

            var endpoint  = new FailedEndpoint("endpoint1");
            var endpoints = new HashSet <Endpoint> {
                endpoint
            };
            var route = new Route("route1", "true", "hub", TelemetryMessageSource.Instance, endpoints);

            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)))
                using (Router router = await Router.CreateAsync("router1", "hub", new RouterConfig(endpoints, new HashSet <Route> {
                    route
                }, Fallback), factory))
                {
                    // Because the buffer size is one and we are failing we should block on the dispatch
                    Task routing = router.RouteAsync(message1);

                    var endpoint2 = new TestEndpoint("endpoint1");
                    var newRoute  = new Route("id", "true", "hub", TelemetryMessageSource.Instance, new HashSet <Endpoint> {
                        endpoint2
                    });
                    Task setting = router.SetRoute(newRoute);

                    Task timeout = Task.Delay(TimeSpan.FromSeconds(1), cts.Token);
                    await Task.WhenAny(routing, setting, timeout);

                    await router.CloseAsync(CancellationToken.None);

                    var expected = new List <IMessage> {
                        message1
                    };
                    Assert.Equal(expected, endpoint2.Processed);
                }
        }
예제 #7
0
        public async Task TestCancellation()
        {
            var      retryStrategy = new FixedInterval(10, TimeSpan.FromSeconds(1));
            TimeSpan revivePeriod  = TimeSpan.FromHours(1);
            TimeSpan execTimeout   = TimeSpan.FromSeconds(60);
            var      config        = new EndpointExecutorConfig(execTimeout, retryStrategy, revivePeriod, true);

            var endpoint = new FailedEndpoint("id");

            IProcessor processor = endpoint.CreateProcessor();

            Assert.Equal(endpoint, processor.Endpoint);

            IEndpointExecutor executor = new SyncEndpointExecutor(endpoint, new NullCheckpointer(), config);
            Task running = executor.Invoke(Default);
            await executor.CloseAsync();

            await running;

            Assert.True(running.IsCompleted);
        }
예제 #8
0
        public EndpointExecutorFsm(Endpoint endpoint, ICheckpointer checkpointer, EndpointExecutorConfig config, ISystemTime systemTime)
        {
            this.processor             = Preconditions.CheckNotNull(endpoint).CreateProcessor();
            this.Checkpointer          = Preconditions.CheckNotNull(checkpointer);
            this.config                = Preconditions.CheckNotNull(config);
            this.systemTime            = Preconditions.CheckNotNull(systemTime);
            this.retryTimer            = new Timer(this.RetryAsync, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
            this.retryPeriod           = Timeout.InfiniteTimeSpan;
            this.lastFailedRevivalTime = checkpointer.LastFailedRevivalTime;
            this.unhealthySince        = checkpointer.UnhealthySince;

            if (checkpointer.LastFailedRevivalTime.HasValue)
            {
                this.state         = State.DeadIdle;
                this.retryAttempts = short.MaxValue; // setting to some big value
            }
            else
            {
                this.state = State.Idle;
            }
        }
예제 #9
0
        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
            }));
        }
예제 #10
0
        public async Task PumpMessagesWithLargeIncomingBatchTest()
        {
            // Arrange
            const int    MessagesCount        = 200;
            const string EndpointId           = "endpoint1";
            const int    RoutingPumpBatchSize = 10;
            var          endpoint             = new TestEndpoint(EndpointId);
            var          priorities           = new List <uint>()
            {
                0, 1, 2, 100, 101, 102
            };
            var checkpointerFactory          = new NullCheckpointerFactory();
            var endpointExecutorConfig       = new EndpointExecutorConfig(TimeSpan.FromHours(1), RetryStrategy.NoRetry, TimeSpan.FromHours(1));
            var asyncEndpointExecutorOptions = new AsyncEndpointExecutorOptions(RoutingPumpBatchSize, TimeSpan.FromMilliseconds(1));
            var messageStore = new TestMessageStore();
            var storingAsyncEndpointExecutor = new StoringAsyncEndpointExecutor(endpoint, checkpointerFactory, endpointExecutorConfig, asyncEndpointExecutorOptions, messageStore);
            await storingAsyncEndpointExecutor.UpdatePriorities(priorities, Option.None <Endpoint>());

            IEnumerable <IMessage> messages = GetNewMessages(MessagesCount, 0);

            // Act - Send messages to invoke
            foreach (IMessage message in messages)
            {
                await storingAsyncEndpointExecutor.Invoke(message, 0, 3600);
            }

            await Task.Delay(TimeSpan.FromSeconds(10));

            // Assert - Make sure the endpoint received all the messages.
            Assert.Equal(MessagesCount, endpoint.N);
            for (int i = 0; i < MessagesCount; i++)
            {
                IMessage message = endpoint.Processed[i];
                Assert.True(message.Properties.ContainsKey($"key{i}"));
                Assert.Equal($"value{i}", message.Properties[$"key{i}"]);
            }
        }
        public async Task <IEndpointExecutor> CreateAsync(Endpoint endpoint, ICheckpointer checkpointer, EndpointExecutorConfig endpointExecutorConfig)
        {
            IEndpointExecutor exec = await this.underlying.CreateAsync(endpoint, checkpointer, endpointExecutorConfig);

            await exec.CloseAsync();

            return(exec);
        }
예제 #12
0
 public Task <IEndpointExecutor> CreateAsync(Endpoint endpoint, ICheckpointer checkpointer, EndpointExecutorConfig endpointExecutorConfig)
 {
     return(this.executorFactory.CreateAsync(endpoint, checkpointer, endpointExecutorConfig));
 }
 public Task <IEndpointExecutor> CreateAsync(Endpoint endpoint, IList <uint> priorities, ICheckpointer checkpointer, EndpointExecutorConfig endpointExecutorConfig)
 {
     return(this.underlying.CreateAsync(endpoint, priorities, checkpointer, endpointExecutorConfig));
 }
예제 #14
0
        async Task <(IMessageConsumer, IMessageConsumer, NullBrokerConnector)> SetupEnvironment()
        {
            Routing.UserMetricLogger    = NullRoutingUserMetricLogger.Instance;
            Routing.PerfCounter         = NullRoutingPerfCounter.Instance;
            Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance;

            var defaultRetryStrategy   = new FixedInterval(5, TimeSpan.FromSeconds(5));
            var defaultRevivePeriod    = TimeSpan.FromHours(1);
            var defaultTimeout         = TimeSpan.FromSeconds(60);
            var endpointExecutorConfig = new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true);

            var cloudProxyDispatcher    = new BrokeredCloudProxyDispatcher();
            var cloudConnectionProvider = new BrokeredCloudConnectionProvider(cloudProxyDispatcher);

            var identityProvider          = new IdentityProvider(iotHubName);
            var deviceConnectivityManager = new BrokeredDeviceConnectivityManager(cloudProxyDispatcher);

            var connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of <ICredentialsCache>(), new IdentityProvider(iotHubName), deviceConnectivityManager);

            var routingMessageConverter = new RoutingMessageConverter();
            var routeFactory            = new EdgeRouteFactory(new EndpointFactory(connectionManager, routingMessageConverter, edgeDeviceId, 10, 10));
            var routesList   = new[] { routeFactory.Create("FROM /messages INTO $upstream") };
            var endpoints    = routesList.Select(r => r.Endpoint);
            var routerConfig = new RouterConfig(endpoints, routesList);

            var dbStoreProvider         = new InMemoryDbStoreProvider();
            var storeProvider           = new StoreProvider(dbStoreProvider);
            var messageStore            = new MessageStore(storeProvider, CheckpointStore.Create(storeProvider), TimeSpan.MaxValue, false, 1800);
            var endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(1, TimeSpan.FromMilliseconds(10)), messageStore);

            var router = await Router.CreateAsync(Guid.NewGuid().ToString(), iotHubName, routerConfig, endpointExecutorFactory);

            var messageConverterProvider = new MessageConverterProvider(
                new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Twin), new TwinMessageConverter() },
                { typeof(TwinCollection), new TwinCollectionMessageConverter() }
            });

            var twinManager           = TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>());
            var invokeMethodHandler   = Mock.Of <IInvokeMethodHandler>();
            var subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager);

            var edgeHub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, edgeDeviceId, edgeModuleName, invokeMethodHandler, subscriptionProcessor, Mock.Of <IDeviceScopeIdentitiesCache>());

            var brokerConnector = new NullBrokerConnector(cloudProxyDispatcher);

            cloudProxyDispatcher.SetConnector(brokerConnector);
            cloudProxyDispatcher.BindEdgeHub(edgeHub);

            var connectionProvider = new ConnectionProvider(connectionManager, edgeHub, TimeSpan.FromSeconds(30));
            var authenticator      = new NullAuthenticator();

            var edgeHubIdentity         = new ModuleIdentity(iotHubName, edgeDeviceId, edgeModuleName);
            var tokenCredentials        = new TokenCredentials(edgeHubIdentity, "qwerty", "test-product", Option.Some("test-model"), Option.None <string>(), false);
            var systemComponentProvider = new SystemComponentIdProvider(tokenCredentials);

            var connectionHandler = default(ConnectionHandler);

            connectionHandler = new ConnectionHandler(
                Task.FromResult <IConnectionProvider>(connectionProvider),
                Task.FromResult <IAuthenticator>(authenticator),
                identityProvider,
                systemComponentProvider,
                DeviceProxyFactory);

            DeviceProxy DeviceProxyFactory(IIdentity identity, bool isDirectClient)
            {
                return(new DeviceProxy(identity, isDirectClient, connectionHandler, Mock.Of <ITwinHandler>(), Mock.Of <IModuleToModuleMessageHandler>(), Mock.Of <ICloud2DeviceMessageHandler>(), Mock.Of <IDirectMethodHandler>()));
            }

            var cloud2DeviceMessageHandler   = new Cloud2DeviceMessageHandler(connectionHandler);
            var moduleToModuleMessageHandler = new ModuleToModuleMessageHandler(connectionHandler, identityProvider, new ModuleToModuleResponseTimeout(TimeSpan.FromSeconds(10)));
            var directMethodHandler          = new DirectMethodHandler(connectionHandler, identityProvider);
            var twinHandler = new TwinHandler(connectionHandler, identityProvider);

            var subscriptionChangeHandler = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionHandler,
                identityProvider);

            return(subscriptionChangeHandler, cloudProxyDispatcher, brokerConnector);
        }
예제 #15
0
 public EndpointExecutorFsm(Endpoint endpoint, ICheckpointer checkpointer, EndpointExecutorConfig config)
     : this(endpoint, checkpointer, config, SystemTime.Instance)
 {
 }
예제 #16
0
        public async Task MessagePrioritiesTest()
        {
            // Arrange
            const string EndpointId = "endpoint1";
            const uint   HighPri    = 0;
            const uint   NormalPri  = 5;
            const uint   LowPri     = 10;
            var          endpoint   = new TestEndpoint(EndpointId);
            var          priorities = new List <uint>()
            {
                HighPri, NormalPri, LowPri
            };
            var checkpointerFactory          = new NullCheckpointerFactory();
            var endpointExecutorConfig       = new EndpointExecutorConfig(TimeSpan.FromHours(1), RetryStrategy.DefaultFixed, TimeSpan.FromHours(1));
            var asyncEndpointExecutorOptions = new AsyncEndpointExecutorOptions(4, TimeSpan.FromSeconds(2));
            var messageStore = new TestMessageStore();
            var storingAsyncEndpointExecutor = new StoringAsyncEndpointExecutor(endpoint, checkpointerFactory, endpointExecutorConfig, asyncEndpointExecutorOptions, messageStore);
            await storingAsyncEndpointExecutor.UpdatePriorities(priorities, Option.None <Endpoint>());

            var normalPriMsg1 = new Message(TelemetryMessageSource.Instance, new byte[] { 1 }, new Dictionary <string, string> {
                { "normalPriority", string.Empty }
            }, 0L);
            var normalPriMsg2 = new Message(TelemetryMessageSource.Instance, new byte[] { 2 }, new Dictionary <string, string> {
                { "normalPriority", string.Empty }
            }, 1L);
            var normalPriMsg3 = new Message(TelemetryMessageSource.Instance, new byte[] { 3 }, new Dictionary <string, string> {
                { "normalPriority", string.Empty }
            }, 2L);
            var lowPriMsg1 = new Message(TelemetryMessageSource.Instance, new byte[] { 4 }, new Dictionary <string, string> {
                { "lowPriority", string.Empty }
            }, 3L);
            var lowPriMsg2 = new Message(TelemetryMessageSource.Instance, new byte[] { 5 }, new Dictionary <string, string> {
                { "lowPriority", string.Empty }
            }, 4L);
            var highPriMsg1 = new Message(TelemetryMessageSource.Instance, new byte[] { 6 }, new Dictionary <string, string> {
                { "highPriority", string.Empty }
            }, 5L);
            var normalPriMsg4 = new Message(TelemetryMessageSource.Instance, new byte[] { 7 }, new Dictionary <string, string> {
                { "normalPriority", string.Empty }
            }, 6L);
            var highPriMsg2 = new Message(TelemetryMessageSource.Instance, new byte[] { 8 }, new Dictionary <string, string> {
                { "highPriority", string.Empty }
            }, 7L);
            const int HighPriCount   = 2;
            const int NormalPriCount = 4;
            const int LowPriCount    = 2;

            // Disable the endpoint so messages are stuck in queue
            endpoint.CanProcess = false;

            // Send normal priority messages
            await storingAsyncEndpointExecutor.Invoke(normalPriMsg1, NormalPri, 3600);

            await storingAsyncEndpointExecutor.Invoke(normalPriMsg2, NormalPri, 3600);

            await storingAsyncEndpointExecutor.Invoke(normalPriMsg3, NormalPri, 3600);

            // Send low priority messages
            await storingAsyncEndpointExecutor.Invoke(lowPriMsg1, LowPri, 3600);

            await storingAsyncEndpointExecutor.Invoke(lowPriMsg2, LowPri, 3600);

            // Send the remaining messages mixed priority
            await storingAsyncEndpointExecutor.Invoke(highPriMsg1, HighPri, 3600);

            await storingAsyncEndpointExecutor.Invoke(normalPriMsg4, NormalPri, 3600);

            await storingAsyncEndpointExecutor.Invoke(highPriMsg2, HighPri, 3600);

            // Message store should have the messages in the corresponding queues
            var highPriQueue = messageStore.GetReceivedMessagesForEndpoint($"{endpoint.Id}_Pri{HighPri}");

            Assert.Equal(2, highPriQueue.Count);
            Assert.Contains(highPriMsg1, highPriQueue);
            Assert.Contains(highPriMsg2, highPriQueue);

            var normalPriQueue = messageStore.GetReceivedMessagesForEndpoint($"{endpoint.Id}_Pri{NormalPri}");

            Assert.Equal(4, normalPriQueue.Count);
            Assert.Contains(normalPriMsg1, normalPriQueue);
            Assert.Contains(normalPriMsg2, normalPriQueue);
            Assert.Contains(normalPriMsg3, normalPriQueue);
            Assert.Contains(normalPriMsg4, normalPriQueue);

            var lowPriQueue = messageStore.GetReceivedMessagesForEndpoint($"{endpoint.Id}_Pri{LowPri}");

            Assert.Equal(2, lowPriQueue.Count);
            Assert.Contains(lowPriMsg1, lowPriQueue);
            Assert.Contains(lowPriMsg2, lowPriQueue);

            // Re-enable the endpoint and let the queues drain
            endpoint.CanProcess = true;
            await Task.Delay(TimeSpan.FromSeconds(10));

            // Assert - Make sure the endpoint received all the messages
            // in the right priority order:
            //  - HighPri messages should finish processing before others
            //  - NormalPri messages should finish processing before LowPri
            Assert.Equal(8, endpoint.Processed.Count());
            int highPriMessagesProcessed   = 0;
            int normalPriMessagesProcessed = 0;
            int lowPriMessagesProcessed    = 0;

            for (int i = 0; i < endpoint.Processed.Count(); i++)
            {
                IMessage message = endpoint.Processed[i];
                if (message.Properties.ContainsKey($"highPriority"))
                {
                    if (++highPriMessagesProcessed == HighPriCount)
                    {
                        // Found all the high-pri messages,
                        // normal and low pri at this point
                        // must not have completed yet
                        Assert.True(normalPriMessagesProcessed < NormalPriCount);
                        Assert.True(lowPriMessagesProcessed < LowPriCount);
                    }
                }
                else if (message.Properties.ContainsKey($"normalPriority"))
                {
                    if (++normalPriMessagesProcessed == NormalPriCount)
                    {
                        // Found all the normal-pri messages,
                        // low pri messages at this point must
                        // not have completed yet
                        Assert.True(lowPriMessagesProcessed < LowPriCount);

                        // High pri messages should have completed
                        Assert.True(highPriMessagesProcessed == HighPriCount);
                    }
                }
                else if (message.Properties.ContainsKey($"lowPriority"))
                {
                    if (++lowPriMessagesProcessed == LowPriCount)
                    {
                        // Found all the low-pri messages,
                        // high-pri and normal-pri should also
                        // have completed before this
                        Assert.True(highPriMessagesProcessed == HighPriCount);
                        Assert.True(normalPriMessagesProcessed == NormalPriCount);
                    }
                }
                else
                {
                    // Bad test setup
                    Assert.True(false, "Bad test setup, processed a message with unexpected priority");
                }
            }
        }
예제 #17
0
        public async Task <IEndpointExecutor> CreateAsync(Endpoint endpoint, IList <uint> priorities, ICheckpointerFactory checkpointerFactory, EndpointExecutorConfig endpointExecutorConfig)
        {
            IEndpointExecutor exec = await this.underlying.CreateAsync(endpoint, priorities, checkpointerFactory, endpointExecutorConfig);

            await exec.CloseAsync();

            return(exec);
        }