public void Parse_SlitUpdate_ShouldReturnParsedEvent()
        {
            // Arrange.
            var text = "id: e7dsDAgMQAkPkG@1588254699243-0\nevent: message\ndata: {\"id\":\"jSOE7oGJWo:0:0\",\"clientId\":\"pri:ODc1NjQyNzY1\",\"timestamp\":1588254699236,\"encoding\":\"json\",\"channel\":\"xxxx_xxxx_splits\",\"data\":\"{\\\"type\\\":\\\"SPLIT_UPDATE\\\",\\\"changeNumber\\\":1585867723838}\"}";

            // Act.
            var result = _notificationParser.Parse(text);

            // Assert.
            Assert.AreEqual(1585867723838, ((SplitChangeNotifiaction)result).ChangeNumber);
            Assert.AreEqual(NotificationType.SPLIT_UPDATE, result.Type);
            Assert.AreEqual("xxxx_xxxx_splits", result.Channel);
        }
        public void Process(TextMessageReceived notification)
        {
            var transaction   = _commandContextManager.EstablishForCommand(new Dolittle.Runtime.Commands.CommandRequest(Guid.NewGuid(), Guid.NewGuid(), 1, new Dictionary <string, object>()));
            var parsingResult = _textMessageParser.Parse(notification);

            //        var filter = Builders<DataCollector>.Filter.AnyEq(c => c.PhoneNumbers, (PhoneNumber)phoneNumber);
            var isTextMessageFormatValid = parsingResult.IsValid;

            var dataCollector = _dataCollectors.Query.Where(_ => _.PhoneNumbers.Contains(new Concepts.DataCollectors.PhoneNumber()
            {
                Value = notification.Sender
            })).FirstOrDefault();

            var unknownDataCollector = dataCollector == null;

            var caseReportId  = Guid.NewGuid();
            var caseReporting = _caseReportingRepository.Get(caseReportId);

            if (!isTextMessageFormatValid && unknownDataCollector)
            {
                caseReporting.ReportInvalidReportFromUnknownDataCollector(
                    notification.Sender,
                    notification.Text,
                    parsingResult.ErrorMessages,
                    notification.Received);

                transaction.Commit();
                return;
            }

            if (!isTextMessageFormatValid && !unknownDataCollector)
            {
                caseReporting.ReportInvalidReport(
                    dataCollector.Id,
                    notification.Sender,
                    notification.Text,
                    dataCollector.Location.Longitude,
                    dataCollector.Location.Latitude,
                    parsingResult.ErrorMessages,
                    notification.Received);

                transaction.Commit();
                return;
            }

            var healthRiskReadableId = parsingResult.HealthRiskReadableId;
            var healthRiskId         = _healthRisks.Query.Where(i => i.ReadableId == healthRiskReadableId).FirstOrDefault()?.Id;

            if (healthRiskId == null || healthRiskId == HealthRiskId.NotSet)
            {
                var errorMessages = new List <string> {
                    $"Unable to find health risk, since there are no health risks with a readable id of {healthRiskReadableId}"
                };
                if (unknownDataCollector)
                {
                    caseReporting.ReportInvalidReportFromUnknownDataCollector(
                        notification.Sender,
                        notification.Text,
                        errorMessages,
                        notification.Received);
                    transaction.Commit();
                    return;
                }

                caseReporting.ReportInvalidReport(
                    dataCollector.Id,
                    notification.Sender,
                    notification.Text,
                    dataCollector.Location.Longitude,
                    dataCollector.Location.Latitude,
                    errorMessages,
                    notification.Received);
                transaction.Commit();
                return;
            }

            if (unknownDataCollector)
            {
                caseReporting.ReportFromUnknownDataCollector(
                    notification.Sender,
                    healthRiskId.Value,
                    parsingResult.MalesUnder5,
                    parsingResult.MalesAged5AndOlder,
                    parsingResult.FemalesUnder5,
                    parsingResult.FemalesAged5AndOlder,
                    notification.Received,
                    notification.Text
                    );
                transaction.Commit();
                return;
            }

            caseReporting.Report(
                dataCollector.Id,
                healthRiskId.Value,
                notification.Sender,
                parsingResult.MalesUnder5,
                parsingResult.MalesAged5AndOlder,
                parsingResult.FemalesUnder5,
                parsingResult.FemalesAged5AndOlder,
                dataCollector.Location.Longitude,
                dataCollector.Location.Latitude,
                notification.Received,
                notification.Text
                );
            transaction.Commit();
        }
        /// <inheritdoc/>
        public void Process(NotificationReceived notification)
        {
            var parsingResult = _textMessageParser.Parse(notification);

            var isTextMessageFormatValid = parsingResult.IsValid;
            var dataCollector            = _dataCollectors.GetByPhoneNumber(notification.OriginNumber);
            var unknownDataCollector     = dataCollector == null;

            var caseReportId  = Guid.NewGuid();
            var caseReporting = _caseReportingRepository.Get(caseReportId);

            if (!isTextMessageFormatValid && unknownDataCollector)
            {
                caseReporting.ReportInvalidReportFromUnknownDataCollector(
                    notification.OriginNumber,
                    notification.Message,
                    parsingResult.ErrorMessages,
                    notification.Sent);
                return;
            }

            if (!isTextMessageFormatValid && !unknownDataCollector)
            {
                caseReporting.ReportInvalidReport(
                    dataCollector.Id,
                    notification.OriginNumber,
                    notification.Message,
                    dataCollector.Location.Longitude,
                    dataCollector.Location.Latitude,
                    parsingResult.ErrorMessages,
                    notification.Sent);
                return;
            }

            var healthRiskReadableId = parsingResult.HealthRiskReadableId;
            var healthRiskId         = _healthRisks.GetIdFromReadableId(healthRiskReadableId);

            if (healthRiskId == HealthRiskId.NotSet)
            {
                var errorMessages = new List <string> {
                    $"Unable to find health risk, since there are no health risks with a readable id of {healthRiskReadableId}"
                };
                if (unknownDataCollector)
                {
                    caseReporting.ReportInvalidReportFromUnknownDataCollector(
                        notification.OriginNumber,
                        notification.Message,
                        errorMessages,
                        notification.Sent);
                    return;
                }

                caseReporting.ReportInvalidReport(
                    dataCollector.Id,
                    notification.OriginNumber,
                    notification.Message,
                    dataCollector.Location.Longitude,
                    dataCollector.Location.Latitude,
                    errorMessages,
                    notification.Sent);
                return;
            }

            if (unknownDataCollector)
            {
                caseReporting.ReportFromUnknownDataCollector(
                    notification.OriginNumber,
                    healthRiskId.Value,
                    parsingResult.MalesUnder5,
                    parsingResult.MalesAged5AndOlder,
                    parsingResult.FemalesUnder5,
                    parsingResult.FemalesAged5AndOlder,
                    notification.Sent,
                    notification.Message
                    );
                return;
            }

            caseReporting.Report(
                dataCollector.Id,
                healthRiskId.Value,
                notification.OriginNumber,
                parsingResult.MalesUnder5,
                parsingResult.MalesAged5AndOlder,
                parsingResult.FemalesUnder5,
                parsingResult.FemalesAged5AndOlder,
                dataCollector.Location.Longitude,
                dataCollector.Location.Latitude,
                notification.Sent,
                notification.Message
                );
        }
        private async Task ReadStreamAsync(Stream stream)
        {
            var encoder = new UTF8Encoding();
            var streamReadcancellationTokenSource = new CancellationTokenSource();

            _log.Debug($"Reading stream ....");

            while (!_cancellationTokenSource.IsCancellationRequested && IsConnected())
            {
                if (stream.CanRead && IsConnected())
                {
                    var buffer = new byte[BufferSize];

                    var timeoutTask    = _wrapperAdapter.TaskDelay(ReadTimeout * 1000);
                    var streamReadTask = stream.ReadAsync(buffer, 0, BufferSize, streamReadcancellationTokenSource.Token);
                    // Creates a task that will complete when any of the supplied tasks have completed.
                    // Returns: A task that represents the completion of one of the supplied tasks. The return task's Result is the task that completed.
                    var finishedTask = await _wrapperAdapter.WhenAny(streamReadTask, timeoutTask);

                    if (finishedTask == timeoutTask)
                    {
                        throw new Exception($"Streaming read time out after {ReadTimeout} seconds.");
                    }

                    int len = streamReadTask.Result;

                    if (len == 0)
                    {
                        throw new Exception($"Streaming end of the file.");
                    }

                    var notificationString = encoder.GetString(buffer, 0, len);
                    _log.Debug($"Read stream encoder buffer: {notificationString}");

                    if (notificationString != KeepAliveResponse && IsConnected())
                    {
                        var lines = notificationString.Split(new[] { "\n\n" }, StringSplitOptions.None);

                        foreach (var line in lines)
                        {
                            try
                            {
                                if (!string.IsNullOrEmpty(line))
                                {
                                    var eventData = _notificationParser.Parse(line);

                                    if (eventData != null)
                                    {
                                        DispatchEvent(eventData);
                                    }
                                }
                            }
                            catch (NotificationErrorException ex)
                            {
                                _log.Debug($"Notification error: {ex.Message}. Status Server: {ex.Notification.StatusCode}.");

                                if (ex.Notification.StatusCode >= 40140 && ex.Notification.StatusCode <= 40149)
                                {
                                    Disconnect(reconnect: true);
                                }
                                else if (ex.Notification.StatusCode >= 40000 && ex.Notification.StatusCode <= 49999)
                                {
                                    Disconnect();
                                }
                            }
                            catch (Exception ex)
                            {
                                _log.Debug($"Error during event parse: {ex.Message}");
                            }
                        }
                    }
                }
            }

            _log.Debug($"Stop read stream");
        }
Beispiel #5
0
        private async Task ReadStreamAsync(Stream stream, CancellationToken cancellationToken)
        {
            _log.Debug($"Reading stream ....");

            try
            {
                while (!cancellationToken.IsCancellationRequested && (IsConnected() || _firstEvent))
                {
                    if (stream.CanRead && (IsConnected() || _firstEvent))
                    {
                        Array.Clear(_buffer, 0, BufferSize);

                        var timeoutToken   = new CancellationTokenSource();
                        var timeoutTask    = _wrapperAdapter.TaskDelay(ReadTimeoutMs, timeoutToken.Token);
                        var streamReadTask = stream.ReadAsync(_buffer, 0, BufferSize, cancellationToken);
                        // Creates a task that will complete when any of the supplied tasks have completed.
                        // Returns: A task that represents the completion of one of the supplied tasks. The return task's Result is the task that completed.
                        var finishedTask = await _wrapperAdapter.WhenAny(streamReadTask, timeoutTask);

                        try
                        {
                            if (finishedTask == timeoutTask)
                            {
                                throw new ReadStreamException(SSEClientActions.RETRYABLE_ERROR, $"Streaming read time out after {ReadTimeoutMs} seconds.");
                            }

                            int len = streamReadTask.Result;

                            if (len == 0)
                            {
                                throw new ReadStreamException(SSEClientActions.RETRYABLE_ERROR, "Streaming end of the file.");
                            }

                            var notificationString = _encoder.GetString(_buffer, 0, len);
                            _log.Debug($"Read stream encoder buffer: {notificationString}");

                            if (_firstEvent)
                            {
                                ProcessFirtsEvent(notificationString);
                            }

                            if (notificationString != KeepAliveResponse && IsConnected())
                            {
                                var lines = notificationString.Split(_notificationSplitArray, StringSplitOptions.None);

                                foreach (var line in lines)
                                {
                                    if (!string.IsNullOrEmpty(line))
                                    {
                                        var eventData = _notificationParser.Parse(line);

                                        if (eventData != null)
                                        {
                                            if (eventData.Type == NotificationType.ERROR)
                                            {
                                                var notificationError = (NotificationError)eventData;

                                                ProcessErrorNotification(notificationError);
                                            }
                                            else
                                            {
                                                DispatchEvent(eventData);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            _log.Debug("Disposing Stream Read Task...");
                            timeoutToken.Cancel();
                            timeoutToken.Dispose();
                            _wrapperAdapter.TaskWaitAndDispose(timeoutTask, streamReadTask, finishedTask);
                        }
                    }
                }
            }
            catch (ReadStreamException ex)
            {
                _log.Debug("ReadStreamException", ex);
                throw ex;
            }
            catch (Exception ex)
            {
                if (!cancellationToken.IsCancellationRequested)
                {
                    _log.Debug("Stream ended abruptly, proceeding to reconnect.", ex);
                    throw new ReadStreamException(SSEClientActions.RETRYABLE_ERROR, ex.Message);
                }

                _log.Debug("Stream Token cancelled.", ex);
            }
            finally
            {
                _log.Debug($"Stop read stream");
            }
        }