Esempio n. 1
0
        async Task <ICloudProxy> GetCloudProxyWithConnectionStringKey(string connectionStringConfigKey, IEdgeHub edgeHub)
        {
            const int ConnectionPoolSize     = 10;
            string    deviceConnectionString = await SecretsHelper.GetSecretFromConfigKey(connectionStringConfigKey);

            var converters = new MessageConverterProvider(new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Client.Message), new DeviceClientMessageConverter() },
                { typeof(Twin), new TwinMessageConverter() },
                { typeof(TwinCollection), new TwinCollectionMessageConverter() }
            });

            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(converters, ConnectionPoolSize, new ClientProvider(), Option.None <UpstreamProtocol>(), Mock.Of <ITokenProvider>(), Mock.Of <IDeviceScopeIdentitiesCache>(), TimeSpan.FromMinutes(60), true);

            cloudConnectionProvider.BindEdgeHub(edgeHub);
            var deviceIdentity    = Mock.Of <IDeviceIdentity>(m => m.Id == ConnectionStringHelper.GetDeviceId(deviceConnectionString));
            var clientCredentials = new SharedKeyCredentials(deviceIdentity, deviceConnectionString, string.Empty);

            Try <ICloudConnection> cloudConnection = await cloudConnectionProvider.Connect(clientCredentials, (_, __) => { });

            Assert.True(cloudConnection.Success);
            Assert.True(cloudConnection.Value.IsActive);
            Assert.True(cloudConnection.Value.CloudProxy.HasValue);
            return(cloudConnection.Value.CloudProxy.OrDefault());
        }
Esempio n. 2
0
        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());
        }
Esempio n. 3
0
        public async Task CreateCloudProxyTest()
        {
            string edgeDeviceId = "edgeDevice";
            string module1Id    = "module1";

            var module1Credentials = new TokenCredentials(new ModuleIdentity("iotHub", edgeDeviceId, module1Id), "token", DummyProductInfo, false);

            IClient client1 = GetDeviceClient();
            IClient client2 = GetDeviceClient();
            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(client1)
            .Returns(client2);

            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>());

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

            Task <Try <ICloudProxy> > getCloudProxyTask1 = connectionManager.CreateCloudConnectionAsync(module1Credentials);
            Task <Try <ICloudProxy> > getCloudProxyTask2 = connectionManager.CreateCloudConnectionAsync(module1Credentials);

            Try <ICloudProxy>[] cloudProxies = await Task.WhenAll(getCloudProxyTask1, getCloudProxyTask2);

            Assert.NotEqual(cloudProxies[0].Value, cloudProxies[1].Value);

            Option <ICloudProxy> currentCloudProxyId1 = await connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            ICloudProxy currentCloudProxy = currentCloudProxyId1.OrDefault();
            ICloudProxy cloudProxy1       = cloudProxies[0].Value;
            ICloudProxy cloudProxy2       = cloudProxies[1].Value;

            Assert.True(currentCloudProxy == cloudProxy1 || currentCloudProxy == cloudProxy2);
            if (currentCloudProxy == cloudProxy1)
            {
                Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Once);
                Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Never);
            }
            else
            {
                Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Once);
                Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Never);
            }
        }
        public async Task ConnectUsingTokenCredentialsTest()
        {
            // Arrange
            var productInfoStore = Mock.Of <IProductInfoStore>();
            var edgeHub          = Mock.Of <IEdgeHub>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                GetMockDeviceClientProvider(),
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                DeviceScopeIdentitiesCache,
                CredentialsCache,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

            cloudConnectionProvider.BindEdgeHub(edgeHub);
            var    deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");
            string token          = TokenHelper.CreateSasToken(IotHubHostName, DateTime.UtcNow.AddMinutes(10));
            var    tokenCreds     = new TokenCredentials(deviceIdentity, token, string.Empty, false);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(tokenCreds, null);

            // Assert
            Assert.True(cloudProxy.Success);
            Assert.NotNull(cloudProxy.Value);
        }
        public async Task ConnectWithInvalidConnectionStringTest()
        {
            var edgeHub = Mock.Of <IEdgeHub>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(MessageConverterProvider, ConnectionPoolSize, new ClientProvider(), Option.None <UpstreamProtocol>(), TokenProvider, DeviceScopeIdentitiesCache, TimeSpan.FromMinutes(60));

            cloudConnectionProvider.BindEdgeHub(edgeHub);
            var deviceIdentity1           = Mock.Of <IIdentity>(m => m.Id == "device1");
            var clientCredentials1        = new SharedKeyCredentials(deviceIdentity1, "dummyConnStr", null);
            Try <ICloudConnection> result = await cloudConnectionProvider.Connect(clientCredentials1, null);

            Assert.False(result.Success);
            Assert.IsType <AggregateException>(result.Exception);

            string deviceConnectionString = await SecretsHelper.GetSecretFromConfigKey("device1ConnStrKey");

            // Change the connection string key, deliberately.
            char updatedLastChar = (char)(deviceConnectionString[deviceConnectionString.Length - 1] + 1);

            deviceConnectionString = deviceConnectionString.Substring(0, deviceConnectionString.Length - 1) + updatedLastChar;
            var deviceIdentity2               = Mock.Of <IIdentity>(m => m.Id == ConnectionStringHelper.GetDeviceId(deviceConnectionString));
            var clientCredentials2            = new SharedKeyCredentials(deviceIdentity2, deviceConnectionString, null);
            Try <ICloudConnection> cloudProxy = cloudConnectionProvider.Connect(clientCredentials2, null).Result;

            Assert.False(cloudProxy.Success);
        }
        public async Task ConnectUsingIdentityInScopeTest()
        {
            // Arrange
            var deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict);
            var deviceServiceIdentity      = new ServiceIdentity(deviceIdentity.Id, "1234", new string[0], new ServiceAuthentication(ServiceAuthenticationType.CertificateAuthority), ServiceIdentityStatus.Enabled);

            deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(It.Is <string>(i => i == deviceIdentity.Id), false))
            .ReturnsAsync(Option.Some(deviceServiceIdentity));

            var edgeHub = Mock.Of <IEdgeHub>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                GetMockDeviceClientProvider(),
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                CredentialsCache,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20));

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(deviceIdentity, null);

            // Assert
            Assert.True(cloudProxy.Success);
            Assert.NotNull(cloudProxy.Value);
            deviceScopeIdentitiesCache.VerifyAll();
        }
Esempio n. 7
0
        public async Task GetCloudProxyTest()
        {
            // Arrange
            string edgeDeviceId       = "edgeDevice";
            string module1Id          = "module1";
            string iotHub             = "foo.azure-devices.net";
            string token              = TokenHelper.CreateSasToken(iotHub);
            var    module1Credentials = new TokenCredentials(new ModuleIdentity(iotHub, edgeDeviceId, module1Id), token, DummyProductInfo, true);

            IClient client1 = GetDeviceClient();
            IClient client2 = GetDeviceClient();
            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(client1)
            .Returns(client2);

            ICredentialsCache credentialsCache = new CredentialsCache(new NullCredentialsCache());
            await credentialsCache.Add(module1Credentials);

            var productInfoStore        = Mock.Of <IProductInfoStore>();
            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                Mock.Of <ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                new ModuleIdentity(iotHub, edgeDeviceId, "$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

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

            // Act
            Option <ICloudProxy> getCloudProxyTask = await connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            // Assert
            Assert.True(getCloudProxyTask.HasValue);
            Assert.True(getCloudProxyTask.OrDefault().IsActive);

            // Act
            await getCloudProxyTask.OrDefault().CloseAsync();

            Option <ICloudProxy> newCloudProxyTask1 = await connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            // Assert
            Assert.True(newCloudProxyTask1.HasValue);
            Assert.NotEqual(newCloudProxyTask1.OrDefault(), getCloudProxyTask.OrDefault());

            Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Once);
            Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Never);
        }
Esempio n. 8
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>());
            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 = connectionManager.GetCloudConnection(deviceId);

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

            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 = 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 = connectionManager.GetCloudConnection(deviceId);
            Assert.False(cloudProxy.HasValue);
            Assert.False(client.IsActive);
        }
Esempio n. 9
0
        public async Task ConnectUsingInvalidTokenCredentialsTest()
        {
            // Arrange
            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.OpenAsync()).ThrowsAsync(new TimeoutException());

            var deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>(), Option.None <string>()))
            .Returns(deviceClient.Object);
            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var edgeHub = Mock.Of <IEdgeHub>();
            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict);

            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                CredentialsCache,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                true,
                true,
                true);

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            var deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");

            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == deviceIdentity.Id)))
            .ReturnsAsync(Option.Some(deviceIdentity.Id));
            string token      = TokenHelper.CreateSasToken(IotHubHostName, DateTime.UtcNow.AddMinutes(10));
            var    tokenCreds = new TokenCredentials(deviceIdentity, token, string.Empty, Option.None <string>(), Option.None <string>(), false);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(tokenCreds, null);

            // Assert
            Assert.False(cloudProxy.Success);
            Assert.IsType <TimeoutException>(cloudProxy.Exception);
        }
Esempio n. 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 <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());
        }
        public void GetTransportSettingsTest(Option <UpstreamProtocol> upstreamProtocol, int connectionPoolSize, Option <IWebProxy> proxy, ITransportSettings[] expectedTransportSettingsList, bool useServerHeartbeat)
        {
            const string expectedAuthChain = "e3;e2;e1";

            ITransportSettings[] transportSettingsList = CloudConnectionProvider.GetTransportSettings(upstreamProtocol, connectionPoolSize, proxy, useServerHeartbeat, expectedAuthChain);

            Assert.NotNull(transportSettingsList);
            Assert.Equal(expectedTransportSettingsList.Length, transportSettingsList.Length);
            for (int i = 0; i < expectedTransportSettingsList.Length; i++)
            {
                ITransportSettings expectedTransportSettings = expectedTransportSettingsList[i];
                ITransportSettings transportSettings         = transportSettingsList[i];

                Assert.Equal(expectedTransportSettings.GetType(), transportSettings.GetType());
                Assert.Equal(expectedTransportSettings.GetTransportType(), transportSettings.GetTransportType());

                // Check authchain via Reflection
                string authChain = (string)transportSettings.GetType()
                                   .GetProperty("AuthenticationChain", BindingFlags.NonPublic | BindingFlags.Instance)
                                   .GetValue(transportSettings);

                Assert.Equal(authChain, expectedAuthChain);

                switch (expectedTransportSettings)
                {
                case AmqpTransportSettings _:
                {
                    var expected = (AmqpTransportSettings)expectedTransportSettings;
                    var actual   = (AmqpTransportSettings)transportSettings;
                    Assert.True(expected.Equals(actual));     // AmqpTransportSettings impls Equals, but doesn't override Object.Equals

                    if (proxy == Option.None <IWebProxy>())
                    {
                        Assert.Null(actual.Proxy);
                    }
                    else
                    {
                        Assert.True(actual.Proxy is WebProxy);
                        Assert.Equal(((WebProxy)expected.Proxy).Address, ((WebProxy)actual.Proxy).Address);
                    }

                    break;
                }

                case MqttTransportSettings _:
                {
                    var expected = (MqttTransportSettings)expectedTransportSettings;
                    var actual   = (MqttTransportSettings)transportSettings;
                    Assert.True(actual.Proxy is WebProxy);
                    Assert.Equal(((WebProxy)expected.Proxy).Address, ((WebProxy)actual.Proxy).Address);
                    break;
                }
                }
            }
        }
Esempio n. 12
0
        async Task <ICloudProxy> GetCloudProxyFromConnectionStringKey(string connectionStringConfigKey, IEdgeHub edgeHub)
        {
            const int ConnectionPoolSize     = 10;
            string    deviceConnectionString = await SecretsHelper.GetSecretFromConfigKey(connectionStringConfigKey);

            string deviceId       = ConnectionStringHelper.GetDeviceId(deviceConnectionString);
            string iotHubHostName = ConnectionStringHelper.GetHostName(deviceConnectionString);
            string sasKey         = ConnectionStringHelper.GetSharedAccessKey(deviceConnectionString);
            var    converters     = new MessageConverterProvider(
                new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Message), new DeviceClientMessageConverter() },
                { typeof(Twin), new TwinMessageConverter() },
                { typeof(TwinCollection), new TwinCollectionMessageConverter() }
            });

            var credentialsCache = Mock.Of <ICredentialsCache>();
            var metadataStore    = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                converters,
                ConnectionPoolSize,
                new ClientProvider(Option.None <string>()),
                Option.None <UpstreamProtocol>(),
                Mock.Of <Util.ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                Mock.Of <IIdentity>(i => i.Id == $"{deviceId}/$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                true,
                true);

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            var    clientTokenProvider = new ClientTokenProvider(new SharedAccessKeySignatureProvider(sasKey), iotHubHostName, deviceId, TimeSpan.FromHours(1));
            string token = await clientTokenProvider.GetTokenAsync(Option.None <TimeSpan>());

            var deviceIdentity    = new DeviceIdentity(iotHubHostName, deviceId);
            var clientCredentials = new TokenCredentials(deviceIdentity, token, string.Empty, Option.None <string>(), Option.None <string>(), false);

            Try <ICloudConnection> cloudConnection = await cloudConnectionProvider.Connect(clientCredentials, (_, __) => { });

            Assert.True(cloudConnection.Success);
            Assert.True(cloudConnection.Value.IsActive);
            Assert.True(cloudConnection.Value.CloudProxy.HasValue);
            return(cloudConnection.Value.CloudProxy.OrDefault());
        }
Esempio n. 13
0
        public async Task ConnectUsingIdentityInCacheTest()
        {
            // Arrange
            var    deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");
            string token          = TokenHelper.CreateSasToken(IotHubHostName, DateTime.UtcNow.AddMinutes(10));
            var    tokenCreds     = new TokenCredentials(deviceIdentity, token, string.Empty, Option.None <string>(), Option.None <string>(), false);

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict);
            var deviceServiceIdentity      = new ServiceIdentity(deviceIdentity.Id, "1234", new string[0], new ServiceAuthentication(ServiceAuthenticationType.CertificateAuthority), ServiceIdentityStatus.Disabled);

            deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(It.Is <string>(i => i == deviceIdentity.Id)))
            .ReturnsAsync(Option.Some(deviceServiceIdentity));
            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == deviceIdentity.Id)))
            .ReturnsAsync(Option.Some(deviceIdentity.Id));

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

            credentialsCache.Setup(c => c.Get(deviceIdentity)).ReturnsAsync(Option.Some((IClientCredentials)tokenCreds));
            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var edgeHub = Mock.Of <IEdgeHub>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                GetMockDeviceClientProvider(),
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                credentialsCache.Object,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                scopeAuthenticationOnly: false,
                trackDeviceState: false,
                nestedEdgeEnabled: true);

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(deviceIdentity, null);

            // Assert
            Assert.True(cloudProxy.Success);
            Assert.NotNull(cloudProxy.Value);
            deviceScopeIdentitiesCache.VerifyAll();
            credentialsCache.VerifyAll();
        }
        public async Task ConnectTest()
        {
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(MessageConverterProvider, ConnectionPoolSize, new ClientProvider(), Option.None <UpstreamProtocol>());
            string deviceConnectionString = await SecretsHelper.GetSecretFromConfigKey("device1ConnStrKey");

            var deviceIdentity                = Mock.Of <IDeviceIdentity>(m => m.Id == ConnectionStringHelper.GetDeviceId(deviceConnectionString));
            var clientCredentials             = new SharedKeyCredentials(deviceIdentity, deviceConnectionString, null);
            Try <ICloudConnection> cloudProxy = cloudConnectionProvider.Connect(clientCredentials, null).Result;

            Assert.True(cloudProxy.Success);
            bool result = await cloudProxy.Value.CloseAsync();

            Assert.True(result);
        }
Esempio n. 15
0
        public async Task Connect_ScopeOnly_TokenCredentials()
        {
            var deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict);

            deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(It.Is <string>(i => i == deviceIdentity.Id)))
            .ReturnsAsync(Option.None <ServiceIdentity>());
            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == deviceIdentity.Id)))
            .ReturnsAsync(Option.Some(deviceIdentity.Id));
            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var    edgeHub          = Mock.Of <IEdgeHub>();
            var    credentialsCache = new Mock <ICredentialsCache>(MockBehavior.Strict);
            string token            = TokenHelper.CreateSasToken(IotHubHostName, DateTime.UtcNow.AddMinutes(10));
            var    tokenCreds       = new TokenCredentials(deviceIdentity, token, string.Empty, Option.None <string>(), Option.None <string>(), false);

            credentialsCache.Setup(cc => cc.Get(deviceIdentity)).ReturnsAsync(Option.Some <IClientCredentials>(tokenCreds));
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                GetMockDeviceClientProvider(),
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                credentialsCache.Object,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                scopeAuthenticationOnly: true,
                trackDeviceState: false);

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(deviceIdentity, null);

            // Assert
            Assert.Throws <InvalidOperationException>(() => cloudProxy.Value);
            deviceScopeIdentitiesCache.VerifyAll();
            credentialsCache.Verify(cc => cc.Get(It.IsAny <IIdentity>()), Times.Never);
        }
        public async Task ConnectUsingIdentityInCacheTest2()
        {
            // Arrange
            var    deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");
            string token          = TokenHelper.CreateSasToken(IotHubHostName, DateTime.UtcNow.AddMinutes(10));
            var    tokenCreds     = new TokenCredentials(deviceIdentity, token, string.Empty, false);

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict);

            deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(It.Is <string>(i => i == deviceIdentity.Id), false))
            .ReturnsAsync(Option.None <ServiceIdentity>());

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

            credentialsCache.Setup(c => c.Get(deviceIdentity)).ReturnsAsync(Option.Some((IClientCredentials)tokenCreds));
            var productInfoStore = Mock.Of <IProductInfoStore>();
            var modelIdStore     = Mock.Of <IModelIdStore>();
            var edgeHub          = Mock.Of <IEdgeHub>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                GetMockDeviceClientProvider(),
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                credentialsCache.Object,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                productInfoStore,
                modelIdStore);

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(deviceIdentity, null);

            // Assert
            Assert.True(cloudProxy.Success);
            Assert.NotNull(cloudProxy.Value);
            deviceScopeIdentitiesCache.VerifyAll();
            credentialsCache.VerifyAll();
        }
Esempio n. 17
0
        public async Task ConnectUsingIdentityInScope_DeviceInvalidStateException_WithRecover(bool isNested)
        {
            // Arrange
            var deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict);
            var deviceServiceIdentity      = new ServiceIdentity(deviceIdentity.Id, "1234", new string[0], new ServiceAuthentication(ServiceAuthenticationType.CertificateAuthority), ServiceIdentityStatus.Disabled);

            deviceScopeIdentitiesCache.Setup(d => d.VerifyServiceIdentityAuthChainState(It.Is <string>(i => i == deviceIdentity.Id), isNested, false))
            .ThrowsAsync(new DeviceInvalidStateException());
            deviceScopeIdentitiesCache.Setup(d => d.VerifyServiceIdentityAuthChainState(It.Is <string>(i => i == deviceIdentity.Id), isNested, true))
            .ReturnsAsync(deviceIdentity.Id);

            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var edgeHub = Mock.Of <IEdgeHub>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                GetMockDeviceClientProvider(),
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                CredentialsCache,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                scopeAuthenticationOnly: true,
                trackDeviceState: true,
                nestedEdgeEnabled: isNested);

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(deviceIdentity, null);

            // Assert
            Assert.True(cloudProxy.Success);
            Assert.NotNull(cloudProxy.Value);
            deviceScopeIdentitiesCache.VerifyAll();
        }
Esempio n. 18
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());
        }
        public void GetTransportSettingsTest(Option <UpstreamProtocol> upstreamProtocol, int connectionPoolSize, Option <IWebProxy> proxy, ITransportSettings[] expectedTransportSettingsList)
        {
            ITransportSettings[] transportSettingsList = CloudConnectionProvider.GetTransportSettings(upstreamProtocol, connectionPoolSize, proxy);

            Assert.NotNull(transportSettingsList);
            Assert.Equal(expectedTransportSettingsList.Length, transportSettingsList.Length);
            for (int i = 0; i < expectedTransportSettingsList.Length; i++)
            {
                ITransportSettings expectedTransportSettings = expectedTransportSettingsList[i];
                ITransportSettings transportSettings         = transportSettingsList[i];

                Assert.Equal(expectedTransportSettings.GetType(), transportSettings.GetType());
                Assert.Equal(expectedTransportSettings.GetTransportType(), transportSettings.GetTransportType());
                switch (expectedTransportSettings)
                {
                case AmqpTransportSettings _:
                {
                    var expected = (AmqpTransportSettings)expectedTransportSettings;
                    var actual   = (AmqpTransportSettings)transportSettings;
                    Assert.True(expected.Equals(actual));     // AmqpTransportSettings impls Equals, but doesn't override Object.Equals

                    if (proxy == Option.None <IWebProxy>())
                    {
                        Assert.Null(actual.Proxy);
                    }
                    else
                    {
                        Assert.True(actual.Proxy is WebProxy);
                        Assert.Equal(((WebProxy)expected.Proxy).Address, ((WebProxy)actual.Proxy).Address);
                    }

                    break;
                }

                case MqttTransportSettings _:
                {
                    var expected = (MqttTransportSettings)expectedTransportSettings;
                    var actual   = (MqttTransportSettings)transportSettings;
                    Assert.True(actual.Proxy is WebProxy);
                    Assert.Equal(((WebProxy)expected.Proxy).Address, ((WebProxy)actual.Proxy).Address);
                    break;
                }
                }
            }
        }
Esempio n. 20
0
        public async Task ConnectUsingTokenCredentialsTest()
        {
            // Arrange
            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var edgeHub = Mock.Of <IEdgeHub>();
            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict);

            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                MessageConverterProvider,
                ConnectionPoolSize,
                GetMockDeviceClientProvider(),
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                CredentialsCache,
                EdgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                true,
                true,
                true);

            cloudConnectionProvider.BindEdgeHub(edgeHub);

            var deviceIdentity = Mock.Of <IDeviceIdentity>(m => m.Id == "d1");

            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == deviceIdentity.Id)))
            .ReturnsAsync(Option.Some(deviceIdentity.Id));
            string token      = TokenHelper.CreateSasToken(IotHubHostName, DateTime.UtcNow.AddMinutes(10));
            var    tokenCreds = new TokenCredentials(deviceIdentity, token, string.Empty, Option.None <string>(), Option.None <string>(), false);

            // Act
            Try <ICloudConnection> cloudProxy = await cloudConnectionProvider.Connect(tokenCreds, null);

            // Assert
            Assert.True(cloudProxy.Success);
            Assert.NotNull(cloudProxy.Value);
        }
Esempio n. 21
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());
        }
Esempio n. 22
0
        public async Task CreateCloudProxyTest()
        {
            string edgeDeviceId = "edgeDevice";
            string module1Id    = "module1";

            var module1Credentials = new SharedKeyCredentials(new ModuleIdentity("iotHub", edgeDeviceId, module1Id), "connStr", DummyProductInfo);

            IClient client1 = GetDeviceClient();
            IClient client2 = GetDeviceClient();
            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(client1)
            .Returns(client2);

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

            Task <Try <ICloudProxy> > getCloudProxyTask1 = connectionManager.CreateCloudConnectionAsync(module1Credentials);
            Task <Try <ICloudProxy> > getCloudProxyTask2 = connectionManager.CreateCloudConnectionAsync(module1Credentials);

            Try <ICloudProxy>[] cloudProxies = await Task.WhenAll(getCloudProxyTask1, getCloudProxyTask2);

            Assert.NotEqual(cloudProxies[0].Value, cloudProxies[1].Value);

            Option <ICloudProxy> currentCloudProxyId1 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);
            ICloudProxy          currentCloudProxy    = currentCloudProxyId1.OrDefault();
            ICloudProxy          cloudProxy1          = cloudProxies[0].Value;
            ICloudProxy          cloudProxy2          = cloudProxies[1].Value;

            Assert.True(currentCloudProxy == cloudProxy1 || currentCloudProxy == cloudProxy2);
            if (currentCloudProxy == cloudProxy1)
            {
                Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Once);
                Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Never);
            }
            else
            {
                Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Once);
                Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Never);
            }
        }
        public void GetTransportSettingsTest(Option <UpstreamProtocol> upstreamProtocol, int connectionPoolSize, ITransportSettings[] expectedTransportSettingsList)
        {
            ITransportSettings[] transportSettingsList = CloudConnectionProvider.GetTransportSettings(upstreamProtocol, connectionPoolSize);

            Assert.NotNull(transportSettingsList);
            Assert.Equal(expectedTransportSettingsList.Length, transportSettingsList.Length);
            for (int i = 0; i < expectedTransportSettingsList.Length; i++)
            {
                ITransportSettings expectedTransportSettings = expectedTransportSettingsList[i];
                ITransportSettings transportSettings         = transportSettingsList[i];

                Assert.Equal(expectedTransportSettings.GetType(), transportSettings.GetType());
                Assert.Equal(expectedTransportSettings.GetTransportType(), transportSettings.GetTransportType());
                if (expectedTransportSettings is AmqpTransportSettings)
                {
                    Assert.True(((AmqpTransportSettings)expectedTransportSettings).Equals((AmqpTransportSettings)transportSettings));
                }
            }
        }
Esempio n. 24
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);
        }
        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
                }
            }
        }
Esempio n. 26
0
        public async Task CloudConnectionTest()
        {
            // ReSharper disable once PossibleUnintendedReferenceComparison
            var deviceCredentials1 = Mock.Of <ITokenCredentials>(c => c.Identity == Mock.Of <IIdentity>(d => d.Id == "Device1"));
            // ReSharper disable once PossibleUnintendedReferenceComparison
            var deviceCredentials2 = Mock.Of <ITokenCredentials>(c => c.Identity == Mock.Of <IIdentity>(d => d.Id == "Device2"));

            string  edgeDeviceId             = "edgeDevice";
            IClient client1                  = GetDeviceClient();
            IClient client2                  = GetDeviceClient();
            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(client1)
            .Returns(client2);

            var productInfoStore = Mock.Of <IProductInfoStore>();
            ICredentialsCache credentialsCache = new CredentialsCache(new NullCredentialsCache());

            var cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                Mock.Of <ITokenProvider>(),
                Mock.Of <IDeviceScopeIdentitiesCache>(),
                credentialsCache,
                new ModuleIdentity(IotHubHostName, edgeDeviceId, "$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());

            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, GetIdentityProvider());

            Option <ICloudProxy> returnedValue = await connectionManager.GetCloudConnection(deviceCredentials1.Identity.Id);

            Assert.False(returnedValue.HasValue);

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

            Assert.True(cloudProxy1.Success);
            Assert.True(cloudProxy1.Value.IsActive);

            returnedValue = await connectionManager.GetCloudConnection(deviceCredentials1.Identity.Id);

            Assert.True(returnedValue.HasValue);
            Assert.Equal(((RetryingCloudProxy)cloudProxy1.Value).InnerCloudProxy, ((RetryingCloudProxy)returnedValue.OrDefault()).InnerCloudProxy);

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

            Assert.True(cloudProxy2.Success);
            Assert.True(cloudProxy2.Value.IsActive);

            await connectionManager.RemoveDeviceConnection(deviceCredentials2.Identity.Id);

            returnedValue = await connectionManager.GetCloudConnection(deviceCredentials2.Identity.Id);

            Assert.True(returnedValue.HasValue);
        }
Esempio n. 27
0
        protected override void Load(ContainerBuilder builder)
        {
            // IMessageConverter<IRoutingMessage>
            builder.Register(c => new RoutingMessageConverter())
            .As <Core.IMessageConverter <IRoutingMessage> >()
            .SingleInstance();

            // IRoutingPerfCounter
            builder.Register(
                c =>
            {
                Routing.PerfCounter = NullRoutingPerfCounter.Instance;
                return(Routing.PerfCounter);
            })
            .As <IRoutingPerfCounter>()
            .AutoActivate()
            .SingleInstance();

            // IRoutingUserAnalyticsLogger
            builder.Register(
                c =>
            {
                Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance;
                return(Routing.UserAnalyticsLogger);
            })
            .As <IRoutingUserAnalyticsLogger>()
            .AutoActivate()
            .SingleInstance();

            // IRoutingUserMetricLogger
            builder.Register(
                c =>
            {
                Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance;
                return(Routing.UserMetricLogger);
            })
            .As <IRoutingUserMetricLogger>()
            .AutoActivate()
            .SingleInstance();

            // IMessageConverter<Message>
            builder.Register(c => new DeviceClientMessageConverter())
            .As <Core.IMessageConverter <Message> >()
            .SingleInstance();

            // IMessageConverter<Twin>
            builder.Register(c => new TwinMessageConverter())
            .As <Core.IMessageConverter <Twin> >()
            .SingleInstance();

            // IMessageConverter<TwinCollection>
            builder.Register(c => new TwinCollectionMessageConverter())
            .As <Core.IMessageConverter <TwinCollection> >()
            .SingleInstance();

            // IMessageConverterProvider
            builder.Register(
                c => new MessageConverterProvider(
                    new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Message), c.Resolve <Core.IMessageConverter <Message> >() },
                { typeof(Twin), c.Resolve <Core.IMessageConverter <Twin> >() },
                { typeof(TwinCollection), c.Resolve <Core.IMessageConverter <TwinCollection> >() }
            }))
            .As <IMessageConverterProvider>()
            .SingleInstance();

            // IDeviceConnectivityManager
            builder.Register(
                c =>
            {
                var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                IDeviceConnectivityManager deviceConnectivityManager = this.experimentalFeatures.DisableConnectivityCheck
                            ? new NullDeviceConnectivityManager()
                            : new DeviceConnectivityManager(this.connectivityCheckFrequency, TimeSpan.FromMinutes(2), edgeHubCredentials.Identity) as IDeviceConnectivityManager;
                return(deviceConnectivityManager);
            })
            .As <IDeviceConnectivityManager>()
            .SingleInstance();

            // IDeviceClientProvider
            builder.Register(
                c =>
            {
                IClientProvider underlyingClientProvider        = new ClientProvider();
                IClientProvider connectivityAwareClientProvider = new ConnectivityAwareClientProvider(underlyingClientProvider, c.Resolve <IDeviceConnectivityManager>());
                return(connectivityAwareClientProvider);
            })
            .As <IClientProvider>()
            .SingleInstance();

            // Task<ICloudConnectionProvider>
            builder.Register(
                async c =>
            {
                var productInfoStore               = await c.Resolve <Task <IProductInfoStore> >();
                var messageConverterProvider       = c.Resolve <IMessageConverterProvider>();
                var clientProvider                 = c.Resolve <IClientProvider>();
                var tokenProvider                  = c.ResolveNamed <ITokenProvider>("EdgeHubClientAuthTokenProvider");
                var credentialsCacheTask           = c.Resolve <Task <ICredentialsCache> >();
                var edgeHubCredentials             = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                var deviceScopeIdentitiesCacheTask = c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                var proxy = c.Resolve <Option <IWebProxy> >();
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask;
                ICredentialsCache credentialsCache = await credentialsCacheTask;
                ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                    messageConverterProvider,
                    this.connectionPoolSize,
                    clientProvider,
                    this.upstreamProtocol,
                    tokenProvider,
                    deviceScopeIdentitiesCache,
                    credentialsCache,
                    edgeHubCredentials.Identity,
                    this.cloudConnectionIdleTimeout,
                    this.closeCloudConnectionOnIdleTimeout,
                    this.operationTimeout,
                    this.useServerHeartbeat,
                    proxy,
                    productInfoStore);
                return(cloudConnectionProvider);
            })
            .As <Task <ICloudConnectionProvider> >()
            .SingleInstance();

            // IIdentityProvider
            builder.Register(_ => new IdentityProvider(this.iotHubName))
            .As <IIdentityProvider>()
            .SingleInstance();

            // Task<IConnectionManager>
            builder.Register(
                async c =>
            {
                var cloudConnectionProviderTask = c.Resolve <Task <ICloudConnectionProvider> >();
                var credentialsCacheTask        = c.Resolve <Task <ICredentialsCache> >();
                var identityProvider            = c.Resolve <IIdentityProvider>();
                var deviceConnectivityManager   = c.Resolve <IDeviceConnectivityManager>();
                ICloudConnectionProvider cloudConnectionProvider = await cloudConnectionProviderTask;
                ICredentialsCache credentialsCache   = await credentialsCacheTask;
                IConnectionManager connectionManager = new ConnectionManager(
                    cloudConnectionProvider,
                    credentialsCache,
                    identityProvider,
                    deviceConnectivityManager,
                    this.maxConnectedClients,
                    this.closeCloudConnectionOnDeviceDisconnect);
                return(connectionManager);
            })
            .As <Task <IConnectionManager> >()
            .SingleInstance();

            // Task<IEndpointFactory>
            builder.Register(
                async c =>
            {
                var messageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >();
                IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                return(new EndpointFactory(connectionManager, messageConverter, this.edgeDeviceId, this.maxUpstreamBatchSize, this.upstreamFanOutFactor) as IEndpointFactory);
            })
            .As <Task <IEndpointFactory> >()
            .SingleInstance();

            // Task<RouteFactory>
            builder.Register(async c => new EdgeRouteFactory(await c.Resolve <Task <IEndpointFactory> >()) as RouteFactory)
            .As <Task <RouteFactory> >()
            .SingleInstance();

            // RouterConfig
            builder.Register(c => new RouterConfig(Enumerable.Empty <Route>()))
            .As <RouterConfig>()
            .SingleInstance();

            if (!this.isStoreAndForwardEnabled)
            {
                // EndpointExecutorConfig
                builder.Register(
                    c =>
                {
                    RetryStrategy defaultRetryStrategy = new FixedInterval(0, TimeSpan.FromSeconds(1));
                    TimeSpan defaultRevivePeriod       = TimeSpan.FromHours(1);
                    TimeSpan defaultTimeout            = TimeSpan.FromSeconds(60);
                    return(new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true));
                })
                .As <EndpointExecutorConfig>()
                .SingleInstance();

                // IEndpointExecutorFactory
                builder.Register(c => new SyncEndpointExecutorFactory(c.Resolve <EndpointExecutorConfig>()))
                .As <IEndpointExecutorFactory>()
                .SingleInstance();

                // Task<Router>
                builder.Register(
                    async c =>
                {
                    var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>();
                    var routerConfig            = c.Resolve <RouterConfig>();
                    Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory);
                    return(router);
                })
                .As <Task <Router> >()
                .SingleInstance();

                // Task<ITwinManager>
                builder.Register(
                    async c =>
                {
                    if (!this.useV1TwinManager)
                    {
                        var messageConverterProvider         = c.Resolve <IMessageConverterProvider>();
                        IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                        ITwinManager twinManager             = new PassThroughTwinManager(connectionManager, messageConverterProvider);
                        return(twinManager);
                    }
                    else
                    {
                        var messageConverterProvider         = c.Resolve <IMessageConverterProvider>();
                        IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                        return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>()));
                    }
                })
                .As <Task <ITwinManager> >()
                .SingleInstance();
            }
            else
            {
                // EndpointExecutorConfig
                builder.Register(
                    c =>
                {
                    // Endpoint executor config values -
                    // ExponentialBackoff - minBackoff = 1s, maxBackoff = 60s, delta (used to add randomness to backoff) - 1s (default)
                    // Num of retries = int.MaxValue(we want to keep retrying till the message is sent)
                    // Revive period - period for which the endpoint should be considered dead if it doesn't respond - 1 min (we want to try continuously till the message expires)
                    // Timeout - time for which we want for the ack from the endpoint = 30s
                    // TODO - Should the number of retries be tied to the Store and Forward ttl? Not
                    // doing that right now as that value can be changed at runtime, but these settings
                    // cannot. Need to make the number of retries dynamically configurable for that.
                    TimeSpan minWait            = TimeSpan.FromSeconds(1);
                    TimeSpan maxWait            = TimeSpan.FromSeconds(60);
                    TimeSpan delta              = TimeSpan.FromSeconds(1);
                    int retries                 = int.MaxValue;
                    RetryStrategy retryStrategy = new ExponentialBackoff(retries, minWait, maxWait, delta);
                    TimeSpan timeout            = TimeSpan.FromSeconds(30);
                    TimeSpan revivePeriod       = TimeSpan.FromSeconds(30);
                    return(new EndpointExecutorConfig(timeout, retryStrategy, revivePeriod));
                })
                .As <EndpointExecutorConfig>()
                .SingleInstance();

                // Task<ICheckpointStore>
                builder.Register(
                    async c =>
                {
                    var dbStoreProvider              = await c.Resolve <Task <IDbStoreProvider> >();
                    IStoreProvider storeProvider     = new StoreProvider(dbStoreProvider);
                    ICheckpointStore checkpointStore = CheckpointStore.Create(storeProvider);
                    return(checkpointStore);
                })
                .As <Task <ICheckpointStore> >()
                .SingleInstance();

                // Task<IMessageStore>
                builder.Register(
                    async c =>
                {
                    var checkpointStore          = await c.Resolve <Task <ICheckpointStore> >();
                    var dbStoreProvider          = await c.Resolve <Task <IDbStoreProvider> >();
                    IStoreProvider storeProvider = new StoreProvider(dbStoreProvider);
                    IMessageStore messageStore   = new MessageStore(storeProvider, checkpointStore, this.storeAndForwardConfiguration.TimeToLive, this.checkEntireQueueOnCleanup);
                    return(messageStore);
                })
                .As <Task <IMessageStore> >()
                .SingleInstance();

                // Task<IEndpointExecutorFactory>
                builder.Register(
                    async c =>
                {
                    var endpointExecutorConfig = c.Resolve <EndpointExecutorConfig>();
                    var messageStore           = await c.Resolve <Task <IMessageStore> >();
                    IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(10, TimeSpan.FromSeconds(10)), messageStore);
                    return(endpointExecutorFactory);
                })
                .As <Task <IEndpointExecutorFactory> >()
                .SingleInstance();

                // Task<Router>
                builder.Register(
                    async c =>
                {
                    var checkpointStore         = await c.Resolve <Task <ICheckpointStore> >();
                    var routerConfig            = c.Resolve <RouterConfig>();
                    var endpointExecutorFactory = await c.Resolve <Task <IEndpointExecutorFactory> >();
                    return(await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory, checkpointStore));
                })
                .As <Task <Router> >()
                .SingleInstance();

                // Task<ITwinManager>
                builder.Register(
                    async c =>
                {
                    if (this.useV1TwinManager)
                    {
                        var dbStoreProvider                  = await c.Resolve <Task <IDbStoreProvider> >();
                        var messageConverterProvider         = c.Resolve <IMessageConverterProvider>();
                        IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                        return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.Some <IStoreProvider>(new StoreProvider(dbStoreProvider))));
                    }
                    else
                    {
                        var messageConverterProvider  = c.Resolve <IMessageConverterProvider>();
                        var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>();
                        var connectionManagerTask     = c.Resolve <Task <IConnectionManager> >();
                        IEntityStore <string, TwinStoreEntity> entityStore = await this.GetTwinStore(c);
                        IConnectionManager connectionManager = await connectionManagerTask;
                        ITwinManager twinManager             = StoringTwinManager.Create(
                            connectionManager,
                            messageConverterProvider,
                            entityStore,
                            deviceConnectivityManager,
                            new ReportedPropertiesValidator(),
                            this.minTwinSyncPeriod,
                            this.reportedPropertiesSyncFrequency);
                        return(twinManager);
                    }
                })
                .As <Task <ITwinManager> >()
                .SingleInstance();
            }

            // IClientCredentials "EdgeHubCredentials"
            builder.Register(
                c =>
            {
                var identityFactory = c.Resolve <IClientCredentialsFactory>();
                IClientCredentials edgeHubCredentials = this.connectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse(
                    () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeModuleId));
                return(edgeHubCredentials);
            })
            .Named <IClientCredentials>("EdgeHubCredentials")
            .SingleInstance();

            // Task<IInvokeMethodHandler>
            builder.Register(
                async c =>
            {
                IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                return(new InvokeMethodHandler(connectionManager) as IInvokeMethodHandler);
            })
            .As <Task <IInvokeMethodHandler> >()
            .SingleInstance();

            // Task<ISubscriptionProcessor>
            builder.Register(
                async c =>
            {
                var connectionManagerTask = c.Resolve <Task <IConnectionManager> >();
                if (this.experimentalFeatures.DisableCloudSubscriptions)
                {
                    return(new LocalSubscriptionProcessor(await connectionManagerTask) as ISubscriptionProcessor);
                }
                else
                {
                    var invokeMethodHandlerTask              = c.Resolve <Task <IInvokeMethodHandler> >();
                    var deviceConnectivityManager            = c.Resolve <IDeviceConnectivityManager>();
                    IConnectionManager connectionManager     = await connectionManagerTask;
                    IInvokeMethodHandler invokeMethodHandler = await invokeMethodHandlerTask;
                    return(new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager) as ISubscriptionProcessor);
                }
            })
            .As <Task <ISubscriptionProcessor> >()
            .SingleInstance();

            // Task<IEdgeHub>
            builder.Register(
                async c =>
            {
                var routingMessageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >();
                var routerTask                = c.Resolve <Task <Router> >();
                var twinManagerTask           = c.Resolve <Task <ITwinManager> >();
                var invokeMethodHandlerTask   = c.Resolve <Task <IInvokeMethodHandler> >();
                var connectionManagerTask     = c.Resolve <Task <IConnectionManager> >();
                var subscriptionProcessorTask = c.Resolve <Task <ISubscriptionProcessor> >();
                Router router                                = await routerTask;
                ITwinManager twinManager                     = await twinManagerTask;
                IConnectionManager connectionManager         = await connectionManagerTask;
                IInvokeMethodHandler invokeMethodHandler     = await invokeMethodHandlerTask;
                ISubscriptionProcessor subscriptionProcessor = await subscriptionProcessorTask;
                IEdgeHub hub = new RoutingEdgeHub(
                    router,
                    routingMessageConverter,
                    connectionManager,
                    twinManager,
                    this.edgeDeviceId,
                    invokeMethodHandler,
                    subscriptionProcessor);
                return(hub);
            })
            .As <Task <IEdgeHub> >()
            .SingleInstance();

            // Task<ConfigUpdater>
            builder.Register(
                async c =>
            {
                IMessageStore messageStore = this.isStoreAndForwardEnabled ? await c.Resolve <Task <IMessageStore> >() : null;
                var storageSpaceChecker    = c.Resolve <IStorageSpaceChecker>();
                var edgeHubCredentials     = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                RouteFactory routeFactory  = await c.Resolve <Task <RouteFactory> >();
                Router router            = await c.Resolve <Task <Router> >();
                var twinManagerTask      = c.Resolve <Task <ITwinManager> >();
                var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >();
                var twinManager          = await twinManagerTask;
                var configUpdater        = new ConfigUpdater(router, messageStore, this.configUpdateFrequency, storageSpaceChecker);
                return(configUpdater);
            })
            .As <Task <ConfigUpdater> >()
            .SingleInstance();

            // Task<IConfigSource>
            builder.Register <Task <IConfigSource> >(
                async c =>
            {
                RouteFactory routeFactory = await c.Resolve <Task <RouteFactory> >();
                if (this.useTwinConfig)
                {
                    var edgeHubCredentials             = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                    var twinCollectionMessageConverter = c.Resolve <Core.IMessageConverter <TwinCollection> >();
                    var twinMessageConverter           = c.Resolve <Core.IMessageConverter <Twin> >();
                    var twinManagerTask                  = c.Resolve <Task <ITwinManager> >();
                    var edgeHubTask                      = c.Resolve <Task <IEdgeHub> >();
                    ITwinManager twinManager             = await twinManagerTask;
                    IEdgeHub edgeHub                     = await edgeHubTask;
                    IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                    IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();

                    var edgeHubConnection = await EdgeHubConnection.Create(
                        edgeHubCredentials.Identity,
                        edgeHub,
                        twinManager,
                        connectionManager,
                        routeFactory,
                        twinCollectionMessageConverter,
                        this.versionInfo,
                        deviceScopeIdentitiesCache);

                    return(new TwinConfigSource(edgeHubConnection, edgeHubCredentials.Identity.Id, this.versionInfo, twinManager, twinMessageConverter, twinCollectionMessageConverter, routeFactory));
                }
                else
                {
                    return(new LocalConfigSource(routeFactory, this.routes, this.storeAndForwardConfiguration));
                }
            })
            .As <Task <IConfigSource> >()
            .SingleInstance();

            // Task<IConnectionProvider>
            builder.Register(
                async c =>
            {
                var connectionManagerTask              = c.Resolve <Task <IConnectionManager> >();
                var edgeHubTask                        = c.Resolve <Task <IEdgeHub> >();
                IConnectionManager connectionManager   = await connectionManagerTask;
                IEdgeHub edgeHub                       = await edgeHubTask;
                IConnectionProvider connectionProvider = new ConnectionProvider(connectionManager, edgeHub, this.messageAckTimeout);
                return(connectionProvider);
            })
            .As <Task <IConnectionProvider> >()
            .SingleInstance();

            base.Load(builder);
        }
Esempio n. 28
0
        public async Task TestGetTwin()
        {
            // Arrange
            const string Id                             = "id1";
            var          identity                       = Mock.Of <IIdentity>(i => i.Id == Id);
            var          twinMessageConverter           = new TwinMessageConverter();
            var          twinCollectionMessageConverter = new TwinCollectionMessageConverter();
            var          messageConverterProvider       = new MessageConverterProvider(
                new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Message), new DeviceClientMessageConverter() },
                { typeof(Shared.Twin), twinMessageConverter },
                { typeof(TwinCollection), twinCollectionMessageConverter }
            });

            var edgeHubTokenProvider = new Mock <ITokenProvider>();

            var clientWatcher = new ClientWatcher();

            var clientProvider = new Mock <IClientProvider>();

            clientProvider.Setup(c => c.Create(identity, edgeHubTokenProvider.Object, It.IsAny <ITransportSettings[]>(), Option.None <string>()))
            .Returns(() => new ThrowingClient(clientWatcher, 3));

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>();

            deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(Id))
            .ReturnsAsync(
                Option.Some(
                    new ServiceIdentity(
                        Id,
                        "dummy",
                        new List <string>(),
                        new ServiceAuthentication(new SymmetricKeyAuthentication("foo", "bar")),
                        ServiceIdentityStatus.Enabled)));
            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == Id)))
            .ReturnsAsync(Option.Some(Id));

            var edgeHubIdentity = Mock.Of <IIdentity>();

            ConnectionMetadata connectionMetadata = new ConnectionMetadata("edgeProdInfo");
            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(p => p.GetMetadata(Id))
            .ReturnsAsync(connectionMetadata);

            var identityProvider = new Mock <IIdentityProvider>();

            identityProvider.Setup(i => i.Create(Id)).Returns(identity);

            var credentialsCache = new Mock <ICredentialsCache>();
            var edgeHub          = new Mock <IEdgeHub>();

            var connectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                clientProvider.Object,
                Option.None <UpstreamProtocol>(),
                edgeHubTokenProvider.Object,
                deviceScopeIdentitiesCache.Object,
                credentialsCache.Object,
                edgeHubIdentity,
                TimeSpan.FromMinutes(10),
                false,
                TimeSpan.FromMinutes(10),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                true);

            connectionProvider.BindEdgeHub(edgeHub.Object);

            var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>();
            var connectionManager         = new ConnectionManager(connectionProvider, credentialsCache.Object, identityProvider.Object, deviceConnectivityManager);

            // Act
            Option <ICloudProxy> cloudProxyOption = await connectionManager.GetCloudConnection(Id);

            // Assert
            Assert.True(cloudProxyOption.HasValue);
            ICloudProxy cloudProxy = cloudProxyOption.OrDefault();

            Assert.True(cloudProxy.IsActive);

            // Act
            await RunGetTwin(cloudProxy, 10);

            // Assert
            Assert.Equal(5, clientWatcher.OpenAsyncCount);
            Assert.True(cloudProxy.IsActive);
            Assert.Equal(10, clientWatcher.GetTwinCount);
        }
Esempio n. 29
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 TokenCredentials(new DeviceIdentity("iotHub", deviceId), "token", "abc", false);

            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 <ITokenProvider>(), It.IsAny <ITransportSettings[]>()))
            .Returns(client);

            var productInfoStore        = Mock.Of <IProductInfoStore>();
            var credentialsManager      = 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>(),
                credentialsManager,
                edgeHubIdentity,
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                Option.None <IWebProxy>(),
                productInfoStore);

            cloudConnectionProvider.BindEdgeHub(edgeHub.Object);
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsManager, GetIdentityProvider());
            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);

            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);
        }
Esempio n. 30
0
        public async Task TestSendMessages()
        {
            // Arrange
            const string Id                             = "id1";
            var          identity                       = Mock.Of <IIdentity>(i => i.Id == Id);
            var          twinMessageConverter           = new TwinMessageConverter();
            var          twinCollectionMessageConverter = new TwinCollectionMessageConverter();
            var          messageConverterProvider       = new MessageConverterProvider(
                new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Message), new DeviceClientMessageConverter() },
                { typeof(Shared.Twin), twinMessageConverter },
                { typeof(TwinCollection), twinCollectionMessageConverter }
            });

            var edgeHubTokenProvider = new Mock <ITokenProvider>();

            var clientWatcher = new ClientWatcher();

            var clientProvider = new Mock <IClientProvider>();

            clientProvider.Setup(c => c.Create(identity, edgeHubTokenProvider.Object, It.IsAny <ITransportSettings[]>(), Option.None <string>()))
            .Returns(() => new ThrowingClient(clientWatcher, 3));

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>();

            deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(Id))
            .ReturnsAsync(
                Option.Some(
                    new ServiceIdentity(
                        Id,
                        "dummy",
                        new List <string>(),
                        new ServiceAuthentication(new SymmetricKeyAuthentication("foo", "bar")),
                        ServiceIdentityStatus.Enabled)));
            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == Id)))
            .ReturnsAsync(Option.Some(Id));

            var edgeHubIdentity = Mock.Of <IIdentity>();

            ConnectionMetadata connectionMetadata = new ConnectionMetadata("edgeProdInfo");
            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(p => p.GetMetadata(Id))
            .ReturnsAsync(connectionMetadata);

            var identityProvider = new Mock <IIdentityProvider>();

            identityProvider.Setup(i => i.Create(Id)).Returns(identity);

            var credentialsCache = new Mock <ICredentialsCache>();
            var edgeHub          = new Mock <IEdgeHub>();

            var connectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                clientProvider.Object,
                Option.None <UpstreamProtocol>(),
                edgeHubTokenProvider.Object,
                deviceScopeIdentitiesCache.Object,
                credentialsCache.Object,
                edgeHubIdentity,
                TimeSpan.FromMinutes(10),
                false,
                TimeSpan.FromMinutes(10),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                scopeAuthenticationOnly: true,
                trackDeviceState: true,
                true);

            connectionProvider.BindEdgeHub(edgeHub.Object);

            var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>();
            var connectionManager         = new ConnectionManager(connectionProvider, credentialsCache.Object, identityProvider.Object, deviceConnectivityManager);
            var messagesToSend            = new List <IMessage>();

            for (int i = 0; i < 10; i++)
            {
                var message = new EdgeMessage.Builder(new byte[i])
                              .SetSystemProperties(
                    new Dictionary <string, string>()
                {
                    [SystemProperties.MessageId] = i.ToString()
                })
                              .Build();
                messagesToSend.Add(message);
            }

            // Act
            Option <ICloudProxy> cloudProxyOption = await connectionManager.GetCloudConnection(Id);

            // Assert
            Assert.True(cloudProxyOption.HasValue);
            ICloudProxy cloudProxy = cloudProxyOption.OrDefault();

            Assert.True(cloudProxy.IsActive);

            // Act
            await RunSendMessages(cloudProxy, messagesToSend);

            // Assert
            Assert.Equal(messagesToSend.Count, clientWatcher.ReceivedMessages.Count());
            Assert.Equal(5, clientWatcher.OpenAsyncCount);
            Assert.True(cloudProxy.IsActive);

            IEnumerable <string> expectedMessageIds = messagesToSend.Select(m => m.SystemProperties[SystemProperties.MessageId]);
            IEnumerable <string> receivedMessageIds = clientWatcher.ReceivedMessages.Select(m => m.MessageId);

            Assert.Equal(expectedMessageIds, receivedMessageIds);
        }