/// <summary>
        /// Decode tags and property into registration object
        /// </summary>
        /// <param name="twin"></param>
        /// <param name="properties"></param>
        /// <returns></returns>
        public static PublisherRegistration ToPublisherRegistration(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 PublisherRegistration {
                // Device

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

                // Tags

                IsDisabled =
                    tags.GetValueOrDefault <bool>(nameof(PublisherRegistration.IsDisabled), null),
                NotSeenSince =
                    tags.GetValueOrDefault <DateTime>(nameof(PublisherRegistration.NotSeenSince), null),
                Thumbprint =
                    tags.GetValueOrDefault <string>(nameof(PublisherRegistration.Thumbprint), null),

                // Properties

                Certificate =
                    properties.GetValueOrDefault <Dictionary <string, string> >(nameof(PublisherRegistration.Certificate), null),
                LogLevel =
                    properties.GetValueOrDefault <TraceLogLevel>(nameof(PublisherRegistration.LogLevel), null),
                JobOrchestratorUrl =
                    properties.GetValueOrDefault <string>(nameof(PublisherRegistration.JobOrchestratorUrl), null),
                JobCheckInterval =
                    properties.GetValueOrDefault <TimeSpan>(nameof(PublisherRegistration.JobCheckInterval), null),
                MaxWorkers =
                    properties.GetValueOrDefault <int>(nameof(PublisherRegistration.MaxWorkers), null),
                HeartbeatInterval =
                    properties.GetValueOrDefault <TimeSpan>(nameof(PublisherRegistration.HeartbeatInterval), null),
                Capabilities =
                    properties.GetValueOrDefault <Dictionary <string, string> >(nameof(PublisherRegistration.Capabilities), null),

                SiteId =
                    properties.GetValueOrDefault <string>(TwinProperty.SiteId, null),
                Connected = connected ??
                            properties.GetValueOrDefault(TwinProperty.Connected, false),
                Type =
                    properties.GetValueOrDefault <string>(TwinProperty.Type, null)
            };

            return(registration);
        }
 /// <summary>
 /// Convert to service model
 /// </summary>
 /// <param name="registration"></param>
 /// <returns></returns>
 public static PublisherModel ToServiceModel(this PublisherRegistration registration)
 {
     return(new PublisherModel {
         Id = PublisherModelEx.CreatePublisherId(registration.DeviceId, registration.ModuleId),
         SiteId = registration.SiteId,
         Certificate = registration.Certificate?.DecodeAsByteArray(),
         LogLevel = registration.LogLevel,
         Configuration = registration.ToConfigModel(),
         Connected = registration.IsConnected() ? true : (bool?)null,
         OutOfSync = registration.IsConnected() && !registration._isInSync ? true : (bool?)null
     });
 }
예제 #3
0
 /// <summary>
 /// Returns config model
 /// </summary>
 /// <param name="registration"></param>
 /// <returns></returns>
 private static PublisherConfigModel ToConfigModel(this PublisherRegistration registration)
 {
     return(registration.IsNullConfig() ? null : new PublisherConfigModel {
         JobOrchestratorUrl = registration.JobOrchestratorUrl,
         MaxWorkers = registration.MaxWorkers == 1 ? null : registration.MaxWorkers,
         JobCheckInterval = registration.JobCheckInterval == Timeout.InfiniteTimeSpan ?
                            null : registration.JobCheckInterval,
         HeartbeatInterval = registration.HeartbeatInterval == Timeout.InfiniteTimeSpan ?
                             null : registration.HeartbeatInterval,
         Capabilities = registration.Capabilities?
                        .ToDictionary(k => k.Key, v => v.Value)
     });
 }
예제 #4
0
 /// <summary>
 /// Returns if no discovery config specified
 /// </summary>
 /// <param name="registration"></param>
 /// <returns></returns>
 private static bool IsNullConfig(this PublisherRegistration registration)
 {
     if (string.IsNullOrEmpty(registration.JobOrchestratorUrl) &&
         (registration.MaxWorkers == null || registration.MaxWorkers == 1) &&
         (registration.JobCheckInterval == null ||
          registration.JobCheckInterval == Timeout.InfiniteTimeSpan) &&
         (registration.Capabilities == null ||
          registration.Capabilities.Count == 0) &&
         (registration.HeartbeatInterval == null ||
          registration.HeartbeatInterval == Timeout.InfiniteTimeSpan))
     {
         return(true);
     }
     return(false);
 }
 /// <summary>
 /// Flag twin as synchronized - i.e. it matches the other.
 /// </summary>
 /// <param name="registration"></param>
 /// <param name="other"></param>
 internal static bool IsInSyncWith(this PublisherRegistration registration,
                                   PublisherRegistration other)
 {
     return
         (other != null &&
          registration.SiteId == other.SiteId &&
          registration.LogLevel == other.LogLevel &&
          registration.JobOrchestratorUrl == other.JobOrchestratorUrl &&
          (registration.MaxWorkers ?? 1) == (other.MaxWorkers ?? 1) &&
          (registration.JobCheckInterval ?? Timeout.InfiniteTimeSpan) ==
          (other.JobCheckInterval ?? Timeout.InfiniteTimeSpan) &&
          (registration.HeartbeatInterval ?? Timeout.InfiniteTimeSpan) ==
          (other.HeartbeatInterval ?? Timeout.InfiniteTimeSpan) &&
          registration.Capabilities.SetEqualsSafe(
              other.Capabilities, (x, y) => x.Key == y.Key && y.Value == x.Value));
 }
예제 #6
0
 /// <summary>
 /// Convert to service model
 /// </summary>
 /// <param name="registration"></param>
 /// <returns></returns>
 public static PublisherModel ToServiceModel(this PublisherRegistration registration)
 {
     if (registration == null)
     {
         return(null);
     }
     return(new PublisherModel {
         Id = PublisherModelEx.CreatePublisherId(registration.DeviceId, registration.ModuleId),
         SiteId = registration.SiteId,
         LogLevel = registration.LogLevel,
         Configuration = registration.ToConfigModel(),
         Version = registration.Version,
         Connected = registration.IsConnected() ? true : (bool?)null,
         OutOfSync = registration.IsConnected() && !registration._isInSync ? true : (bool?)null
     });
 }
예제 #7
0
        /// <summary>
        /// Create patch twin model to upload
        /// </summary>
        /// <param name="existing"></param>
        /// <param name="update"></param>
        /// <param name="serializer"></param>
        public static DeviceTwinModel Patch(this PublisherRegistration existing,
                                            PublisherRegistration 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?.IsDisabled != null && update.IsDisabled != existing?.IsDisabled)
            {
                twin.Tags.Add(nameof(PublisherRegistration.IsDisabled), (update?.IsDisabled ?? false) ?
                              true : (bool?)null);
                twin.Tags.Add(nameof(PublisherRegistration.NotSeenSince), (update?.IsDisabled ?? false) ?
                              DateTime.UtcNow : (DateTime?)null);
            }

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


            // Settings

            var capsUpdate = update?.Capabilities.SetEqualsSafe(
                existing?.Capabilities, (x, y) => x.Key == y.Key && y.Value == x.Value);

            if (!(capsUpdate ?? true))
            {
                twin.Properties.Desired.Add(nameof(PublisherRegistration.Capabilities),
                                            update?.Capabilities == null ?
                                            null : serializer.FromObject(update.Capabilities));
            }

            if (update?.JobOrchestratorUrl != existing?.JobOrchestratorUrl)
            {
                twin.Properties.Desired.Add(nameof(PublisherRegistration.JobOrchestratorUrl),
                                            update?.JobOrchestratorUrl);
            }
            if (update?.LogLevel != existing?.LogLevel)
            {
                twin.Properties.Desired.Add(nameof(PublisherRegistration.LogLevel),
                                            update?.LogLevel == null ?
                                            null : serializer.FromObject(update.LogLevel.ToString()));
            }


            if ((update?.JobCheckInterval ?? Timeout.InfiniteTimeSpan) !=
                (existing?.JobCheckInterval ?? Timeout.InfiniteTimeSpan))
            {
                twin.Properties.Desired.Add(nameof(PublisherRegistration.JobCheckInterval),
                                            update?.JobCheckInterval);
            }

            if ((update?.MaxWorkers ?? 1) != (existing?.MaxWorkers ?? 1))
            {
                twin.Properties.Desired.Add(nameof(PublisherRegistration.MaxWorkers),
                                            update?.MaxWorkers);
            }

            if ((update?.HeartbeatInterval ?? Timeout.InfiniteTimeSpan) !=
                (existing?.HeartbeatInterval ?? Timeout.InfiniteTimeSpan))
            {
                twin.Properties.Desired.Add(nameof(PublisherRegistration.HeartbeatInterval),
                                            update?.HeartbeatInterval);
            }

            if (update?.SiteId != existing?.SiteId)
            {
                twin.Properties.Desired.Add(TwinProperty.SiteId, update?.SiteId);
            }

            twin.Tags.Add(nameof(PublisherRegistration.DeviceType), update?.DeviceType);
            twin.Id       = update?.DeviceId ?? existing?.DeviceId;
            twin.ModuleId = update?.ModuleId ?? existing?.ModuleId;
            return(twin);
        }
예제 #8
0
 /// <summary>
 /// Create device twin
 /// </summary>
 /// <param name="registration"></param>
 /// <param name="serializer"></param>
 /// <returns></returns>
 public static DeviceTwinModel ToDeviceTwin(
     this PublisherRegistration registration, IJsonSerializer serializer)
 {
     return(Patch(null, registration, serializer));
 }
 /// <summary>
 /// Create device twin
 /// </summary>
 /// <param name="registration"></param>
 /// <returns></returns>
 public static DeviceTwinModel ToDeviceTwin(this PublisherRegistration registration)
 {
     return(Patch(null, registration));
 }