/// <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);
        }
Example #2
0
 /// <summary>
 /// Returns true if this registration matches the server endpoint
 /// model provided.
 /// </summary>
 /// <param name="registration"></param>
 /// <param name="model"></param>
 /// <returns></returns>
 public static bool Matches(this EndpointRegistration registration, EndpointInfoModel model)
 {
     return(model != null &&
            registration.Matches(model.Registration?.Endpoint) &&
            registration.NotSeenSince == model.NotSeenSince &&
            registration.ApplicationId == model.ApplicationId &&
            (registration.ActivationState ?? EndpointActivationState.Deactivated) ==
            (model.ActivationState ?? EndpointActivationState.Deactivated));
 }
Example #3
0
 /// <summary>
 /// Returns true if this registration matches the endpoint
 /// model provided.
 /// </summary>
 /// <param name="registration"></param>
 /// <param name="endpoint"></param>
 /// <returns></returns>
 public static bool Matches(this EndpointRegistration registration, EndpointModel endpoint)
 {
     return(endpoint != null &&
            registration.EndpointUrl == endpoint.Url &&
            registration.AlternativeUrls.DecodeAsList().ToHashSetSafe().SetEqualsSafe(
                endpoint.AlternativeUrls) &&
            registration.SecurityMode == (endpoint.SecurityMode ?? SecurityMode.Best) &&
            registration.SecurityPolicy == endpoint.SecurityPolicy &&
            endpoint.Certificate.SequenceEqualsSafe(
                registration.Certificate.DecodeAsByteArray()));
 }
        public void TestEqualIsEqualWithDeviceModel()
        {
            var r1 = CreateRegistration();
            var m  = EndpointRegistration.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);
        }
        public void TestEqualIsNotEqualWithServiceModelConversionWhenDisabled()
        {
            var r1 = CreateRegistration();
            var m  = r1.ToServiceModel();
            var r2 = EndpointRegistration.FromServiceModel(m, true);

            Assert.NotEqual(r1, r2);
            Assert.NotEqual(r1.GetHashCode(), r2.GetHashCode());
            Assert.True(r1 != r2);
            Assert.False(r1 == r2);
        }
 /// <summary>
 /// Flag endpoint as synchronized - i.e. it matches the other.
 /// </summary>
 /// <param name="registration"></param>
 /// <param name="other"></param>
 internal static bool IsInSyncWith(this EndpointRegistration registration,
                                   EndpointRegistration other)
 {
     return
         (other != null &&
          registration.EndpointUrl == other.EndpointUrl &&
          registration.AlternativeUrls.DecodeAsList().ToHashSetSafe().SetEqualsSafe(
              other.AlternativeUrls.DecodeAsList()) &&
          registration.SecurityPolicy == other.SecurityPolicy &&
          registration.SecurityMode == other.SecurityMode &&
          registration.Certificate.DecodeAsByteArray().SequenceEqualsSafe(
              other.Certificate.DecodeAsByteArray()));
 }
        public void TestEqualIsNotEqualWithDeviceModel()
        {
            var r1 = CreateRegistration();
            var m  = EndpointRegistration.Patch(null, r1);

            m.Properties.Desired["Credential"] = "password";
            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.Registration.Endpoint.SecurityPolicy = "";
            var r2 = EndpointRegistration.FromServiceModel(m);

            Assert.NotEqual(r1, r2);
            Assert.NotEqual(r1.GetHashCode(), r2.GetHashCode());
            Assert.True(r1 != r2);
            Assert.False(r1 == r2);
        }
 /// <summary>
 /// Flag endpoint as synchronized - i.e. it matches the other.
 /// </summary>
 /// <param name="registration"></param>
 /// <param name="other"></param>
 internal static bool IsInSyncWith(this EndpointRegistration registration,
                                   EndpointRegistration other)
 {
     if (registration == null)
     {
         return(other == null);
     }
     return
         (other != null &&
          registration.EndpointUrl == other.EndpointUrl &&
          registration.AlternativeUrls.DecodeAsList().ToHashSetSafe().SetEqualsSafe(
              other.AlternativeUrls.DecodeAsList()) &&
          registration.SecurityPolicy == other.SecurityPolicy &&
          registration.SecurityMode == other.SecurityMode &&
          registration.Thumbprint == other.Thumbprint);
 }
 /// <summary>
 /// Flag endpoint as synchronized - i.e. it matches the other.
 /// </summary>
 /// <param name="other"></param>
 internal void MarkAsInSyncWith(EndpointRegistration other)
 {
     _isInSync =
         other != null &&
         EndpointUrl == other.EndpointUrl &&
         AlternativeUrls.DecodeAsList().ToHashSetSafe().SetEqualsSafe(
             other.AlternativeUrls.DecodeAsList()) &&
         CredentialType == other.CredentialType &&
         JToken.DeepEquals(Credential, other.Credential) &&
         SecurityPolicy == other.SecurityPolicy &&
         SecurityMode == other.SecurityMode &&
         ClientCertificate.DecodeAsByteArray().SequenceEqualsSafe(
             other.ClientCertificate.DecodeAsByteArray()) &&
         ServerThumbprint.DecodeAsByteArray().SequenceEqualsSafe(
             other.ServerThumbprint.DecodeAsByteArray());
 }
        public void TestEqualIsEqualWithDeviceModelWhenDisabled()
        {
            var fix = new Fixture();

            var r1 = CreateRegistration();
            var r2 = EndpointRegistration.FromServiceModel(
                r1.ToServiceModel(), true);
            var m1 = EndpointRegistration.Patch(r1, r2);
            var r3 = EndpointRegistration.FromServiceModel(
                r2.ToServiceModel(), false);
            var m2 = EndpointRegistration.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)]);
        }
Example #12
0
        /// <summary>
        /// Get site or gateway id from registration
        /// </summary>
        /// <param name="registration"></param>
        /// <returns></returns>
        public static string GetSiteOrGatewayId(this EndpointRegistration registration)
        {
            if (registration == null)
            {
                return(null);
            }
            var siteOrGatewayId = registration?.SiteId;

            if (siteOrGatewayId == null)
            {
                var id = registration?.DiscovererId ?? registration?.SupervisorId;
                if (id != null)
                {
                    siteOrGatewayId = DiscovererModelEx.ParseDeviceId(id, out _);
                }
            }
            return(siteOrGatewayId);
        }
Example #13
0
 /// <summary>
 /// Convert to service model
 /// </summary>
 /// <param name="registration"></param>
 /// <returns></returns>
 public static EndpointInfoModel ToServiceModel(this EndpointRegistration registration)
 {
     if (registration == null)
     {
         return(null);
     }
     return(new EndpointInfoModel {
         ApplicationId = registration.ApplicationId,
         Registration = new EndpointRegistrationModel {
             Id = registration.DeviceId,
             SiteId = string.IsNullOrEmpty(registration.SiteId) ?
                      null : registration.SiteId,
             SupervisorId = string.IsNullOrEmpty(registration.SupervisorId) ?
                            null : registration.SupervisorId,
             DiscovererId = string.IsNullOrEmpty(registration.DiscovererId) ?
                            null : registration.DiscovererId,
             AuthenticationMethods = registration.AuthenticationMethods?.DecodeAsList(j =>
                                                                                      j.ToObject <AuthenticationMethodModel>()),
             SecurityLevel = registration.SecurityLevel,
             EndpointUrl = string.IsNullOrEmpty(registration.EndpointRegistrationUrl) ?
                           (string.IsNullOrEmpty(registration.EndpointUrl) ?
                            registration.EndpointUrlLC : registration.EndpointUrl) : registration.EndpointRegistrationUrl,
             Endpoint = new EndpointModel {
                 Url = string.IsNullOrEmpty(registration.EndpointUrl) ?
                       registration.EndpointUrlLC : registration.EndpointUrl,
                 AlternativeUrls = registration.AlternativeUrls?.DecodeAsList().ToHashSetSafe(),
                 SecurityMode = registration.SecurityMode == SecurityMode.Best ?
                                null : registration.SecurityMode,
                 SecurityPolicy = string.IsNullOrEmpty(registration.SecurityPolicy) ?
                                  null : registration.SecurityPolicy,
                 Certificate = registration.Certificate.DecodeAsByteArray()
             }
         },
         ActivationState = registration.ActivationState,
         NotSeenSince = registration.NotSeenSince,
         EndpointState = registration.ActivationState == EndpointActivationState.ActivatedAndConnected ?
                         (registration.State == EndpointConnectivityState.Disconnected ?
                          EndpointConnectivityState.Connecting : registration.State) :
                         EndpointConnectivityState.Disconnected,
         OutOfSync = registration.Connected && !registration._isInSync ? true : (bool?)null
     });
 }
        /// <summary>
        /// Create patch twin model to upload
        /// </summary>
        /// <param name="existing"></param>
        /// <param name="update"></param>
        public static DeviceTwinModel Patch(this EndpointRegistration existing,
                                            EndpointRegistration update)
        {
            var twin = BaseRegistrationEx.PatchBase(existing, update);

            // Tags

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

            if (update?.SecurityLevel != existing?.SecurityLevel)
            {
                twin.Tags.Add(nameof(EndpointRegistration.SecurityLevel), update?.SecurityLevel == null ?
                              null : JToken.FromObject(update?.SecurityLevel));
            }

            if (update?.Activated != null &&
                update.Activated != existing?.Activated)
            {
                twin.Tags.Add(nameof(EndpointRegistration.Activated), update?.Activated);
            }

            var methodEqual = update?.AuthenticationMethods.DecodeAsList().SetEqualsSafe(
                existing?.AuthenticationMethods?.DecodeAsList(), JToken.DeepEquals);

            if (!(methodEqual ?? true))
            {
                twin.Tags.Add(nameof(EndpointRegistration.AuthenticationMethods),
                              update?.AuthenticationMethods == null ?
                              null : JToken.FromObject(update.AuthenticationMethods,
                                                       new JsonSerializer {
                    NullValueHandling = NullValueHandling.Ignore
                }));
            }

            // Endpoint Property

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

            var urlsEqual = update?.AlternativeUrls.DecodeAsList().ToHashSetSafe().SetEqualsSafe(
                existing?.AlternativeUrls?.DecodeAsList());

            if (!(urlsEqual ?? true))
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.AlternativeUrls),
                                            update?.AlternativeUrls == null ?
                                            null : JToken.FromObject(update.AlternativeUrls));
            }

            if (update?.SecurityMode != null &&
                update.SecurityMode != existing?.SecurityMode)
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.SecurityMode),
                                            JToken.FromObject(update.SecurityMode));
            }

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

            if (update?.CredentialType != existing?.CredentialType)
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.CredentialType),
                                            update?.CredentialType == null ?
                                            null : JToken.FromObject(update?.CredentialType));
            }

            if (!JToken.DeepEquals(update?.Credential, existing?.Credential))
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.Credential),
                                            update?.Credential);
            }

            var certEqual = update?.Certificate.DecodeAsByteArray().SequenceEqualsSafe(
                existing?.Certificate.DecodeAsByteArray());

            if (update?.Certificate != null && !(certEqual ?? true))
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.Certificate),
                                            update?.Certificate == null ?
                                            null : JToken.FromObject(update.Certificate));
            }

            // 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;
            }

            twin.Id = EndpointInfoModelEx.CreateEndpointId(
                applicationId, reportedEndpointUrl, securityMode, securityPolicy);

            if (existing?.DeviceId != twin.Id)
            {
                twin.Etag = null; // Force creation of new identity
            }
            return(twin);
        }
Example #15
0
        /// <summary>
        /// Create patch twin model to upload
        /// </summary>
        /// <param name="existing"></param>
        /// <param name="update"></param>
        public static DeviceTwinModel Patch(this EndpointRegistration existing,
                                            EndpointRegistration update)
        {
            var twin = new DeviceTwinModel {
                Etag       = existing?.Etag,
                Tags       = new Dictionary <string, JToken>(),
                Properties = new TwinPropertiesModel {
                    Desired = new Dictionary <string, JToken>()
                }
            };

            // 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?.SupervisorId != existing?.SupervisorId)
            {
                twin.Tags.Add(nameof(EndpointRegistration.SupervisorId), update?.SupervisorId);
            }

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

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

            var certUpdate = update?.Certificate.DecodeAsByteArray().SequenceEqualsSafe(
                existing?.Certificate.DecodeAsByteArray());

            if (!(certUpdate ?? true))
            {
                twin.Tags.Add(nameof(EntityRegistration.Certificate), update?.Certificate == null ?
                              null : JToken.FromObject(update.Certificate));
                twin.Tags.Add(nameof(EntityRegistration.Thumbprint),
                              update?.Certificate?.DecodeAsByteArray()?.ToSha1Hash());
            }

            twin.Tags.Add(nameof(EntityRegistration.DeviceType), update?.DeviceType);


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

            if (update?.SecurityLevel != existing?.SecurityLevel)
            {
                twin.Tags.Add(nameof(EndpointRegistration.SecurityLevel), update?.SecurityLevel == null ?
                              null : JToken.FromObject(update?.SecurityLevel));
            }

            if (update?.Activated != null &&
                update.Activated != existing?.Activated)
            {
                twin.Tags.Add(nameof(EndpointRegistration.Activated), update?.Activated);
            }

            var methodEqual = update?.AuthenticationMethods.DecodeAsList().SetEqualsSafe(
                existing?.AuthenticationMethods?.DecodeAsList(), JToken.DeepEquals);

            if (!(methodEqual ?? true))
            {
                twin.Tags.Add(nameof(EndpointRegistration.AuthenticationMethods),
                              update?.AuthenticationMethods == null ?
                              null : JToken.FromObject(update.AuthenticationMethods,
                                                       new JsonSerializer {
                    NullValueHandling = NullValueHandling.Ignore
                }));
            }

            // Endpoint Property

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

            var urlsEqual = update?.AlternativeUrls.DecodeAsList().ToHashSetSafe().SetEqualsSafe(
                existing?.AlternativeUrls?.DecodeAsList());

            if (!(urlsEqual ?? true))
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.AlternativeUrls),
                                            update?.AlternativeUrls == null ?
                                            null : JToken.FromObject(update.AlternativeUrls));
            }

            if (update?.SecurityMode != null &&
                update.SecurityMode != existing?.SecurityMode)
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.SecurityMode),
                                            JToken.FromObject(update.SecurityMode));
            }

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

            var certEqual = update?.Certificate.DecodeAsByteArray().SequenceEqualsSafe(
                existing?.Certificate.DecodeAsByteArray());

            if (update?.Certificate != null && !(certEqual ?? true))
            {
                twin.Properties.Desired.Add(nameof(EndpointRegistration.Certificate),
                                            update?.Certificate == null ?
                                            null : JToken.FromObject(update.Certificate));
            }

            // 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;
            }

            twin.Id = EndpointInfoModelEx.CreateEndpointId(
                applicationId, reportedEndpointUrl, securityMode, securityPolicy);

            if (existing?.DeviceId != twin.Id)
            {
                twin.Etag = null; // Force creation of new identity
            }
            return(twin);
        }
 /// <summary>
 /// Create device twin
 /// </summary>
 /// <param name="registration"></param>
 /// <param name="serializer"></param>
 /// <returns></returns>
 public static DeviceTwinModel ToDeviceTwin(this EndpointRegistration registration,
                                            IJsonSerializer serializer)
 {
     return(Patch(null, registration, serializer));
 }
Example #17
0
 /// <summary>
 /// Create device twin
 /// </summary>
 /// <param name="registration"></param>
 /// <returns></returns>
 public static DeviceTwinModel ToDeviceTwin(this EndpointRegistration registration)
 {
     return(Patch(null, registration));
 }
Example #18
0
        /// <summary>
        /// Decode tags and property into registration object
        /// </summary>
        /// <param name="twin"></param>
        /// <param name="properties"></param>
        /// <returns></returns>
        public static EndpointRegistration ToEndpointRegistration(this DeviceTwinModel twin,
                                                                  Dictionary <string, JToken> properties)
        {
            if (twin == null)
            {
                return(null);
            }

            var tags      = twin.Tags ?? new Dictionary <string, JToken>();
            var connected = twin.IsConnected();

            var registration = new EndpointRegistration {
                // Device

                DeviceId = twin.Id,
                Etag     = twin.Etag,

                // Tags
                IsDisabled =
                    tags.GetValueOrDefault(nameof(EndpointRegistration.IsDisabled), twin.IsDisabled()),
                NotSeenSince =
                    tags.GetValueOrDefault <DateTime>(nameof(EndpointRegistration.NotSeenSince), null),

                Thumbprint =
                    tags.GetValueOrDefault <string>(nameof(EndpointRegistration.Thumbprint), null),
                SupervisorId =
                    tags.GetValueOrDefault <string>(nameof(EndpointRegistration.SupervisorId), null),
                DiscovererId =
                    tags.GetValueOrDefault <string>(nameof(EndpointRegistration.DiscovererId),
                                                    tags.GetValueOrDefault <string>(nameof(EndpointRegistration.SupervisorId), null)),
                Activated =
                    tags.GetValueOrDefault <bool>(nameof(EndpointRegistration.Activated), null),
                ApplicationId =
                    tags.GetValueOrDefault <string>(nameof(EndpointRegistration.ApplicationId), null),
                SecurityLevel =
                    tags.GetValueOrDefault <int>(nameof(EndpointRegistration.SecurityLevel), null),
                AuthenticationMethods =
                    tags.GetValueOrDefault <Dictionary <string, JToken> >(nameof(EndpointRegistration.AuthenticationMethods), null),
                EndpointRegistrationUrl =
                    tags.GetValueOrDefault <string>(nameof(EndpointRegistration.EndpointRegistrationUrl), null),

                // Properties

                Connected = connected ??
                            properties.GetValueOrDefault(TwinProperty.Connected, false),
                Type =
                    properties.GetValueOrDefault <string>(TwinProperty.Type, null),
                State =
                    properties.GetValueOrDefault(nameof(EndpointRegistration.State), EndpointConnectivityState.Connecting),
                SiteId =
                    properties.GetValueOrDefault(TwinProperty.SiteId,
                                                 tags.GetValueOrDefault <string>(nameof(EndpointRegistration.SiteId), null)),
                EndpointUrl =
                    properties.GetValueOrDefault <string>(nameof(EndpointRegistration.EndpointUrl), null),
                AlternativeUrls =
                    properties.GetValueOrDefault <Dictionary <string, string> >(nameof(EndpointRegistration.AlternativeUrls), null),
                SecurityMode =
                    properties.GetValueOrDefault <SecurityMode>(nameof(EndpointRegistration.SecurityMode), null),
                SecurityPolicy =
                    properties.GetValueOrDefault <string>(nameof(EndpointRegistration.SecurityPolicy), null),
                Certificate =
                    properties.GetValueOrDefault <Dictionary <string, string> >(nameof(EndpointRegistration.Certificate), null),
            };

            return(registration);
        }