/// <summary> /// Returns true if this registration matches the application /// model provided. /// </summary> /// <param name="registration"></param> /// <param name="model"></param> /// <returns></returns> public static bool Matches(this ApplicationRegistration registration, ApplicationInfoModel model) { return(model != null && registration.ApplicationId == model.ApplicationId && registration.ApplicationType == model.ApplicationType && (registration.ApplicationState ?? ApplicationState.New) == model.State && registration.ApplicationUri == model.ApplicationUri && registration.HostAddresses.DecodeAsList().SequenceEqualsSafe( model.HostAddresses) && registration.ApproveAuthorityId == model.Approved?.AuthorityId && registration.CreateAuthorityId == model.Created?.AuthorityId && registration.UpdateAuthorityId == model.Updated?.AuthorityId && registration.ApproveTime == model.Approved?.Time && registration.CreateTime == model.Created?.Time && registration.UpdateTime == model.Updated?.Time && registration.DiscoveryProfileUri == model.DiscoveryProfileUri && registration.GatewayServerUri == model.GatewayServerUri && registration.NotSeenSince == model.NotSeenSince && registration.SupervisorId == model.SupervisorId && registration.SiteId == model.SiteId && registration.Capabilities.DecodeAsSet().SetEqualsSafe( model.Capabilities?.Select(x => JTokenEx.SanitizePropertyName(x).ToUpperInvariant())) && registration.DiscoveryUrls.DecodeAsList().SequenceEqualsSafe( model.DiscoveryUrls) && registration.Certificate.DecodeAsByteArray().SequenceEqualsSafe( model.Certificate)); }
/// <summary> /// Convert twin to registration information. /// </summary> /// <param name="twin"></param> /// <param name="onlyServerState"></param> /// <returns></returns> public static BaseRegistration ToRegistration(DeviceTwinModel twin, bool onlyServerState = false) { if (twin == null) { return(null); } var type = twin.Tags.GetValueOrDefault <string>(nameof(DeviceType), null); if (string.IsNullOrEmpty(type) && twin.Properties.Reported != null) { type = twin.Properties.Reported.GetValueOrDefault <string>(TwinProperty.kType, null); } switch (type?.ToLowerInvariant() ?? "") { case "endpoint": return(EndpointRegistration.FromTwin(twin, onlyServerState)); case "application": return(ApplicationRegistration.FromTwin(twin)); case "supervisor": return(SupervisorRegistration.FromTwin(twin, onlyServerState)); } return(null); }
/// <summary> /// Returns true if this registration matches the application /// model provided. /// </summary> /// <param name="registration"></param> /// <param name="model"></param> /// <returns></returns> public static bool Matches(this ApplicationRegistration registration, ApplicationInfoModel model) { if (registration == null) { return(model == null); } return(model != null && registration.ApplicationId == model.ApplicationId && registration.ApplicationType == model.ApplicationType && registration.ApplicationUri == model.ApplicationUri && registration.HostAddresses.DecodeAsList().SequenceEqualsSafe( model.HostAddresses) && registration.CreateAuthorityId == model.Created?.AuthorityId && registration.UpdateAuthorityId == model.Updated?.AuthorityId && registration.CreateTime == model.Created?.Time && registration.UpdateTime == model.Updated?.Time && registration.DiscoveryProfileUri == model.DiscoveryProfileUri && registration.GatewayServerUri == model.GatewayServerUri && registration.NotSeenSince == model.NotSeenSince && registration.DiscovererId == model.DiscovererId && registration.SiteId == model.SiteId && registration.Capabilities.DecodeAsSet().SetEqualsSafe( model.Capabilities?.Select(x => VariantValueEx.SanitizePropertyName(x).ToUpperInvariant())) && registration.DiscoveryUrls.DecodeAsList().SequenceEqualsSafe( model.DiscoveryUrls)); }
/// <summary> /// Convert to service model /// </summary> /// <param name="registration"></param> /// <returns></returns> public static ApplicationInfoModel ToServiceModel(this ApplicationRegistration registration) { if (registration == null) { return(null); } return(new ApplicationInfoModel { ApplicationId = registration.ApplicationId, ApplicationName = registration.ApplicationName, Locale = registration.Locale, LocalizedNames = registration.LocalizedNames, HostAddresses = registration.HostAddresses.DecodeAsList().ToHashSetSafe(), NotSeenSince = registration.NotSeenSince, ApplicationType = registration.ApplicationType ?? ApplicationType.Server, ApplicationUri = string.IsNullOrEmpty(registration.ApplicationUri) ? registration.ApplicationUriLC : registration.ApplicationUri, ProductUri = registration.ProductUri, SiteId = string.IsNullOrEmpty(registration.SiteId) ? null : registration.SiteId, DiscovererId = string.IsNullOrEmpty(registration.DiscovererId) ? null : registration.DiscovererId, DiscoveryUrls = registration.DiscoveryUrls.DecodeAsList().ToHashSetSafe(), DiscoveryProfileUri = registration.DiscoveryProfileUri, GatewayServerUri = registration.GatewayServerUri, Capabilities = registration.Capabilities?.DecodeAsSet(), Created = ToOperationModel(registration.CreateAuthorityId, registration.CreateTime), Updated = ToOperationModel(registration.UpdateAuthorityId, registration.UpdateTime), }); }
public void TestEqualIsEqualWithServiceModelConversionWhenDisabled() { var r1 = CreateRegistration(); var m = r1.ToServiceModel(); var r2 = ApplicationRegistration.FromServiceModel(m, true); Assert.NotEqual(r1, r2); Assert.NotEqual(r1.GetHashCode(), r2.GetHashCode()); Assert.True(r1 != r2); Assert.False(r1 == r2); }
public void TestEqualIsEqualWithDeviceModel() { var r1 = CreateRegistration(); var m = ApplicationRegistration.Patch(null, r1); var r2 = BaseRegistration.ToRegistration(m); Assert.Equal(r1, r2); Assert.Equal(r1.GetHashCode(), r2.GetHashCode()); Assert.True(r1 == r2); Assert.False(r1 != r2); }
/// <summary> /// Patch registration /// </summary> /// <param name="registration"></param> /// <param name="request"></param> public static void Patch(this ApplicationRegistration registration, ApplicationRegistrationUpdateModel request) { // Patch if (!string.IsNullOrEmpty(request.ApplicationName)) { registration.ApplicationName = request.ApplicationName; } if (request.Capabilities != null) { registration.Capabilities = request.Capabilities.EncodeAsDictionary(); } if (!string.IsNullOrEmpty(request.DiscoveryProfileUri)) { registration.DiscoveryProfileUri = request.DiscoveryProfileUri; } if (!string.IsNullOrEmpty(request.GatewayServerUri)) { registration.GatewayServerUri = request.GatewayServerUri; } if (!string.IsNullOrEmpty(request.ProductUri)) { registration.ProductUri = request.ProductUri; } if (request.DiscoveryUrls != null) { registration.DiscoveryUrls = request.DiscoveryUrls?.ToList().EncodeAsDictionary(); } if (request.LocalizedNames != null) { var table = registration.LocalizedNames; if (table == null) { table = new Dictionary <string, string>(); } foreach (var item in request.LocalizedNames) { if (item.Value == null) { table.Remove(item.Key); } else { table.AddOrUpdate(item.Key, item.Value); } } registration.LocalizedNames = table; } registration.Validate(); }
public void TestEqualIsNotEqualWithDeviceModel() { var r1 = CreateRegistration(); var m = ApplicationRegistration.Patch(null, r1); m.Tags["DiscoveryProfileUri"] = null; var r2 = BaseRegistration.ToRegistration(m); Assert.NotEqual(r1, r2); Assert.NotEqual(r1.GetHashCode(), r2.GetHashCode()); Assert.True(r1 != r2); Assert.False(r1 == r2); }
public void TestEqualIsNotEqualWithServiceModelConversion() { var r1 = CreateRegistration(); var m = r1.ToServiceModel(); m.DiscoveryProfileUri = ""; var r2 = ApplicationRegistration.FromServiceModel(m); Assert.NotEqual(r1, r2); Assert.NotEqual(r1.GetHashCode(), r2.GetHashCode()); Assert.True(r1 != r2); Assert.False(r1 == r2); }
/// <summary> /// Returns application name /// </summary> /// <param name="registration">The application record.</param> public static string GetApplicationName(this ApplicationRegistration registration) { if (!string.IsNullOrEmpty(registration.ApplicationName)) { return(registration.ApplicationName); } if (registration.LocalizedNames != null && registration.LocalizedNames.Count != 0 && !string.IsNullOrEmpty(registration.LocalizedNames.First().Value)) { return(registration.LocalizedNames.First().Value); } return(null); }
public void TestEqualIsNotEqualWithDeviceModelWhenDisabled() { var fix = new Fixture(); var r1 = CreateRegistration(); var r2 = ApplicationRegistration.FromServiceModel( r1.ToServiceModel(), true); var m1 = ApplicationRegistration.Patch(r1, r2); var r3 = ApplicationRegistration.FromServiceModel( r2.ToServiceModel(), false); var m2 = ApplicationRegistration.Patch(r2, r3); Assert.True((bool?)m1.Tags[nameof(BaseRegistration.IsDisabled)] ?? false); Assert.NotNull((DateTime?)m1.Tags[nameof(BaseRegistration.NotSeenSince)]); Assert.Null((bool?)m2.Tags[nameof(BaseRegistration.IsDisabled)]); Assert.Null((DateTime?)m2.Tags[nameof(BaseRegistration.NotSeenSince)]); }
/// <summary> /// Clone /// </summary> /// <param name="registration"></param> /// <returns></returns> public static ApplicationRegistration Clone(this ApplicationRegistration registration) { if (registration == null) { return(null); } return(new ApplicationRegistration { DeviceId = registration.Id, ModuleId = registration.ModuleId, Type = registration.Type, Etag = registration.Etag, IsDisabled = registration.IsDisabled, NotSeenSince = registration.NotSeenSince, SiteId = registration.SiteId, ApplicationName = registration.ApplicationName, Locale = registration.Locale, LocalizedNames = registration.LocalizedNames? .ToDictionary(k => k.Key, v => v.Value), ApplicationUri = registration.ApplicationUri, RecordId = registration.RecordId, ProductUri = registration.ProductUri, SupervisorId = registration.SupervisorId, DiscoveryProfileUri = registration.DiscoveryProfileUri, GatewayServerUri = registration.GatewayServerUri, ApplicationId = registration.ApplicationId, ApplicationType = registration.ApplicationType, ApplicationState = registration.ApplicationState, Capabilities = registration.Capabilities? .ToDictionary(k => k.Key, v => v.Value), HostAddresses = registration.HostAddresses? .ToDictionary(k => k.Key, v => v.Value), DiscoveryUrls = registration.DiscoveryUrls? .ToDictionary(k => k.Key, v => v.Value), Certificate = registration.Certificate? .ToDictionary(k => k.Key, v => v.Value), Thumbprint = registration.Thumbprint, ApproveTime = registration.ApproveTime, ApproveAuthorityId = registration.ApproveAuthorityId, CreateTime = registration.CreateTime, CreateAuthorityId = registration.CreateAuthorityId, UpdateTime = registration.UpdateTime, UpdateAuthorityId = registration.UpdateAuthorityId, Connected = registration.Connected, }); }
/// <summary> /// Get site or gateway id from registration /// </summary> /// <param name="registration"></param> /// <returns></returns> public static string GetSiteOrGatewayId(this ApplicationRegistration registration) { if (registration == null) { return(null); } var siteOrGatewayId = registration?.SiteId; if (siteOrGatewayId == null) { var id = registration?.DiscovererId; if (id != null) { siteOrGatewayId = DiscovererModelEx.ParseDeviceId(id, out _); } } return(siteOrGatewayId); }
/// <summary> /// Create device twin /// </summary> /// <param name="registration"></param> /// <returns></returns> public static DeviceTwinModel ToDeviceTwin(this ApplicationRegistration registration) { return(Patch(null, registration)); }
/// <summary> /// Create patch twin model to upload /// </summary> /// <param name="registration"></param> /// <param name="update"></param> public static DeviceTwinModel Patch(this ApplicationRegistration registration, ApplicationRegistration update) { var twin = BaseRegistrationEx.PatchBase(registration, update); // Tags if (update?.ApplicationType != null && update?.ApplicationType != registration?.ApplicationType) { twin.Tags.Add(nameof(ApplicationRegistration.ApplicationType), JToken.FromObject(update.ApplicationType)); twin.Tags.Add(nameof(ApplicationType.Server), update.ApplicationType != ApplicationType.Client); twin.Tags.Add(nameof(ApplicationType.Client), update.ApplicationType != ApplicationType.Server && update.ApplicationType != ApplicationType.DiscoveryServer); twin.Tags.Add(nameof(ApplicationType.DiscoveryServer), update.ApplicationType == ApplicationType.DiscoveryServer); } if ((update?.ApplicationState ?? ApplicationState.New) != registration?.ApplicationState) { twin.Tags.Add(nameof(ApplicationRegistration.ApplicationState), JToken.FromObject( update?.ApplicationState ?? ApplicationState.New)); } if (update?.ApplicationUri != registration?.ApplicationUri) { twin.Tags.Add(nameof(ApplicationRegistration.ApplicationUri), update?.ApplicationUri); twin.Tags.Add(nameof(ApplicationRegistration.ApplicationUriLC), update?.ApplicationUriLC); } if (update?.RecordId != registration?.RecordId) { twin.Tags.Add(nameof(ApplicationRegistration.RecordId), update?.RecordId); } if (update?.ApplicationName != registration?.ApplicationName) { twin.Tags.Add(nameof(ApplicationRegistration.ApplicationName), update?.ApplicationName); } if (update?.Locale != registration?.Locale) { twin.Tags.Add(nameof(ApplicationRegistration.Locale), update?.Locale); } if (update?.DiscoveryProfileUri != registration?.DiscoveryProfileUri) { twin.Tags.Add(nameof(ApplicationRegistration.DiscoveryProfileUri), update?.DiscoveryProfileUri); } if (update?.GatewayServerUri != registration?.GatewayServerUri) { twin.Tags.Add(nameof(ApplicationRegistration.GatewayServerUri), update?.GatewayServerUri); } if (update?.ProductUri != registration?.ProductUri) { twin.Tags.Add(nameof(ApplicationRegistration.ProductUri), update?.ProductUri); } var urlUpdate = update?.DiscoveryUrls.DecodeAsList().SequenceEqualsSafe( registration?.DiscoveryUrls?.DecodeAsList()); if (!(urlUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.DiscoveryUrls), update?.DiscoveryUrls == null ? null : JToken.FromObject(update.DiscoveryUrls)); } var capsUpdate = update?.Capabilities.DecodeAsSet().SetEqualsSafe( registration?.Capabilities?.DecodeAsSet()); if (!(capsUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.Capabilities), update?.Capabilities == null ? null : JToken.FromObject(update.Capabilities)); } var namesUpdate = update?.LocalizedNames.DictionaryEqualsSafe( registration?.LocalizedNames); if (!(namesUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.LocalizedNames), update?.LocalizedNames == null ? null : JToken.FromObject(update.LocalizedNames)); } var hostsUpdate = update?.HostAddresses.DecodeAsList().SequenceEqualsSafe( registration?.HostAddresses?.DecodeAsList()); if (!(hostsUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.HostAddresses), update?.HostAddresses == null ? null : JToken.FromObject(update.HostAddresses)); } if (update?.ApproveAuthorityId != registration?.ApproveAuthorityId) { twin.Tags.Add(nameof(ApplicationRegistration.ApproveAuthorityId), update?.ApproveAuthorityId); } if (update?.ApproveTime != registration?.ApproveTime) { twin.Tags.Add(nameof(ApplicationRegistration.ApproveTime), update?.ApproveTime); } if (update?.CreateAuthorityId != registration?.CreateAuthorityId) { twin.Tags.Add(nameof(ApplicationRegistration.CreateAuthorityId), update?.CreateAuthorityId); } if (update?.CreateTime != registration?.CreateTime) { twin.Tags.Add(nameof(ApplicationRegistration.CreateTime), update?.CreateTime); } if (update?.UpdateAuthorityId != registration?.UpdateAuthorityId) { twin.Tags.Add(nameof(ApplicationRegistration.UpdateAuthorityId), update?.UpdateAuthorityId); } if (update?.UpdateTime != registration?.UpdateTime) { twin.Tags.Add(nameof(ApplicationRegistration.UpdateTime), update?.UpdateTime); } // Recalculate identity var applicationUri = registration?.ApplicationUri; if (update?.ApplicationUri != null) { applicationUri = update?.ApplicationUri; } if (applicationUri == null) { throw new ArgumentException(nameof(ApplicationRegistration.ApplicationUri)); } var siteOrSupervisorId = registration?.SiteId ?? registration?.SupervisorId; if (update?.SupervisorId != null || update?.SiteId != null) { siteOrSupervisorId = update?.SiteId ?? update?.SupervisorId; } var applicationType = registration?.ApplicationType; if (update?.ApplicationType != null) { applicationType = update?.ApplicationType; } var applicationId = ApplicationInfoModelEx.CreateApplicationId( siteOrSupervisorId, applicationUri, applicationType); twin.Tags.Remove(nameof(ApplicationId)); twin.Tags.Add(nameof(ApplicationId), applicationId); twin.Id = applicationId; if (registration?.DeviceId != twin.Id) { twin.Etag = null; // Force creation of new identity } return(twin); }
/// <summary> /// Create device twin /// </summary> /// <param name="serializer"></param> /// <param name="registration"></param> /// <returns></returns> public static DeviceTwinModel ToDeviceTwin( this ApplicationRegistration registration, IJsonSerializer serializer) { return(Patch(null, registration, serializer)); }
/// <summary> /// Create patch twin model to upload /// </summary> /// <param name="serializer"></param> /// <param name="existing"></param> /// <param name="update"></param> public static DeviceTwinModel Patch(this ApplicationRegistration existing, ApplicationRegistration update, IJsonSerializer serializer) { var twin = new DeviceTwinModel { Etag = existing?.Etag, Tags = new Dictionary <string, VariantValue>(), Properties = new TwinPropertiesModel { Desired = new Dictionary <string, VariantValue>() } }; // Tags if (update?.ApplicationId != null && update.ApplicationId != existing?.ApplicationId) { twin.Tags.Add(nameof(ApplicationId), update.ApplicationId); } if (update?.IsDisabled != null && update.IsDisabled != existing?.IsDisabled) { twin.Tags.Add(nameof(EntityRegistration.IsDisabled), (update?.IsDisabled ?? false) ? true : (bool?)null); twin.Tags.Add(nameof(EntityRegistration.NotSeenSince), (update?.IsDisabled ?? false) ? DateTime.UtcNow : (DateTime?)null); } if (update?.SiteOrGatewayId != existing?.SiteOrGatewayId) { twin.Tags.Add(nameof(EntityRegistration.SiteOrGatewayId), update?.SiteOrGatewayId); } if (update?.DiscovererId != existing?.DiscovererId) { twin.Tags.Add(nameof(ApplicationRegistration.DiscovererId), update?.DiscovererId); } if (update?.SiteId != existing?.SiteId) { twin.Tags.Add(nameof(EntityRegistration.SiteId), update?.SiteId); } twin.Tags.Add(nameof(EntityRegistration.DeviceType), update?.DeviceType); if (update?.ApplicationType != null && update?.ApplicationType != existing?.ApplicationType) { twin.Tags.Add(nameof(ApplicationRegistration.ApplicationType), serializer.FromObject(update.ApplicationType.ToString())); twin.Tags.Add(nameof(ApplicationType.Server), update.ApplicationType != ApplicationType.Client); twin.Tags.Add(nameof(ApplicationType.Client), update.ApplicationType != ApplicationType.Server && update.ApplicationType != ApplicationType.DiscoveryServer); twin.Tags.Add(nameof(ApplicationType.DiscoveryServer), update.ApplicationType == ApplicationType.DiscoveryServer); } if (update?.ApplicationUri != existing?.ApplicationUri) { twin.Tags.Add(nameof(ApplicationRegistration.ApplicationUri), update?.ApplicationUri); twin.Tags.Add(nameof(ApplicationRegistration.ApplicationUriLC), update?.ApplicationUriLC); } if (update?.RecordId != existing?.RecordId) { twin.Tags.Add(nameof(ApplicationRegistration.RecordId), update?.RecordId); } if (update?.ApplicationName != existing?.ApplicationName) { twin.Tags.Add(nameof(ApplicationRegistration.ApplicationName), update?.ApplicationName); } if (update?.Locale != existing?.Locale) { twin.Tags.Add(nameof(ApplicationRegistration.Locale), update?.Locale); } if (update?.DiscoveryProfileUri != existing?.DiscoveryProfileUri) { twin.Tags.Add(nameof(ApplicationRegistration.DiscoveryProfileUri), update?.DiscoveryProfileUri); } if (update?.GatewayServerUri != existing?.GatewayServerUri) { twin.Tags.Add(nameof(ApplicationRegistration.GatewayServerUri), update?.GatewayServerUri); } if (update?.ProductUri != existing?.ProductUri) { twin.Tags.Add(nameof(ApplicationRegistration.ProductUri), update?.ProductUri); } var urlUpdate = update?.DiscoveryUrls.DecodeAsList().SequenceEqualsSafe( existing?.DiscoveryUrls?.DecodeAsList()); if (!(urlUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.DiscoveryUrls), update?.DiscoveryUrls == null ? null : serializer.FromObject(update.DiscoveryUrls)); } var capsUpdate = update?.Capabilities.DecodeAsSet().SetEqualsSafe( existing?.Capabilities?.DecodeAsSet()); if (!(capsUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.Capabilities), update?.Capabilities == null ? null : serializer.FromObject(update.Capabilities)); } var namesUpdate = update?.LocalizedNames.DictionaryEqualsSafe( existing?.LocalizedNames); if (!(namesUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.LocalizedNames), update?.LocalizedNames == null ? null : serializer.FromObject(update.LocalizedNames)); } var hostsUpdate = update?.HostAddresses.DecodeAsList().SequenceEqualsSafe( existing?.HostAddresses?.DecodeAsList()); if (!(hostsUpdate ?? true)) { twin.Tags.Add(nameof(ApplicationRegistration.HostAddresses), update?.HostAddresses == null ? null : serializer.FromObject(update.HostAddresses)); } if (update?.CreateAuthorityId != existing?.CreateAuthorityId) { twin.Tags.Add(nameof(ApplicationRegistration.CreateAuthorityId), update?.CreateAuthorityId); } if (update?.CreateTime != existing?.CreateTime) { twin.Tags.Add(nameof(ApplicationRegistration.CreateTime), update?.CreateTime); } if (update?.UpdateAuthorityId != existing?.UpdateAuthorityId) { twin.Tags.Add(nameof(ApplicationRegistration.UpdateAuthorityId), update?.UpdateAuthorityId); } if (update?.UpdateTime != existing?.UpdateTime) { twin.Tags.Add(nameof(ApplicationRegistration.UpdateTime), update?.UpdateTime); } // Recalculate identity var applicationUri = existing?.ApplicationUri; if (update?.ApplicationUri != null) { applicationUri = update?.ApplicationUri; } if (applicationUri == null) { throw new ArgumentException(nameof(ApplicationRegistration.ApplicationUri)); } var siteOrGatewayId = existing?.SiteOrGatewayId; if (siteOrGatewayId == null) { siteOrGatewayId = update?.SiteOrGatewayId; if (siteOrGatewayId == null) { throw new ArgumentException(nameof(ApplicationRegistration.SiteOrGatewayId)); } } var applicationType = existing?.ApplicationType; if (update?.ApplicationType != null) { applicationType = update?.ApplicationType; } var applicationId = ApplicationInfoModelEx.CreateApplicationId( siteOrGatewayId, applicationUri, applicationType); twin.Id = applicationId; if (existing?.DeviceId != twin.Id) { twin.Etag = null; // Force creation of new identity } return(twin); }
/// <summary> /// Make sure to get the registration information from the right place. /// Reported (truth) properties take precedence over desired. /// </summary> /// <param name="twin"></param> /// <returns></returns> public static ApplicationRegistration ToApplicationRegistration(this DeviceTwinModel twin) { if (twin == null) { return(null); } var tags = twin.Tags ?? new Dictionary <string, VariantValue>(); var registration = new ApplicationRegistration { // Device DeviceId = twin.Id, Etag = twin.Etag, // Tags IsDisabled = tags.GetValueOrDefault(nameof(ApplicationRegistration.IsDisabled), twin.IsDisabled()), NotSeenSince = tags.GetValueOrDefault <DateTime>(nameof(ApplicationRegistration.NotSeenSince), null), SiteId = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.SiteId), null), ApplicationName = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.ApplicationName), null), Locale = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.Locale), null), LocalizedNames = tags.GetValueOrDefault <Dictionary <string, string> >(nameof(ApplicationRegistration.LocalizedNames), null), ApplicationUri = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.ApplicationUri), null), RecordId = tags.GetValueOrDefault <uint>(nameof(ApplicationRegistration.RecordId), null), ProductUri = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.ProductUri), null), DiscovererId = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.DiscovererId), tags.GetValueOrDefault <string>("SupervisorId", null)), DiscoveryProfileUri = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.DiscoveryProfileUri), null), GatewayServerUri = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.GatewayServerUri), null), ApplicationType = tags.GetValueOrDefault <ApplicationType>(nameof(ApplicationType), null), Capabilities = tags.GetValueOrDefault <Dictionary <string, bool> >(nameof(ApplicationRegistration.Capabilities), null), HostAddresses = tags.GetValueOrDefault <Dictionary <string, string> >(nameof(ApplicationRegistration.HostAddresses), null), DiscoveryUrls = tags.GetValueOrDefault <Dictionary <string, string> >(nameof(ApplicationRegistration.DiscoveryUrls), null), CreateTime = tags.GetValueOrDefault <DateTime>(nameof(ApplicationRegistration.CreateTime), null), CreateAuthorityId = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.CreateAuthorityId), null), UpdateTime = tags.GetValueOrDefault <DateTime>(nameof(ApplicationRegistration.UpdateTime), null), UpdateAuthorityId = tags.GetValueOrDefault <string>(nameof(ApplicationRegistration.UpdateAuthorityId), null), }; return(registration); }
/// <summary> /// Validates all fields in an application record to be consistent with /// the OPC UA specification. /// </summary> /// <param name="registration">The application registration</param> public static void Validate(this ApplicationRegistration registration) { if (registration == null) { throw new ArgumentNullException(nameof(registration)); } if (registration.ApplicationUri == null) { throw new ArgumentNullException(nameof(registration.ApplicationUri)); } if (!Uri.IsWellFormedUriString(registration.ApplicationUri, UriKind.Absolute)) { throw new ArgumentException(registration.ApplicationUri + " is not a valid URI.", nameof(registration.ApplicationUri)); } if ((registration.ApplicationType < ApplicationType.Server) || (registration.ApplicationType > ApplicationType.DiscoveryServer)) { throw new ArgumentException(registration.ApplicationType.ToString() + " is not a valid ApplicationType.", nameof(registration.ApplicationType)); } if (string.IsNullOrEmpty(registration.GetApplicationName())) { throw new ArgumentException( "At least one ApplicationName must be provided.", nameof(registration.LocalizedNames)); } if (string.IsNullOrEmpty(registration.ProductUri)) { throw new ArgumentException( "A ProductUri must be provided.", nameof(registration.ProductUri)); } if (!Uri.IsWellFormedUriString(registration.ProductUri, UriKind.Absolute)) { throw new ArgumentException(registration.ProductUri + " is not a valid URI.", nameof(registration.ProductUri)); } if (registration.DiscoveryUrls != null) { foreach (var discoveryUrl in registration.DiscoveryUrls.DecodeAsList()) { if (string.IsNullOrEmpty(discoveryUrl)) { continue; } if (!Uri.IsWellFormedUriString(discoveryUrl, UriKind.Absolute)) { throw new ArgumentException(discoveryUrl + " is not a valid URL.", nameof(registration.DiscoveryUrls)); } // TODO: check for https:/hostname:62541, typo is not detected here } } if (registration.ApplicationType != ApplicationType.Client) { if (!(registration.DiscoveryUrls.DecodeAsList()?.Any() ?? false)) { throw new ArgumentException( "At least one DiscoveryUrl must be provided.", nameof(registration.DiscoveryUrls)); } if (!registration.Capabilities.Any()) { throw new ArgumentException( "At least one Server Capability must be provided.", nameof(registration.Capabilities)); } // TODO: check for valid servercapabilities } else { if (registration.DiscoveryUrls.DecodeAsList()?.Any() ?? false) { throw new ArgumentException( "DiscoveryUrls must not be specified for clients.", nameof(registration.DiscoveryUrls)); } } }