public async Task CapturesModuleIdentityFromTopic()
        {
            var publishInfo = new MqttPublishInfo("$edgehub/captured_device_id/captured_module_id/subscriptions", Encoding.UTF8.GetBytes("[]"));

            var(cloud2DeviceMessageHandler, moduleToModuleMessageHandler, directMethodHandler, twinHandler) = GetSubscriptionWatchers();
            var(connectionRegistry, _) = GetHandlerDependencies();
            var identityProvider = Mock.Of <IIdentityProvider>();

            string passedDeviceId = null;
            string passedModuleId = null;

            Mock.Get(identityProvider)
            .Setup(ip => ip.Create(It.IsAny <string>(), It.IsAny <string>()))
            .Returns((string device_id, string module_id) =>
            {
                passedDeviceId = device_id;
                passedModuleId = module_id;
                return(new DeviceIdentity("host", device_id));
            });

            var sut = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionRegistry,
                identityProvider);

            _ = await sut.HandleAsync(publishInfo);

            Assert.Equal("captured_device_id", passedDeviceId);
            Assert.Equal("captured_module_id", passedModuleId);
        }
        public async Task DifferentIdentityDoesNotMatch()
        {
            var listenerCapture = new DeviceListenerCapture();

            var publishInfo = new MqttPublishInfo("$edgehub/device_id/module_id/subscriptions", Encoding.UTF8.GetBytes("[\"$edgehub/device_id_x/module_id_x/MatchingPattern\"]"));

            var(_, moduleToModuleMessageHandler, directMethodHandler, twinHandler) = GetSubscriptionWatchers();

            var cloud2DeviceMessageHandler = Mock.Of <ICloud2DeviceMessageHandler>();

            Mock.Get(cloud2DeviceMessageHandler)
            .Setup(sw => sw.WatchedSubscriptions)
            .Returns(() => new List <SubscriptionPattern>()
            {
                new SubscriptionPattern(@"(?<id1>[^/\+\#]+)(/(?<id2>[^/\+\#]+))?/MatchingPattern", DeviceSubscription.C2D)
            });

            var(connectionRegistry, identityProvider) = GetHandlerDependencies(listenerCapture: listenerCapture);
            var sut = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionRegistry,
                identityProvider);

            _ = await sut.HandleAsync(publishInfo);

            Assert.Equal(DeviceSubscription.C2D, listenerCapture.Captured.RemovedSubscription);
        }
        public async Task TurnsOnOffSubscriptions()
        {
            var listenerCapture = new DeviceListenerCapture();

            var publishInfo = new MqttPublishInfo("$edgehub/device_id/module_id/subscriptions", Encoding.UTF8.GetBytes("[\"$edgehub/device_id/module_id/MatchingPattern\"]"));

            var(_, moduleToModuleMessageHandler, directMethodHandler, twinHandler) = GetSubscriptionWatchers();

            var cloud2DeviceMessageHandler = Mock.Of <ICloud2DeviceMessageHandler>();

            Mock.Get(cloud2DeviceMessageHandler)
            .Setup(sw => sw.WatchedSubscriptions)
            .Returns(() => new List <SubscriptionPattern>()
            {
                new SubscriptionPattern(@"(?<id1>[^/\+\#]+)(/(?<id2>[^/\+\#]+))?/patternX", DeviceSubscription.Methods),
                new SubscriptionPattern(@"(?<id1>[^/\+\#]+)(/(?<id2>[^/\+\#]+))?/MatchingPattern", DeviceSubscription.C2D),
            });

            var(connectionRegistry, identityProvider) = GetHandlerDependencies(listenerCapture: listenerCapture);

            var sut = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionRegistry,
                identityProvider);

            _ = await sut.HandleAsync(publishInfo);

            Assert.Equal(DeviceSubscription.C2D, listenerCapture.Captured.AddedSubscription);
            // Assert.Equal(DeviceSubscription.Methods, listenerCapture.Captured.RemovedSubscription); TODO: removed this line temporarily until unsubscribe is fixed
        }
Example #4
0
        public async Task CapturesModuleIdentityFromTopicForIndirectClient()
        {
            var publishInfo = new MqttPublishInfo("$edgehub/somedevice/$edgeHub/subscriptions", Encoding.UTF8.GetBytes(@"[""$edgehub/captured_device_id/captured_module_id/methods/post/#""]"));

            var(cloud2DeviceMessageHandler, moduleToModuleMessageHandler, _, twinHandler) = GetSubscriptionWatchers();
            var(connectionRegistry, _) = GetHandlerDependencies();
            var identityProvider = Mock.Of <IIdentityProvider>();

            Mock.Get(connectionRegistry)
            .Setup(cr => cr.GetNestedConnectionsAsync())
            .Returns(() => Task.FromResult <IReadOnlyList <IIdentity> >(new List <IIdentity>()
            {
                (IIdentity) new ModuleIdentity("host", "captured_device_id", "captured_module_id")
            }));

            var directMethodHandler = Mock.Of <IDirectMethodHandler>();

            Mock.Get(directMethodHandler)
            .Setup(sw => sw.WatchedSubscriptions)
            .Returns(() => new List <SubscriptionPattern>()
            {
                new SubscriptionPattern(@"^((?<dialect>(\$edgehub)|(\$iothub)))/(?<id1>[^/\+\#]+)(/(?<id2>[^/\+\#]+))?/methods/post/\#$", DeviceSubscription.Methods)
            });

            string passedDeviceId = null;
            string passedModuleId = null;

            Mock.Get(identityProvider)
            .Setup(ip => ip.Create(It.IsAny <string>(), It.IsAny <string>()))
            .Returns((string device_id, string module_id) =>
            {
                passedDeviceId = device_id;
                passedModuleId = module_id;
                return(new DeviceIdentity("host", device_id));
            });

            var sut = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionRegistry,
                identityProvider);

            _ = await sut.HandleAsync(publishInfo);

            Assert.Equal("captured_device_id", passedDeviceId);
            Assert.Equal("captured_module_id", passedModuleId);
        }
Example #5
0
        public Task SetOnSubscriptionChangeAction <T>(Func <StreamSubscriptionHandle <T>, Task> onAdd)
        {
            ISubscriptionChangeHandler handler;

            if (onSubscriptionChangeActionMap.TryGetValue(typeof(T), out handler))
            {
                var typedHandler = handler as SubscriptionChangeHandler <T>;
                typedHandler.OnAdd = onAdd;
            }
            else
            {
                var newHandler = new SubscriptionChangeHandler <T>(onAdd);
                onSubscriptionChangeActionMap.Add(typeof(T), newHandler);
            }
            return(TaskDone.Done);
        }
        public async Task HandlesSubscriptionTopics(string topic)
        {
            var publishInfo = new MqttPublishInfo(topic, new byte[0]);

            var(cloud2DeviceMessageHandler, moduleToModuleMessageHandler, directMethodHandler, twinHandler) = GetSubscriptionWatchers();
            var(connectionRegistry, identityProvider) = GetHandlerDependencies();

            var sut = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionRegistry,
                identityProvider);

            var isHandled = await sut.HandleAsync(publishInfo);

            Assert.True(isHandled);
        }
        public async Task TurnsOnOffSubscriptionsForIndirectClients()
        {
            var listenerCapture = new DeviceListenerCapture();

            var publishInfo = new MqttPublishInfo("$edgehub/somedevice/$edgeHub/subscriptions", Encoding.UTF8.GetBytes("[\"$edgehub/device_id/module_id/MatchingPattern\"]"));

            var(_, moduleToModuleMessageHandler, directMethodHandler, twinHandler) = GetSubscriptionWatchers();

            var cloud2DeviceMessageHandler = Mock.Of <ICloud2DeviceMessageHandler>();

            Mock.Get(cloud2DeviceMessageHandler)
            .Setup(sw => sw.WatchedSubscriptions)
            .Returns(() => new List <SubscriptionPattern>()
            {
                new SubscriptionPattern(@"(?<id1>[^/\+\#]+)(/(?<id2>[^/\+\#]+))?/patternX", DeviceSubscription.Methods),
                new SubscriptionPattern(@"(?<id1>[^/\+\#]+)(/(?<id2>[^/\+\#]+))?/MatchingPattern", DeviceSubscription.C2D),
            });

            var(connectionRegistry, identityProvider) = GetHandlerDependencies(listenerCapture: listenerCapture);

            Mock.Get(connectionRegistry)
            .Setup(cr => cr.GetNestedConnectionsAsync())
            .Returns(() => Task.FromResult <IReadOnlyList <IIdentity> >(new List <IIdentity>()
            {
                (IIdentity) new ModuleIdentity("host", "device_id", "module_id")
            }));

            var sut = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionRegistry,
                identityProvider);

            _ = await sut.HandleAsync(publishInfo);

            Assert.Equal(DeviceSubscription.C2D, listenerCapture.Captured.AddedSubscription);
            Assert.Equal(DeviceSubscription.Methods, listenerCapture.Captured.RemovedSubscription);
        }
Example #8
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);
        }