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);
        }
Example #2
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());
        }
        public async Task CloudConnectionUpdateTest()
        {
            ITokenProvider receivedTokenProvider    = null;
            var            messageConverterProvider = Mock.Of <IMessageConverterProvider>();
            var            deviceClientProvider     = new Mock <IClientProvider>();

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

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

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

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

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

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

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

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

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

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

            Assert.True(receivedCloudProxy2.Success);
            Assert.NotNull(receivedCloudProxy2.Value);
            Assert.True(receivedCloudProxy2.Value.IsActive);
            Assert.False(receivedCloudProxy1.Value.IsActive);
            Assert.NotNull(receivedTokenProvider);
            Assert.Equal(token2, receivedTokenProvider.GetTokenAsync(Option.None <TimeSpan>()).Result);
            Assert.Equal(deviceProxy, connectionManager.GetDeviceConnection(deviceCredentials.Identity.Id).OrDefault());
        }
        public async Task 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();
        }
        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 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);
        }
Example #8
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);
        }
        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());
        }
Example #10
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());
        }
Example #11
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();
        }
Example #12
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 ConnectTest()
        {
            var edgeHub = Mock.Of <IEdgeHub>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(MessageConverterProvider, ConnectionPoolSize, new ClientProvider(), Option.None <UpstreamProtocol>(), TokenProvider, DeviceScopeIdentitiesCache, TimeSpan.FromMinutes(60));

            cloudConnectionProvider.BindEdgeHub(edgeHub);
            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);
        }
        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();
        }
Example #15
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();
        }
Example #16
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());
        }
Example #17
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);
        }
Example #18
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());
        }
        public async Task GetMultipleCloudProxiesTest()
        {
            // Arrange
            string  edgeDeviceId             = "edgeDevice";
            string  module1Id                = "module1";
            string  token                    = TokenHelper.CreateSasToken(IotHubHostName);
            var     module1Credentials       = new TokenCredentials(new ModuleIdentity(IotHubHostName, 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 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));

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

            // Act
            Task <Option <ICloudProxy> > getCloudProxyTask1 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);
            Task <Option <ICloudProxy> > getCloudProxyTask2 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);
            Task <Option <ICloudProxy> > getCloudProxyTask3 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);
            Task <Option <ICloudProxy> > getCloudProxyTask4 = connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

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

            // Assert
            Assert.True(cloudProxies[0].HasValue);
            Assert.True(cloudProxies[1].HasValue);
            Assert.True(cloudProxies[2].HasValue);
            Assert.True(cloudProxies[3].HasValue);
            Assert.Equal(cloudProxies[0].OrDefault(), cloudProxies[1].OrDefault());
            Assert.Equal(cloudProxies[0].OrDefault(), cloudProxies[2].OrDefault());
            Assert.Equal(cloudProxies[0].OrDefault(), cloudProxies[3].OrDefault());

            // Act
            await cloudProxies[0].OrDefault().CloseAsync();
            Option <ICloudProxy> newCloudProxyTask1 = await connectionManager.GetCloudConnection(module1Credentials.Identity.Id);

            // Assert
            Assert.True(newCloudProxyTask1.HasValue);
            Assert.NotEqual(newCloudProxyTask1.OrDefault(), cloudProxies[0].OrDefault());
            Mock.Get(client1).Verify(cp => cp.CloseAsync(), Times.Once);
            Mock.Get(client2).Verify(cp => cp.CloseAsync(), Times.Never);
        }
Example #20
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
                }
            }
        }
        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);
        }
Example #23
0
        public async Task TestAddRemoveDeviceConnectionTest()
        {
            string deviceId = "id1";

            var deviceProxyMock1 = new Mock <IDeviceProxy>();

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

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

            var edgeHub = new Mock <IEdgeHub>();

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

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

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

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

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

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

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

            await connectionManager.AddDeviceConnection(deviceCredentials);

            deviceListener.BindDeviceProxy(deviceProxyMock1.Object);

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

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

            cloudProxy = await connectionManager.GetCloudConnection(deviceId);

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

            await deviceListener.CloseAsync();

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

            cloudProxy = await connectionManager.GetCloudConnection(deviceId);

            Assert.True(cloudProxy.HasValue);
            Assert.True(client.IsActive);
        }
        public async Task UpdateDeviceConnectionTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = null;
            string hostname = "dummy.azure-devices.net";
            string deviceId = "device1";

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

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

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

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

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

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

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

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

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

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

            var metadataStore = new Mock <IMetadataStore>();

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

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>();

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

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

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

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

            Assert.True(cloudProxyTry1.Success);

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

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

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

            Assert.False(tokenGetter.IsCompleted);

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

            Assert.True(cloudProxyTry2.Success);

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

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

            Assert.False(tokenGetter.IsCompleted);

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

            Assert.True(cloudProxyTry3.Success);

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

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

            Assert.True(tokenGetter.IsCompleted);
            Assert.Equal(tokenGetter.Result, clientCredentials3.Token);
        }
        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);
        }
        public async Task TestMultipleOperations()
        {
            // 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[]>()))
            .Returns(() => new ThrowingClient(clientWatcher, 15));

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>();

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

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

            var productInfoStore = new Mock <IProductInfoStore>();

            productInfoStore.Setup(p => p.GetEdgeProductInfo(Id))
            .ReturnsAsync("ProdInfo1");

            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),
                Option.None <IWebProxy>(),
                productInfoStore.Object);

            connectionProvider.BindEdgeHub(edgeHub.Object);

            var connectionManager = new ConnectionManager(connectionProvider, credentialsCache.Object, identityProvider.Object);

            async Task <ICloudProxy> GetCloudProxy(IConnectionManager cm)
            {
                // Act
                Option <ICloudProxy> cloudProxyOption = await cm.GetCloudConnection(Id);

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

                Assert.True(cloudProxy.IsActive);
                return(cloudProxy);
            }

            var messagesToSend = new List <IMessage>();

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

            // Act
            ICloudProxy cloudProxy1 = await GetCloudProxy(connectionManager);

            ICloudProxy cloudProxy2 = await GetCloudProxy(connectionManager);

            ICloudProxy cloudProxy3 = await GetCloudProxy(connectionManager);

            // Act
            var tasks = new[]
            {
                RunGetTwin(cloudProxy1, 10),
                RunGetTwin(cloudProxy2, 30),
                RunGetTwin(cloudProxy3, 10),
                RunSendMessages(cloudProxy1, messagesToSend.Take(20), 2),
                RunSendMessages(cloudProxy2, messagesToSend.Skip(20).Take(10)),
                RunSendMessages(cloudProxy3, messagesToSend.Skip(30).Take(30), 3)
            };
            await Task.WhenAll(tasks);

            // Assert
            Assert.Equal(50, clientWatcher.GetTwinCount);
            List <string> expectedMessageIds = messagesToSend
                                               .Select(m => m.SystemProperties[SystemProperties.MessageId])
                                               .OrderBy(s => s)
                                               .ToList();
            List <string> receivedMessageIds = clientWatcher.ReceivedMessages
                                               .Select(m => m.MessageId)
                                               .OrderBy(s => s)
                                               .ToList();

            Assert.Equal(expectedMessageIds.Count, receivedMessageIds.Count);
            Assert.Equal(expectedMessageIds, receivedMessageIds);
        }
        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);
        }
Example #28
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);
        }