示例#1
0
        public async Task MaxClientsTest()
        {
            var cloudProviderMock = new Mock <ICloudConnectionProvider>();

            cloudProviderMock.Setup(p => p.Connect(It.IsAny <IClientCredentials>(), It.IsAny <Action <string, CloudConnectionStatus> >()))
            .ReturnsAsync(() => Try.Success(GetCloudConnectionMock()));

            var deviceIdentity1 = Mock.Of <IDeviceIdentity>(d => d.Id == "Device1");
            var deviceIdentity2 = Mock.Of <IDeviceIdentity>(d => d.Id == "Device2");
            var deviceIdentity3 = Mock.Of <IDeviceIdentity>(d => d.Id == "Device3");

            var deviceCredentials1 = Mock.Of <IClientCredentials>(c => c.Identity == deviceIdentity1);
            var deviceCredentials2 = Mock.Of <IClientCredentials>(c => c.Identity == deviceIdentity2);
            var deviceCredentials3 = Mock.Of <IClientCredentials>(c => c.Identity == deviceIdentity3);

            var deviceProxy1 = Mock.Of <IDeviceProxy>(d => d.IsActive);
            var deviceProxy2 = Mock.Of <IDeviceProxy>(d => d.IsActive);

            var connectionManager = new ConnectionManager(cloudProviderMock.Object, 2);

            await connectionManager.AddDeviceConnection(deviceCredentials1);

            connectionManager.BindDeviceProxy(deviceIdentity1, deviceProxy1);
            await connectionManager.AddDeviceConnection(deviceCredentials2);

            connectionManager.BindDeviceProxy(deviceIdentity2, deviceProxy2);
            await Assert.ThrowsAsync <EdgeHubConnectionException>(async() => await connectionManager.AddDeviceConnection(deviceCredentials3));
        }
示例#2
0
        public async Task GetConnectedClientsTest()
        {
            // Arrange
            var cloudConnectionProvider = Mock.Of <ICloudConnectionProvider>();
            var credentialsCache        = Mock.Of <ICredentialsCache>();
            var connectionManager       = new ConnectionManager(cloudConnectionProvider, credentialsCache, EdgeDeviceId, EdgeModuleId);

            var deviceProxies = new List <IDeviceProxy>();

            for (int i = 0; i < 10; i++)
            {
                string deviceId    = $"device{i}";
                var    identity    = Mock.Of <IIdentity>(id => id.Id == deviceId);
                var    deviceProxy = Mock.Of <IDeviceProxy>(d => d.Identity == identity && d.IsActive);
                Mock.Get(deviceProxy).Setup(d => d.CloseAsync(It.IsAny <Exception>()))
                .Callback(() => Mock.Get(deviceProxy).SetupGet(dp => dp.IsActive).Returns(false))
                .Returns(Task.CompletedTask);
                await connectionManager.AddDeviceConnection(identity, deviceProxy);

                deviceProxies.Add(deviceProxy);
            }

            var edgeHubIdentity    = Mock.Of <IIdentity>(e => e.Id == $"{EdgeDeviceId}/{EdgeModuleId}");
            var edgeHubDeviceProxy = Mock.Of <IDeviceProxy>(e => e.Identity == edgeHubIdentity && e.IsActive);
            await connectionManager.AddDeviceConnection(edgeHubIdentity, edgeHubDeviceProxy);

            // Act
            IEnumerable <IIdentity> connectedClients = connectionManager.GetConnectedClients();

            // Assert
            Assert.NotNull(connectedClients);
            List <IIdentity> connectedClientsList = connectedClients.ToList();

            Assert.Equal(10, connectedClientsList.Count);

            for (int i = 0; i < 10; i++)
            {
                string deviceId = $"device{i}";
                Assert.True(connectedClientsList.Any(c => c.Id.Equals(deviceId)));
            }

            // Act
            for (int i = 0; i < 5; i++)
            {
                await deviceProxies[i].CloseAsync(new Exception());
            }

            connectedClients = connectionManager.GetConnectedClients();

            // Assert
            Assert.NotNull(connectedClients);
            connectedClientsList = connectedClients.ToList();
            Assert.Equal(5, connectedClientsList.Count);

            for (int i = 5; i < 10; i++)
            {
                string deviceId = $"device{i}";
                Assert.True(connectedClientsList.Any(c => c.Id.Equals(deviceId)));
            }
        }
示例#3
0
        public async Task DeviceConnectionTest()
        {
            var cloudProviderMock = new Mock <ICloudConnectionProvider>();
            IConnectionManager connectionManager = new ConnectionManager(cloudProviderMock.Object);

            var deviceProxyMock1 = new Mock <IDeviceProxy>();

            deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(true);
            deviceProxyMock1.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
            .Callback(() => deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(false))
            .Returns(Task.CompletedTask);

            var deviceProxyMock2 = new Mock <IDeviceProxy>();

            deviceProxyMock2.SetupGet(dp => dp.IsActive).Returns(true);
            deviceProxyMock2.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
            .Callback(() => deviceProxyMock2.SetupGet(dp => dp.IsActive).Returns(false))
            .Returns(Task.CompletedTask);

            var deviceIdentityMock = new Mock <IIdentity>();

            deviceIdentityMock.SetupGet(di => di.Id).Returns("Device1");
            var deviceCredentials1 = Mock.Of <IClientCredentials>(c => c.Identity == deviceIdentityMock.Object);
            var deviceCredentials2 = Mock.Of <IClientCredentials>(c => c.Identity == deviceIdentityMock.Object);

            Option <IDeviceProxy> returnedDeviceProxy = connectionManager.GetDeviceConnection(deviceIdentityMock.Object.Id);

            Assert.False(returnedDeviceProxy.HasValue);

            await connectionManager.AddDeviceConnection(deviceCredentials1);

            connectionManager.BindDeviceProxy(deviceIdentityMock.Object, deviceProxyMock1.Object);
            Assert.True(deviceProxyMock1.Object.IsActive);

            returnedDeviceProxy = connectionManager.GetDeviceConnection(deviceIdentityMock.Object.Id);
            Assert.True(returnedDeviceProxy.HasValue);
            Assert.Equal(deviceProxyMock1.Object, returnedDeviceProxy.OrDefault());

            await connectionManager.AddDeviceConnection(deviceCredentials2);

            connectionManager.BindDeviceProxy(deviceIdentityMock.Object, deviceProxyMock2.Object);
            Assert.True(deviceProxyMock2.Object.IsActive);
            Assert.False(deviceProxyMock1.Object.IsActive);

            returnedDeviceProxy = connectionManager.GetDeviceConnection(deviceIdentityMock.Object.Id);
            Assert.True(returnedDeviceProxy.HasValue);
            Assert.Equal(deviceProxyMock2.Object, returnedDeviceProxy.OrDefault());

            await connectionManager.RemoveDeviceConnection(deviceIdentityMock.Object.Id);

            returnedDeviceProxy = connectionManager.GetDeviceConnection(deviceIdentityMock.Object.Id);
            Assert.False(returnedDeviceProxy.HasValue);
        }
        public async Task CloudConnectionUpdateTest()
        {
            ITokenProvider receivedTokenProvider    = null;
            var            messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var            deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.Setup(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>()))
            .Callback <IIdentity, ITokenProvider, ITransportSettings[]>((i, s, t) => receivedTokenProvider = s)
            .Returns(GetDeviceClient);

            var productInfoStore        = Mock.Of <IProductInfoStore>();
            var credentialsCache        = Mock.Of <ICredentialsCache>();
            var edgeHubIdentity         = Mock.Of <IIdentity>(i => i.Id == "edgeDevice/$edgeHub");
            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                Mock.Of <ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                edgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());

            string token1            = TokenHelper.CreateSasToken("foo.azure-devices.net", DateTime.UtcNow.AddHours(2));
            var    deviceCredentials = new TokenCredentials(new DeviceIdentity("iotHub", "Device1"), token1, DummyProductInfo, true);
            var    deviceProxy       = Mock.Of <IDeviceProxy>(d => d.IsActive);

            Try <ICloudProxy> receivedCloudProxy1 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials);

            await connectionManager.AddDeviceConnection(deviceCredentials.Identity, deviceProxy);

            Assert.True(receivedCloudProxy1.Success);
            Assert.NotNull(receivedCloudProxy1.Value);
            Assert.True(receivedCloudProxy1.Value.IsActive);
            Assert.NotNull(receivedTokenProvider);
            Assert.Equal(token1, receivedTokenProvider.GetTokenAsync(Option.None <TimeSpan>()).Result);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials.Identity.Id).OrDefault());

            string token2 = TokenHelper.CreateSasToken("foo.azure-devices.net", DateTime.UtcNow.AddHours(2));

            deviceCredentials = new TokenCredentials(new DeviceIdentity("iotHub", "Device1"), token2, DummyProductInfo, true);

            Try <ICloudProxy> receivedCloudProxy2 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials);

            Assert.True(receivedCloudProxy2.Success);
            Assert.NotNull(receivedCloudProxy2.Value);
            Assert.True(receivedCloudProxy2.Value.IsActive);
            Assert.False(receivedCloudProxy1.Value.IsActive);
            Assert.NotNull(receivedTokenProvider);
            Assert.Equal(token2, receivedTokenProvider.GetTokenAsync(Option.None <TimeSpan>()).Result);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials.Identity.Id).OrDefault());
        }
        public async Task CloudProxyCallbackTest()
        {
            string device            = "device1";
            var    identity          = new DeviceIdentity("iotHub", device);
            var    deviceCredentials = new TokenCredentials(identity, "dummyToken", DummyProductInfo, true);

            Action <string, CloudConnectionStatus> callback = null;
            var cloudProxy      = Mock.Of <ICloudProxy>(c => c.IsActive);
            var cloudConnection = Mock.Of <ICloudConnection>(
                cp => cp.IsActive && cp.CloseAsync() == Task.FromResult(true) && cp.CloudProxy == Option.Some(cloudProxy));
            var cloudProxyProviderMock = new Mock <ICloudConnectionProvider>();

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

            var deviceProxy = new Mock <IDeviceProxy>(MockBehavior.Strict);

            deviceProxy.Setup(d => d.CloseAsync(It.Is <Exception>(e => e is EdgeHubConnectionException))).Returns(Task.CompletedTask);
            deviceProxy.SetupGet(d => d.IsActive).Returns(true);

            var credentialsCache = new Mock <ICredentialsCache>(MockBehavior.Strict);

            credentialsCache.Setup(c => c.Get(identity)).ReturnsAsync(Option.None <IClientCredentials>());
            var connectionManager = new ConnectionManager(cloudProxyProviderMock.Object, credentialsCache.Object, GetIdentityProvider());
            await connectionManager.AddDeviceConnection(deviceCredentials.Identity, deviceProxy.Object);

            Try <ICloudProxy> cloudProxyTry = await connectionManager.GetOrCreateCloudConnectionAsync(deviceCredentials);

            Assert.True(cloudProxyTry.Success);
            Assert.NotNull(callback);

            callback.Invoke(device, CloudConnectionStatus.TokenNearExpiry);
            deviceProxy.VerifyAll();
        }
示例#6
0
        public async Task GetClientCredentialsTest()
        {
            // Arrange
            var identity           = Mock.Of <IIdentity>(i => i.Id == "d1");
            var clientCredentials1 = Mock.Of <ITokenCredentials>(c => c.Identity == identity && c.Token == Guid.NewGuid().ToString());
            var clientCredentials2 = Mock.Of <ITokenCredentials>(c => c.Identity == identity && c.Token == Guid.NewGuid().ToString());
            var deviceProxy1       = Mock.Of <IDeviceProxy>(d => d.IsActive);
            var deviceProxy2       = Mock.Of <IDeviceProxy>(d => d.IsActive);

            Mock.Get(deviceProxy2).Setup(d => d.CloseAsync(It.IsAny <Exception>()))
            .Callback(() => Mock.Get(deviceProxy2).SetupGet(d2 => d2.IsActive).Returns(false))
            .Returns(Task.CompletedTask);
            var connectionManager = new ConnectionManager(Mock.Of <ICloudConnectionProvider>());

            // Act
            await connectionManager.AddDeviceConnection(clientCredentials1);

            connectionManager.BindDeviceProxy(identity, deviceProxy1);
            Option <IClientCredentials> d1ClientCredentials     = connectionManager.GetClientCredentials("d1");
            Option <IClientCredentials> absentClientCredentials = connectionManager.GetClientCredentials("d2");

            // Assert
            Assert.True(d1ClientCredentials.HasValue);
            Assert.IsAssignableFrom <ITokenCredentials>(d1ClientCredentials.OrDefault());
            Assert.Equal(clientCredentials1.Token, (d1ClientCredentials.OrDefault() as ITokenCredentials)?.Token);

            Assert.False(absentClientCredentials.HasValue);

            // Act
            await connectionManager.AddDeviceConnection(clientCredentials2);

            connectionManager.BindDeviceProxy(identity, deviceProxy2);
            d1ClientCredentials = connectionManager.GetClientCredentials("d1");

            // Assert
            Assert.True(d1ClientCredentials.HasValue);
            Assert.IsAssignableFrom <ITokenCredentials>(d1ClientCredentials.OrDefault());
            Assert.Equal(clientCredentials2.Token, (d1ClientCredentials.OrDefault() as ITokenCredentials)?.Token);

            // Act
            await connectionManager.RemoveDeviceConnection("d1");

            d1ClientCredentials = connectionManager.GetClientCredentials("d1");

            // Assert
            Assert.False(d1ClientCredentials.HasValue);
        }
        public async Task CloudConnectionInvalidUpdateTest()
        {
            var messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.SetupSequence(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>()))
            .Returns(GetDeviceClient())
            .Throws(new UnauthorizedException("connstr2 is invalid!"))
            .Throws(new UnauthorizedException("connstr2 is invalid!"));

            var productInfoStore        = Mock.Of <IProductInfoStore>();
            var credentialsCache        = Mock.Of <ICredentialsCache>();
            var edgeHubIdentity         = Mock.Of <IIdentity>(i => i.Id == "edgeDevice/$edgeHub");
            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                Mock.Of <ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                edgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());

            string token1             = TokenHelper.CreateSasToken("foo.azure-devices.net", DateTime.UtcNow.AddHours(2));
            var    deviceCredentials1 = new TokenCredentials(new DeviceIdentity("iotHub", "Device1"), token1, DummyProductInfo, true);
            var    deviceProxy        = Mock.Of <IDeviceProxy>(d => d.IsActive);

            Try <ICloudProxy> receivedCloudProxy1 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials1);

            await connectionManager.AddDeviceConnection(deviceCredentials1.Identity, deviceProxy);

            Assert.True(receivedCloudProxy1.Success);
            Assert.NotNull(receivedCloudProxy1.Value);
            Assert.True(receivedCloudProxy1.Value.IsActive);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials1.Identity.Id).OrDefault());

            string token2             = TokenHelper.CreateSasToken("foo.azure-devices.net", DateTime.UtcNow.AddHours(2));
            var    deviceCredentials2 = new TokenCredentials(new DeviceIdentity("iotHub", "Device1"), token2, DummyProductInfo, true);

            Try <ICloudProxy> receivedCloudProxy2 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials2);

            Assert.False(receivedCloudProxy2.Success);
            Assert.IsType <EdgeHubConnectionException>(receivedCloudProxy2.Exception);
            Assert.IsType <UnauthorizedException>(receivedCloudProxy2.Exception.InnerException);
            Assert.True(receivedCloudProxy1.Value.IsActive);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials2.Identity.Id).OrDefault());
        }
示例#8
0
        public async Task AddRemoveSubscriptionsTest()
        {
            // Arrange
            string deviceId = "d1";
            var    cloudConnectionProvider = Mock.Of <ICloudConnectionProvider>();
            var    credentialsCache        = Mock.Of <ICredentialsCache>();
            var    connectionManager       = new ConnectionManager(cloudConnectionProvider, credentialsCache, EdgeDeviceId, EdgeModuleId);
            var    identity = Mock.Of <IIdentity>(i => i.Id == deviceId);
            // ReSharper disable once PossibleUnintendedReferenceComparison
            var deviceCredentials = Mock.Of <IClientCredentials>(c => c.Identity == identity);

            // Act
            await connectionManager.AddDeviceConnection(identity, Mock.Of <IDeviceProxy>(d => d.IsActive));

            Option <IReadOnlyDictionary <DeviceSubscription, bool> > subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            IReadOnlyDictionary <DeviceSubscription, bool> subscriptions = subscriptionsOption.OrDefault();

            Assert.Empty(subscriptions);

            // Act
            connectionManager.AddSubscription(deviceId, DeviceSubscription.Methods);
            connectionManager.AddSubscription(deviceId, DeviceSubscription.C2D);
            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            subscriptions = subscriptionsOption.OrDefault();
            Assert.Equal(2, subscriptions.Count);
            Assert.Equal(true, subscriptions[DeviceSubscription.Methods]);
            Assert.Equal(true, subscriptions[DeviceSubscription.C2D]);

            // Act
            connectionManager.RemoveSubscription(deviceId, DeviceSubscription.Methods);
            connectionManager.RemoveSubscription(deviceId, DeviceSubscription.DesiredPropertyUpdates);
            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            subscriptions = subscriptionsOption.OrDefault();
            Assert.Equal(3, subscriptions.Count);
            Assert.Equal(false, subscriptions[DeviceSubscription.Methods]);
            Assert.Equal(true, subscriptions[DeviceSubscription.C2D]);
            Assert.Equal(false, subscriptions[DeviceSubscription.DesiredPropertyUpdates]);
        }
        public async Task AddRemoveSubscriptionsTest()
        {
            // Arrange
            string deviceId = "d1";
            var    cloudConnectionProvider = Mock.Of <ICloudConnectionProvider>();
            var    credentialsCache        = Mock.Of <ICredentialsCache>();
            var    connectionManager       = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());
            var    identity = Mock.Of <IIdentity>(i => i.Id == deviceId);

            // Act
            await connectionManager.AddDeviceConnection(identity, Mock.Of <IDeviceProxy>(d => d.IsActive));

            Option <IReadOnlyDictionary <DeviceSubscription, bool> > subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            IReadOnlyDictionary <DeviceSubscription, bool> subscriptions = subscriptionsOption.OrDefault();

            Assert.Empty(subscriptions);

            // Act
            connectionManager.AddSubscription(deviceId, DeviceSubscription.Methods);
            connectionManager.AddSubscription(deviceId, DeviceSubscription.C2D);
            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            subscriptions = subscriptionsOption.OrDefault();
            Assert.Equal(2, subscriptions.Count);
            Assert.True(subscriptions[DeviceSubscription.Methods]);
            Assert.True(subscriptions[DeviceSubscription.C2D]);

            // Act
            connectionManager.RemoveSubscription(deviceId, DeviceSubscription.Methods);
            connectionManager.RemoveSubscription(deviceId, DeviceSubscription.DesiredPropertyUpdates);
            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            subscriptions = subscriptionsOption.OrDefault();
            Assert.Equal(3, subscriptions.Count);
            Assert.False(subscriptions[DeviceSubscription.Methods]);
            Assert.True(subscriptions[DeviceSubscription.C2D]);
            Assert.False(subscriptions[DeviceSubscription.DesiredPropertyUpdates]);
        }
示例#10
0
        public async Task CloudConnectionInvalidUpdateTest()
        {
            var messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.SetupSequence(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <string>(), It.IsAny <Client.ITransportSettings[]>()))
            .Returns(GetDeviceClient())
            .Throws(new UnauthorizedException("connstr2 is invalid!"))
            .Throws(new UnauthorizedException("connstr2 is invalid!"));

            var cloudConnectionProvider = new CloudConnectionProvider(messageConverterProvider, 1, deviceClientProvider.Object, Option.None <UpstreamProtocol>(), Mock.Of <ITokenProvider>(), Mock.Of <IDeviceScopeIdentitiesCache>(), TimeSpan.FromMinutes(60));

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            var credentialsCache = Mock.Of <ICredentialsCache>();
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, EdgeDeviceId, EdgeModuleId);

            string deviceConnStr1    = "connstr1";
            var    deviceCredentials = new SharedKeyCredentials(new DeviceIdentity("iotHub", "Device1"), deviceConnStr1, DummyProductInfo);
            var    deviceProxy       = Mock.Of <IDeviceProxy>(d => d.IsActive);

            Try <ICloudProxy> receivedCloudProxy1 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials);

            await connectionManager.AddDeviceConnection(deviceCredentials.Identity, deviceProxy);

            Assert.True(receivedCloudProxy1.Success);
            Assert.NotNull(receivedCloudProxy1.Value);
            Assert.True(receivedCloudProxy1.Value.IsActive);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials.Identity.Id).OrDefault());

            string deviceConnStr2 = "connstr2";

            deviceCredentials = new SharedKeyCredentials(new DeviceIdentity("iotHub", "Device1"), deviceConnStr2, DummyProductInfo);

            Try <ICloudProxy> receivedCloudProxy2 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials);

            Assert.False(receivedCloudProxy2.Success);
            Assert.IsType <EdgeHubConnectionException>(receivedCloudProxy2.Exception);
            List <Exception> innerExceptions = (receivedCloudProxy2.Exception.InnerException as AggregateException)?.InnerExceptions.ToList() ?? new List <Exception>();

            Assert.Equal(2, innerExceptions.Count);
            Assert.IsType <UnauthorizedException>(innerExceptions[0]);
            Assert.IsType <UnauthorizedException>(innerExceptions[1]);
            Assert.True(receivedCloudProxy1.Value.IsActive);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials.Identity.Id).OrDefault());
        }
示例#11
0
        public async Task CloudProxyCallbackTest2()
        {
            string             device                   = "device1";
            var                deviceIdentity           = new DeviceIdentity("iotHub", device);
            IClientCredentials deviceCredentials        = new TokenCredentials(deviceIdentity, "dummyToken", DummyProductInfo, true);
            ITokenCredentials  updatedDeviceCredentials = new TokenCredentials(deviceIdentity, "dummyToken", DummyProductInfo, true);

            Action <string, CloudConnectionStatus> callback = null;
            var cloudProxy      = Mock.Of <ICloudProxy>(c => c.IsActive);
            var cloudConnection = Mock.Of <IClientTokenCloudConnection>(
                cp => cp.IsActive && cp.CloudProxy == Option.Some(cloudProxy));
            bool updatedCredentialsPassed = false;

            Mock.Get(cloudConnection).Setup(c => c.UpdateTokenAsync(updatedDeviceCredentials))
            .Callback(() => updatedCredentialsPassed = true)
            .ReturnsAsync(cloudProxy);
            var cloudProxyProviderMock = new Mock <ICloudConnectionProvider>();

            cloudProxyProviderMock.Setup(c => c.Connect(It.IsAny <IClientCredentials>(), It.IsAny <Action <string, CloudConnectionStatus> >()))
            .Callback <IClientCredentials, Action <string, CloudConnectionStatus> >((i, c) => callback = c)
            .ReturnsAsync(Try.Success(cloudConnection as ICloudConnection));

            var deviceProxy = new Mock <IDeviceProxy>(MockBehavior.Strict);

            var credentialsCache = new Mock <ICredentialsCache>(MockBehavior.Strict);

            credentialsCache.Setup(c => c.Get(deviceIdentity)).ReturnsAsync(Option.Some((IClientCredentials)updatedDeviceCredentials));
            var connectionManager = new ConnectionManager(cloudProxyProviderMock.Object, credentialsCache.Object, GetIdentityProvider());
            await connectionManager.AddDeviceConnection(deviceCredentials.Identity, deviceProxy.Object);

            Try <ICloudProxy> cloudProxyTry = await connectionManager.GetOrCreateCloudConnectionAsync(deviceCredentials);

            Assert.True(cloudProxyTry.Success);
            Assert.NotNull(callback);

            callback.Invoke(device, CloudConnectionStatus.TokenNearExpiry);

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

            deviceProxy.VerifyAll();
            credentialsCache.VerifyAll();
            Assert.True(updatedCredentialsPassed);
        }
示例#12
0
        public async Task CloudConnectionUpdateTest()
        {
            string receivedConnStr          = null;
            var    messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var    deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.Setup(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <string>(), It.IsAny <Client.ITransportSettings[]>()))
            .Callback <IIdentity, string, Client.ITransportSettings[]>((i, s, t) => receivedConnStr = s)
            .Returns(() => GetDeviceClient());

            var cloudConnectionProvider = new CloudConnectionProvider(messageConverterProvider, 1, deviceClientProvider.Object, Option.None <UpstreamProtocol>(), Mock.Of <ITokenProvider>(), Mock.Of <IDeviceScopeIdentitiesCache>(), TimeSpan.FromMinutes(60));

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            var credentialsCache = Mock.Of <ICredentialsCache>();
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, EdgeDeviceId, EdgeModuleId);

            string deviceConnStr1    = "connstr1";
            var    deviceCredentials = new SharedKeyCredentials(new DeviceIdentity("iotHub", "Device1"), deviceConnStr1, DummyProductInfo);
            var    deviceProxy       = Mock.Of <IDeviceProxy>(d => d.IsActive);

            Try <ICloudProxy> receivedCloudProxy1 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials);

            await connectionManager.AddDeviceConnection(deviceCredentials.Identity, deviceProxy);

            Assert.True(receivedCloudProxy1.Success);
            Assert.NotNull(receivedCloudProxy1.Value);
            Assert.True(receivedCloudProxy1.Value.IsActive);
            Assert.Equal(deviceConnStr1, receivedConnStr);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials.Identity.Id).OrDefault());

            string deviceConnStr2 = "connstr2";

            deviceCredentials = new SharedKeyCredentials(new DeviceIdentity("iotHub", "Device1"), deviceConnStr2, DummyProductInfo);

            Try <ICloudProxy> receivedCloudProxy2 = await connectionManager.CreateCloudConnectionAsync(deviceCredentials);

            Assert.True(receivedCloudProxy2.Success);
            Assert.NotNull(receivedCloudProxy2.Value);
            Assert.True(receivedCloudProxy2.Value.IsActive);
            Assert.False(receivedCloudProxy1.Value.IsActive);
            Assert.Equal(deviceConnStr2, receivedConnStr);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials.Identity.Id).OrDefault());
        }
示例#13
0
        public async Task KeepSubscriptionsOnDeviceRemoveTest()
        {
            // Arrange
            string deviceId = "d1";
            var    cloudConnectionProvider = Mock.Of <ICloudConnectionProvider>();
            var    credentialsCache        = Mock.Of <ICredentialsCache>();
            var    connectionManager       = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());
            var    identity      = Mock.Of <IIdentity>(i => i.Id == deviceId);
            bool   isProxyActive = true;
            // ReSharper disable once PossibleUnintendedReferenceComparison
            var deviceProxy = Mock.Of <IDeviceProxy>(d => d.Identity == identity);

            Mock.Get(deviceProxy).Setup(d => d.CloseAsync(It.IsAny <Exception>()))
            .Callback(() => isProxyActive = false)
            .Returns(Task.CompletedTask);
            Mock.Get(deviceProxy).SetupGet(d => d.IsActive)
            .Returns(() => isProxyActive);
            // ReSharper disable once PossibleUnintendedReferenceComparison
            var deviceProxy2 = Mock.Of <IDeviceProxy>(d => d.IsActive && d.Identity == identity);

            // Act
            Option <IReadOnlyDictionary <DeviceSubscription, bool> > subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.False(subscriptionsOption.HasValue);

            // Act
            await connectionManager.AddDeviceConnection(identity, deviceProxy);

            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            IReadOnlyDictionary <DeviceSubscription, bool> subscriptions = subscriptionsOption.OrDefault();

            Assert.Empty(subscriptions);

            // Act
            connectionManager.AddSubscription(deviceId, DeviceSubscription.Methods);
            connectionManager.AddSubscription(deviceId, DeviceSubscription.C2D);
            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            subscriptions = subscriptionsOption.OrDefault();
            Assert.Equal(2, subscriptions.Count);
            Assert.True(subscriptions[DeviceSubscription.Methods]);
            Assert.True(subscriptions[DeviceSubscription.C2D]);

            // Act
            await connectionManager.RemoveDeviceConnection(deviceId);

            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.False(subscriptionsOption.HasValue);

            // Act
            await connectionManager.AddDeviceConnection(identity, deviceProxy2);

            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            subscriptions = subscriptionsOption.OrDefault();
            Assert.Equal(2, subscriptions.Count);
            Assert.True(subscriptions[DeviceSubscription.Methods]);
            Assert.True(subscriptions[DeviceSubscription.C2D]);

            // Act
            connectionManager.AddSubscription(deviceId, DeviceSubscription.DesiredPropertyUpdates);
            connectionManager.AddSubscription(deviceId, DeviceSubscription.ModuleMessages);
            subscriptionsOption = connectionManager.GetSubscriptions(deviceId);

            // Assert
            Assert.True(subscriptionsOption.HasValue);
            subscriptions = subscriptionsOption.OrDefault();
            Assert.Equal(4, subscriptions.Count);
            Assert.True(subscriptions[DeviceSubscription.Methods]);
            Assert.True(subscriptions[DeviceSubscription.C2D]);
            Assert.True(subscriptions[DeviceSubscription.DesiredPropertyUpdates]);
            Assert.True(subscriptions[DeviceSubscription.ModuleMessages]);
        }
示例#14
0
        public async Task TestAddRemoveDeviceConnectionTest()
        {
            string deviceId = "id1";

            var deviceProxyMock1 = new Mock <IDeviceProxy>();

            deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(true);
            deviceProxyMock1.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
            .Callback(() => deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(false))
            .Returns(Task.FromResult(true));

            var deviceCredentials = new SharedKeyCredentials(new DeviceIdentity("iotHub", deviceId), "dummyConnStr", "abc");

            var edgeHub = new Mock <IEdgeHub>();

            IClient client = GetDeviceClient();
            var     messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var     deviceClientProvider     = new Mock <IClientProvider>();

            deviceClientProvider.Setup(d => d.Create(It.IsAny <IIdentity>(), It.IsAny <string>(), It.IsAny <Client.ITransportSettings[]>()))
            .Returns(client);

            var cloudConnectionProvider = new CloudConnectionProvider(messageConverterProvider, 1, deviceClientProvider.Object, Option.None <UpstreamProtocol>());

            cloudConnectionProvider.BindEdgeHub(edgeHub.Object);
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider);
            Try <ICloudProxy>  cloudProxyTry     = await connectionManager.CreateCloudConnectionAsync(deviceCredentials);

            Assert.True(cloudProxyTry.Success);
            var deviceListener = new DeviceMessageHandler(deviceCredentials.Identity, edgeHub.Object, connectionManager);

            Option <ICloudProxy> cloudProxy = await connectionManager.GetCloudConnection(deviceId);

            Assert.True(cloudProxy.HasValue);
            Assert.True(cloudProxy.OrDefault().IsActive);

            await connectionManager.AddDeviceConnection(deviceCredentials);

            deviceListener.BindDeviceProxy(deviceProxyMock1.Object);

            Option <IDeviceProxy> deviceProxy = connectionManager.GetDeviceConnection(deviceId);

            Assert.True(deviceProxy.HasValue);
            Assert.True(deviceProxy.OrDefault().IsActive);
            Assert.True(deviceProxyMock1.Object.IsActive);

            cloudProxy = await connectionManager.GetCloudConnection(deviceId);

            Assert.True(cloudProxy.HasValue);
            Assert.True(cloudProxy.OrDefault().IsActive);

            await deviceListener.CloseAsync();

            deviceProxy = connectionManager.GetDeviceConnection(deviceId);
            Assert.False(deviceProxy.HasValue);
            Assert.False(deviceProxyMock1.Object.IsActive);

            cloudProxy = await connectionManager.GetCloudConnection(deviceId);

            Assert.True(cloudProxy.HasValue);
            Assert.True(client.IsActive);
        }
        public async Task TestEdgeHubConnection()
        {
            const string EdgeDeviceId                   = "testHubEdgeDevice1";
            var          twinMessageConverter           = new TwinMessageConverter();
            var          twinCollectionMessageConverter = new TwinCollectionMessageConverter();
            var          messageConverterProvider       = new MessageConverterProvider(
                new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Message), new DeviceClientMessageConverter() },
                { typeof(Twin), twinMessageConverter },
                { typeof(TwinCollection), twinCollectionMessageConverter }
            });

            string iotHubConnectionString = await SecretsHelper.GetSecretFromConfigKey("iotHubConnStrKey");

            IotHubConnectionStringBuilder iotHubConnectionStringBuilder = IotHubConnectionStringBuilder.Create(iotHubConnectionString);
            RegistryManager registryManager = RegistryManager.CreateFromConnectionString(iotHubConnectionString);
            await registryManager.OpenAsync();

            string iothubHostName   = iotHubConnectionStringBuilder.HostName;
            var    identityProvider = new IdentityProvider(iothubHostName);
            var    identityFactory  = new ClientCredentialsFactory(identityProvider);

            (string edgeDeviceId, string deviceConnStr) = await RegistryManagerHelper.CreateDevice(EdgeDeviceId, iotHubConnectionString, registryManager, true, false);

            string edgeHubConnectionString = $"{deviceConnStr};ModuleId={EdgeHubModuleId}";

            IClientCredentials edgeHubCredentials = identityFactory.GetWithConnectionString(edgeHubConnectionString);
            string             sasKey             = ConnectionStringHelper.GetSharedAccessKey(deviceConnStr);
            var signatureProvider = new SharedAccessKeySignatureProvider(sasKey);
            var credentialsCache  = Mock.Of <ICredentialsCache>();
            var metadataStore     = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                new ClientProvider(),
                Option.None <UpstreamProtocol>(),
                new ClientTokenProvider(signatureProvider, iothubHostName, edgeDeviceId, TimeSpan.FromMinutes(60)),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                edgeHubCredentials.Identity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object);
            var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>();
            var connectionManager         = new ConnectionManager(cloudConnectionProvider, Mock.Of <ICredentialsCache>(), identityProvider, deviceConnectivityManager);

            try
            {
                Mock.Get(credentialsCache)
                .Setup(c => c.Get(edgeHubCredentials.Identity))
                .ReturnsAsync(Option.Some(edgeHubCredentials));
                Assert.NotNull(edgeHubCredentials);
                Assert.NotNull(edgeHubCredentials.Identity);

                // Set Edge hub desired properties
                await this.SetDesiredProperties(registryManager, edgeDeviceId);

                var endpointFactory = new EndpointFactory(connectionManager, new RoutingMessageConverter(), edgeDeviceId, 10, 10);
                var routeFactory    = new EdgeRouteFactory(endpointFactory);

                var            dbStoreProvider            = new InMemoryDbStoreProvider();
                IStoreProvider storeProvider              = new StoreProvider(dbStoreProvider);
                IEntityStore <string, TwinInfo> twinStore = storeProvider.GetEntityStore <string, TwinInfo>("twins");
                var      twinManager             = new TwinManager(connectionManager, twinCollectionMessageConverter, twinMessageConverter, Option.Some(twinStore));
                var      routerConfig            = new RouterConfig(Enumerable.Empty <Route>());
                TimeSpan defaultTimeout          = TimeSpan.FromSeconds(60);
                var      endpointExecutorFactory = new SyncEndpointExecutorFactory(new EndpointExecutorConfig(defaultTimeout, new FixedInterval(0, TimeSpan.FromSeconds(1)), defaultTimeout, true));
                Router   router = await Router.CreateAsync(Guid.NewGuid().ToString(), iothubHostName, routerConfig, endpointExecutorFactory);

                IInvokeMethodHandler invokeMethodHandler = new InvokeMethodHandler(connectionManager);
                var      subscriptionProcessor           = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager);
                IEdgeHub edgeHub = new RoutingEdgeHub(router, new RoutingMessageConverter(), connectionManager, twinManager, edgeDeviceId, invokeMethodHandler, subscriptionProcessor);
                cloudConnectionProvider.BindEdgeHub(edgeHub);

                var versionInfo = new VersionInfo("v1", "b1", "c1");

                // Create Edge Hub connection
                EdgeHubConnection edgeHubConnection = await EdgeHubConnection.Create(
                    edgeHubCredentials.Identity,
                    edgeHub,
                    twinManager,
                    connectionManager,
                    routeFactory,
                    twinCollectionMessageConverter,
                    versionInfo,
                    new NullDeviceScopeIdentitiesCache());

                await Task.Delay(TimeSpan.FromMinutes(1));

                TwinConfigSource configSource = new TwinConfigSource(edgeHubConnection, edgeHubCredentials.Identity.Id, versionInfo, twinManager, twinMessageConverter, twinCollectionMessageConverter, routeFactory);

                // Get and Validate EdgeHubConfig
                Option <EdgeHubConfig> edgeHubConfigOption = await configSource.GetConfig();

                Assert.True(edgeHubConfigOption.HasValue);
                EdgeHubConfig edgeHubConfig = edgeHubConfigOption.OrDefault();
                Assert.Equal("1.0", edgeHubConfig.SchemaVersion);
                Assert.NotNull(edgeHubConfig.Routes);
                Assert.NotNull(edgeHubConfig.StoreAndForwardConfiguration);
                Assert.Equal(20, edgeHubConfig.StoreAndForwardConfiguration.TimeToLiveSecs);

                IReadOnlyDictionary <string, RouteConfig> routes = edgeHubConfig.Routes;
                Assert.Equal(4, routes.Count);

                RouteConfig route1 = routes["route1"];
                Assert.True(route1.Route.Endpoint.GetType() == typeof(CloudEndpoint));
                Assert.Equal("route1", route1.Name);
                Assert.Equal("from /* INTO $upstream", route1.Value);

                RouteConfig route2   = routes["route2"];
                Endpoint    endpoint = route2.Route.Endpoint;
                Assert.True(endpoint.GetType() == typeof(ModuleEndpoint));
                Assert.Equal($"{edgeDeviceId}/module2/input1", endpoint.Id);
                Assert.Equal("route2", route2.Name);
                Assert.Equal("from /modules/module1 INTO BrokeredEndpoint(\"/modules/module2/inputs/input1\")", route2.Value);

                RouteConfig route3 = routes["route3"];
                endpoint = route3.Route.Endpoint;
                Assert.True(endpoint.GetType() == typeof(ModuleEndpoint));
                Assert.Equal($"{edgeDeviceId}/module3/input1", endpoint.Id);
                Assert.Equal("route3", route3.Name);
                Assert.Equal("from /modules/module2 INTO BrokeredEndpoint(\"/modules/module3/inputs/input1\")", route3.Value);

                RouteConfig route4 = routes["route4"];
                endpoint = route4.Route.Endpoint;
                Assert.True(endpoint.GetType() == typeof(ModuleEndpoint));
                Assert.Equal($"{edgeDeviceId}/module4/input1", endpoint.Id);
                Assert.Equal("route4", route4.Name);
                Assert.Equal("from /modules/module3 INTO BrokeredEndpoint(\"/modules/module4/inputs/input1\")", route4.Value);

                // Make sure reported properties were updated appropriately
                EdgeHubConnection.ReportedProperties reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId);

                Assert.Equal(200, reportedProperties.LastDesiredStatus.Code);
                Assert.NotNull(reportedProperties.Clients);
                Assert.Equal(0, reportedProperties.Clients.Count);
                Assert.Equal("1.0", reportedProperties.SchemaVersion);
                Assert.Equal(versionInfo, reportedProperties.VersionInfo);

                // Simulate a module and a downstream device that connects to Edge Hub.
                string             moduleId = "module1";
                string             sasToken = TokenHelper.CreateSasToken($"{iothubHostName}/devices/{edgeDeviceId}/modules/{moduleId}");
                string             moduleConnectionstring  = $"HostName={iothubHostName};DeviceId={edgeDeviceId};ModuleId={moduleId};SharedAccessSignature={sasToken}";
                IClientCredentials moduleClientCredentials = identityFactory.GetWithConnectionString(moduleConnectionstring);
                var moduleProxy = Mock.Of <IDeviceProxy>(d => d.IsActive);

                string downstreamDeviceId = "device1";
                sasToken = TokenHelper.CreateSasToken($"{iothubHostName}/devices/{downstreamDeviceId}");
                string             downstreamDeviceConnectionstring = $"HostName={iothubHostName};DeviceId={downstreamDeviceId};SharedAccessSignature={sasToken}";
                IClientCredentials downstreamDeviceCredentials      = identityFactory.GetWithConnectionString(downstreamDeviceConnectionstring);
                var downstreamDeviceProxy = Mock.Of <IDeviceProxy>(d => d.IsActive);

                // Connect the module and downstream device and make sure the reported properties are updated as expected.
                await connectionManager.AddDeviceConnection(moduleClientCredentials.Identity, moduleProxy);

                await connectionManager.AddDeviceConnection(downstreamDeviceCredentials.Identity, downstreamDeviceProxy);

                string moduleIdKey = $"{edgeDeviceId}/{moduleId}";
                await Task.Delay(TimeSpan.FromSeconds(10));

                reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId);

                Assert.Equal(2, reportedProperties.Clients.Count);
                Assert.Equal(ConnectionStatus.Connected, reportedProperties.Clients[moduleIdKey].Status);
                Assert.NotNull(reportedProperties.Clients[moduleIdKey].LastConnectedTimeUtc);
                Assert.Null(reportedProperties.Clients[moduleIdKey].LastDisconnectTimeUtc);
                Assert.Equal(ConnectionStatus.Connected, reportedProperties.Clients[downstreamDeviceId].Status);
                Assert.NotNull(reportedProperties.Clients[downstreamDeviceId].LastConnectedTimeUtc);
                Assert.Null(reportedProperties.Clients[downstreamDeviceId].LastDisconnectTimeUtc);
                Assert.Equal(200, reportedProperties.LastDesiredStatus.Code);
                Assert.Equal("1.0", reportedProperties.SchemaVersion);
                Assert.Equal(versionInfo, reportedProperties.VersionInfo);

                // Update desired propertied and make sure callback is called with valid values
                bool callbackCalled = false;

                Task ConfigUpdatedCallback(EdgeHubConfig updatedConfig)
                {
                    Assert.NotNull(updatedConfig);
                    Assert.NotNull(updatedConfig.StoreAndForwardConfiguration);
                    Assert.NotNull(updatedConfig.Routes);

                    routes = updatedConfig.Routes;
                    Assert.Equal(4, routes.Count);

                    route1 = routes["route1"];
                    Assert.True(route1.Route.Endpoint.GetType() == typeof(CloudEndpoint));
                    Assert.Equal("route1", route1.Name);
                    Assert.Equal("from /* INTO $upstream", route1.Value);

                    route2   = routes["route2"];
                    endpoint = route2.Route.Endpoint;
                    Assert.True(endpoint.GetType() == typeof(ModuleEndpoint));
                    Assert.Equal($"{edgeDeviceId}/module2/input1", endpoint.Id);
                    Assert.Equal("route2", route2.Name);
                    Assert.Equal("from /modules/module1 INTO BrokeredEndpoint(\"/modules/module2/inputs/input1\")", route2.Value);

                    route3   = routes["route4"];
                    endpoint = route3.Route.Endpoint;
                    Assert.True(endpoint.GetType() == typeof(ModuleEndpoint));
                    Assert.Equal($"{edgeDeviceId}/module5/input1", endpoint.Id);
                    Assert.Equal("route4", route3.Name);
                    Assert.Equal("from /modules/module3 INTO BrokeredEndpoint(\"/modules/module5/inputs/input1\")", route3.Value);

                    route4   = routes["route5"];
                    endpoint = route4.Route.Endpoint;
                    Assert.True(endpoint.GetType() == typeof(ModuleEndpoint));
                    Assert.Equal($"{edgeDeviceId}/module6/input1", endpoint.Id);
                    Assert.Equal("route5", route4.Name);
                    Assert.Equal("from /modules/module5 INTO BrokeredEndpoint(\"/modules/module6/inputs/input1\")", route4.Value);

                    callbackCalled = true;
                    return(Task.CompletedTask);
                }

                configSource.SetConfigUpdatedCallback(ConfigUpdatedCallback);
                await this.UpdateDesiredProperties(registryManager, edgeDeviceId);

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

                Assert.True(callbackCalled);

                reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId);

                Assert.Equal(200, reportedProperties.LastDesiredStatus.Code);
                Assert.NotNull(reportedProperties.Clients);
                Assert.Equal(2, reportedProperties.Clients.Count);
                Assert.Equal("1.0", reportedProperties.SchemaVersion);
                Assert.Equal(versionInfo, reportedProperties.VersionInfo);

                // Disconnect the downstream device and make sure the reported properties are updated as expected.
                await connectionManager.RemoveDeviceConnection(moduleIdKey);

                await connectionManager.RemoveDeviceConnection(downstreamDeviceId);

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

                reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId);

                Assert.Equal(1, reportedProperties.Clients.Count);
                Assert.True(reportedProperties.Clients.ContainsKey(moduleIdKey));
                Assert.False(reportedProperties.Clients.ContainsKey(downstreamDeviceId));
                Assert.Equal(ConnectionStatus.Disconnected, reportedProperties.Clients[moduleIdKey].Status);
                Assert.NotNull(reportedProperties.Clients[moduleIdKey].LastConnectedTimeUtc);
                Assert.NotNull(reportedProperties.Clients[moduleIdKey].LastDisconnectTimeUtc);
                Assert.Equal(200, reportedProperties.LastDesiredStatus.Code);
                Assert.Equal("1.0", reportedProperties.SchemaVersion);
                Assert.Equal(versionInfo, reportedProperties.VersionInfo);

                // If the edge hub restarts, clear out the connected devices in the reported properties.
                await EdgeHubConnection.Create(
                    edgeHubCredentials.Identity,
                    edgeHub,
                    twinManager,
                    connectionManager,
                    routeFactory,
                    twinCollectionMessageConverter,
                    versionInfo,
                    new NullDeviceScopeIdentitiesCache());

                await Task.Delay(TimeSpan.FromMinutes(1));

                reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId);

                Assert.Null(reportedProperties.Clients);
                Assert.Equal("1.0", reportedProperties.SchemaVersion);
                Assert.Equal(versionInfo, reportedProperties.VersionInfo);
            }
            finally
            {
                try
                {
                    await RegistryManagerHelper.RemoveDevice(edgeDeviceId, registryManager);
                }
                catch (Exception)
                {
                    // ignored
                }
            }
        }
        public async Task UpdateDeviceConnectionTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = null;
            string hostname = "dummy.azure-devices.net";
            string deviceId = "device1";

            ITokenCredentials GetClientCredentials(TimeSpan tokenExpiryDuration)
            {
                string token    = TokenHelper.CreateSasToken(hostname, DateTime.UtcNow.AddSeconds(tokenExpiryDuration.TotalSeconds));
                var    identity = new DeviceIdentity(hostname, deviceId);

                return(new TokenCredentials(identity, token, string.Empty, Option.None <string>(), Option.None <string>(), false));
            }

            IDeviceProxy GetMockDeviceProxy()
            {
                var deviceProxyMock1 = new Mock <IDeviceProxy>();

                deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(true);
                deviceProxyMock1.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
                .Callback(() => deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(false))
                .Returns(Task.CompletedTask);
                return(deviceProxyMock1.Object);
            }

            IClient GetMockedDeviceClient()
            {
                var deviceClient = new Mock <IClient>();

                deviceClient.SetupGet(dc => dc.IsActive).Returns(true);
                deviceClient.Setup(dc => dc.CloseAsync())
                .Callback(() => deviceClient.SetupGet(dc => dc.IsActive).Returns(false))
                .Returns(Task.FromResult(true));

                deviceClient.Setup(dc => dc.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
                .Callback <ConnectionStatusChangesHandler>(c => connectionStatusChangesHandler = c);

                deviceClient.Setup(dc => dc.OpenAsync())
                .Callback(
                    () =>
                {
                    int currentCount = receivedConnectedStatusCount;
                    Assert.NotNull(connectionStatusChangesHandler);
                    connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
                    Assert.Equal(receivedConnectedStatusCount, currentCount);
                })
                .Returns(Task.CompletedTask);
                return(deviceClient.Object);
            }

            ITokenProvider tokenProvider        = null;
            var            deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>(), Option.None <string>()))
            .Callback <IIdentity, ITokenProvider, ITransportSettings[], Option <string> >((s, a, t, m) => tokenProvider = a)
            .Returns(GetMockedDeviceClient);

            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var messageConverterProvider = Mock.Of <IMessageConverterProvider>();

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>();

            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == deviceId))).ReturnsAsync(Option.Some(deviceId));

            var credentialsCache = Mock.Of <ICredentialsCache>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                credentialsCache,
                Mock.Of <IIdentity>(i => i.Id == $"{deviceId}/$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                scopeAuthenticationOnly: true,
                trackDeviceState: true,
                true);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            var deviceConnectivityManager        = Mock.Of <IDeviceConnectivityManager>();
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of <ICredentialsCache>(), new IdentityProvider(hostname), deviceConnectivityManager);

            ITokenCredentials clientCredentials1 = GetClientCredentials(TimeSpan.FromSeconds(10));
            Try <ICloudProxy> cloudProxyTry1     = await connectionManager.CreateCloudConnectionAsync(clientCredentials1);

            Assert.True(cloudProxyTry1.Success);

            IDeviceProxy deviceProxy1 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials1.Identity, deviceProxy1);

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

            Assert.NotNull(tokenProvider);
            Task <string> tokenGetter = tokenProvider.GetTokenAsync(Option.None <TimeSpan>());

            Assert.False(tokenGetter.IsCompleted);

            ITokenCredentials clientCredentials2 = GetClientCredentials(TimeSpan.FromMinutes(2));
            Try <ICloudProxy> cloudProxyTry2     = await connectionManager.CreateCloudConnectionAsync(clientCredentials2);

            Assert.True(cloudProxyTry2.Success);

            IDeviceProxy deviceProxy2 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials2.Identity, deviceProxy2);

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

            Assert.False(tokenGetter.IsCompleted);

            ITokenCredentials clientCredentials3 = GetClientCredentials(TimeSpan.FromMinutes(10));
            Try <ICloudProxy> cloudProxyTry3     = await connectionManager.CreateCloudConnectionAsync(clientCredentials3);

            Assert.True(cloudProxyTry3.Success);

            IDeviceProxy deviceProxy3 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials3.Identity, deviceProxy3);

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

            Assert.True(tokenGetter.IsCompleted);
            Assert.Equal(tokenGetter.Result, clientCredentials3.Token);
        }
示例#17
0
        public async Task UpdateDeviceConnectionTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = null;
            string hostname = "dummy.azure-devices.net";
            string deviceId = "device1";

            IClientCredentials GetClientCredentials(TimeSpan tokenExpiryDuration)
            {
                string token    = TokenHelper.CreateSasToken(hostname, DateTime.UtcNow.AddSeconds(tokenExpiryDuration.TotalSeconds));
                var    identity = new DeviceIdentity(hostname, deviceId);

                return(new TokenCredentials(identity, token, string.Empty));
            }

            IDeviceProxy GetMockDeviceProxy()
            {
                var deviceProxyMock1 = new Mock <IDeviceProxy>();

                deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(true);
                deviceProxyMock1.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
                .Callback(() => deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(false))
                .Returns(Task.CompletedTask);
                return(deviceProxyMock1.Object);
            }

            IClient GetMockedDeviceClient()
            {
                var deviceClient = new Mock <IClient>();

                deviceClient.SetupGet(dc => dc.IsActive).Returns(true);
                deviceClient.Setup(dc => dc.CloseAsync())
                .Callback(() => deviceClient.SetupGet(dc => dc.IsActive).Returns(false))
                .Returns(Task.FromResult(true));

                deviceClient.Setup(dc => dc.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
                .Callback <ConnectionStatusChangesHandler>(c => connectionStatusChangesHandler = c);

                deviceClient.Setup(dc => dc.OpenAsync())
                .Callback(() =>
                {
                    int currentCount = receivedConnectedStatusCount;
                    Assert.NotNull(connectionStatusChangesHandler);
                    connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
                    Assert.Equal(receivedConnectedStatusCount, currentCount);
                })
                .Returns(Task.CompletedTask);
                return(deviceClient.Object);
            }

            IAuthenticationMethod authenticationMethod = null;
            var deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <IAuthenticationMethod>(), It.IsAny <ITransportSettings[]>()))
            .Callback <IIdentity, IAuthenticationMethod, ITransportSettings[]>((s, a, t) => authenticationMethod = a)
            .Returns(() => GetMockedDeviceClient());

            var messageConverterProvider = Mock.Of <IMessageConverterProvider>();

            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(messageConverterProvider, 1, deviceClientProvider.Object, Option.None <UpstreamProtocol>(), TokenProvider, DeviceScopeIdentitiesCache, TimeSpan.FromMinutes(60), true);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            var credentialsCache = Mock.Of <ICredentialsCache>();
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, deviceId, "$edgeHub");

            IClientCredentials clientCredentials1 = GetClientCredentials(TimeSpan.FromSeconds(10));
            Try <ICloudProxy>  cloudProxyTry1     = await connectionManager.CreateCloudConnectionAsync(clientCredentials1);

            Assert.True(cloudProxyTry1.Success);

            IDeviceProxy deviceProxy1 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials1.Identity, deviceProxy1);

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

            Assert.NotNull(authenticationMethod);
            var deviceTokenRefresher = authenticationMethod as DeviceAuthenticationWithTokenRefresh;

            Assert.NotNull(deviceTokenRefresher);
            Task <string> tokenGetter = deviceTokenRefresher.GetTokenAsync(hostname);

            Assert.False(tokenGetter.IsCompleted);

            IClientCredentials clientCredentials2 = GetClientCredentials(TimeSpan.FromMinutes(2));
            Try <ICloudProxy>  cloudProxyTry2     = await connectionManager.CreateCloudConnectionAsync(clientCredentials2);

            Assert.True(cloudProxyTry2.Success);

            IDeviceProxy deviceProxy2 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials2.Identity, deviceProxy2);

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

            Assert.False(tokenGetter.IsCompleted);

            IClientCredentials clientCredentials3 = GetClientCredentials(TimeSpan.FromMinutes(10));
            Try <ICloudProxy>  cloudProxyTry3     = await connectionManager.CreateCloudConnectionAsync(clientCredentials3);

            Assert.True(cloudProxyTry3.Success);

            IDeviceProxy deviceProxy3 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials3.Identity, deviceProxy3);

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

            Assert.True(tokenGetter.IsCompleted);
            Assert.Equal(tokenGetter.Result, (clientCredentials3 as ITokenCredentials)?.Token);
        }
示例#18
0
        public async Task InvokeMethodLateSubscriptionTest()
        {
            // Create a mock endpoint capable of returning a mock processor
            var processor = Mock.Of <IProcessor>();
            var endpoint  = new Mock <Endpoint>("myId");

            endpoint.Setup(ep => ep.CreateProcessor()).Returns(processor);
            endpoint.SetupGet(ep => ep.Id).Returns("myId");

            // Create a mock endpoint executor factory to create the endpoint executor to verify invocation
            var endpointExecutor = Mock.Of <IEndpointExecutor>();

            Mock.Get(endpointExecutor).SetupGet(ee => ee.Endpoint).Returns(() => endpoint.Object);
            var endpointExecutorFactory = Mock.Of <IEndpointExecutorFactory>();

            Mock.Get(endpointExecutorFactory).Setup(eef => eef.CreateAsync(It.IsAny <Endpoint>())).ReturnsAsync(endpointExecutor);

            // Create a route to map to the message
            var endpoints = new HashSet <Endpoint> {
                endpoint.Object
            };
            var route = new Route("myRoute", "true", "myIotHub", TelemetryMessageSource.Instance, endpoints);

            // Create a router
            var    routerConfig = new RouterConfig(new[] { route });
            Router router       = await Router.CreateAsync("myRouter", "myIotHub", routerConfig, endpointExecutorFactory);

            // Create mock message converter to generate a message with source matching the route
            var messageConverter = Mock.Of <Core.IMessageConverter <IMessage> >();
            var methodRequest    = new DirectMethodRequest("device1/module1", "shutdown", null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(20));

            // Mock of twin manager
            var twinManager = Mock.Of <ITwinManager>();

            // DeviceListener
            var identity            = Mock.Of <IModuleIdentity>(m => m.DeviceId == "device1" && m.ModuleId == "module1" && m.Id == "device1/module1");
            var credentialsProvider = Mock.Of <IClientCredentials>(c => c.Identity == identity);
            var cloudProxy          = new Mock <ICloudProxy>();

            // ICloudConnectionProvider
            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 connectionManager = new ConnectionManager(cloudConnectionProvider.Object);

            IInvokeMethodHandler invokeMethodHandler = new InvokeMethodHandler(connectionManager);

            // RoutingEdgeHub
            var routingEdgeHub = new RoutingEdgeHub(router, messageConverter, connectionManager, twinManager, "testEdgeDevice", invokeMethodHandler);

            var deviceMessageHandler  = new DeviceMessageHandler(identity, routingEdgeHub, connectionManager);
            var underlyingDeviceProxy = new Mock <IDeviceProxy>();

            // Arrange
            Message message = new Message.Builder(new byte[0]).Build();

            message.Properties[Core.SystemProperties.CorrelationId] = methodRequest.CorrelationId;
            message.Properties[Core.SystemProperties.StatusCode]    = "200";

            underlyingDeviceProxy.Setup(d => d.InvokeMethodAsync(It.IsAny <DirectMethodRequest>()))
            .Callback(() => deviceMessageHandler.ProcessMethodResponseAsync(message))
            .ReturnsAsync(default(DirectMethodResponse));
            underlyingDeviceProxy.SetupGet(d => d.IsActive).Returns(true);


            // Act
            await connectionManager.AddDeviceConnection(credentialsProvider);

            deviceMessageHandler.BindDeviceProxy(underlyingDeviceProxy.Object);
            Task <DirectMethodResponse> responseTask = routingEdgeHub.InvokeMethodAsync(identity.Id, methodRequest);

            // Assert
            Assert.False(responseTask.IsCompleted);

            // Act
            await routingEdgeHub.AddSubscription(identity.Id, DeviceSubscription.Methods);

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

            // Assert
            Assert.True(responseTask.IsCompleted);
            Assert.Equal(methodRequest.CorrelationId, responseTask.Result.CorrelationId);
            Assert.Equal(200, responseTask.Result.Status);
            Assert.False(responseTask.Result.Exception.HasValue);
            Assert.Equal(HttpStatusCode.OK, responseTask.Result.HttpStatusCode);
        }