/// <summary>
        /// Method that runs asynchronously to connect to event hub and check
        /// a) if all expected value changes are delivered
        /// b) that time between value changes is expected
        /// </summary>
        /// <param name="token">Token to cancel the operation</param>
        /// <returns>Task that run until token is canceled</returns>
        public async Task <StartResult> StartAsync(ValidatorConfiguration configuration)
        {
            _logger.LogInformation("StartAsync called.");
            var sw = Stopwatch.StartNew();

            try {
                // Check if already started.
                if (_cancellationTokenSource != null)
                {
                    return(new StartResult());
                }

                // Check provided configuration.
                if (configuration == null)
                {
                    throw new ArgumentNullException(nameof(configuration));
                }

                if (configuration.ExpectedValueChangesPerTimestamp < 0)
                {
                    throw new ArgumentNullException("Invalid configuration detected, expected value changes per timestamp can't be lower than zero");
                }
                if (configuration.ExpectedIntervalOfValueChanges < 0)
                {
                    throw new ArgumentNullException("Invalid configuration detected, expected interval of value changes can't be lower than zero");
                }
                if (configuration.ExpectedMaximalDuration < 0)
                {
                    throw new ArgumentNullException("Invalid configuration detected, maximal total duration can't be lower than zero");
                }
                if (configuration.ThresholdValue <= 0)
                {
                    throw new ArgumentNullException("Invalid configuration detected, threshold can't be negative or zero");
                }

                if (string.IsNullOrWhiteSpace(configuration.IoTHubEventHubEndpointConnectionString))
                {
                    throw new ArgumentNullException(nameof(configuration.IoTHubEventHubEndpointConnectionString));
                }
                if (string.IsNullOrWhiteSpace(configuration.StorageConnectionString))
                {
                    throw new ArgumentNullException(nameof(configuration.StorageConnectionString));
                }
                if (string.IsNullOrWhiteSpace(configuration.BlobContainerName))
                {
                    throw new ArgumentNullException(nameof(configuration.BlobContainerName));
                }
                if (string.IsNullOrWhiteSpace(configuration.EventHubConsumerGroup))
                {
                    throw new ArgumentNullException(nameof(configuration.EventHubConsumerGroup));
                }

                if (configuration.ExpectedMaximalDuration == 0)
                {
                    configuration.ExpectedMaximalDuration = uint.MaxValue;
                }

                _currentConfiguration = configuration;

                Interlocked.Exchange(ref _totalValueChangesCount, 0);

                _cancellationTokenSource = new CancellationTokenSource();

                //// Initialize EventProcessorWrapper
                if (_clientWrapper == null || _clientWrapper.GetHashCode() != EventProcessorWrapper.GetHashCode(_currentConfiguration))
                {
                    _clientWrapper = new EventProcessorWrapper(_currentConfiguration, _logger);
                    await _clientWrapper.InitializeClient(_cancellationTokenSource.Token).ConfigureAwait(false);
                }

                _clientWrapper.ProcessEventAsync += Client_ProcessEventAsync;
                await _clientWrapper.StartProcessingAsync(_cancellationTokenSource.Token).ConfigureAwait(false);

                _startTime = DateTime.UtcNow;

                // Initialize checkers.
                _missingTimestampsChecker = new MissingTimestampsChecker(
                    TimeSpan.FromMilliseconds(_currentConfiguration.ExpectedIntervalOfValueChanges),
                    TimeSpan.FromMilliseconds(_currentConfiguration.ThresholdValue),
                    _logger
                    );
                _missingTimestampsChecker.StartAsync(
                    TimeSpan.FromMilliseconds(kCheckerDelayMilliseconds),
                    _cancellationTokenSource.Token
                    ).Start();

                _messageProcessingDelayChecker = new MessageProcessingDelayChecker(
                    TimeSpan.FromMilliseconds(_currentConfiguration.ThresholdValue),
                    _logger
                    );

                _messageDeliveryDelayChecker = new MessageDeliveryDelayChecker(
                    TimeSpan.FromMilliseconds(_currentConfiguration.ExpectedMaximalDuration),
                    _logger
                    );

                _valueChangeCounterPerNodeId = new ValueChangeCounterPerNodeId(_logger);

                _missingValueChangesChecker = new MissingValueChangesChecker(
                    _currentConfiguration.ExpectedValueChangesPerTimestamp,
                    _logger
                    );
                _missingValueChangesChecker.StartAsync(
                    TimeSpan.FromMilliseconds(kCheckerDelayMilliseconds),
                    _cancellationTokenSource.Token
                    ).Start();

                _incrementalIntValueChecker = new IncrementalIntValueChecker(_logger);

                _incrementalSequenceChecker = new SequenceNumberChecker(_logger);

                _restartAnnouncementReceived = false;

                return(new StartResult());
            }
            finally {
                _logger.LogInformation("StartAsync finished in {elapsed}", sw.Elapsed);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Method that runs asynchronously to connect to event hub and check
        /// a) if all expected value changes are delivered
        /// b) that time between value changes is expected
        /// </summary>
        /// <param name="token">Token to cancel the operation</param>
        /// <returns>Task that run until token is canceled</returns>
        public async Task <StartResult> StartAsync(ValidatorConfiguration configuration)
        {
            // Check if already started.
            if (_cancellationTokenSource != null)
            {
                return(new StartResult());
            }

            // Check provided configuration.
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (configuration.ExpectedValueChangesPerTimestamp < 0)
            {
                throw new ArgumentNullException("Invalid configuration detected, expected value changes per timestamp can't be lower than zero");
            }
            if (configuration.ExpectedIntervalOfValueChanges < 0)
            {
                throw new ArgumentNullException("Invalid configuration detected, expected interval of value changes can't be lower than zero");
            }
            if (configuration.ExpectedMaximalDuration < 0)
            {
                throw new ArgumentNullException("Invalid configuration detected, maximal total duration can't be lower than zero");
            }
            if (configuration.ThresholdValue <= 0)
            {
                throw new ArgumentNullException("Invalid configuration detected, threshold can't be negative or zero");
            }

            if (string.IsNullOrWhiteSpace(configuration.IoTHubEventHubEndpointConnectionString))
            {
                throw new ArgumentNullException(nameof(configuration.IoTHubEventHubEndpointConnectionString));
            }
            if (string.IsNullOrWhiteSpace(configuration.StorageConnectionString))
            {
                throw new ArgumentNullException(nameof(configuration.StorageConnectionString));
            }
            if (string.IsNullOrWhiteSpace(configuration.BlobContainerName))
            {
                throw new ArgumentNullException(nameof(configuration.BlobContainerName));
            }
            if (string.IsNullOrWhiteSpace(configuration.EventHubConsumerGroup))
            {
                throw new ArgumentNullException(nameof(configuration.EventHubConsumerGroup));
            }

            if (configuration.ExpectedMaximalDuration == 0)
            {
                configuration.ExpectedMaximalDuration = uint.MaxValue;
            }

            Interlocked.Exchange(ref _shuttingDown, 0);
            _currentConfiguration = configuration;

            Interlocked.Exchange(ref _totalValueChangesCount, 0);

            _cancellationTokenSource = new CancellationTokenSource();

            // Initialize EventProcessorClient
            _logger.LogInformation("Connecting to blob storage...");
            var blobContainerClient = new BlobContainerClient(configuration.StorageConnectionString, configuration.BlobContainerName);

            _logger.LogInformation("Connecting to IoT Hub...");
            _client = new EventProcessorClient(blobContainerClient, configuration.EventHubConsumerGroup, configuration.IoTHubEventHubEndpointConnectionString);
            _client.PartitionInitializingAsync += Client_PartitionInitializingAsync;
            _client.ProcessEventAsync          += Client_ProcessEventAsync;
            _client.ProcessErrorAsync          += Client_ProcessErrorAsync;

            _logger.LogInformation("Starting monitoring of events...");
            await _client.StartProcessingAsync(_cancellationTokenSource.Token);

            _startTime = DateTime.UtcNow;

            // Initialize checkers.
            _missingTimestampsChecker = new MissingTimestampsChecker(
                TimeSpan.FromMilliseconds(_currentConfiguration.ExpectedIntervalOfValueChanges),
                TimeSpan.FromMilliseconds(_currentConfiguration.ThresholdValue),
                _logger
                );
            _missingTimestampsChecker.StartAsync(
                TimeSpan.FromMilliseconds(kCheckerDelayMilliseconds),
                _cancellationTokenSource.Token
                ).Start();

            _messageProcessingDelayChecker = new MessageProcessingDelayChecker(
                TimeSpan.FromMilliseconds(_currentConfiguration.ThresholdValue),
                _logger
                );

            _messageDeliveryDelayChecker = new MessageDeliveryDelayChecker(
                TimeSpan.FromMilliseconds(_currentConfiguration.ExpectedMaximalDuration),
                _logger
                );

            _valueChangeCounterPerNodeId = new ValueChangeCounterPerNodeId(_logger);

            _missingValueChangesChecker = new MissingValueChangesChecker(
                _currentConfiguration.ExpectedValueChangesPerTimestamp,
                _logger
                );
            _missingValueChangesChecker.StartAsync(
                TimeSpan.FromMilliseconds(kCheckerDelayMilliseconds),
                _cancellationTokenSource.Token
                ).Start();

            _incrementalIntValueChecker = new IncrementalIntValueChecker(_logger);

            return(new StartResult());
        }