Example #1
0
        /// <summary>
        /// Convert to document model
        /// </summary>
        /// <returns></returns>
        internal static ApplicationInfoModel ToServiceModel(Application application)
        {
            var app = new ApplicationInfoModel {
                ApplicationUri      = application.ApplicationUri,
                ApplicationName     = GetApplicationName(application, out var locale),
                Locale              = locale,
                ApplicationType     = application.ApplicationType,
                LocalizedNames      = ToServiceModel(application.ApplicationNames),
                ProductUri          = application.ProductUri,
                DiscoveryUrls       = application.DiscoveryUrls.ToHashSetSafe(),
                Capabilities        = ToServiceModel(application.ServerCapabilities),
                GatewayServerUri    = application.GatewayServerUri,
                DiscoveryProfileUri = application.DiscoveryProfileUri,
                Created             = ToServiceModel(
                    application.CreateTime, null),
                Updated = ToServiceModel(
                    application.UpdateTime, null),
                ApplicationId = null,
                HostAddresses = null,
                NotSeenSince  = null,
                SiteId        = null,
                DiscovererId  = null
            };

            app.ApplicationId = ApplicationInfoModelEx.CreateApplicationId(app);
            return(app);
        }
        /// <inheritdoc/>
        public async Task MigrateAsync()
        {
            string continuation = null;

            do
            {
                var results = await _source.ListAsync(continuation, null, null);

                continuation = results.ContinuationToken;
                foreach (var application in results.Items)
                {
                    try {
                        var clone = application.Clone();
                        clone.ApplicationId =
                            ApplicationInfoModelEx.CreateApplicationId(application);
                        await _repo.AddAsync(clone);
                    }
                    catch (ConflictingResourceException ex) {
                        _logger.Error(ex,
                                      "Application {application} already exists - not migrating...",
                                      application.ApplicationName);
                        continue;
                    }
                    catch (Exception e) {
                        _logger.Error(e, "Error adding {application} - skip migration...",
                                      application.ApplicationName);
                        continue;
                    }
                    // Force delete now
                    await _source.DeleteAsync(application.ApplicationId);
                }
            }while (continuation != null);
        }
        /// <summary>
        /// Create server model
        /// </summary>
        /// <param name="result"></param>
        /// <param name="hostAddress"></param>
        /// <param name="siteId"></param>
        /// <param name="gatewayId"></param>
        /// <param name="moduleId"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public static ApplicationRegistrationModel ToServiceModel(this DiscoveredEndpointModel result,
                                                                  string hostAddress, string siteId, string gatewayId, string moduleId,
                                                                  IJsonSerializer serializer)
        {
            var type = result.Description.Server.ApplicationType.ToServiceType() ??
                       ApplicationType.Server;
            var discovererId = DiscovererModelEx.CreateDiscovererId(gatewayId, moduleId);

            return(new ApplicationRegistrationModel {
                Application = new ApplicationInfoModel {
                    SiteId = siteId,
                    DiscovererId = discovererId,
                    ApplicationType = type,
                    ApplicationId = ApplicationInfoModelEx.CreateApplicationId(siteId ?? gatewayId,
                                                                               result.Description.Server.ApplicationUri, type), // TODO: Assign at onboarder and leave null
                    ProductUri = result.Description.Server.ProductUri,
                    ApplicationUri = result.Description.Server.ApplicationUri,
                    DiscoveryUrls = new HashSet <string>(result.Description.Server.DiscoveryUrls),
                    DiscoveryProfileUri = result.Description.Server.DiscoveryProfileUri,
                    HostAddresses = new HashSet <string> {
                        hostAddress
                    },
                    ApplicationName = result.Description.Server.ApplicationName.Text,
                    LocalizedNames = string.IsNullOrEmpty(result.Description.Server.ApplicationName.Locale) ?
                                     null : new Dictionary <string, string> {
                        [result.Description.Server.ApplicationName.Locale] =
                            result.Description.Server.ApplicationName.Text
                    },
                    NotSeenSince = null,
                    Capabilities = new HashSet <string>(result.Capabilities)
                },
                Endpoints = new List <EndpointRegistrationModel> {
                    new EndpointRegistrationModel {
                        SiteId = siteId,
                        DiscovererId = discovererId,
                        SupervisorId = null,
                        Id = null,
                        SecurityLevel = result.Description.SecurityLevel,
                        AuthenticationMethods = result.Description.UserIdentityTokens
                                                .ToServiceModel(serializer),
                        EndpointUrl = result.Description.EndpointUrl, // Reported
                        Endpoint = new EndpointModel {
                            Url = result.AccessibleEndpointUrl,       // Accessible
                            AlternativeUrls = new HashSet <string> {
                                result.AccessibleEndpointUrl,
                                result.Description.EndpointUrl,
                            },
                            Certificate = result.Description.ServerCertificate?.ToThumbprint(),
                            SecurityMode = result.Description.SecurityMode.ToServiceType() ??
                                           SecurityMode.None,
                            SecurityPolicy = result.Description.SecurityPolicyUri
                        }
                    }
                }
            });
        }
        /// <summary>
        /// Create server model
        /// </summary>
        /// <param name="result"></param>
        /// <param name="hostAddress"></param>
        /// <param name="siteId"></param>
        /// <param name="supervisorId"></param>
        /// <returns></returns>
        public static ApplicationRegistrationModel ToServiceModel(this DiscoveredEndpointModel result,
                                                                  string hostAddress, string siteId, string supervisorId)
        {
            var type = result.Description.Server.ApplicationType.ToServiceType() ??
                       ApplicationType.Server;

            return(new ApplicationRegistrationModel {
                Application = new ApplicationInfoModel {
                    SiteId = siteId,
                    SupervisorId = supervisorId,
                    ApplicationType = type,
                    ApplicationId = ApplicationInfoModelEx.CreateApplicationId(
                        siteId ?? supervisorId, result.Description.Server.ApplicationUri, type),
                    ProductUri = result.Description.Server.ProductUri,
                    ApplicationUri = result.Description.Server.ApplicationUri,
                    DiscoveryUrls = new HashSet <string>(result.Description.Server.DiscoveryUrls),
                    DiscoveryProfileUri = result.Description.Server.DiscoveryProfileUri,
                    HostAddresses = new HashSet <string> {
                        hostAddress
                    },
                    ApplicationName = result.Description.Server.ApplicationName.Text,
                    Locale = result.Description.Server.ApplicationName.Locale,
                    NotSeenSince = null,
                    Certificate = result.Description.ServerCertificate,
                    Capabilities = new HashSet <string>(result.Capabilities)
                },
                Endpoints = new List <EndpointRegistrationModel> {
                    new EndpointRegistrationModel {
                        SiteId = siteId,
                        SupervisorId = supervisorId,
                        Certificate = result.Description.ServerCertificate,
                        SecurityLevel = result.Description.SecurityLevel,
                        AuthenticationMethods = result.Description.UserIdentityTokens.ToServiceModel(),
                        EndpointUrl = result.Description.EndpointUrl, // Reported
                        Endpoint = new EndpointModel {
                            Url = result.AccessibleEndpointUrl,       // Accessible
                            AlternativeUrls = new HashSet <string> {
                                result.AccessibleEndpointUrl,
                                result.Description.EndpointUrl,
                            },
                            SecurityMode = result.Description.SecurityMode.ToServiceType() ??
                                           SecurityMode.None,
                            SecurityPolicy = result.Description.SecurityPolicyUri
                        }
                    }
                }
            });
        }
Example #5
0
        /// <inheritdoc/>
        public async Task MigrateAsync()
        {
            if (_source == null)
            {
                return;
            }
            var query = _source.OpenSqlClient().Query <Application>(
                "SELECT * FROM Applications a WHERE " +
                $"a.{nameof(Application.ClassType)} = '{Application.ClassTypeName}'",
                null, null);

            // Read results
            while (query.HasMore())
            {
                var results = await query.ReadAsync();

                foreach (var document in results)
                {
                    var application = ToServiceModel(document.Value);
                    try {
                        application.ApplicationId =
                            ApplicationInfoModelEx.CreateApplicationId(application);
                        await _repo.AddAsync(application);
                    }
                    catch (ConflictingResourceException ex) {
                        _logger.Error(ex,
                                      "Application {application} already exists - not migrating...",
                                      application.ApplicationName);
                        continue;
                    }
                    catch (Exception e) {
                        _logger.Error(e, "Error adding {application} - skip migration...",
                                      application.ApplicationName);
                        continue;
                    }
                    // Force delete now
                    await _source.DeleteAsync(document.Id);
                }
            }

            // Removing the container after migration is complete.
            await _database.DeleteContainerAsync(_config.CosmosDBCollection);
        }
        public void GetApplicationThatExists()
        {
            CreateAppFixtures(out var site, out var super, out var apps, out var devices);
            var first = apps.First();

            using (var mock = AutoMock.GetLoose()) {
                mock.Provide <IIoTHubTwinServices>(new IoTHubServices(devices));
                var service = mock.Create <RegistryServices>();

                // Run
                var result = service.GetApplicationAsync(
                    ApplicationInfoModelEx.CreateApplicationId(site,
                                                               first.ApplicationUri, first.ApplicationType), false).Result;

                // Assert
                Assert.True(result.Application.IsSameAs(apps.First()));
                Assert.True(result.Endpoints.Count == 0);
            }
        }
        public void GetApplicationThatExists()
        {
            CreateAppFixtures(out var site, out var super, out var apps, out var devices);
            var first = apps.First();

            using (var mock = AutoMock.GetLoose(builder => {
                var hub = IoTHubServices.Create(devices);
                builder.RegisterType <NewtonSoftJsonConverters>().As <IJsonSerializerConverterProvider>();
                builder.RegisterType <NewtonSoftJsonSerializer>().As <IJsonSerializer>();
                builder.RegisterInstance(hub).As <IIoTHubTwinServices>();
                builder.RegisterType <ApplicationTwins>().As <IApplicationRepository>();
            })) {
                IApplicationRegistry service = mock.Create <ApplicationRegistry>();

                // Run
                var result = service.GetApplicationAsync(
                    ApplicationInfoModelEx.CreateApplicationId(site,
                                                               first.ApplicationUri, first.ApplicationType), false).Result;

                // Assert
                Assert.True(result.Application.IsSameAs(apps.First()));
                Assert.True(result.Endpoints.Count == 0);
            }
        }
        /// <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()));
        }
        /// <summary>
        /// Helper to create fixtures
        /// </summary>
        /// <param name="site"></param>
        /// <param name="super"></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 static void CreateFixtures(out string site, out string super,
                                           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(JToken), typeof(JObject)));
            var sitex = site = fix.Create <string>();

            var module = fix.Create <string>();
            var device = fix.Create <string>();
            var superx = super = SupervisorModelEx.CreateSupervisorId(device, module);

            var supervisor = (
                SupervisorRegistration.Patch(null,
                                             SupervisorRegistration.FromServiceModel(new SupervisorModel {
                SiteId = site,
                Id = superx
            })), new DeviceModel {
                Id = device, 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.SupervisorId, superx)
                                                    .Create())
                           .Without(x => x.Endpoints)
                           .Do(c => c.Endpoints = fix
                                                  .Build <EndpointRegistrationModel>()
                                                  .With(x => x.SiteId, sitex)
                                                  .With(x => x.SupervisorId, superx)
                                                  .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 => ApplicationRegistration.FromServiceModel(a.Application, disable))
                             .Select(a => ApplicationRegistration.Patch(null, a))
                             .Select(d => (d, new DeviceModel {
                Id = d.Id
            }));
            var epdevices = existing
                            .SelectMany(a => a.Endpoints
                                        .Select(e => EndpointRegistration.FromServiceModel(
                                                    new EndpointInfoModel {
                ApplicationId = a.Application.ApplicationId,
                Registration  = e
            }, disable)))
                            .Select(e => EndpointRegistration.Patch(null, e))
                            .Select(d => (d, new DeviceModel {
                Id = d.Id
            }));

            appdevices = appdevices.Concat(epdevices);
            if (countDevices != -1)
            {
                appdevices = appdevices.Take(countDevices);
            }
            registry = new IoTHubServices(appdevices.Concat(supervisor.YieldReturn()));
        }