예제 #1
0
        public async Task CloseSendsDisconnectSignal()
        {
            var connectionProvider = Mock.Of <IConnectionProvider>();

            Mock.Get(connectionProvider)
            .Setup(p => p.GetDeviceListenerAsync(
                       It.IsAny <Identity>(),
                       It.IsAny <Option <string> >()))
            .Returns(Task.FromResult(Mock.Of <IDeviceListener>()));

            var authenticator = Mock.Of <IAuthenticator>();

            Mock.Get(authenticator)
            .Setup(p => p.AuthenticateAsync(It.IsAny <IClientCredentials>()))
            .Returns(Task.FromResult(true));

            var connectionProviderGetter = Task.FromResult(connectionProvider);
            var authenticatorGetter      = Task.FromResult(authenticator);

            var identityProvider          = new IdentityProvider("hub");
            var systemComponentIdProvider = new SystemComponentIdProvider(
                new TokenCredentials(
                    new ModuleIdentity("hub", "device1", "$edgeHub"), "token", "prodinfo", Option.Some("x"), Option.None <string>(), false));

            var identity = identityProvider.Create("device_test");

            var brokerConnector = Mock.Of <IMqttBrokerConnector>();

            Mock.Get(brokerConnector)
            .Setup(p => p.SendAsync(It.IsAny <string>(), It.IsAny <byte[]>()))
            .Returns(() => Task.FromResult(true));

            var sut = default(ConnectionHandler);

            DeviceProxy.Factory deviceProxyFactory = GetProxy;

            sut = new ConnectionHandler(connectionProviderGetter, authenticatorGetter, identityProvider, systemComponentIdProvider, deviceProxyFactory);
            sut.SetConnector(brokerConnector);
            await sut.HandleAsync(new MqttPublishInfo("$edgehub/connected", Encoding.UTF8.GetBytes("[\"device_test\"]")));

            await sut.CloseConnectionAsync(identity);

            Mock.Get(brokerConnector).Verify(
                c => c.SendAsync(
                    It.Is <string>(topic => topic.Equals("$edgehub/disconnect")),
                    It.Is <byte[]>(payload => Encoding.UTF8.GetString(payload).Equals($"\"device_test\""))),
                Times.Once);

            DeviceProxy GetProxy(IIdentity identity, bool isDirectClient = true)
            {
                return(new DeviceProxy(
                           identity,
                           isDirectClient,
                           sut,
                           Mock.Of <ITwinHandler>(),
                           Mock.Of <IModuleToModuleMessageHandler>(),
                           Mock.Of <ICloud2DeviceMessageHandler>(),
                           Mock.Of <IDirectMethodHandler>()));
            }
        }
예제 #2
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);
        }
예제 #3
0
        public async Task ReconnectAsDirectRemovesNestedInstance()
        {
            var connectionManager = Mock.Of <IConnectionManager>();

            Mock.Get(connectionManager)
            .Setup(p => p.RemoveDeviceConnection(It.IsAny <string>()))
            .Returns(() => Task.CompletedTask);

            var edgeHub = Mock.Of <IEdgeHub>();

            var connectionProvider = new ConnectionProvider(connectionManager, edgeHub, TimeSpan.FromSeconds(30)) as IConnectionProvider;

            var authenticator = Mock.Of <IAuthenticator>();

            Mock.Get(authenticator)
            .Setup(p => p.AuthenticateAsync(It.IsAny <IClientCredentials>()))
            .Returns(Task.FromResult(true));

            var connectionProviderGetter = Task.FromResult(connectionProvider);
            var authenticatorGetter      = Task.FromResult(authenticator);

            var identityProvider          = new IdentityProvider("hub");
            var systemComponentIdProvider = new SystemComponentIdProvider(
                new TokenCredentials(
                    new ModuleIdentity("hub", "device1", "$edgeHub"), "token", "prodinfo", Option.Some("x"), Option.None <string>(), false));

            var brokerConnector = Mock.Of <IMqttBrokerConnector>();

            Mock.Get(brokerConnector)
            .Setup(p => p.SendAsync(It.IsAny <string>(), It.IsAny <byte[]>(), It.IsAny <bool>()))
            .Returns(() => Task.FromResult(true));

            var sut = default(ConnectionHandler);

            DeviceProxy.Factory deviceProxyFactory = GetProxy;

            sut = new ConnectionHandler(connectionProviderGetter, authenticatorGetter, identityProvider, systemComponentIdProvider, deviceProxyFactory);
            sut.SetConnector(brokerConnector);

            await sut.GetOrCreateDeviceListenerAsync(new ModuleIdentity("hub", "device1", "direct_module"), true);

            await sut.GetOrCreateDeviceListenerAsync(new ModuleIdentity("hub", "device1", "indirect_module"), false);

            await sut.GetOrCreateDeviceListenerAsync(new ModuleIdentity("hub", "device1", "$edgeHub"), false);

            await sut.GetOrCreateDeviceListenerAsync(new ModuleIdentity("hub", "device1", "indirect_reconnecting"), false);

            // after indirect_reconnecting comes back as direct, the broker would send 3 connected clients: [direct_module, $edgeHub, indirect_reconnecting]
            // $edgeHub is indirect but listed, yet it should not be bothered as it is a special case.
            // indirect_module is not listed, but as indirect, it should not be removed
            // direct_module should keep its state
            // indirect_reconnecting should be recreated as direct

            await sut.HandleAsync(new MqttPublishInfo("$edgehub/connected", Encoding.UTF8.GetBytes("[\"device1/direct_module\", \"device1/$edgeHub\", \"device1/indirect_reconnecting\"]")));

            var knownConnections = sut.AsPrivateAccessible().knownConnections as ConcurrentDictionary <IIdentity, IDeviceListener>;

            Assert.Equal(4, knownConnections.Count());

            Assert.True(HasModule(knownConnections, "direct_module", true));
            Assert.True(HasModule(knownConnections, "indirect_module", false));
            Assert.True(HasModule(knownConnections, "$edgeHub", false));
            Assert.True(HasModule(knownConnections, "indirect_reconnecting", true));

            bool HasModule(ConcurrentDictionary <IIdentity, IDeviceListener> knownConnections, string name, bool isDirect)
            {
                return(knownConnections.Values.OfType <IDeviceProxy>().Any(p => p.IsDirectClient == isDirect && p.Identity is ModuleIdentity i && string.Equals(i.ModuleId, name)));
            }

            DeviceProxy GetProxy(IIdentity identity, bool isDirectClient = true)
            {
                return(new DeviceProxy(
                           identity,
                           isDirectClient,
                           sut,
                           Mock.Of <ITwinHandler>(),
                           Mock.Of <IModuleToModuleMessageHandler>(),
                           Mock.Of <ICloud2DeviceMessageHandler>(),
                           Mock.Of <IDirectMethodHandler>()));
            }
        }