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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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);
        }