/// <summary> /// Convert to service model /// </summary> /// <returns></returns> public static ApplicationDocument ToDocumentModel( this ApplicationRegistrationRequestModel model, uint id) { var document = new ApplicationDocument { ID = id, ApplicationState = ApplicationState.New, CreateTime = DateTime.UtcNow, SiteId = model.SiteId, ApplicationId = ApplicationInfoModelEx.CreateApplicationId( model.SiteId, model.ApplicationUri, model.ApplicationType), ApplicationUri = model.ApplicationUri, ApplicationName = model.ApplicationName ?? model.LocalizedNames.FirstOrDefault().Value, ApplicationType = model.ApplicationType ?? ApplicationType.ClientAndServer, ApplicationNames = GetLocalizedText(model.LocalizedNames), ProductUri = model.ProductUri, DiscoveryUrls = model.DiscoveryUrls?.ToArray(), ServerCapabilities = GetServerCapabilitiesAsString(model.Capabilities), GatewayServerUri = model.GatewayServerUri, DiscoveryProfileUri = model.DiscoveryProfileUri, }; document.Validate(); return(document); }
/// <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> /// 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); }