/// <summary> /// Creates a new <see cref="TagDefinition"/> object. /// </summary> /// <param name="historian">The <see cref="IHistorian"/> instance that the tag belongs to.</param> /// <param name="id">The tag ID. If <see langword="null"/>, a new tag ID will ge generated automatically.</param> /// <param name="settings">The tag settings.</param> /// <param name="metadata">The tag metadata.</param> /// <param name="security">The tag security settings.</param> /// <param name="initialTagValues">The initial values to configure the tag's exception and compression filters with.</param> /// <param name="changeHistory">The change history for the tag.</param> /// <exception cref="ArgumentNullException"><paramref name="historian"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="settings"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="metadata"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="security"/> is <see langword="null"/>.</exception> /// <exception cref="ValidationException"><paramref name="settings"/> is not valid.</exception> protected TagDefinition(HistorianBase historian, string id, TagSettings settings, TagMetadata metadata, TagSecurity security, InitialTagValues initialTagValues, IEnumerable <TagChangeHistoryEntry> changeHistory) { _historian = historian ?? throw new ArgumentNullException(nameof(historian)); _historian.ThrowIfDisposed(); _logger = _historian.LoggerFactory?.CreateLogger <TagDefinition>(); if (settings == null) { throw new ArgumentNullException(nameof(settings)); } Validator.ValidateObject(settings, new ValidationContext(settings), true); Id = id ?? CreateTagId(); Name = settings.Name; Description = settings.Description; Units = settings.Units; DataType = settings.DataType; StateSet = settings.StateSet; Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); Security = security ?? throw new ArgumentNullException(nameof(security)); var exceptionFilterSettings = settings.ExceptionFilterSettings?.ToTagValueFilterSettings() ?? new TagValueFilterSettings(false, TagValueFilterDeviationType.Absolute, 0, TimeSpan.FromDays(1)); var compressionFilterSettings = settings.CompressionFilterSettings?.ToTagValueFilterSettings() ?? new TagValueFilterSettings(false, TagValueFilterDeviationType.Absolute, 0, TimeSpan.FromDays(1)); if (changeHistory != null) { _changeHistory.AddRange(changeHistory); } _snapshotValue = initialTagValues?.SnapshotValue; DataFilter = new DataFilter(Name, new ExceptionFilterState(exceptionFilterSettings, _snapshotValue), new CompressionFilterState(compressionFilterSettings, initialTagValues?.LastArchivedValue, initialTagValues?.LastExceptionValue, initialTagValues?.CompressionAngleMinimum ?? Double.NaN, initialTagValues?.CompressionAngleMaximum ?? Double.NaN), _historian.LoggerFactory); DataFilter.Emit += (values, nextArchiveCandidate) => { if (values.Length > 0 && _logger.IsEnabled(LogLevel.Trace)) { _logger.LogTrace($"[{Name}] Archiving {values.Count()} values emitted by the compression filter."); } _pendingArchiveWrites.Enqueue(new PendingArchiveWrite() { ArchiveValues = values, NextArchiveCandidate = nextArchiveCandidate }); _historian.TaskRunner.RunBackgroundTask(async ct => { if (Interlocked.CompareExchange(ref _archiveLock, 1, 0) != 0) { return; } try { while (!ct.IsCancellationRequested && _pendingArchiveWrites.TryDequeue(out var item)) { await InsertArchiveValuesInternal(ClaimsPrincipal.Current, item.ArchiveValues, item.NextArchiveCandidate, false, ct).ConfigureAwait(false); } } catch (OperationCanceledException) { // App is shutting down... } catch (Exception e) { _logger?.LogError($"[{Name}] An error occurred while archiving values emitted by the compression filter.", e); } finally { _archiveLock = 0; } }); }; }
/// <summary> /// Creates a new <see cref="ElasticsearchTagDefinition"/> object. /// </summary> /// <param name="historian">The owning historian.</param> /// <param name="id">The tag ID.</param> /// <param name="settings">The tag settings.</param> /// <param name="metadata">The tag metadata.</param> /// <param name="security">The tag security configuration.</param> /// <param name="initialTagValues">The initial tag values, to use with the exception and compression filters.</param> /// <param name="changeHistory">The change history information for the tag.</param> /// <exception cref="ArgumentNullException"><paramref name="historian"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="security"/> is <see langword="null"/>.</exception> internal ElasticsearchTagDefinition(ElasticsearchHistorian historian, Guid id, TagSettings settings, TagMetadata metadata, TagSecurity security, InitialTagValues initialTagValues, IEnumerable <TagChangeHistoryEntry> changeHistory) : base(historian, id.ToString(), settings, metadata, security, initialTagValues, changeHistory) { _historian = historian ?? throw new ArgumentNullException(nameof(historian)); IdAsGuid = id; }