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); }
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); }
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); }
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)); }
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)); }
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); }
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(); } } }
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(); } }