public static DeviceTwinModel Patch()

in src/Azure.IIoT.OpcUa.Publisher.Service/src/Services/Extensions/EndpointRegistrationEx.cs [49:192]


        public static DeviceTwinModel Patch(this EndpointRegistration? existing,
            EndpointRegistration? update, IJsonSerializer serializer, TimeProvider timeProvider)
        {
            var tags = new Dictionary<string, VariantValue>();
            var desired = new Dictionary<string, VariantValue>();

            // Tags

            if (update?.ApplicationId != null &&
                update.ApplicationId != existing?.ApplicationId)
            {
                tags.Add(nameof(ApplicationId), update.ApplicationId);
            }

            if (update?.IsDisabled != null &&
                update.IsDisabled != existing?.IsDisabled)
            {
                tags.Add(nameof(EntityRegistration.IsDisabled), (update?.IsDisabled ?? false) ?
                    true : (bool?)null);
                tags.Add(nameof(EntityRegistration.NotSeenSince), (update?.IsDisabled ?? false) ?
                    timeProvider.GetUtcNow().UtcDateTime : (DateTime?)null);
            }

            if (update?.SiteOrGatewayId != existing?.SiteOrGatewayId)
            {
                tags.Add(nameof(EntityRegistration.SiteOrGatewayId), update?.SiteOrGatewayId);
            }

            if (update?.DiscovererId != existing?.DiscovererId)
            {
                tags.Add(nameof(EndpointRegistration.DiscovererId), update?.DiscovererId);
            }

            if (update?.SiteId != existing?.SiteId)
            {
                tags.Add(nameof(EntityRegistration.SiteId), update?.SiteId);
            }

            tags.Add(nameof(EntityRegistration.DeviceType), update?.DeviceType);

            if (update?.EndpointRegistrationUrl != null &&
                update.EndpointRegistrationUrl != existing?.EndpointRegistrationUrl)
            {
                tags.Add(nameof(EndpointRegistration.EndpointUrlLC),
                    update.EndpointUrlLC);
                tags.Add(nameof(EndpointRegistration.EndpointRegistrationUrl),
                    update.EndpointRegistrationUrl);
            }

            if (update?.SecurityLevel != existing?.SecurityLevel)
            {
                tags.Add(nameof(EndpointRegistration.SecurityLevel), update?.SecurityLevel == null ?
                    VariantValue.Null : serializer.FromObject(update.SecurityLevel?.ToString(CultureInfo.InvariantCulture)));
            }

            var methodEqual = update?.AuthenticationMethods.DecodeAsList().SetEqualsSafe(
                existing?.AuthenticationMethods?.DecodeAsList(), (a, b) => a.IsSameAs(b));
            if (!(methodEqual ?? true))
            {
                tags.Add(nameof(EndpointRegistration.AuthenticationMethods),
                    update?.AuthenticationMethods == null ?
                    VariantValue.Null : serializer.FromObject(update.AuthenticationMethods));
            }

            // Endpoint Property

            if (update?.EndpointUrl != null &&
                update.EndpointUrl != existing?.EndpointUrl)
            {
                desired.Add(nameof(EndpointRegistration.EndpointUrl),
                    update.EndpointUrl);
            }

            var urlsEqual = update?.AlternativeUrls.DecodeAsList().ToHashSetSafe().SetEqualsSafe(
                existing?.AlternativeUrls?.DecodeAsList());
            if (!(urlsEqual ?? true))
            {
                desired.Add(nameof(EndpointRegistration.AlternativeUrls),
                    update?.AlternativeUrls == null ?
                        VariantValue.Null : serializer.FromObject(update.AlternativeUrls));
            }

            if (update?.SecurityMode != null &&
                update.SecurityMode != existing?.SecurityMode)
            {
                desired.Add(nameof(EndpointRegistration.SecurityMode),
                    update?.SecurityMode == null ?
                        VariantValue.Null : serializer.FromObject(update.SecurityMode.ToString()));
            }

            if (update?.SecurityPolicy != null &&
                update.SecurityPolicy != existing?.SecurityPolicy)
            {
                desired.Add(nameof(EndpointRegistration.SecurityPolicy),
                    update.SecurityPolicy);
            }

            if (update?.Thumbprint != existing?.Thumbprint)
            {
                desired.Add(nameof(EndpointRegistration.Thumbprint), update?.Thumbprint);
            }

            // Recalculate identity

            var reportedEndpointUrl = existing?.EndpointRegistrationUrl;
            if (update?.EndpointRegistrationUrl != null)
            {
                reportedEndpointUrl = update.EndpointRegistrationUrl;
            }
            if (reportedEndpointUrl == null)
            {
                throw new ArgumentException(nameof(EndpointRegistration.EndpointUrl));
            }
            var applicationId = existing?.ApplicationId;
            if (update?.ApplicationId != null)
            {
                applicationId = update.ApplicationId;
            }
            if (applicationId == null)
            {
                throw new ArgumentException(nameof(EndpointRegistration.ApplicationId));
            }
            var securityMode = existing?.SecurityMode;
            if (update?.SecurityMode != null)
            {
                securityMode = update.SecurityMode;
            }
            var securityPolicy = existing?.SecurityPolicy;
            if (update?.SecurityPolicy != null)
            {
                securityPolicy = update.SecurityPolicy;
            }

            var id = EndpointInfoModelEx.CreateEndpointId(
                applicationId, reportedEndpointUrl, securityMode, securityPolicy);
            return new DeviceTwinModel
            {
                Id = id ?? string.Empty,
                // Force creation of new identity
                Etag = existing?.DeviceId != id ? string.Empty : existing?.Etag ?? string.Empty,
                Tags = tags,
                Desired = desired
            };
        }