/// <summary> /// Create subscription from template /// </summary> /// <param name="outer"></param> /// <param name="dataSetWriter"></param> public DataSetWriterSubscription(WriterGroupMessageTrigger outer, DataSetWriterModel dataSetWriter) { _outer = outer ?? throw new ArgumentNullException(nameof(outer)); _dataSetWriter = dataSetWriter.Clone() ?? throw new ArgumentNullException(nameof(dataSetWriter)); _subscriptionInfo = _dataSetWriter.ToSubscriptionModel(); if (dataSetWriter.KeyFrameInterval.HasValue && dataSetWriter.KeyFrameInterval.Value > TimeSpan.Zero) { _keyframeTimer = new Timer( dataSetWriter.KeyFrameInterval.Value.TotalMilliseconds); _keyframeTimer.Elapsed += KeyframeTimerElapsedAsync; } else { _keyFrameCount = dataSetWriter.KeyFrameCount; } if (dataSetWriter.DataSetMetaDataSendInterval.HasValue && dataSetWriter.DataSetMetaDataSendInterval.Value > TimeSpan.Zero) { _metaData = dataSetWriter.DataSet?.DataSetMetaData ?? throw new ArgumentNullException(nameof(dataSetWriter.DataSet)); _metadataTimer = new Timer( dataSetWriter.DataSetMetaDataSendInterval.Value.TotalMilliseconds); _metadataTimer.Elapsed += MetadataTimerElapsed; } }
/// <summary> /// /// Initializes the Metadata triggering mechanism from the cconfiguration model /// </summary> private void InitializeMetaDataTrigger(DataSetWriterModel dataSetWriter) { var metaDataSendInterval = dataSetWriter.DataSetMetaDataSendInterval .GetValueOrDefault(TimeSpan.Zero) .TotalMilliseconds; if (metaDataSendInterval > 0) { _metaData = dataSetWriter.DataSet?.DataSetMetaData ?? throw new ArgumentNullException(nameof(dataSetWriter.DataSet)); if (_metadataTimer == null) { _metadataTimer = new Timer(metaDataSendInterval); _metadataTimer.Elapsed += MetadataTimerElapsed; } else { _metadataTimer.Interval = metaDataSendInterval; } } else { if (_metadataTimer != null) { _metadataTimer.Stop(); _metadataTimer.Dispose(); _metadataTimer = null; } } }
/// <summary> /// Initializes the key frame triggering mechanism from the cconfiguration model /// </summary> private void InitializeKeyframeTrigger(DataSetWriterModel dataSetWriter) { var keyframeTriggerInterval = dataSetWriter.KeyFrameInterval .GetValueOrDefault(TimeSpan.Zero) .TotalMilliseconds; if (keyframeTriggerInterval > 0) { if (_keyframeTimer == null) { _keyframeTimer = new Timer(keyframeTriggerInterval); _keyframeTimer.Elapsed += KeyframeTimerElapsedAsync; } else { _keyframeTimer.Interval = keyframeTriggerInterval; } } else { if (_keyframeTimer != null) { _keyframeTimer.Stop(); _keyframeTimer.Dispose(); _keyframeTimer = null; } _keyFrameCount = dataSetWriter.KeyFrameCount; } }
/// <summary> /// Create subscription from a DataSetWriterModel template /// </summary> public DataSetWriterSubscription(WriterGroupMessageTrigger outer, DataSetWriterModel dataSetWriter, IWriterGroupConfig writerGroup) { _outer = outer ?? throw new ArgumentNullException(nameof(outer)); _dataSetWriter = dataSetWriter?.Clone() ?? throw new ArgumentNullException(nameof(dataSetWriter)); _subscriptionInfo = _dataSetWriter.ToSubscriptionModel(writerGroup); InitializeKeyframeTrigger(dataSetWriter); InitializeMetaDataTrigger(dataSetWriter); }
/// <summary> /// Create api model from service model /// </summary> /// <param name="model"></param> public DataSetWriterApiModel(DataSetWriterModel model) { if (model == null) { throw new ArgumentNullException(nameof(model)); } DataSetWriterId = model.DataSetWriterId; DataSet = model.DataSet == null ? null : new PublishedDataSetApiModel(model.DataSet); DataSetFieldContentMask = model.DataSetFieldContentMask; MessageSettings = model.MessageSettings == null ? null : new DataSetWriterMessageSettingsApiModel(model.MessageSettings); KeyFrameInterval = model.KeyFrameInterval; DataSetMetaDataSendInterval = model.DataSetMetaDataSendInterval; KeyFrameCount = model.KeyFrameCount; }
/// <summary> /// Clone /// </summary> /// <param name="model"></param> /// <returns></returns> public static DataSetWriterModel Clone(this DataSetWriterModel model) { if (model == null) { return(null); } return(new DataSetWriterModel { DataSet = model.DataSet.Clone(), DataSetFieldContentMask = model.DataSetFieldContentMask, DataSetMetaDataSendInterval = model.DataSetMetaDataSendInterval, DataSetWriterId = model.DataSetWriterId, KeyFrameCount = model.KeyFrameCount, KeyFrameInterval = model.KeyFrameInterval, MessageSettings = model.MessageSettings.Clone() }); }
/// <summary> /// Add or update item in job /// </summary> /// <param name="publishJob"></param> /// <param name="publishedItem"></param> /// <param name="endpointId"></param> /// <param name="connection"></param> private void AddOrUpdateItemInJob(WriterGroupJobModel publishJob, PublishedItemModel publishedItem, string endpointId, ConnectionModel connection) { // Simple - first remove - then add. RemoveItemFromJob(publishJob, publishedItem.NodeId, connection); // Find existing subscription we can add node to List <PublishedDataSetVariableModel> variables = null; foreach (var writer in publishJob.WriterGroup.DataSetWriters) { if (writer.DataSet.DataSetSource.Connection.IsSameAs(connection) && writer.DataSet.DataSetSource.SubscriptionSettings?.PublishingInterval == publishedItem.PublishingInterval) { System.Diagnostics.Debug.Assert(writer.DataSet.DataSetSource.PublishedVariables.PublishedData != null); variables = writer.DataSet.DataSetSource.PublishedVariables.PublishedData; writer.DataSet.DataSetMetaData.ConfigurationVersion.MinorVersion++; break; } } if (variables == null) { // No writer found - add new one with a published dataset var dataSetWriter = new DataSetWriterModel { DataSetWriterId = GetDefaultId(endpointId), DataSet = new PublishedDataSetModel { Name = null, DataSetMetaData = new DataSetMetaDataModel { ConfigurationVersion = new ConfigurationVersionModel { MajorVersion = 1, MinorVersion = 0 }, DataSetClassId = Guid.NewGuid(), Name = endpointId }, ExtensionFields = new Dictionary <string, string> { ["EndpointId"] = endpointId }, DataSetSource = new PublishedDataSetSourceModel { Connection = connection, PublishedEvents = null, PublishedVariables = new PublishedDataItemsModel { PublishedData = new List <PublishedDataSetVariableModel>() }, SubscriptionSettings = new PublishedDataSetSettingsModel { PublishingInterval = publishedItem.PublishingInterval, // ... } } }, MessageSettings = null, KeyFrameCount = null, DataSetFieldContentMask = null, DataSetMetaDataSendInterval = null, KeyFrameInterval = null }; variables = dataSetWriter.DataSet.DataSetSource.PublishedVariables.PublishedData; publishJob.WriterGroup.DataSetWriters.Add(dataSetWriter); } // Add to published variable list items variables.Add(new PublishedDataSetVariableModel { SamplingInterval = publishedItem.SamplingInterval, PublishedVariableNodeId = publishedItem.NodeId }); }
/// <summary> /// Add or update item in job /// </summary> /// <param name="publishJob"></param> /// <param name="publishedItem"></param> /// <param name="endpointId"></param> /// <param name="publisherId"></param> /// <param name="connection"></param> /// <param name="dataSetWriterName"></param> private void AddOrUpdateItemInJob(WriterGroupJobModel publishJob, PublishedItemModel publishedItem, string endpointId, string publisherId, ConnectionModel connection, string dataSetWriterName = null) { var dataSetWriterId = (string.IsNullOrEmpty(dataSetWriterName) ? GetDefaultId(endpointId) : dataSetWriterName) + (publishedItem.PublishingInterval.HasValue ? ('_' + publishedItem.PublishingInterval.Value.TotalMilliseconds.ToString()) : String.Empty); // Simple - first remove - then add. RemoveItemFromJob(publishJob, publishedItem.NodeId, connection); // Find existing subscription we can add node to List <PublishedDataSetVariableModel> variables = null; foreach (var writer in publishJob.WriterGroup.DataSetWriters) { if (writer.DataSet.DataSetSource.Connection.IsSameAs(connection) && writer.DataSetWriterId == dataSetWriterId) { System.Diagnostics.Debug.Assert(writer.DataSet.DataSetSource.PublishedVariables.PublishedData != null); variables = writer.DataSet.DataSetSource.PublishedVariables.PublishedData; writer.DataSet.DataSetMetaData.ConfigurationVersion.MinorVersion++; break; } } if (variables == null) { // No writer found - add new one with a published dataset var dataSetWriter = new DataSetWriterModel { DataSetWriterId = dataSetWriterId, DataSet = new PublishedDataSetModel { Name = null, DataSetMetaData = new DataSetMetaDataModel { ConfigurationVersion = new ConfigurationVersionModel { MajorVersion = 1, MinorVersion = 0 }, DataSetClassId = Guid.NewGuid(), Name = endpointId }, ExtensionFields = new Dictionary <string, string> { ["EndpointId"] = endpointId, ["PublisherId"] = publisherId, // todo, probably not needed ["DataSetWriterId"] = dataSetWriterId }, DataSetSource = new PublishedDataSetSourceModel { Connection = connection, PublishedEvents = null, PublishedVariables = new PublishedDataItemsModel { PublishedData = new List <PublishedDataSetVariableModel>() }, SubscriptionSettings = new PublishedDataSetSettingsModel { PublishingInterval = publishedItem.PublishingInterval, ResolveDisplayName = true // ... } } }, DataSetFieldContentMask = DataSetFieldContentMask.StatusCode | DataSetFieldContentMask.SourceTimestamp | DataSetFieldContentMask.ServerTimestamp | DataSetFieldContentMask.NodeId | DataSetFieldContentMask.DisplayName | DataSetFieldContentMask.ApplicationUri | DataSetFieldContentMask.EndpointUrl | DataSetFieldContentMask.ExtensionFields, MessageSettings = new DataSetWriterMessageSettingsModel() { DataSetMessageContentMask = DataSetContentMask.Timestamp | DataSetContentMask.MetaDataVersion | DataSetContentMask.Status | DataSetContentMask.DataSetWriterId | DataSetContentMask.MajorVersion | DataSetContentMask.MinorVersion | DataSetContentMask.SequenceNumber }, // TODO provide default settings KeyFrameCount = null, DataSetMetaDataSendInterval = null, KeyFrameInterval = null }; variables = dataSetWriter.DataSet.DataSetSource.PublishedVariables.PublishedData; publishJob.WriterGroup.DataSetWriters.Add(dataSetWriter); } // Add to published variable list items variables.Add(new PublishedDataSetVariableModel { SamplingInterval = publishedItem.SamplingInterval, PublishedVariableNodeId = publishedItem.NodeId, PublishedVariableDisplayName = publishedItem.DisplayName, HeartbeatInterval = publishedItem.HeartbeatInterval, QueueSize = 1, }); }