Beispiel #1
0
        private async Task AddConversationForUser(string username, Conversation conversation)
        {
            var conversationOrderEntity = new OrderedConversationEntity(username, conversation.Id, conversation.Participants, conversation.LastModifiedDateUtc);
            var conversationEntity      = new ConversationEntity(username, conversation.Id, conversation.Participants,
                                                                 conversationOrderEntity.RowKey);

            TableBatchOperation batchInsert = new TableBatchOperation
            {
                TableOperation.Insert(conversationEntity),
                TableOperation.Insert(conversationOrderEntity)
            };

            try
            {
                await table.ExecuteBatchAsync(batchInsert);
            }
            catch (StorageException e)
            {
                // Do nothing if the conversation already exists.
                // The client should list all conversations periodically or based on events and will get
                // the latest list of conversations.
                if (e.RequestInformation.HttpStatusCode != 409)
                {
                    throw new StorageErrorException("Failed to reach storage", e);
                }
            }
        }
Beispiel #2
0
        private async Task UpdateConversationModifiedDateForUser(string username, string conversationId, Message message)
        {
            ConversationEntity conversationEntity = await RetrieveConversationEntity(username, conversationId);

            var newOrderedConversationEntity = new OrderedConversationEntity(
                username, conversationId, conversationEntity.GetParticipants(), message.UtcTime);
            string oldTicksRowKey = conversationEntity.TicksRowKey;
            string newTicksRowKey = newOrderedConversationEntity.RowKey;

            conversationEntity.TicksRowKey = newTicksRowKey;

            TableBatchOperation batchOperation = new TableBatchOperation
            {
                TableOperation.Replace(conversationEntity), // will fail if entity has changed since we retrieved it (ETAG)
                TableOperation.Delete(new TableEntity(partitionKey: username, rowKey: oldTicksRowKey)
                {
                    ETag = "*"
                }),                                                 // delete old conversation order entity
                TableOperation.Insert(newOrderedConversationEntity) // will fail if another entity with the same ticks exists
            };

            try
            {
                await table.ExecuteBatchAsync(batchOperation);
            }
            catch (StorageException e)
            {
                throw new StorageErrorException("Failed to update conversation modified time", e);
            }
        }
Beispiel #3
0
        public async Task AddMessage(string conversationId, string messageId, Message message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (string.IsNullOrWhiteSpace(conversationId))
            {
                throw new ArgumentNullException(nameof(conversationId));
            }

            if (string.IsNullOrWhiteSpace(messageId))
            {
                throw new ArgumentNullException(nameof(messageId));
            }

            if (string.IsNullOrWhiteSpace(message.SenderUsername))
            {
                throw new ArgumentNullException(nameof(message.SenderUsername));
            }

            // Add the message first
            await messagesStore.AddMessage(conversationId, messageId, message);

            // Then update the conversations modified date for each user
            ConversationEntity conversationEntity = await RetrieveConversationEntity(message.SenderUsername, conversationId);

            var tasks = new List <Task>();

            foreach (var participant in conversationEntity.Participants.Split(ParticipantsSeparator))
            {
                tasks.Add(UpdateConversationModifiedDateForUser(participant, conversationId, message));
            }
            await Task.WhenAll(tasks);
        }
Beispiel #4
0
        private async Task <ConversationEntity> RetrieveConversationEntity(string username, string conversationId)
        {
            TableOperation retrieveOperation = TableOperation.Retrieve <ConversationEntity>(partitionKey: username, rowkey: ConversationEntity.ToRowKey(conversationId));

            try
            {
                TableResult tableResult = await table.ExecuteAsync(retrieveOperation);

                var entity = (ConversationEntity)tableResult.Result;

                if (entity == null)
                {
                    throw new ConversationNotFoundException($"Could not find a conversation with id {conversationId}");
                }

                return(entity);
            }
            catch (StorageException e)
            {
                throw new StorageErrorException($"Could not retrieve conversation {conversationId} from storage", e);
            }
        }