/// <summary>
 /// Compare items
 /// </summary>
 /// <param name="model"></param>
 /// <param name="other"></param>
 /// <returns></returns>
 public static bool IsSameAs(this SubscriptionConfigurationModel model,
                             SubscriptionConfigurationModel other)
 {
     if (model == null && other == null)
     {
         return(true);
     }
     if (model == null || other == null)
     {
         return(false);
     }
     if (model.PublishingInterval != other.PublishingInterval)
     {
         return(false);
     }
     if (model.LifetimeCount != other.LifetimeCount)
     {
         return(false);
     }
     if (model.KeepAliveCount != other.KeepAliveCount)
     {
         return(false);
     }
     if (model.MaxNotificationsPerPublish != other.MaxNotificationsPerPublish)
     {
         return(false);
     }
     if (model.Priority != other.Priority)
     {
         return(false);
     }
     return(true);
 }
예제 #2
0
            /// <inheritdoc/>
            public async Task ApplyAsync(IEnumerable <MonitoredItemModel> monitoredItems,
                                         SubscriptionConfigurationModel configuration)
            {
                await _lock.WaitAsync();

                try {
                    var rawSubscription = await GetSubscriptionAsync(configuration);

                    ReviseConfiguration(rawSubscription, configuration);

                    if (configuration?.ResolveDisplayName ?? false)
                    {
                        await ResolveDisplayName(rawSubscription, monitoredItems);
                    }

                    await SetMonitoredItemsAsync(rawSubscription, monitoredItems);
                }
                catch (ServiceResultException sre) {
                    // TODO: Convert to better exception
                    _logger.Error(sre, "Failed apply monitored items.");
                    await _outer._sessionManager.RemoveSessionAsync(Connection, false);

                    throw;
                }
                finally {
                    _lock.Release();
                }
            }
            /// <summary>
            /// Retrieve a raw subscription with all settings applied (no lock)
            /// </summary>
            /// <param name="configuration"></param>
            /// <returns></returns>
            private async Task <Subscription> GetSubscriptionAsync(
                SubscriptionConfigurationModel configuration = null)
            {
                var session = await _outer._sessionManager.GetOrCreateSessionAsync(Connection, true);

                if (session == null)
                {
                    return(null);
                }
                var subscription = session.Subscriptions.SingleOrDefault(s => s.Handle == this);

                if (subscription == null)
                {
                    if (configuration != null)
                    {
                        // Apply new configuration right here saving us from modifying later
                        _subscription.Configuration = configuration.Clone();
                    }

                    // calculate the KeepAliveCount
                    var revisedKeepAliveCount = _subscription.Configuration.KeepAliveCount ??
                                                session.DefaultSubscription.KeepAliveCount;
                    _subscription.MonitoredItems.ForEach(m => {
                        if (m.HeartbeatInterval != null && m.HeartbeatInterval != TimeSpan.Zero)
                        {
                            var itemKeepAliveCount = (uint)m.HeartbeatInterval.Value.TotalMilliseconds /
                                                     (uint)_subscription.Configuration.PublishingInterval.Value.TotalMilliseconds;
                            revisedKeepAliveCount = GreatCommonDivisor(revisedKeepAliveCount, itemKeepAliveCount);
                        }
                    });

                    subscription = new Subscription(session.DefaultSubscription)
                    {
                        Handle             = this,
                        PublishingInterval = (int)
                                             (_subscription.Configuration.PublishingInterval ?? TimeSpan.Zero).TotalMilliseconds,
                        DisplayName = Id,
                        MaxNotificationsPerPublish = _subscription.Configuration.MaxNotificationsPerPublish ?? 0,
                        PublishingEnabled          = true,
                        KeepAliveCount             = revisedKeepAliveCount,
                        LifetimeCount          = _subscription.Configuration.LifetimeCount ?? session.DefaultSubscription.LifetimeCount,
                        Priority               = _subscription.Configuration.Priority ?? session.DefaultSubscription.Priority,
                        TimestampsToReturn     = session.DefaultSubscription.TimestampsToReturn,
                        FastDataChangeCallback = OnSubscriptionDataChanged
                    };

                    session.AddSubscription(subscription);
                    subscription.Create();

                    _logger.Debug("Added subscription '{name}' to session '{session}'.",
                                  Id, session.SessionName);
                }
                else
                {
                    // Set configuration on original subscription
                    ReviseConfiguration(subscription, configuration);
                }
                return(subscription);
            }
 /// <summary>
 /// Clone
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 public static SubscriptionConfigurationModel Clone(this SubscriptionConfigurationModel model)
 {
     if (model == null)
     {
         return(null);
     }
     return(new SubscriptionConfigurationModel {
         PublishingInterval = model.PublishingInterval,
         LifetimeCount = model.LifetimeCount,
         KeepAliveCount = model.KeepAliveCount,
         MaxNotificationsPerPublish = model.MaxNotificationsPerPublish,
         Priority = model.Priority
     });
 }
            /// <summary>
            /// Retrieve a raw subscription with all settings applied (no lock)
            /// </summary>
            /// <param name="configuration"></param>
            /// <returns></returns>
            private async Task <Subscription> GetSubscriptionAsync(
                SubscriptionConfigurationModel configuration = null)
            {
                var session = await _outer._sessionManager.GetOrCreateSessionAsync(Connection, true);

                var subscription = session.Subscriptions.SingleOrDefault(s => s.Handle == this);

                if (subscription == null)
                {
                    if (configuration != null)
                    {
                        // Apply new configuration right here saving us from modifying later
                        _subscription.Configuration = configuration.Clone();
                    }

                    subscription = new Subscription(session.DefaultSubscription)
                    {
                        Handle             = this,
                        PublishingInterval = (int)
                                             (_subscription.Configuration.PublishingInterval ?? TimeSpan.Zero).TotalMilliseconds,
                        DisplayName                = Id,
                        KeepAliveCount             = _subscription.Configuration.KeepAliveCount ?? 10,
                        MaxNotificationsPerPublish = _subscription.Configuration.MaxNotificationsPerPublish ?? 0,
                        PublishingEnabled          = true,
                        Priority               = _subscription.Configuration.Priority ?? 0,
                        LifetimeCount          = _subscription.Configuration.LifetimeCount ?? 2400,
                        TimestampsToReturn     = TimestampsToReturn.Both,
                        FastDataChangeCallback = OnSubscriptionDataChanged

                                                 // MaxMessageCount = 10,
                    };

                    session.AddSubscription(subscription);
                    subscription.Create();

                    _logger.Debug("Added subscription '{name}' to session '{session}'.",
                                  Id, session.SessionName);
                }
                else
                {
                    // Set configuration on original subscription
                    ReviseConfiguration(subscription, configuration);
                }
                return(subscription);
            }
            /// <inheritdoc/>
            public async Task ApplyAsync(IEnumerable <MonitoredItemModel> monitoredItems,
                                         SubscriptionConfigurationModel configuration)
            {
                await _lock.WaitAsync();

                try {
                    var rawSubscription = await GetSubscriptionAsync(configuration);

                    if (rawSubscription == null)
                    {
                        throw new ResourceNotFoundException("Subscription not found");
                    }

                    ReviseConfiguration(rawSubscription, configuration);

                    if (monitoredItems == null)
                    {
                        // Apply currently monitoring
                        monitoredItems = _currentlyMonitored?.Select(m => m.Template);
                        if (monitoredItems == null)
                        {
                            return;
                        }
                    }

                    if (configuration?.ResolveDisplayName ?? false)
                    {
                        await ResolveDisplayNameAsync(monitoredItems);
                    }

                    await SetMonitoredItemsAsync(rawSubscription, monitoredItems);
                }
                catch (ServiceResultException sre) {
                    // TODO: Convert to better exception
                    _logger.Error(sre, "Failed apply monitored items.");
                    await _outer._sessionManager.RemoveSessionAsync(Connection, false);

                    throw;
                }
                finally {
                    _lock.Release();
                }
            }
            /// <summary>
            /// Synchronize subscription configuration
            /// </summary>
            /// <param name="rawSubscription"></param>
            /// <param name="configuration"></param>
            /// <returns></returns>
            private void ReviseConfiguration(Subscription rawSubscription,
                                             SubscriptionConfigurationModel configuration)
            {
                if (configuration == null)
                {
                    return;
                }

                var modifySubscription = false;

                if ((configuration?.PublishingInterval ?? TimeSpan.Zero) !=
                    (_subscription.Configuration?.PublishingInterval ?? TimeSpan.Zero))
                {
                    _logger.Debug(
                        "{subscription} Changing publishing interval from {old} to {new}",
                        _subscription.Id,
                        _subscription.Configuration?.PublishingInterval ?? TimeSpan.Zero,
                        configuration?.PublishingInterval ?? TimeSpan.Zero);
                    rawSubscription.PublishingInterval = (int)
                                                         (configuration?.PublishingInterval ?? TimeSpan.Zero).TotalMilliseconds;
                    modifySubscription = true;
                }
                if ((configuration?.KeepAliveCount ?? 0) !=
                    (_subscription.Configuration?.KeepAliveCount ?? 0))
                {
                    _logger.Debug(
                        "{subscription} Changing KeepAlive Count from {old} to {new}",
                        _subscription.Id, _subscription.Configuration?.KeepAliveCount ?? 0,
                        configuration?.KeepAliveCount ?? 0);
                    rawSubscription.KeepAliveCount = configuration?.KeepAliveCount ?? 0;
                    modifySubscription             = true;
                }
                if ((configuration?.LifetimeCount ?? 0) !=
                    (_subscription.Configuration?.LifetimeCount ?? 0))
                {
                    _logger.Debug(
                        "{subscription} Changing Lifetime Count from {old} to {new}",
                        _subscription.Id, _subscription.Configuration?.LifetimeCount ?? 0,
                        configuration?.LifetimeCount ?? 0);
                    rawSubscription.LifetimeCount = configuration?.LifetimeCount ?? 0;
                    modifySubscription            = true;
                }
                if ((configuration?.MaxNotificationsPerPublish ?? 0) !=
                    (_subscription.Configuration?.MaxNotificationsPerPublish ?? 0))
                {
                    _logger.Debug(
                        "{subscription} Changing Max NotificationsPerPublish from {old} to {new}",
                        _subscription.Id, _subscription.Configuration?.MaxNotificationsPerPublish ?? 0,
                        configuration?.MaxNotificationsPerPublish ?? 0);
                    rawSubscription.MaxNotificationsPerPublish =
                        configuration?.MaxNotificationsPerPublish ?? 0;
                    modifySubscription = true;
                }
                if ((configuration?.Priority ?? 0) !=
                    (_subscription.Configuration?.Priority ?? 0))
                {
                    _logger.Debug("{subscription} Changing Priority from {old} to {new}",
                                  _subscription.Id, _subscription.Configuration?.Priority ?? 0,
                                  configuration?.Priority ?? 0);
                    rawSubscription.Priority = configuration?.Priority ?? 0;
                    modifySubscription       = true;
                }

                if (modifySubscription)
                {
                    _subscription.Configuration = configuration.Clone();
                    rawSubscription.Modify();
                }
            }