public async Task PostConversationEdgeCaseFailedToAddToOnePartition(int participantIndex) { Profile profile1 = CreateRandomProfile(); await _chatServiceClient.AddProfile(profile1); Profile profile2 = CreateRandomProfile(); await _chatServiceClient.AddProfile(profile2); var messageResponse = CreateRandomPostMessageResponse(profile1.Username); string[] participants = { profile1.Username, profile2.Username }; string conversationId = ParticipantsToId(participants); await _messageStore.AddMessage(messageResponse, conversationId); var messageRequest = new PostMessageRequest { Id = messageResponse.Id, Text = messageResponse.Text, SenderUsername = profile1.Username }; var conversationRequest = CreateRandomPostConversationRequest(messageRequest, participants); var conversationResponse = new PostConversationResponse { Id = conversationId, CreatedUnixTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }; await _conversationStore.AddConversationToPartition(conversationResponse, participants, participants[participantIndex]); var fetchedConversation = await _chatServiceClient.AddConversation(conversationRequest); Assert.Equal(fetchedConversation.Id, conversationId); }
public async Task UpdateConversation(string conversationId, long lastModifiedTime) { try { PostConversationResponse conversation = new PostConversationResponse { Id = conversationId, CreatedUnixTime = lastModifiedTime }; string username1 = conversationId.Substring(0, conversationId.IndexOf('_')); string username2 = conversationId.Substring(conversationId.IndexOf('_') + 1, conversationId.Length - conversationId.IndexOf('_') - 1); string[] participants = { username1, username2 }; var entity1 = ToEntity(conversation, participants, username1); var entity2 = ToEntity(conversation, participants, username2); Task task1 = _documentClient.UpsertDocumentAsync(DocumentCollectionUri, entity1); Task task2 = _documentClient.UpsertDocumentAsync(DocumentCollectionUri, entity2); await Task.WhenAll(task1, task2); } catch (DocumentClientException e) { if ((int)e.StatusCode == 404) { throw new ConversationNotFoundException($"Conversation with conversation Id {conversationId} was not found in storage"); } throw new StorageErrorException($"Failed to update conversation {conversationId}", e); } }
public async Task <PostConversationResponse> PostConversation(PostConversationRequest postConversationRequest, string conversationId) { using (_logger.BeginScope("{ConversationId}", conversationId)) { PostMessageResponse message = new PostMessageResponse { Id = postConversationRequest.FirstMessage.Id, Text = postConversationRequest.FirstMessage.Text, SenderUsername = postConversationRequest.FirstMessage.SenderUsername, UnixTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }; PostConversationResponse conversation = new PostConversationResponse { Id = conversationId, CreatedUnixTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }; var stopWatch = Stopwatch.StartNew(); await _messageStore.AddMessage(message, conversationId); var fetchedConversation = await _conversationStore.AddConversation(conversation, postConversationRequest.Participants); _telemetryClient.TrackMetric("ConversationStore.AddConversation.Time", stopWatch.ElapsedMilliseconds); _telemetryClient.TrackEvent("ConversationAdded"); return(fetchedConversation); } }
public async Task PostGetConversationListContinuationTokenTest() { Profile profile1 = CreateRandomProfile(); await _chatServiceClient.AddProfile(profile1); PostConversationResponse[] sentConversationsArray = new PostConversationResponse[6]; for (int index = 0; index < 6; index++) { Profile profile2 = CreateRandomProfile(); await _chatServiceClient.AddProfile(profile2); sentConversationsArray[index] = await _chatServiceClient.AddConversation(CreateRandomPostConversationRequest(profile1.Username, profile2.Username)); } GetConversationsResponse fetchedConversationList1 = await _chatServiceClient.GetConversationList(profile1.Username, 3, sentConversationsArray[0].CreatedUnixTime); Assert.Equal(3, fetchedConversationList1.Conversations.Length); Assert.NotEmpty(fetchedConversationList1.NextUri); GetConversationsResponse fetchedConversationList2 = await _chatServiceClient.GetConversationList(fetchedConversationList1.NextUri); Assert.Equal(2, fetchedConversationList2.Conversations.Length); Assert.Empty(fetchedConversationList2.NextUri); }
DocumentDbConversationEntity ToEntity(PostConversationResponse conversation, string[] participants, string userPartition) { DocumentDbConversationEntity entity = new DocumentDbConversationEntity { PartitionKey = $"c_{userPartition}", Id = $"{conversation.Id}", Participants = participants, LastModifiedUnixTime = conversation.CreatedUnixTime }; return(entity); }
public async Task <PostConversationResponse> AddConversation(PostConversationResponse conversation, string[] participants) { Task <PostConversationResponse> task1 = AddConversationToPartition(conversation, participants, participants[0]); Task <PostConversationResponse> task2 = AddConversationToPartition(conversation, participants, participants[1]); await Task.WhenAll(task1, task2); //Here we have the choice to return task1.Result or task2.Result. //In most cases, it won't matter. //In an edge case where only one conversation fails. The client will try to create this conversation again. //In this case, the one that failed first will have a more recent created time. // We chose to always return the oldest for no technical reason. return(task1.Result.CreatedUnixTime <= task2.Result.CreatedUnixTime ? task1.Result : task2.Result); }
public async Task <PostConversationResponse> AddConversationToPartition(PostConversationResponse conversation, string[] participants, string username) { try { var entity = ToEntity(conversation, participants, username); await _documentClient.CreateDocumentAsync(DocumentCollectionUri, entity); return(conversation); } catch (DocumentClientException e) { if ((int)e.StatusCode == 409) { return(await GetConversation(conversation.Id, username)); } throw new StorageErrorException($"Failed to add conversation {conversation.Id} to user {username}", e); } }
public async Task PostGetConversationListLastSeenConversationTimeTest(int indexOfLastSeenConversation) { Profile profile1 = CreateRandomProfile(); await _chatServiceClient.AddProfile(profile1); PostConversationResponse[] sentConversationsArray = new PostConversationResponse[11]; for (int index = 0; index < 11; index++) { Profile profile2 = CreateRandomProfile(); await _chatServiceClient.AddProfile(profile2); sentConversationsArray[index] = await _chatServiceClient.AddConversation(CreateRandomPostConversationRequest(profile1.Username, profile2.Username)); } GetConversationsResponse fetchedConversationList = await _chatServiceClient.GetConversationList(profile1.Username, 30, sentConversationsArray[indexOfLastSeenConversation].CreatedUnixTime); int numberOfMessagesfetched = 10 - indexOfLastSeenConversation; Assert.Equal(numberOfMessagesfetched, fetchedConversationList.Conversations.Length); Assert.Empty(fetchedConversationList.NextUri); }