public void ProcessDiscoveryWithNoResultsAndNoExistingApplications()
        {
            var found = new List <DiscoveryEventModel>();
            var fix   = new Fixture();

            var device      = fix.Create <string>();
            var module      = fix.Create <string>();
            var super       = SupervisorModelEx.CreateSupervisorId(device, module);
            var deviceModel = new DeviceModel {
                Id       = device,
                ModuleId = module
            };
            var twinModel = SupervisorRegistration.Patch(null,
                                                         SupervisorRegistration.FromServiceModel(new SupervisorModel {
                Id = super
            }));

            var registry = new IoTHubServices((twinModel, deviceModel).YieldReturn());

            using (var mock = AutoMock.GetLoose()) {
                // Setup
                mock.Provide <IIoTHubTwinServices>(registry);
                var service = mock.Create <RegistryServices>();

                // Run
                service.ProcessDiscoveryAsync(super, new DiscoveryResultModel(), found, false).Wait();

                // Assert
                Assert.Empty(registry.Devices);
            }
        }
        public void ProcessDiscoveryWithNoResultsAndNoExistingApplications()
        {
            var found = new List <DiscoveryEventModel>();
            var fix   = new Fixture();

            var device      = fix.Create <string>();
            var module      = fix.Create <string>();
            var super       = SupervisorModelEx.CreateSupervisorId(device, module);
            var deviceModel = new DeviceModel {
                Id       = device,
                ModuleId = module
            };
            var twinModel = new SupervisorModel {
                Id = super
            }.ToSupervisorRegistration().ToDeviceTwin();

            var registry = IoTHubServices.Create((twinModel, deviceModel).YieldReturn());

            using (var mock = AutoMock.GetLoose()) {
                // Setup
                mock.Provide <IIoTHubTwinServices>(registry);
                mock.Provide <ISupervisorRegistry, SupervisorRegistry>();
                mock.Provide <IApplicationBulkProcessor, ApplicationRegistry>();
                mock.Provide <IEndpointBulkProcessor, EndpointRegistry>();
                var service = mock.Create <DiscoveryProcessor>();

                // Run
                service.ProcessDiscoveryResultsAsync(super, new DiscoveryResultModel(), found).Wait();

                // Assert
                Assert.Empty(registry.Devices);
            }
        }
        public void ProcessDiscoveryWithNoResultsWithDifferentSupervisorsFromExisting()
        {
            var fix    = new Fixture();
            var super2 = SupervisorModelEx.CreateSupervisorId(fix.Create <string>(), fix.Create <string>());

            // Readjust existing to be reported from different supervisor...
            CreateFixtures(out var site, out var super, out var existing,
                           out var found, out var registry, -1, x => {
                x.Application.SupervisorId = super2;
                x.Endpoints.ForEach(e => e.SupervisorId = super2);
                return(x);
            });

            // Found nothing
            found = new List <DiscoveryEventModel>();
            // Assert there is still the same content as originally

            using (var mock = AutoMock.GetLoose()) {
                // Setup
                mock.Provide <IIoTHubTwinServices>(registry);
                var service = mock.Create <RegistryServices>();

                // Run
                service.ProcessDiscoveryAsync(super, new DiscoveryResultModel(), found, false).Wait();

                // Assert

                Assert.True(ApplicationsIn(registry).IsSameAs(existing));
            }
        }
        public void ProcessDiscoveryWithDifferentSupervisorsSameSiteApplications()
        {
            var fix    = new Fixture();
            var super2 = SupervisorModelEx.CreateSupervisorId(fix.Create <string>(), fix.Create <string>());

            // Readjust existing to be reported from different supervisor...
            CreateFixtures(out var site, out var super, out var existing,
                           out var found, out var registry, -1, x => {
                x.Application.SupervisorId = super2;
                x.Endpoints.ForEach(e => e.SupervisorId = super2);
                return(x);
            });

            // Assert no changes

            using (var mock = AutoMock.GetLoose()) {
                // Setup
                var service = Setup(mock, registry);

                // Run
                service.ProcessDiscoveryResultsAsync(super, new DiscoveryResultModel(), found).Wait();

                // Assert
                Assert.True(ApplicationsIn(registry).IsSameAs(existing));
            }
        }
        public void ProcessDiscoveryWithDifferentSupervisorsFromExistingWhenExistingDisabled()
        {
            var fix    = new Fixture();
            var super2 = SupervisorModelEx.CreateSupervisorId(fix.Create <string>(), fix.Create <string>());

            // Readjust existing to be reported from different supervisor...
            CreateFixtures(out var site, out var super, out var existing,
                           out var found, out var registry, -1, x => {
                x.Application.SupervisorId = super2;
                x.Endpoints.ForEach(e => e.SupervisorId = super2);
                return(x);
            }, true);

            // Assert disabled items are now enabled
            var count = registry.Devices.Count();

            using (var mock = AutoMock.GetLoose()) {
                // Setup
                mock.Provide <IIoTHubTwinServices>(registry);
                var service = mock.Create <RegistryServices>();

                // Run
                service.ProcessDiscoveryAsync(super, new DiscoveryResultModel(), found, false).Wait();

                // Assert
                var inreg = ApplicationsIn(registry);
                Assert.False(inreg.IsSameAs(existing));
                Assert.Equal(count, registry.Devices.Count());
                Assert.All(inreg, a => Assert.Equal(super, a.Application.SupervisorId));
                Assert.All(inreg, a => Assert.Null(a.Application.NotSeenSince));
                Assert.All(inreg, a => Assert.All(a.Endpoints, e => Assert.Equal(super, e.SupervisorId)));
            }
        }
        /// <inheritdoc/>
        public async Task HandleDeviceTwinEventAsync(DeviceTwinEvent ev)
        {
            if (ev.Handled)
            {
                return;
            }
            if (string.IsNullOrEmpty(ev.Twin.Id) || string.IsNullOrEmpty(ev.Twin.ModuleId))
            {
                return;
            }
            var type = ev.Twin.Properties?.Reported.GetValueOrDefault <string>(
                TwinProperty.Type, null);

            if ((ev.Event != DeviceTwinEventType.Delete && ev.IsPatch) || string.IsNullOrEmpty(type))
            {
                try {
                    ev.Twin = await _iothub.GetAsync(ev.Twin.Id, ev.Twin.ModuleId);

                    ev.IsPatch = false;
                    type       = ev.Twin.Properties?.Reported?.GetValueOrDefault <string>(
                        TwinProperty.Type, null);
                }
                catch (Exception ex) {
                    _logger.Verbose(ex, "Failed to materialize twin");
                }
            }
            if (IdentityType.Supervisor.EqualsIgnoreCase(type))
            {
                var ctx = new RegistryOperationContextModel {
                    AuthorityId = ev.AuthorityId,
                    Time        = ev.Timestamp
                };
                switch (ev.Event)
                {
                case DeviceTwinEventType.New:
                    break;

                case DeviceTwinEventType.Create:
                    await _broker.NotifyAllAsync(l => l.OnSupervisorNewAsync(ctx,
                                                                             ev.Twin.ToSupervisorRegistration(false).ToServiceModel()));

                    break;

                case DeviceTwinEventType.Update:
                    await _broker.NotifyAllAsync(l => l.OnSupervisorUpdatedAsync(ctx,
                                                                                 ev.Twin.ToSupervisorRegistration(false).ToServiceModel()));

                    break;

                case DeviceTwinEventType.Delete:
                    await _broker.NotifyAllAsync(l => l.OnSupervisorDeletedAsync(ctx,
                                                                                 SupervisorModelEx.CreateSupervisorId(
                                                                                     ev.Twin.Id, ev.Twin.ModuleId)));

                    break;
                }
                ev.Handled = true;
            }
        }
 /// <summary>
 /// Create listener
 /// </summary>
 /// <param name="logger"></param>
 /// <param name="events"></param>
 /// <param name="processor"></param>
 public DiscoveryMessagePublisher(ILogger logger, IEventEmitter events,
                                  ITaskProcessor processor) : base(logger)
 {
     _events       = events ?? throw new ArgumentNullException(nameof(events));
     _processor    = processor ?? throw new ArgumentNullException(nameof(processor));
     _supervisorId = SupervisorModelEx.CreateSupervisorId(_events.DeviceId,
                                                          _events.ModuleId);
 }
 private HistoryReadValuesTests <EndpointRegistrationModel> GetTests()
 {
     return(new HistoryReadValuesTests <EndpointRegistrationModel>(
                () => _module.HubContainer.Resolve <IHistorianServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer"
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(
             _module.DeviceId, _module.ModuleId)
     }));
 }
 private ReadArrayValueTests <EndpointRegistrationModel> GetTests(
     string deviceId, string moduleId, IContainer services)
 {
     return(new ReadArrayValueTests <EndpointRegistrationModel>(
                () => services.Resolve <INodeServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer"
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(deviceId, moduleId)
     }, (ep, n) => _server.Client.ReadValueAsync(ep.Endpoint, n)));
 }
Ejemplo n.º 10
0
 private CallArrayMethodTests <EndpointRegistrationModel> GetTests(
     string deviceId, string moduleId, IContainer services)
 {
     return(new CallArrayMethodTests <EndpointRegistrationModel>(
                () => services.Resolve <INodeServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer"
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(deviceId, moduleId)
     }));
 }
Ejemplo n.º 11
0
 private WriteScalarValueTests <EndpointRegistrationModel> GetTests()
 {
     return(new WriteScalarValueTests <EndpointRegistrationModel>(
                () => _module.HubContainer.Resolve <INodeServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer"
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(
             _module.DeviceId, _module.ModuleId)
     }, (ep, n) => _server.Client.ReadValueAsync(ep.Endpoint, n)));
 }
 private HistoryReadValuesTests <EndpointRegistrationModel> GetTests(
     string deviceId, string moduleId, IContainer services)
 {
     return(new HistoryReadValuesTests <EndpointRegistrationModel>(
                () => services.Resolve <IHistorianServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer",
             Certificate = _server.Certificate?.RawData
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(deviceId, moduleId)
     }));
 }
Ejemplo n.º 13
0
 private CallScalarMethodTests <EndpointRegistrationModel> GetTests()
 {
     return(new CallScalarMethodTests <EndpointRegistrationModel>(
                () => _module.HubContainer.Resolve <INodeServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer",
             Certificate = _server.Certificate?.RawData
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(
             _module.DeviceId, _module.ModuleId)
     }));
 }
        private CallArrayMethodTests <string> GetTests()
        {
            var endpoint = new EndpointRegistrationModel {
                Endpoint = new EndpointModel {
                    Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer"
                },
                Id           = "testid",
                SupervisorId = SupervisorModelEx.CreateSupervisorId(
                    _module.DeviceId, _module.ModuleId)
            };

            endpoint = _module.RegisterAndActivateTwinId(endpoint);
            return(new CallArrayMethodTests <string>(
                       () => _module.HubContainer.Resolve <INodeServices <string> >(), endpoint.Id));
        }
        private ReadScalarValueTests <string> GetTests()
        {
            var endpoint = new EndpointRegistrationModel {
                Endpoint = new EndpointModel {
                    Url = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer"
                },
                Id           = "testid",
                SupervisorId = SupervisorModelEx.CreateSupervisorId(
                    _module.DeviceId, _module.ModuleId)
            };

            endpoint = _module.RegisterAndActivateTwinId(endpoint);
            return(new ReadScalarValueTests <string>(
                       () => _module.HubContainer.Resolve <INodeServices <string> >(),
                       endpoint.Id, (ep, n) => _server.Client.ReadValueAsync(endpoint.Endpoint, n)));
        }
Ejemplo n.º 16
0
        private BrowseServicesTests <string> GetTests()
        {
            var endpoint = new EndpointRegistrationModel {
                Endpoint = new EndpointModel {
                    Url         = $"opc.tcp://{Dns.GetHostName()}:{_server.Port}/UA/SampleServer",
                    Certificate = _server.Certificate?.RawData?.ToThumbprint()
                },
                Id           = "testid",
                SupervisorId = SupervisorModelEx.CreateSupervisorId(
                    _module.DeviceId, _module.ModuleId)
            };

            endpoint = _module.RegisterAndActivateTwinId(endpoint);
            return(new BrowseServicesTests <string>(
                       () => _module.HubContainer.Resolve <IBrowseServices <string> >(), endpoint.Id));
        }
Ejemplo n.º 17
0
        public async Task TestGetSupervisor()
        {
            using (var harness = new TwinModuleFixture()) {
                await harness.RunTestAsync(async (device, module, services) => {
                    // Setup
                    var registry = services.Resolve <ISupervisorRegistry>();

                    // Act
                    var supervisor = await registry.GetSupervisorAsync(SupervisorModelEx.CreateSupervisorId(device, module));

                    // Assert
                    Assert.True(supervisor.Connected.Value);
                    Assert.True(supervisor.OutOfSync.Value);
                });
            }
        }
Ejemplo n.º 18
0
 private CallArrayMethodTests <EndpointRegistrationModel> GetTests(
     string deviceId, string moduleId, IContainer services)
 {
     return(new CallArrayMethodTests <EndpointRegistrationModel>(
                () => services.Resolve <INodeServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{_hostEntry?.HostName ?? "localhost"}:{_server.Port}/UA/SampleServer",
             AlternativeUrls = _hostEntry?.AddressList
                               .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork)
                               .Select(ip => $"opc.tcp://{ip}:{_server.Port}/UA/SampleServer").ToHashSet(),
             Certificate = _server.Certificate?.RawData?.ToThumbprint()
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(deviceId, moduleId)
     }));
 }
 private WriteScalarValueTests <EndpointRegistrationModel> GetTests()
 {
     return(new WriteScalarValueTests <EndpointRegistrationModel>(
                () => _module.HubContainer.Resolve <INodeServices <EndpointRegistrationModel> >(),
                new EndpointRegistrationModel {
         Endpoint = new EndpointModel {
             Url = $"opc.tcp://{_hostEntry?.HostName ?? "localhost"}:{_server.Port}/UA/SampleServer",
             AlternativeUrls = _hostEntry?.AddressList
                               .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork)
                               .Select(ip => $"opc.tcp://{ip}:{_server.Port}/UA/SampleServer").ToHashSet(),
             Certificate = _server.Certificate?.RawData?.ToThumbprint()
         },
         Id = "testid",
         SupervisorId = SupervisorModelEx.CreateSupervisorId(
             _module.DeviceId, _module.ModuleId)
     }, (ep, n) => _server.Client.ReadValueAsync(ep.Endpoint, n)));
 }
Ejemplo n.º 20
0
        public async Task TestActivateDeactivate20Endpoints5TimesMultiThreaded()
        {
            using (var harness = new TwinModuleFixture()) {
                await harness.RunTestAsync(async (device, module, services) => {
                    // Setup
                    var supervisorId = SupervisorModelEx.CreateSupervisorId(device, module);
                    var activation   = services.Resolve <IActivationServices <EndpointRegistrationModel> >();
                    var hub          = services.Resolve <IIoTHubTwinServices>();

                    for (var i = 0; i < 20; i++)
                    {
                        var twin = new EndpointInfoModel {
                            Registration = new EndpointRegistrationModel {
                                Endpoint = new EndpointModel {
                                    Url = "opc.tcp://test"
                                },
                                SupervisorId = supervisorId
                            },
                            ApplicationId = "uas" + i
                        }.ToEndpointRegistration().ToDeviceTwin();
                        await hub.CreateAsync(twin);
                    }

                    var registry  = services.Resolve <IEndpointRegistry>();
                    var endpoints = await registry.ListAllEndpointsAsync();

                    for (var i = 0; i < 5; i++)
                    {
                        await Task.WhenAll(endpoints.Select(ep => registry.ActivateEndpointAsync(ep.Registration.Id)));
                        await Task.WhenAll(endpoints.Select(ep => registry.DeactivateEndpointAsync(ep.Registration.Id)));
                    }

                    var diagnostics = services.Resolve <ISupervisorDiagnostics>();
                    endpoints       = await registry.ListAllEndpointsAsync();
                    var status      = await diagnostics.GetSupervisorStatusAsync(supervisorId);

                    // Assert
                    Assert.Equal(device, status.DeviceId);
                    Assert.Equal(module, status.ModuleId);
                    Assert.Null(status.SiteId);
                    Assert.Empty(status.Endpoints);
                    Assert.True(endpoints.All(ep => ep.ActivationState == EndpointActivationState.Deactivated));
                    Assert.True(endpoints.All(ep => ep.EndpointState == null));
                });
            }
        }
Ejemplo n.º 21
0
        public async Task TestActivateDeactivateEndpoint20Times()
        {
            using (var harness = new TwinModuleFixture()) {
                await harness.RunTestAsync(async (device, module, services) => {
                    // Setup
                    var supervisorId = SupervisorModelEx.CreateSupervisorId(device, module);
                    var activation   = services.Resolve <IActivationServices <EndpointRegistrationModel> >();
                    var hub          = services.Resolve <IIoTHubTwinServices>();
                    var twin         = new EndpointInfoModel {
                        Registration = new EndpointRegistrationModel {
                            Endpoint = new EndpointModel {
                                Url = "opc.tcp://test"
                            },
                            SupervisorId = supervisorId
                        },
                        ApplicationId = "ua326029342304923"
                    }.ToEndpointRegistration().ToDeviceTwin();

                    await hub.CreateAsync(twin);
                    var registry  = services.Resolve <IEndpointRegistry>();
                    var endpoints = await registry.ListAllEndpointsAsync();
                    var ep1       = endpoints.FirstOrDefault();
                    Assert.NotNull(ep1);

                    for (var i = 0; i < 20; i++)
                    {
                        // Act
                        await registry.ActivateEndpointAsync(ep1.Registration.Id);
                        await registry.DeactivateEndpointAsync(ep1.Registration.Id);
                    }

                    var diagnostics = services.Resolve <ISupervisorDiagnostics>();
                    endpoints       = await registry.ListAllEndpointsAsync();
                    var ep3         = endpoints.FirstOrDefault();
                    var status      = await diagnostics.GetSupervisorStatusAsync(supervisorId);

                    // Assert
                    Assert.Equal(device, status.DeviceId);
                    Assert.Equal(module, status.ModuleId);
                    Assert.Null(status.SiteId);
                    Assert.Empty(status.Endpoints);
                    Assert.Equal(EndpointActivationState.Deactivated, ep3.ActivationState);
                    Assert.Null(ep3.EndpointState);
                });
            }
        }
Ejemplo n.º 22
0
        public async Task TestGetSupervisorStatus()
        {
            using (var harness = new TwinModuleFixture()) {
                await harness.RunTestAsync(async (device, module, services) => {
                    // Setup
                    var diagnostics = services.Resolve <ISupervisorDiagnostics>();

                    // Act
                    var status = await diagnostics.GetSupervisorStatusAsync(SupervisorModelEx.CreateSupervisorId(device, module));

                    // Assert
                    Assert.Equal(status.DeviceId, device);
                    Assert.Equal(status.ModuleId, module);
                    Assert.Null(status.SiteId);
                    Assert.Empty(status.Endpoints);
                });
            }
        }
Ejemplo n.º 23
0
        public async Task TestActivateEndpoint()
        {
            using (var harness = new TwinModuleFixture()) {
                await harness.RunTestAsync(async (device, module, services) => {
                    // Setup
                    var supervisorId = SupervisorModelEx.CreateSupervisorId(device, module);
                    var activation   = services.Resolve <IEndpointActivation>();
                    var hub          = services.Resolve <IIoTHubTwinServices>();
                    var twin         = new EndpointInfoModel {
                        Registration = new EndpointRegistrationModel {
                            Endpoint = new EndpointModel {
                                Url = "opc.tcp://test"
                            },
                            SupervisorId = supervisorId
                        },
                        ApplicationId = "ua326029342304923"
                    }.ToEndpointRegistration(_serializer).ToDeviceTwin(_serializer);
                    await hub.CreateOrUpdateAsync(twin);
                    var registry  = services.Resolve <IEndpointRegistry>();
                    var endpoints = await registry.ListAllEndpointsAsync();
                    var ep1       = endpoints.FirstOrDefault();
                    Assert.NotNull(ep1);

                    // Act
                    await activation.ActivateEndpointAsync(ep1.Registration.Id);
                    endpoints       = await registry.ListAllEndpointsAsync();
                    var ep2         = endpoints.FirstOrDefault();
                    var diagnostics = services.Resolve <ISupervisorDiagnostics>();
                    var status      = await diagnostics.GetSupervisorStatusAsync(supervisorId);

                    // Assert
                    Assert.Equal(device, status.DeviceId);
                    Assert.Equal(module, status.ModuleId);
                    Assert.Null(status.SiteId);
                    Assert.Single(status.Endpoints);
                    Assert.Equal(ep1.Registration.Id, status.Endpoints.Single().Id);
                    Assert.Equal(EndpointActivationState.ActivatedAndConnected, status.Endpoints.Single().ActivationState);
                    Assert.Equal(EndpointActivationState.ActivatedAndConnected, ep2.ActivationState);
                    Assert.True(
                        ep2.EndpointState == EndpointConnectivityState.Connecting ||
                        ep2.EndpointState == EndpointConnectivityState.NotReachable);
                });
            }
        }
Ejemplo n.º 24
0
        private CallScalarMethodTests <string> GetTests()
        {
            var endpoint = new EndpointRegistrationModel {
                Endpoint = new EndpointModel {
                    Url             = $"opc.tcp://{_hostEntry?.HostName ?? "localhost"}:{_server.Port}/UA/SampleServer",
                    AlternativeUrls = _hostEntry?.AddressList
                                      .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork)
                                      .Select(ip => $"opc.tcp://{ip}:{_server.Port}/UA/SampleServer").ToHashSet(),
                    Certificate = _server.Certificate?.RawData?.ToThumbprint()
                },
                Id           = "testid",
                SupervisorId = SupervisorModelEx.CreateSupervisorId(
                    _module.DeviceId, _module.ModuleId)
            };

            endpoint = _module.RegisterAndActivateTwinId(endpoint);
            return(new CallScalarMethodTests <string>(
                       () => _module.HubContainer.Resolve <INodeServices <string> >(), endpoint.Id));
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Discover servers using opcua discovery and filter by optional locale
        /// </summary>
        /// <param name="request"></param>
        /// <param name="discoveryUrls"></param>
        /// <param name="locales"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        private async Task <List <ApplicationRegistrationModel> > DiscoverServersAsync(
            DiscoveryRequest request, Dictionary <IPEndPoint, Uri> discoveryUrls,
            List <string> locales, CancellationToken ct)
        {
            var discovered   = new List <ApplicationRegistrationModel>();
            var supervisorId = SupervisorModelEx.CreateSupervisorId(_events.DeviceId,
                                                                    _events.ModuleId);

            _listener.OnServerDiscoveryStarted(request.Request, discoveryUrls);

            foreach (var item in discoveryUrls)
            {
                ct.ThrowIfCancellationRequested();
                var url = item.Value;

                _listener.OnFindEndpointsStarted(request.Request, url, item.Key.Address);

                // Find endpoints at the real accessible ip address
                var eps = await _client.FindEndpointsAsync(new UriBuilder(url) {
                    Host = item.Key.Address.ToString()
                }.Uri, locales, ct).ConfigureAwait(false);

                var endpoints = eps.Count();
                _listener.OnFindEndpointsFinished(request.Request, url, item.Key.Address,
                                                  endpoints);
                if (endpoints == 0)
                {
                    continue;
                }

                // Merge results...
                foreach (var ep in eps)
                {
                    discovered.AddOrUpdate(ep.ToServiceModel(item.Key.ToString(),
                                                             _events.SiteId, supervisorId));
                }
            }

            _listener.OnServerDiscoveryFinished(request.Request, discovered.Count);
            ct.ThrowIfCancellationRequested();
            return(discovered);
        }
        public void ProcessOneDiscoveryWithDifferentSupervisorsFromExistingWhenExistingDisabled()
        {
            var fix    = new Fixture();
            var super2 = SupervisorModelEx.CreateSupervisorId(fix.Create <string>(), fix.Create <string>());

            // Readjust existing to be reported from different supervisor...
            CreateFixtures(out var site, out var super, out var existing,
                           out var found, out var registry, -1, x => {
                x.Application.SupervisorId = super2;
                x.Endpoints.ForEach(e => e.SupervisorId = super2);
                return(x);
            }, true);

            // Found one app and endpoint
            found = new List <DiscoveryEventModel> {
                found.First()
            };
            var count = registry.Devices.Count();

            // Assert disabled items are now enabled

            using (var mock = AutoMock.GetLoose()) {
                // Setup
                var service = Setup(mock, registry);

                // Run
                service.ProcessDiscoveryResultsAsync(super, new DiscoveryResultModel(), found).Wait();

                // Assert
                var inreg = ApplicationsIn(registry);
                Assert.Equal(count, registry.Devices.Count());
                Assert.False(inreg.IsSameAs(existing));
                Assert.Equal(super, inreg.First().Application.SupervisorId);
                Assert.Null(inreg.First().Application.NotSeenSince);
                Assert.Equal(super, inreg.First().Endpoints.First().SupervisorId);
            }
        }
        /// <inheritdoc/>
        public async Task HandleAsync(string deviceId, string moduleId,
                                      byte[] payload, Func <Task> checkpoint)
        {
            var json = Encoding.UTF8.GetString(payload);
            DiscoveryEventModel discovery;

            try {
                discovery = JsonConvertEx.DeserializeObject <DiscoveryEventModel>(json);
            }
            catch (Exception ex) {
                _logger.Error(ex, "Failed to convert discovery {json}", json);
                return;
            }
            try {
                var supervisorId = SupervisorModelEx.CreateSupervisorId(
                    deviceId, moduleId?.ToString());

                await ProcessServerEndpointDiscoveryAsync(supervisorId,
                                                          discovery, checkpoint);
            }
            catch (Exception ex) {
                _logger.Error(ex, "Handling discovery event failed with exception - skip");
            }
        }
        public async Task RunTestAsync(EndpointModel ep,
                                       Func <EndpointRegistrationModel, IContainer, Task> test)
        {
            var endpoint = new EndpointRegistrationModel {
                Endpoint     = ep,
                SupervisorId = SupervisorModelEx.CreateSupervisorId(
                    DeviceId, ModuleId)
            };

            AssertRunning();
            try {
                endpoint = RegisterAndActivateTwinId(endpoint);
                await test(endpoint, HubContainer);

                DeactivateTwinId(endpoint);
            }
            finally {
                _module.Exit(1);
                var result = await _process;
                Assert.Equal(1, result);
                _running = false;
            }
            AssertStopped();
        }
        public void ProcessDiscoveryWithNoResultsAndNoExistingApplications()
        {
            var found = new List <DiscoveryEventModel>();
            var fix   = new Fixture();

            var gateway = fix.Create <string>();
            var Gateway = (new GatewayModel {
                Id = gateway
            }.ToGatewayRegistration().ToDeviceTwin(),
                           new DeviceModel {
                Id = gateway
            });
            var module     = fix.Create <string>();
            var discoverer = DiscovererModelEx.CreateDiscovererId(gateway, module);
            var Discoverer = (new DiscovererModel {
                Id = discoverer
            }.ToDiscovererRegistration().ToDeviceTwin(_serializer),
                              new DeviceModel {
                Id = gateway, ModuleId = module
            });

            module = fix.Create <string>();
            var supervisor = SupervisorModelEx.CreateSupervisorId(gateway, module);
            var Supervisor = (new SupervisorModel {
                Id = supervisor
            }.ToSupervisorRegistration().ToDeviceTwin(_serializer),
                              new DeviceModel {
                Id = gateway, ModuleId = module
            });

            module = fix.Create <string>();
            var publisher = PublisherModelEx.CreatePublisherId(gateway, module);
            var Publisher = (new PublisherModel {
                Id = publisher
            }.ToPublisherRegistration().ToDeviceTwin(_serializer),
                             new DeviceModel {
                Id = gateway, ModuleId = module
            });

            var registry = IoTHubServices.Create(Gateway.YieldReturn() // Single device
                                                 .Append(Discoverer)
                                                 .Append(Supervisor)
                                                 .Append(Publisher));

            using (var mock = AutoMock.GetLoose(builder => {
                // Setup
                builder.RegisterInstance(registry).As <IIoTHubTwinServices>();
                builder.RegisterType <ApplicationTwins>().As <IApplicationRepository>();
                builder.RegisterType <DiscovererRegistry>().As <IDiscovererRegistry>();
                builder.RegisterType <SupervisorRegistry>().As <ISupervisorRegistry>();
                builder.RegisterType <PublisherRegistry>().As <IPublisherRegistry>();
                builder.RegisterType <GatewayRegistry>().As <IGatewayRegistry>();
                builder.RegisterType <ApplicationRegistry>().As <IApplicationBulkProcessor>();
                builder.RegisterType <EndpointRegistry>().As <IEndpointBulkProcessor>();
            })) {
                var service = mock.Create <DiscoveryProcessor>();

                // Run
                service.ProcessDiscoveryResultsAsync(discoverer, new DiscoveryResultModel(), found).Wait();

                // Assert
                Assert.Single(registry.Devices);
                Assert.Equal(gateway, registry.Devices.First().Device.Id);
            }
        }
        /// <summary>
        /// Helper to create fixtures
        /// </summary>
        /// <param name="site"></param>
        /// <param name="discoverer"></param>
        /// <param name="existing"></param>
        /// <param name="found"></param>
        /// <param name="registry"></param>
        /// <param name="countDevices"></param>
        /// <param name="fixup"></param>
        /// <param name="disable"></param>
        private void CreateFixtures(out string site, out string discoverer,
                                    out string supervisor, out string publisher, out string gateway,
                                    out List <ApplicationRegistrationModel> existing, out List <DiscoveryEventModel> found,
                                    out IoTHubServices registry, int countDevices = -1,
                                    Func <ApplicationRegistrationModel, ApplicationRegistrationModel> fixup = null,
                                    bool disable = false)
        {
            var fix = new Fixture();

            // Create template applications and endpoints
            fix.Customizations.Add(new TypeRelay(typeof(VariantValue), typeof(VariantValue)));
            fix.Behaviors.OfType <ThrowingRecursionBehavior>().ToList()
            .ForEach(b => fix.Behaviors.Remove(b));
            fix.Behaviors.Add(new OmitOnRecursionBehavior());
            var sitex = site = fix.Create <string>();

            gateway = fix.Create <string>();
            var Gateway = (new GatewayModel {
                SiteId = site,
                Id = gateway
            }.ToGatewayRegistration().ToDeviceTwin(),
                           new DeviceModel {
                Id = gateway
            });
            var module      = fix.Create <string>();
            var discovererx = discoverer = DiscovererModelEx.CreateDiscovererId(gateway, module);
            var Discoverer  = (new DiscovererModel {
                SiteId = site,
                Id = discovererx
            }.ToDiscovererRegistration().ToDeviceTwin(_serializer),
                               new DeviceModel {
                Id = gateway, ModuleId = module
            });

            module = fix.Create <string>();
            var supervisorx = supervisor = SupervisorModelEx.CreateSupervisorId(gateway, module);
            var Supervisor  = (new SupervisorModel {
                SiteId = site,
                Id = supervisorx
            }.ToSupervisorRegistration().ToDeviceTwin(_serializer),
                               new DeviceModel {
                Id = gateway, ModuleId = module
            });

            module = fix.Create <string>();
            var publisherx = publisher = PublisherModelEx.CreatePublisherId(gateway, module);
            var Publisher  = (new PublisherModel {
                SiteId = site,
                Id = publisherx
            }.ToPublisherRegistration().ToDeviceTwin(_serializer),
                              new DeviceModel {
                Id = gateway, ModuleId = module
            });

            var template = fix
                           .Build <ApplicationRegistrationModel>()
                           .Without(x => x.Application)
                           .Do(c => c.Application = fix
                                                    .Build <ApplicationInfoModel>()
                                                    .Without(x => x.NotSeenSince)
                                                    .With(x => x.SiteId, sitex)
                                                    .With(x => x.DiscovererId, discovererx)
                                                    .Create())
                           .Without(x => x.Endpoints)
                           .Do(c => c.Endpoints = fix
                                                  .Build <EndpointRegistrationModel>()
                                                  .With(x => x.SiteId, sitex)
                                                  .With(x => x.DiscovererId, discovererx)
                                                  .With(x => x.SupervisorId, supervisorx)
                                                  .CreateMany(5)
                                                  .ToList())
                           .CreateMany(5)
                           .ToList();

            template.ForEach(a =>
                             a.Application.ApplicationId =
                                 ApplicationInfoModelEx.CreateApplicationId(a.Application)
                             );

            // Create discovery results from template
            var i = 0; var now = DateTime.UtcNow;

            found = template
                    .SelectMany(a => a.Endpoints.Select(
                                    e => new DiscoveryEventModel {
                Application  = a.Application,
                Registration = e,
                Index        = i++,
                TimeStamp    = now
            }))
                    .ToList();

            // Clone and fixup existing applications as per test case
            existing = template
                       .Select(e => e.Clone())
                       .Select(fixup ?? (a => a))
                       .ToList();
            // and fill registry with them...
            var appdevices = existing
                             .Select(a => a.Application.ToApplicationRegistration(disable))
                             .Select(a => a.ToDeviceTwin(_serializer))
                             .Select(d => (d, new DeviceModel {
                Id = d.Id
            }));
            var epdevices = existing
                            .SelectMany(a => a.Endpoints
                                        .Select(e =>
                                                new EndpointInfoModel {
                ApplicationId = a.Application.ApplicationId,
                Registration  = e
            }.ToEndpointRegistration(_serializer, disable))
                                        .Select(e => e.ToDeviceTwin(_serializer)))
                            .Select(d => (d, new DeviceModel {
                Id = d.Id
            }));

            appdevices = appdevices.Concat(epdevices);
            if (countDevices != -1)
            {
                appdevices = appdevices.Take(countDevices);
            }
            registry = IoTHubServices.Create(appdevices
                                             .Concat(Gateway.YieldReturn())
                                             .Concat(Discoverer.YieldReturn())
                                             .Concat(Supervisor.YieldReturn())
                                             .Concat(Publisher.YieldReturn()));
        }