Ejemplo n.º 1
0
        public async Task PostNotificationTest()
        {
            var service  = new Mock <INotificationService>();
            var response = new SendNotificationResponse
            {
                NotificationRecordId = Guid.NewGuid(),
                Results = new List <NotificationSendingResult>()
            };

            var request = new SendNotificationRequest
            {
                EventType       = NotificationEvent.ArticleCreated,
                RecipientUserId = "userId",
                Parameters      = new Dictionary <string, object>()
            };

            SendNotificationRequest req = null;

            service.Setup(x => x.PostAsync(It.Is <SendNotificationRequest>(notificationRequest => notificationRequest == request)))
            .Callback <SendNotificationRequest>(r => req = r)
            .ReturnsAsync(response)
            .Verifiable();

            var controller = new NotificationController(_logger, service.Object).WithUser();
            var result     = await controller.SendNotificationAsync(request);

            service.Verify();
            Assert.NotNull(req);

            var res = Assert.IsType <OkObjectResult>(result);

            Assert.IsType <SendNotificationResponse>(res.Value);
            Assert.Equal(response, res.Value);
        }
Ejemplo n.º 2
0
        public async Task <SendNotificationResponse> SendNotificationToAllUsersAsync(MessageData messageData)
        {
            SendNotificationResponse response;

            using (var _db = new MoMoFirebaseDbContext())
            {
                var fcmTokens = await _db.FCMTokens.Where(t => t.Active == true)
                                .Select(t => t.FcmTokenValue)
                                .ToListAsync();

                if (fcmTokens != null && fcmTokens.Count > 0)
                {
                    var postData = new PostData()
                    {
                        MessageData = messageData,
                        FcmTokens   = fcmTokens
                    };

                    response = await SendNotificationAsync(postData);
                }
                else
                {
                    response = new SendNotificationResponse()
                    {
                        SendNotificationStatus = SendNotificationEnum.MissingToken,
                        StatusMessage          = "Don't have active tokens in database!"
                    };
                }

                return(response);
            }
        }
        public async Task <SendNotificationResponse> SendCitizenNotificationAsync(Account notification)
        {
            var sendNotificationResponse = new SendNotificationResponse();

            try
            {
                var response = clientProxy.SendEmail(
                    configuration.GetConfig <string>(
                        Constants.GovUkNotifyApiKey),
                    notification.EMail,
                    configuration.GetConfig <string>(
                        Constants.GovUkNotifyTemplateId),
                    Convert(GetGovUkNotifyPersonalisation(notification)));

                sendNotificationResponse.Success = !string.IsNullOrEmpty(response?.id);
            }
            catch (NotifyClientException ex)
            {
                if (ex.Message.ToLowerInvariant()
                    .Contains(configuration.GetConfig <string>(
                                  Constants.GovUkNotifyRateLimitException)))
                {
                    sendNotificationResponse.RateLimitException = true;
                    await accountsService.OpenCircuitBreakerAsync();
                }

                applicationLogger.Error("Failed to send citizen email with GovUKNotify", ex);
            }

            return(sendNotificationResponse);
        }
Ejemplo n.º 4
0
        private async Task <SendNotificationResponse> SendNotificationAsync(PostData postData)
        {
            SendNotificationResponse response;

            if (postData.FcmTokens?.Any() == true)
            {
                var sendStatus = await _fcmMessaging.SendNotificationAsync(postData);

                if (sendStatus.IsAllSuccess())
                {
                    response = new SendNotificationResponse
                    {
                        SendNotificationStatus = SendNotificationEnum.Success,
                        StatusMessage          = "Notification has been successfully sent!",
                    };
                }
                else if (sendStatus.IsAllFail())
                {
                    response = new SendNotificationResponse
                    {
                        SendNotificationStatus = SendNotificationEnum.NotificationPostFail,
                        StatusMessage          = "Notification has not been sent!"
                    };
                }
                else
                {
                    response = new SendNotificationResponse
                    {
                        SendNotificationStatus = SendNotificationEnum.NotAllSuccess,
                        StatusMessage          = "Some notification has not been sent!"
                    };
                }

                var tokensForMarkAsInactive = sendStatus.Results
                                              .Select((r, index) => new
                {
                    Result = r,
                    Index  = index
                })
                                              .Where(r => _badTokenRespMessange.Contains(r.Result.Error))
                                              .Select(resultWithIndex => postData.FcmTokens[resultWithIndex.Index])
                                              .ToArray();

                await RemoveRegistrationAsync(tokensForMarkAsInactive);
            }
            else
            {
                response = new SendNotificationResponse()
                {
                    SendNotificationStatus = SendNotificationEnum.MissingToken,
                    StatusMessage          = "FCM token is not found!"
                };
            }

            return(response);
        }
Ejemplo n.º 5
0
        public Task <SendNotificationResponse> SendNotificationToChannel(SlackChannelIdentifier channelId, string message)
        {
            if (ChannelsMessages.ContainsKey(channelId) == false)
            {
                ChannelsMessages.Add(channelId, new List <string>());
            }

            ChannelsMessages[channelId].Add(message);

            var sendNotificationResponse = new SendNotificationResponse
            {
                Ok        = true,
                TimeStamp = "1355517523.000005"
            };

            return(Task.FromResult(sendNotificationResponse));
        }
Ejemplo n.º 6
0
        public Task <SendNotificationResponse> SendNotificationToUser(string email, string message)
        {
            if (UsersToNotifications.ContainsKey(email) == false)
            {
                UsersToNotifications.Add(email, new List <string>());
            }

            UsersToNotifications[email].Add(message);


            var sendNotificationResponse = new SendNotificationResponse
            {
                Ok        = true,
                TimeStamp = "1355517523.000005"
            };

            return(Task.FromResult(sendNotificationResponse));
        }
Ejemplo n.º 7
0
        public async Task <SendNotificationResponse> PostAsync(SendNotificationRequest request)
        {
            Ensure.That(request, nameof(request)).IsNotNull();

            var settings = await _settingsStore.FindAsync(request.RecipientUserId);

            if (settings == null)
            {
                throw new NotFoundException(new ErrorDto(ErrorCode.NotFound, "User settings do not exist."));
            }

            var message = Mapper.Map <NotificationMessage>(request);

            var response = new SendNotificationResponse();

            foreach (var sender in _senders)
            {
                var senderResult = await sender.SendAsync(message, settings);

                if (senderResult.Status != NotificationSendingStatus.Skipped)
                {
                    response.Results.Add(senderResult);
                }
            }

            if (response.Results.Any(x => x.Status == NotificationSendingStatus.Success))
            {
                var newRecord = Mapper.Map <NotificationRecord>(request);
                newRecord.UserSettingsId = settings.Id;

                var record = await _historyStore.SaveAsync(newRecord);

                response.NotificationRecordId = record.Id;
            }

            return(response);
        }
Ejemplo n.º 8
0
        public async Task <ActionResult <SendNotificationResponse> > Send([FromBody] SendNotificationRequest request)
        {
            var responseValue = new SendNotificationResponse();

            // create new guid and insert into postgres table
            var pgDataRow = new NotificationRequest
            {
                Id                   = Guid.NewGuid(),
                ApplicationId        = request.ApplicationId,
                NotificationStatusId = Convert.ToInt32(NotificationStatus.New),
                NotificationTypeId   = request.NotificationTypeId,
                CountryCode          = request.CountryCode,
                FromEmail            = request.FromEmail?.Trim(),
                Attributes           = request.Attributes,
                RequestData          = request.RequestData,
                RecipientList        = request.RecipientList.Select(x => new Recipient
                {
                    Email    = x.Email?.Trim(),
                    Name     = x.Name,
                    Language = x.Language,
                    SendCode = x.SendCode
                })
            };

            bool success;

            try
            {
                success = await pgClient.Insert(new InsertNotificationRequest(), pgDataRow, CancellationToken.None) > 0;
            }
            catch (Exception e)
            {
                if (e.Message.Contains("violates foreign key"))
                {
                    responseValue.ValidationResult = $"Send failed with : An ID in this request violates a foreign key constraint";
                    return(StatusCode(StatusCodes.Status400BadRequest, responseValue));
                }
                LambdaLogger.Log($"Email Api: Send failed when inserting into database: {e.Message}");
                throw;
            }

            if (!success)
            {
                LambdaLogger.Log($"Email Api: Send failed with : Could not insert request into postgres environment name- {Config.EnvironmentName}");

                responseValue.ValidationResult = $"Send failed with : Could not insert request into postgres environment name- {Config.EnvironmentName}";
                return(StatusCode(StatusCodes.Status503ServiceUnavailable, responseValue));
            }

            // insert into SQS for processor to pick up
            var newMessage = new QueueMessage
            {
                RequestId = pgDataRow.Id
            };
            var serializedMessage = JsonConvert.SerializeObject(newMessage);

            success = await queueService.SendMessage(serializedMessage, Config.EmailServiceSqsUrl);

            // if not successful warn the caller
            if (!success)
            {
                LambdaLogger.Log($"Email Api: Send failed with : Could not insert message into queue - {Config.EmailServiceSqsUrl}");

                responseValue.ValidationResult = $"Send failed with : Could not insert message into queue";
                return(StatusCode(StatusCodes.Status503ServiceUnavailable, responseValue));
            }

            // on success return the Guid so that the caller can use to check the message status
            LambdaLogger.Log($"Email Api: Send succeeded with guid : {serializedMessage}");
            responseValue.RequestId = pgDataRow.Id;
            return(Ok(responseValue));
        }
        public async Task SendCitizenNotificationAsyncTests(string responseId, bool throwException, bool isRateLimitException, SendNotificationResponse expectation)
        {
            //Fakes
            var citizenEmailNotification = new Account
            {
                EMail = "*****@*****.**"
            };
            var emailResponse = responseId == null ? null : new Notify.Models.Responses.EmailNotificationResponse
            {
                id = responseId
            };

            //Configure calls
            if (throwException)
            {
                A.CallTo(() => fakeGovUkNotifyClient.SendEmail(A <string> ._, A <string> ._, A <string> ._, A <Dictionary <string, dynamic> > ._)).Throws(() => new NotifyClientException(isRateLimitException ? nameof(NotifyClientException).ToLowerInvariant() : nameof(Exception).ToLowerInvariant()));
            }
            else
            {
                A.CallTo(() => fakeGovUkNotifyClient.SendEmail(A <string> ._, A <string> ._, A <string> ._, A <Dictionary <string, dynamic> > ._)).Returns(emailResponse);
            }

            A.CallTo(() => fakeConfiguration.GetConfig <string>(A <string> ._)).Returns(isRateLimitException ? nameof(NotifyClientException).ToLowerInvariant() : "test");

            //Act
            var govUkNotifyService = new GovUkNotifyService(fakeApplicationLogger, fakeGovUkNotifyClient, fakeConfiguration, fakeAccountsService);
            var result             = await govUkNotifyService.SendCitizenNotificationAsync(citizenEmailNotification);

            //Assertions
            result.Should().BeEquivalentTo(expectation);
            A.CallTo(() => fakeGovUkNotifyClient.SendEmail(A <string> ._, A <string> .That.IsEqualTo(citizenEmailNotification.EMail), A <string> ._, A <Dictionary <string, dynamic> > ._)).MustHaveHappened();
            if (throwException)
            {
                A.CallTo(() => fakeApplicationLogger.Error(A <string> ._, A <Exception> ._)).MustHaveHappened();
                if (isRateLimitException)
                {
                    A.CallTo(() => fakeAccountsService.OpenCircuitBreakerAsync()).MustHaveHappened();
                }
            }
        }
Ejemplo n.º 10
0
        public async Task ProcessEmailNotificationsAsyncTests(
            CircuitBreakerDetails circuitBreakerDetails,
            int batchAccountSize,
            SendNotificationResponse sendNotificationResponse,
            bool throwSendNotificationException = false,
            int halfOpenRetryMax = 5)
        {
            // Configure Calls
            A.CallTo(() => fakeAccountsService.GetCircuitBreakerStatusAsync()).Returns(circuitBreakerDetails);
            A.CallTo(() => fakeAccountsService.GetNextBatchOfEmailsAsync(A <int> ._)).Returns(GetAccountsToProcess(batchAccountSize));
            if (throwSendNotificationException)
            {
                A.CallTo(() => fakeSendCitizenNotificationService.SendCitizenNotificationAsync(A <Account> ._)).Throws(() => new Exception(nameof(Exception), new Exception(nameof(Exception))));
            }
            else
            {
                A.CallTo(() => fakeSendCitizenNotificationService.SendCitizenNotificationAsync(A <Account> ._)).Returns(sendNotificationResponse);
            }

            A.CallTo(() => fakeConfiguration.GetConfig <int>(A <string> ._))
            .Returns(halfOpenRetryMax);

            //For this test the function call is not diasbled in the config.
            A.CallTo(() => fakeConfiguration.GetConfig <bool>(A <string> ._)).Returns(false);

            // Assign
            var emailProcessor = new EmailNotificationProcessor(fakeSendCitizenNotificationService, fakeApplicationLogger, fakeConfiguration, fakeAccountsService);

            // Act
            await emailProcessor.ProcessEmailNotificationsAsync();

            // Assert
            A.CallTo(() => fakeAccountsService.GetCircuitBreakerStatusAsync()).MustHaveHappened();

            if (circuitBreakerDetails.CircuitBreakerStatus != CircuitBreakerStatus.Open)
            {
                if (throwSendNotificationException)
                {
                    A.CallTo(() =>
                             fakeAccountsService.InsertAuditAsync(A <AccountNotificationAudit> .That.Matches(audit =>
                                                                                                             audit.NotificationProcessingStatus == NotificationProcessingStatus.Failed && !string.IsNullOrWhiteSpace(audit.Note))))
                    .MustHaveHappened();
                    A.CallTo(() => fakeAccountsService.HalfOpenCircuitBreakerAsync()).MustHaveHappened();
                    if (circuitBreakerDetails.HalfOpenRetryCount == halfOpenRetryMax)
                    {
                        A.CallTo(() => fakeAccountsService.SetBatchToCircuitGotBrokenAsync(A <IEnumerable <Account> > ._)).MustHaveHappened();

                        A.CallTo(() => fakeAccountsService.OpenCircuitBreakerAsync()).MustHaveHappened();
                    }
                }
                else
                {
                    if (sendNotificationResponse.Success)
                    {
                        A.CallTo(() =>
                                 fakeAccountsService.InsertAuditAsync(A <AccountNotificationAudit> ._)).MustHaveHappened(batchAccountSize, Times.Exactly);
                        if (circuitBreakerDetails.CircuitBreakerStatus == CircuitBreakerStatus.HalfOpen)
                        {
                            A.CallTo(() =>
                                     fakeAccountsService.CloseCircuitBreakerAsync()).MustHaveHappened();
                        }
                    }
                    else
                    {
                        if (sendNotificationResponse.RateLimitException)
                        {
                            A.CallTo(() => fakeAccountsService.OpenCircuitBreakerAsync()).MustHaveHappened();
                            A.CallTo(() =>
                                     fakeAccountsService.SetBatchToCircuitGotBrokenAsync(
                                         A <IEnumerable <Account> > ._))
                            .MustHaveHappened();
                            A.CallTo(() => fakeApplicationLogger.Info(A <string> ._)).MustHaveHappened();
                        }
                        else
                        {
                            A.CallTo(() =>
                                     fakeAccountsService.InsertAuditAsync(A <AccountNotificationAudit> .That.Matches(audit =>
                                                                                                                     audit.NotificationProcessingStatus == NotificationProcessingStatus.Failed)))
                            .MustHaveHappened();
                        }
                    }
                }
            }
            else
            {
                A.CallTo(() => fakeAccountsService.GetNextBatchOfEmailsAsync(A <int> ._)).MustNotHaveHappened();
                A.CallTo(() => fakeSendCitizenNotificationService.SendCitizenNotificationAsync(A <Account> ._)).MustNotHaveHappened();
            }
        }