Exemplo n.º 1
0
        public static TwinConfigSource GetTwinConfigSource(Option <X509Certificate2> manifestTrustBundle)
        {
            var            connectionManager = new ConnectionManager(Mock.Of <ICloudConnectionProvider>(), Mock.Of <ICredentialsCache>(), Mock.Of <IIdentityProvider>(), Mock.Of <IDeviceConnectivityManager>());
            var            endpointFactory   = new EndpointFactory(connectionManager, new RoutingMessageConverter(), "testHubEdgeDevice1", 10, 10, false);
            var            routeFactory      = new EdgeRouteFactory(endpointFactory);
            var            configParser      = new EdgeHubConfigParser(routeFactory, new BrokerPropertiesValidator());
            var            twinCollectionMessageConverter = new TwinCollectionMessageConverter();
            var            twinMessageConverter           = new TwinMessageConverter();
            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 versionInfo = new VersionInfo(string.Empty, string.Empty, string.Empty);

            // Create Edge Hub connection
            EdgeHubConnection edgeHubConnection = GetEdgeHubConnection().Result;

            // TwinConfig Source
            return(new TwinConfigSource(
                       edgeHubConnection,
                       string.Empty,
                       versionInfo,
                       twinManager,
                       twinMessageConverter,
                       twinCollectionMessageConverter,
                       configParser,
                       manifestTrustBundle));
        }
Exemplo n.º 2
0
        public async Task RoundtripTokenCredentialsWithEncryptionTest()
        {
            // Arrange
            string iothubHostName    = "iothub1.azure.net";
            string callerProductInfo = "productInfo";
            string sasToken          = TokenHelper.CreateSasToken($"{iothubHostName}/devices/device1/modules/moduleId");
            var    identity          = Mock.Of <IIdentity>(i => i.Id == "d1");
            var    credentials       = new TokenCredentials(identity, sasToken, callerProductInfo, false);

            var            dbStoreProvider       = new InMemoryDbStoreProvider();
            IStoreProvider storeProvider         = new StoreProvider(dbStoreProvider);
            var            encryptedStore        = new EncryptedStore <string, string>(storeProvider.GetEntityStore <string, string>("tokenCredentials"), new TestEncryptionProvider());
            var            tokenCredentialsStore = new PersistedTokenCredentialsCache(encryptedStore);

            // Act
            await tokenCredentialsStore.Add(credentials);

            Option <IClientCredentials> storedCredentials = await tokenCredentialsStore.Get(identity);

            // Assert
            Assert.True(storedCredentials.HasValue);
            var storedTokenCredentials = storedCredentials.OrDefault() as ITokenCredentials;

            Assert.NotNull(storedTokenCredentials);
            Assert.Equal(sasToken, storedTokenCredentials.Token);
            Assert.Equal(credentials.IsUpdatable, storedTokenCredentials.IsUpdatable);
        }
Exemplo n.º 3
0
        static IEntityStore <string, TwinStoreEntity> GetTwinEntityStore()
        {
            var dbStoreProvider     = new InMemoryDbStoreProvider();
            var entityStoreProvider = new StoreProvider(dbStoreProvider);
            IEntityStore <string, TwinStoreEntity> entityStore = entityStoreProvider.GetEntityStore <string, TwinStoreEntity>($"twin{Guid.NewGuid()}");

            return(entityStore);
        }
        static IEntityStore <string, TwinStoreEntity> GetReportedPropertiesEntityStore()
        {
            var dbStoreProvider     = new InMemoryDbStoreProvider();
            var entityStoreProvider = new StoreProvider(dbStoreProvider);
            IEntityStore <string, TwinStoreEntity> entityStore = entityStoreProvider.GetEntityStore <string, TwinStoreEntity>($"rp{Guid.NewGuid()}");

            return(entityStore);
        }
Exemplo n.º 5
0
        async Task <(IMessageStore, ICheckpointStore)> GetMessageStore(int ttlSecs = 300)
        {
            var              dbStoreProvider = new InMemoryDbStoreProvider();
            IStoreProvider   storeProvider   = new StoreProvider(dbStoreProvider);
            ICheckpointStore checkpointStore = CheckpointStore.Create(storeProvider);
            IMessageStore    messageStore    = new MessageStore(storeProvider, checkpointStore, TimeSpan.FromSeconds(ttlSecs));
            await messageStore.AddEndpoint("module1");

            await messageStore.AddEndpoint("module2");

            return(messageStore, checkpointStore);
        }
Exemplo n.º 6
0
        async Task <(IMessageStore, ICheckpointStore, InMemoryDbStore)> GetMessageStore(bool checkEntireQueueOnCleanup, int ttlSecs = 300, int messageCleanupIntervalSecs = 30)
        {
            var              dbStoreProvider = new InMemoryDbStoreProvider();
            IStoreProvider   storeProvider   = new StoreProvider(dbStoreProvider);
            InMemoryDbStore  inMemoryDbStore = dbStoreProvider.GetDbStore("messages") as InMemoryDbStore;
            ICheckpointStore checkpointStore = CheckpointStore.Create(storeProvider);
            IMessageStore    messageStore    = new MessageStore(storeProvider, checkpointStore, TimeSpan.FromSeconds(ttlSecs), checkEntireQueueOnCleanup, messageCleanupIntervalSecs);
            await messageStore.AddEndpoint("module1");

            await messageStore.AddEndpoint("module2");

            return(messageStore, checkpointStore, inMemoryDbStore);
        }
Exemplo n.º 7
0
        static async Task <(IEdgeHub, IConnectionManager)> SetupEdgeHub(IEnumerable <string> routes, IoTHub iotHub, string edgeDeviceId)
        {
            string iotHubName = "testHub";

            Routing.UserMetricLogger    = NullRoutingUserMetricLogger.Instance;
            Routing.PerfCounter         = NullRoutingPerfCounter.Instance;
            Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance;

            RetryStrategy defaultRetryStrategy   = new FixedInterval(0, TimeSpan.FromSeconds(1));
            TimeSpan      defaultRevivePeriod    = TimeSpan.FromHours(1);
            TimeSpan      defaultTimeout         = TimeSpan.FromSeconds(60);
            var           endpointExecutorConfig = new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true);

            var cloudProxy = new Mock <ICloudProxy>();

            cloudProxy.Setup(c => c.SendMessageAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask);
            cloudProxy.Setup(c => c.SendMessageBatchAsync(It.IsAny <IEnumerable <IMessage> >())).Callback <IEnumerable <IMessage> >(m => iotHub.ReceivedMessages.AddRange(m)).Returns(Task.CompletedTask);
            cloudProxy.Setup(c => c.UpdateReportedPropertiesAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask);
            cloudProxy.SetupGet(c => c.IsActive).Returns(true);
            var cloudConnection = Mock.Of <ICloudConnection>(c => c.IsActive && c.CloudProxy == Option.Some(cloudProxy.Object));

            var cloudConnectionProvider = new Mock <ICloudConnectionProvider>();

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

            var deviceConnectivityManager                    = Mock.Of <IDeviceConnectivityManager>();
            IConnectionManager connectionManager             = new ConnectionManager(cloudConnectionProvider.Object, Mock.Of <ICredentialsCache>(), new IdentityProvider(iotHubName), deviceConnectivityManager);
            var                      routingMessageConverter = new RoutingMessageConverter();
            RouteFactory             routeFactory            = new EdgeRouteFactory(new EndpointFactory(connectionManager, routingMessageConverter, edgeDeviceId, 10, 10));
            IEnumerable <Route>      routesList              = routeFactory.Create(routes).ToList();
            IEnumerable <Endpoint>   endpoints               = routesList.Select(r => r.Endpoint);
            var                      routerConfig            = new RouterConfig(endpoints, routesList);
            IDbStoreProvider         dbStoreProvider         = new InMemoryDbStoreProvider();
            IStoreProvider           storeProvider           = new StoreProvider(dbStoreProvider);
            IMessageStore            messageStore            = new MessageStore(storeProvider, CheckpointStore.Create(storeProvider), TimeSpan.MaxValue);
            IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(1, TimeSpan.FromMilliseconds(10)), messageStore);
            Router                   router                  = await Router.CreateAsync(Guid.NewGuid().ToString(), iotHubName, routerConfig, endpointExecutorFactory);

            ITwinManager twinManager           = new TwinManager(connectionManager, new TwinCollectionMessageConverter(), new TwinMessageConverter(), Option.None <IEntityStore <string, TwinInfo> >());
            var          invokeMethodHandler   = Mock.Of <IInvokeMethodHandler>();
            var          subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager);
            IEdgeHub     edgeHub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, edgeDeviceId, invokeMethodHandler, subscriptionProcessor);

            return(edgeHub, connectionManager);
        }
Exemplo n.º 8
0
        public async Task RoundtripNonTokenCredentialsTest()
        {
            // Arrange
            string callerProductInfo = "productInfo";
            var    identity          = Mock.Of <IIdentity>(i => i.Id == "d1");
            var    credentials       = new X509CertCredentials(identity, callerProductInfo);

            var            dbStoreProvider       = new InMemoryDbStoreProvider();
            IStoreProvider storeProvider         = new StoreProvider(dbStoreProvider);
            var            tokenCredentialsStore = new TokenCredentialsStore(storeProvider.GetEntityStore <string, string>("tokenCredentials"), new NullEncryptionProvider());

            // Act
            await tokenCredentialsStore.Add(credentials);

            Option <IClientCredentials> storedCredentials = await tokenCredentialsStore.Get(identity);

            // Assert
            Assert.False(storedCredentials.HasValue);
        }
Exemplo n.º 9
0
        async Task <(IMessageStore, ICheckpointStore)> GetMessageStore(long initialCheckpointOffset, bool checkEntireQueueOnCleanup, int ttlSecs = 300)
        {
            var            dbStoreProvider = new InMemoryDbStoreProvider();
            IStoreProvider storeProvider   = new StoreProvider(dbStoreProvider);

            IEntityStore <string, CheckpointStore.CheckpointEntity> checkpointUnderlyingStore = storeProvider.GetEntityStore <string, CheckpointStore.CheckpointEntity>($"Checkpoint{Guid.NewGuid().ToString()}");

            if (initialCheckpointOffset >= 0)
            {
                await checkpointUnderlyingStore.Put("module1", new CheckpointStore.CheckpointEntity(initialCheckpointOffset, null, null));

                await checkpointUnderlyingStore.Put("module2", new CheckpointStore.CheckpointEntity(initialCheckpointOffset, null, null));
            }

            ICheckpointStore checkpointStore = new CheckpointStore(checkpointUnderlyingStore);
            IMessageStore    messageStore    = new MessageStore(storeProvider, checkpointStore, TimeSpan.FromSeconds(ttlSecs), checkEntireQueueOnCleanup, 1800);
            await messageStore.AddEndpoint("module1");

            await messageStore.AddEndpoint("module2");

            return(messageStore, checkpointStore);
        }
        public async Task RoundtripNonTokenCredentialsTest()
        {
            // Arrange
            string callerProductInfo = "productInfo";
            var    identity          = Mock.Of <IIdentity>(i => i.Id == "d1");
            var    clientCertificate = new X509Certificate2();
            var    clientCertChain   = new List <X509Certificate2>();
            var    credentials       = new X509CertCredentials(identity, callerProductInfo, Option.None <string>(), Option.None <string>(), clientCertificate, clientCertChain);

            var            dbStoreProvider       = new InMemoryDbStoreProvider();
            IStoreProvider storeProvider         = new StoreProvider(dbStoreProvider);
            var            encryptedStore        = new EncryptedStore <string, string>(storeProvider.GetEntityStore <string, string>("tokenCredentials"), new TestEncryptionProvider());
            var            tokenCredentialsStore = new PersistedTokenCredentialsCache(encryptedStore);

            // Act
            await tokenCredentialsStore.Add(credentials);

            Option <IClientCredentials> storedCredentials = await tokenCredentialsStore.Get(identity);

            // Assert
            Assert.False(storedCredentials.HasValue);
        }
Exemplo n.º 11
0
        public static async Task <EdgeHubConnection> GetEdgeHubConnection()
        {
            var            connectionManager = new ConnectionManager(Mock.Of <ICloudConnectionProvider>(), Mock.Of <ICredentialsCache>(), Mock.Of <IIdentityProvider>(), Mock.Of <IDeviceConnectivityManager>());
            var            endpointFactory   = new EndpointFactory(connectionManager, new RoutingMessageConverter(), "testHubEdgeDevice1", 10, 10, false);
            var            routeFactory      = new EdgeRouteFactory(endpointFactory);
            var            twinCollectionMessageConverter = new TwinCollectionMessageConverter();
            var            twinMessageConverter           = new TwinMessageConverter();
            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 versionInfo = new VersionInfo(string.Empty, string.Empty, string.Empty);

            return(await EdgeHubConnection.Create(
                       Mock.Of <IIdentity>(i => i.Id == "someid"),
                       Mock.Of <IEdgeHub>(),
                       twinManager,
                       Mock.Of <IConnectionManager>(),
                       routeFactory,
                       twinCollectionMessageConverter,
                       versionInfo,
                       new NullDeviceScopeIdentitiesCache()));
        }
        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
                }
            }
        }
Exemplo n.º 13
0
        public async Task MessageStoreAddRemoveEndpointTest(bool checkEntireQueueOnCleanup)
        {
            // Arrange
            var              dbStoreProvider = new InMemoryDbStoreProvider();
            IStoreProvider   storeProvider   = new StoreProvider(dbStoreProvider);
            ICheckpointStore checkpointStore = CheckpointStore.Create(storeProvider);
            IMessageStore    messageStore    = new MessageStore(storeProvider, checkpointStore, TimeSpan.FromHours(1), checkEntireQueueOnCleanup, 1800);

            // Act
            await messageStore.AddEndpoint("module1");

            for (int i = 0; i < 10; i++)
            {
                await messageStore.Add("module1", this.GetMessage(i), 0);
            }

            // Assert
            IMessageIterator module1Iterator = messageStore.GetMessageIterator("module1");

            Assert.NotNull(module1Iterator);

            IEnumerable <IMessage> batch = await module1Iterator.GetNext(1000);

            List <IMessage> batchItemsAsList = batch.ToList();

            Assert.Equal(10, batchItemsAsList.Count);

            for (int i = 0; i < 10; i++)
            {
                Assert.Equal($"{i}", batchItemsAsList.ElementAt(i).SystemProperties[SystemProperties.MessageId]);
            }

            // Remove
            await messageStore.RemoveEndpoint("module1");

            // Assert
            await Assert.ThrowsAsync <InvalidOperationException>(() => messageStore.Add("module1", this.GetMessage(0), 0));

            Assert.Throws <InvalidOperationException>(() => messageStore.GetMessageIterator("module1"));

            // Act
            await messageStore.AddEndpoint("module1");

            for (int i = 20; i < 30; i++)
            {
                await messageStore.Add("module1", this.GetMessage(i), 0);
            }

            // Assert
            module1Iterator = messageStore.GetMessageIterator("module1");
            Assert.NotNull(module1Iterator);

            batch = await module1Iterator.GetNext(1000);

            batchItemsAsList = batch.ToList();
            Assert.Equal(10, batchItemsAsList.Count);

            for (int i = 20; i < 30; i++)
            {
                Assert.Equal($"{i}", batchItemsAsList.ElementAt(i - 20).SystemProperties[SystemProperties.MessageId]);
            }
        }
Exemplo n.º 14
0
        public async Task SpaceCheckViolationsTest()
        {
            Option <long>        maxStorageBytes = Option.Some(90L);
            IStorageSpaceChecker checker         = new MemorySpaceChecker(() => 0L);

            checker.SetMaxSizeBytes(maxStorageBytes);
            InMemoryDbStoreProvider storeProvider = new InMemoryDbStoreProvider(Option.Some(checker));

            string   store1Name = "store1";
            IDbStore store1     = storeProvider.GetDbStore(store1Name);

            string   store2Name = "store2";
            IDbStore store2     = storeProvider.GetDbStore(store2Name);

            byte[] message1 = new byte[10];
            byte[] message2 = new byte[20];
            await store1.Put(message1, message1);

            await store2.Put(message2, message2);

            // Current sizes -
            // store1 -> (message1 * 2)
            // store2 -> (message2 * 2)
            // Aggregated size is less than limit, adding another item should succeed.
            byte[] message3 = new byte[30];
            await store1.Put(message3, message3, CancellationToken.None);

            // Current sizes -
            // store1 -> (message1 * 2) + (message3 * 2)
            // store2 -> (message2 * 2)
            // Aggregated size is greater than limit, adding another item should fail.
            byte[] message4 = new byte[40];
            await Assert.ThrowsAsync <StorageFullException>(() => store2.Put(message4, message4));

            await Assert.ThrowsAsync <StorageFullException>(() => store2.Put(message4, message4, CancellationToken.None));

            // Remove store2. The usage of store1 alone should be less than the max limit.
            // Current sizes -
            // store1 -> (message1 * 2) + (message3 * 2)
            // store2 -> X
            // Aggregated size is less than limit, adding another item should succeed.
            storeProvider.RemoveDbStore(store2Name);
            await store1.Put(message4, message4);

            // Current sizes -
            // store1 -> (message1 * 2) + (message3 * 2) + (message4 * 2)
            // store2 -> X
            // Aggregated size is greater than limit, adding another item should fail.
            byte[] message5 = new byte[45];
            await Assert.ThrowsAsync <StorageFullException>(() => store1.Put(message5, message5));

            // Re-add store2.
            store2 = storeProvider.GetDbStore(store2Name);

            await store1.Remove(message4);

            // Current sizes -
            // store1 -> (message1 * 2) + (message3 * 2)
            // store2 -> X
            // Aggregated size is less than limit, adding another item should succeed.
            await store2.Put(message1, message1);

            // Current sizes -
            // store1 -> (message1 * 2) + (message3 * 2)
            // store2 -> (message1 * 2)
            // Aggregated size is greater than limit, adding another item should fail.
            await Assert.ThrowsAsync <StorageFullException>(() => store2.Put(message5, message5));

            // Remove an item from store1 and then try adding a smaller item to store2 which should succeed.
            await store1.Remove(message3, CancellationToken.None);

            // Current sizes -
            // store1 -> (message1 * 2)
            // store2 -> (message1 * 2)
            // Aggregated size is less than limit, adding another item should succeed.
            await store2.Put(message3, message3, CancellationToken.None);

            // Current sizes -
            // store1 -> (message1 * 2)
            // store2 -> (message1 * 2) + (message3 * 2)
            // Aggregated size is greater than limit, adding another item should fail.
            await Assert.ThrowsAsync <StorageFullException>(() => store2.Put(message4, message4));

            // Set max storage size to be greater than the current db size.
            Option <long> newMaxStorageBytes = Option.Some((message1.Length * 2) * 2L + (message3.Length * 2) + 10);

            checker.SetMaxSizeBytes(newMaxStorageBytes);

            // Adding another item should now succeed after the limits have been increased.
            await store1.Put(message4, message4);

            // Adding a new item to store1 should fail.
            // Current sizes -
            // store1 -> (message1 * 2) + (message4 * 2)
            // store2 -> (message1 * 2) + (message3 * 2)
            // Aggregated size is greater than limit, adding another item should fail.
            await Assert.ThrowsAsync <StorageFullException>(() => store1.Put(message5, message5));

            // Updating the message4 item in store1 should succeed as the size difference between
            // the existing and updated value is zero bytes which doesn't lead to the limit being breached.
            await store1.Put(message4, message4);
        }
Exemplo n.º 15
0
        async Task <(IMessageConsumer, IMessageConsumer, NullBrokerConnector)> SetupEnvironment()
        {
            Routing.UserMetricLogger    = NullRoutingUserMetricLogger.Instance;
            Routing.PerfCounter         = NullRoutingPerfCounter.Instance;
            Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance;

            var defaultRetryStrategy   = new FixedInterval(5, TimeSpan.FromSeconds(5));
            var defaultRevivePeriod    = TimeSpan.FromHours(1);
            var defaultTimeout         = TimeSpan.FromSeconds(60);
            var endpointExecutorConfig = new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true);

            var cloudProxyDispatcher    = new BrokeredCloudProxyDispatcher();
            var cloudConnectionProvider = new BrokeredCloudConnectionProvider(cloudProxyDispatcher);

            var identityProvider          = new IdentityProvider(iotHubName);
            var deviceConnectivityManager = new BrokeredDeviceConnectivityManager(cloudProxyDispatcher);

            var connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of <ICredentialsCache>(), new IdentityProvider(iotHubName), deviceConnectivityManager);

            var routingMessageConverter = new RoutingMessageConverter();
            var routeFactory            = new EdgeRouteFactory(new EndpointFactory(connectionManager, routingMessageConverter, edgeDeviceId, 10, 10));
            var routesList   = new[] { routeFactory.Create("FROM /messages INTO $upstream") };
            var endpoints    = routesList.Select(r => r.Endpoint);
            var routerConfig = new RouterConfig(endpoints, routesList);

            var dbStoreProvider         = new InMemoryDbStoreProvider();
            var storeProvider           = new StoreProvider(dbStoreProvider);
            var messageStore            = new MessageStore(storeProvider, CheckpointStore.Create(storeProvider), TimeSpan.MaxValue, false, 1800);
            var endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(1, TimeSpan.FromMilliseconds(10)), messageStore);

            var router = await Router.CreateAsync(Guid.NewGuid().ToString(), iotHubName, routerConfig, endpointExecutorFactory);

            var messageConverterProvider = new MessageConverterProvider(
                new Dictionary <Type, IMessageConverter>()
            {
                { typeof(Twin), new TwinMessageConverter() },
                { typeof(TwinCollection), new TwinCollectionMessageConverter() }
            });

            var twinManager           = TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>());
            var invokeMethodHandler   = Mock.Of <IInvokeMethodHandler>();
            var subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager);

            var edgeHub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, edgeDeviceId, edgeModuleName, invokeMethodHandler, subscriptionProcessor, Mock.Of <IDeviceScopeIdentitiesCache>());

            var brokerConnector = new NullBrokerConnector(cloudProxyDispatcher);

            cloudProxyDispatcher.SetConnector(brokerConnector);
            cloudProxyDispatcher.BindEdgeHub(edgeHub);

            var connectionProvider = new ConnectionProvider(connectionManager, edgeHub, TimeSpan.FromSeconds(30));
            var authenticator      = new NullAuthenticator();

            var edgeHubIdentity         = new ModuleIdentity(iotHubName, edgeDeviceId, edgeModuleName);
            var tokenCredentials        = new TokenCredentials(edgeHubIdentity, "qwerty", "test-product", Option.Some("test-model"), Option.None <string>(), false);
            var systemComponentProvider = new SystemComponentIdProvider(tokenCredentials);

            var connectionHandler = default(ConnectionHandler);

            connectionHandler = new ConnectionHandler(
                Task.FromResult <IConnectionProvider>(connectionProvider),
                Task.FromResult <IAuthenticator>(authenticator),
                identityProvider,
                systemComponentProvider,
                DeviceProxyFactory);

            DeviceProxy DeviceProxyFactory(IIdentity identity, bool isDirectClient)
            {
                return(new DeviceProxy(identity, isDirectClient, connectionHandler, Mock.Of <ITwinHandler>(), Mock.Of <IModuleToModuleMessageHandler>(), Mock.Of <ICloud2DeviceMessageHandler>(), Mock.Of <IDirectMethodHandler>()));
            }

            var cloud2DeviceMessageHandler   = new Cloud2DeviceMessageHandler(connectionHandler);
            var moduleToModuleMessageHandler = new ModuleToModuleMessageHandler(connectionHandler, identityProvider, new ModuleToModuleResponseTimeout(TimeSpan.FromSeconds(10)));
            var directMethodHandler          = new DirectMethodHandler(connectionHandler, identityProvider);
            var twinHandler = new TwinHandler(connectionHandler, identityProvider);

            var subscriptionChangeHandler = new SubscriptionChangeHandler(
                cloud2DeviceMessageHandler,
                moduleToModuleMessageHandler,
                directMethodHandler,
                twinHandler,
                connectionHandler,
                identityProvider);

            return(subscriptionChangeHandler, cloudProxyDispatcher, brokerConnector);
        }