in src/Azure.IIoT.OpcUa.Publisher.Service/src/Services/Extensions/ApplicationRegistrationEx.cs [42:228]
public static DeviceTwinModel Patch(this ApplicationRegistration? existing,
ApplicationRegistration 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(ApplicationRegistration.DiscovererId), update?.DiscovererId);
}
if (update?.SiteId != existing?.SiteId)
{
tags.Add(nameof(EntityRegistration.SiteId), update?.SiteId);
}
tags.Add(nameof(EntityRegistration.DeviceType), update?.DeviceType);
if (update?.ApplicationType != null &&
update.ApplicationType != existing?.ApplicationType)
{
tags.Add(nameof(ApplicationRegistration.ApplicationType),
serializer.FromObject(update.ApplicationType.ToString()));
tags.Add(nameof(ApplicationType.Server),
update.ApplicationType != ApplicationType.Client);
tags.Add(nameof(ApplicationType.Client),
update.ApplicationType != ApplicationType.Server &&
update.ApplicationType != ApplicationType.DiscoveryServer);
tags.Add(nameof(ApplicationType.DiscoveryServer),
update.ApplicationType == ApplicationType.DiscoveryServer);
}
if (update?.ApplicationUri != existing?.ApplicationUri)
{
tags.Add(nameof(ApplicationRegistration.ApplicationUri),
update?.ApplicationUri);
tags.Add(nameof(ApplicationRegistration.ApplicationUriLC),
update?.ApplicationUriLC);
}
if (update?.RecordId != existing?.RecordId)
{
tags.Add(nameof(ApplicationRegistration.RecordId),
update?.RecordId);
}
if (update?.ApplicationName != existing?.ApplicationName)
{
tags.Add(nameof(ApplicationRegistration.ApplicationName),
update?.ApplicationName);
}
if (update?.Locale != existing?.Locale)
{
tags.Add(nameof(ApplicationRegistration.Locale),
update?.Locale);
}
if (update?.DiscoveryProfileUri != existing?.DiscoveryProfileUri)
{
tags.Add(nameof(ApplicationRegistration.DiscoveryProfileUri),
update?.DiscoveryProfileUri);
}
if (update?.GatewayServerUri != existing?.GatewayServerUri)
{
tags.Add(nameof(ApplicationRegistration.GatewayServerUri),
update?.GatewayServerUri);
}
if (update?.ProductUri != existing?.ProductUri)
{
tags.Add(nameof(ApplicationRegistration.ProductUri), update?.ProductUri);
}
var urlUpdate = update?.DiscoveryUrls.DecodeAsList().SequenceEqualsSafe(
existing?.DiscoveryUrls?.DecodeAsList());
if (!(urlUpdate ?? true))
{
tags.Add(nameof(ApplicationRegistration.DiscoveryUrls),
update?.DiscoveryUrls == null ?
VariantValue.Null : serializer.FromObject(update.DiscoveryUrls));
}
var capsUpdate = update?.Capabilities.DecodeAsSet().SetEqualsSafe(
existing?.Capabilities?.DecodeAsSet());
if (!(capsUpdate ?? true))
{
tags.Add(nameof(ApplicationRegistration.Capabilities),
update?.Capabilities == null ?
VariantValue.Null : serializer.FromObject(update.Capabilities));
}
var namesUpdate = update?.LocalizedNames.DictionaryEqualsSafe(
existing?.LocalizedNames);
if (!(namesUpdate ?? true))
{
tags.Add(nameof(ApplicationRegistration.LocalizedNames),
update?.LocalizedNames == null ?
VariantValue.Null : serializer.FromObject(update.LocalizedNames));
}
var hostsUpdate = update?.HostAddresses.DecodeAsList().SequenceEqualsSafe(
existing?.HostAddresses?.DecodeAsList());
if (!(hostsUpdate ?? true))
{
tags.Add(nameof(ApplicationRegistration.HostAddresses),
update?.HostAddresses == null ?
VariantValue.Null : serializer.FromObject(update.HostAddresses));
}
if (update?.CreateAuthorityId != existing?.CreateAuthorityId)
{
tags.Add(nameof(ApplicationRegistration.CreateAuthorityId),
update?.CreateAuthorityId);
}
if (update?.CreateTime != existing?.CreateTime)
{
tags.Add(nameof(ApplicationRegistration.CreateTime),
update?.CreateTime);
}
if (update?.UpdateAuthorityId != existing?.UpdateAuthorityId)
{
tags.Add(nameof(ApplicationRegistration.UpdateAuthorityId),
update?.UpdateAuthorityId);
}
if (update?.UpdateTime != existing?.UpdateTime)
{
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) ??
(update?.SiteOrGatewayId) ?? EntityRegistration.UnknownGatewayOrSiteId;
var applicationType = existing?.ApplicationType;
if (update?.ApplicationType != null)
{
applicationType = update?.ApplicationType ?? ApplicationType.Server;
}
var id = ApplicationInfoModelEx.CreateApplicationId(
siteOrGatewayId, applicationUri, applicationType);
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
};
}