コード例 #1
0
        public async Task AddOrUpdate_callsFindAsyncAndReplaceOneAsync()
        {
            var record = new MongoRecord {
                Details = new Audit(TestCorrelationId, TestUser).Details
            };

            MongoCollectionMock.Setup(x => x.FindAsync(
                                          It.IsAny <FilterDefinition <MongoRecord> >(),
                                          It.IsAny <FindOptions <MongoRecord> >(),
                                          It.IsAny <CancellationToken>())).ReturnsAsync(new TestMongoCursor <MongoRecord>(record));
            MongoCollectionMock.Setup(x => x.ReplaceOneAsync(
                                          It.IsAny <FilterDefinition <MongoRecord> >(),
                                          It.IsAny <MongoRecord>(),
                                          It.IsAny <ReplaceOptions>(),
                                          It.IsAny <CancellationToken>())).ReturnsAsync(new ReplaceOneResult.Acknowledged(1, 0, new BsonString("")));

            await Storage.AddOrUpdate(TestKey, TestValue);

            MongoCollectionMock.Verify(x => x.FindAsync(
                                           It.IsAny <FilterDefinition <MongoRecord> >(),
                                           It.IsAny <FindOptions <MongoRecord> >(),
                                           It.IsAny <CancellationToken>()),
                                       Times.Once);
            MongoCollectionMock.Verify(x => x.InsertOneAsync(
                                           It.IsAny <MongoRecord>(),
                                           It.IsAny <InsertOneOptions>(),
                                           It.IsAny <CancellationToken>()),
                                       Times.Never);
            MongoCollectionMock.Verify(x => x.ReplaceOneAsync(
                                           It.IsAny <FilterDefinition <MongoRecord> >(),
                                           It.IsAny <MongoRecord>(),
                                           It.IsAny <ReplaceOptions>(),
                                           It.IsAny <CancellationToken>()),
                                       Times.Once);
        }
コード例 #2
0
        public async Task Publish(object message, CancellationToken token)
        {
            var messageName = typeEncoder.Encode(message.GetType())
                              ?? throw new NotSupportedException($"Not supported  message type '{message.GetType()}'.");
            var messageId = message.GetSha1();
            var audit     = new Audit {
                CorrelationId = context.CorrelationId, Requested = clock.UtcNow, User = context.User
            };

            var requested = new MongoRecord(messageId, messageName, message, audit);

            await InsertOne(requested, token);
        }
コード例 #3
0
 private async Task InsertOne(MongoRecord record, CancellationToken token)
 {
     try
     {
         await collection.InsertOneAsync(
             record,
             new InsertOneOptions(),
             token);
     }
     catch (MongoWriteException ex) when(ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
     {
         logger.LogDebug("Message({MessageName}/{MessageId}) polling: already requested.", record.MessageName, record.Id);
     }
 }
コード例 #4
0
        /// <inheritdoc/>
        public async Task Update(MongoRecord record, CancellationToken token)
        {
            try
            {
                var result = await collection.ReplaceOneAsync(
                    filter : x => x.Id == record.Id && x.Status == HandlingStatus.Requested,
                    record,
                    new ReplaceOptions(),
                    token);

                if (result.MatchedCount == 0)
                {
                    logger.LogWarning("Message({MessageType}/{MessageId}) handling: already responded concurrently.", record.MessageName, record.Id);
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Message({MessageType}/{MessageId}) handling: write error.", record.MessageName, record.Id);
            }
        }
コード例 #5
0
        /// <inheritdoc/>
        public async Task <Option <MongoRecord> > Process(MongoRecord record, CancellationToken token)
        {
            logger.LogInformation("Message({MessageName}/{MessageId}) handling: started.", record.MessageName, record.Id);
            try
            {
                var client   = clientFactory.Create(MongoOptionsNames.DefaultName);
                var response = await client.RequestObject(record.Message, token);

                return(record.Succeed(response, clock.UtcNow).AsOption());
            }
            catch (Exception ex)
            {
                var clientOptions = options.Get(MongoOptionsNames.DefaultName);
                if (ex is MessageDeferredException or TimeoutException or OperationCanceledException ||
                    clientOptions.TransientExceptions.Any(x => x.IsInstanceOfType(ex)))
                {
                    logger.LogInformation(ex, "Message({MessageType}/{MessageId}) handling: deferred or transient error.", record.MessageName, record.Id);
                    return(Option.None);
                }

                logger.LogError(ex, "Message({MessageType}/{MessageId}) handling: permanent error.", record.MessageName, record.Id);
                return(record.Fail(converter.ConvertTo(ex) !, clock.UtcNow).AsOption());
            }
        }