コード例 #1
0
        public async Task <IReadOnlyCollection <Employee> > ExecuteQueryAsync(EmployeeGetAllQuery query, CancellationToken cancellationToken)
        {
            ReadModelDescription readModelDescription = _readModelDescriptionProvider.GetReadModelDescription <EmployeeReadModel>();
            string indexName = "eventflow-" + readModelDescription.IndexName.Value;

            await _elasticClient.FlushAsync(indexName,
                                            d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            await _elasticClient.RefreshAsync(indexName,
                                              d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            var searchResponse = await _elasticClient.SearchAsync <EmployeeReadModel>(d => d
                                                                                      .RequestConfiguration(c => c
                                                                                                            .AllowedStatusCodes((int)HttpStatusCode.NotFound))
                                                                                      .Index(readModelDescription.IndexName.Value)
                                                                                      .Query(q => q),
                                                                                      cancellationToken)
                                 .ConfigureAwait(false);

            var retList = new List <Employee>();

            foreach (var doc in searchResponse?.Documents)
            {
                var dataEmployee = new Employee(new EmployeeId(doc.Id), doc.FullName ?? string.Empty, doc.Department ?? string.Empty, doc.TenantId);
                retList.Add(dataEmployee);
            }
            return(retList);
        }
コード例 #2
0
        private async Task UpdateReadModelAsync(
            ReadModelDescription readModelDescription,
            ReadModelUpdate readModelUpdate,
            IReadModelContext readModelContext,
            Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken, Task <ReadModelEnvelope <TReadModel> > > updateReadModel,
            CancellationToken cancellationToken)
        {
            var response = await _elasticClient.GetAsync <TReadModel>(
                readModelUpdate.ReadModelId,
                d => d
                .RequestConfiguration(c => c
                                      .AllowedStatusCodes((int)HttpStatusCode.NotFound))
                .Index(readModelDescription.IndexName.Value),
                cancellationToken)
                           .ConfigureAwait(false);

            var readModelEnvelope = response.Found
                ? ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, response.Source, response.Version)
                : ReadModelEnvelope <TReadModel> .Empty(readModelUpdate.ReadModelId);

            readModelEnvelope = await updateReadModel(
                readModelContext,
                readModelUpdate.DomainEvents,
                readModelEnvelope,
                cancellationToken)
                                .ConfigureAwait(false);

            if (readModelContext.IsMarkedForDeletion)
            {
                await DeleteAsync(readModelUpdate.ReadModelId, cancellationToken);

                return;
            }

            try
            {
                await _elasticClient.IndexAsync(
                    readModelEnvelope.ReadModel,
                    d =>
                {
                    d = d
                        .RequestConfiguration(c => c)
                        .Id(readModelUpdate.ReadModelId)
                        .Index(readModelDescription.IndexName.Value);
                    d = response.Found
                            ? d.VersionType(VersionType.ExternalGte).Version(readModelEnvelope.Version.GetValueOrDefault())
                            : d.OpType(OpType.Create);
                    return(d);
                },
                    cancellationToken)
                .ConfigureAwait(false);
            }
            catch (ElasticsearchClientException e)
                when(e.Response?.HttpStatusCode == (int)HttpStatusCode.Conflict)
                {
                    throw new OptimisticConcurrencyException(
                              $"Read model '{readModelUpdate.ReadModelId}' updated by another",
                              e);
                }
        }
コード例 #3
0
        private async Task UpdateReadModelAsync(ReadModelDescription readModelDescription,
                                                ReadModelUpdate readModelUpdate,
                                                IReadModelContextFactory readModelContextFactory,
                                                Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken,
                                                      Task <ReadModelUpdateResult <TReadModel> > > updateReadModel,
                                                CancellationToken cancellationToken)
        {
            var collection = _mongoDatabase.GetCollection <TReadModel>(readModelDescription.RootCollectionName.Value);
            var filter     = Builders <TReadModel> .Filter.Eq(readmodel => readmodel.Id, readModelUpdate.ReadModelId);

            var result = collection.Find(filter).FirstOrDefault();

            var isNew = result == null;

            var readModelEnvelope = !isNew
                ? ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, result)
                : ReadModelEnvelope <TReadModel> .Empty(readModelUpdate.ReadModelId);

            var readModelContext      = readModelContextFactory.Create(readModelUpdate.ReadModelId, isNew);
            var readModelUpdateResult =
                await updateReadModel(readModelContext, readModelUpdate.DomainEvents, readModelEnvelope,
                                      cancellationToken).ConfigureAwait(false);

            if (!readModelUpdateResult.IsModified)
            {
                return;
            }

            if (readModelContext.IsMarkedForDeletion)
            {
                await DeleteAsync(readModelUpdate.ReadModelId, cancellationToken);

                return;
            }

            readModelEnvelope = readModelUpdateResult.Envelope;
            var originalVersion = readModelEnvelope.ReadModel.Version;

            readModelEnvelope.ReadModel.Version = readModelEnvelope.Version;
            try
            {
                await collection.ReplaceOneAsync <TReadModel>(
                    x => x.Id == readModelUpdate.ReadModelId && x.Version == originalVersion,
                    readModelEnvelope.ReadModel,
                    new UpdateOptions()
                {
                    IsUpsert = true
                },
                    cancellationToken);
            }
            catch (MongoWriteException e)
            {
                throw new OptimisticConcurrencyException(
                          $"Read model '{readModelUpdate.ReadModelId}' updated by another",
                          e);
            }
        }
        public async Task <IPagedResponse <Company> > ExecuteQueryAsync(CompanySearchByNameQuery query, CancellationToken cancellationToken)
        {
            ReadModelDescription readModelDescription = _readModelDescriptionProvider.GetReadModelDescription <CompanyReadModel>();
            string indexName = readModelDescription.IndexName.Value;

            await _elasticClient.FlushAsync(indexName,
                                            d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            await _elasticClient.RefreshAsync(indexName,
                                              d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            var querySearch = !string.IsNullOrEmpty(query.Name)
                ? new WildcardQuery()
            {
                Field = Infer.Field <CompanyReadModel>(f => f.Name),
                Value = query.Name.ToLower() + "*",
            }
                : null;
            var searchRequest = new SearchRequest(indexName)
            {
                Query = new BoolQuery()
                {
                    Must = new QueryContainer[]
                    {
                        querySearch
                    },
                    //MustNot = new QueryContainer[]
                    //{
                    //    new ExistsQuery()
                    //    {
                    //        Field = Infer.Field<CompanyReadModel>(f => f.IsDeleted)
                    //    }
                    //}
                },
                From = 1,
                Size = 10,
            };

            var companyRecords = await _elasticClient.SearchAsync <CompanyReadModel>(searchRequest, cancellationToken);

            IPagedResponse <Company> response = new PagedResponse <Company>()
            {
                Records    = (companyRecords?.Documents?.Count > 0) ? companyRecords.Documents.Select(collection => collection.ToCompany()).ToList() : new List <Company>(),
                TotalCount = (companyRecords?.Documents?.Count > 0) ? companyRecords.Total : 0
            };

            return(response);
        }
コード例 #5
0
        public async Task <Employee> ExecuteQueryAsync(EmployeeGetQuery query, CancellationToken cancellationToken)
        {
            ReadModelDescription readModelDescription = _readModelDescriptionProvider.GetReadModelDescription <EmployeeReadModel>();
            string indexName = "eventflow-" + readModelDescription.IndexName.Value;

            await _elasticClient.Indices.FlushAsync(indexName,
                                                    d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            await _elasticClient.Indices.RefreshAsync(indexName,
                                                      d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            IGetResponse <EmployeeReadModel> searchResponse = await _elasticClient.GetAsync <EmployeeReadModel>(query.EmployeeId.Value,
                                                                                                                d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)).Index(readModelDescription.IndexName.Value), cancellationToken)
                                                              .ConfigureAwait(false);

            return(searchResponse.Source.ToEmployee());
        }
コード例 #6
0
        private async Task UpdateReadModelAsync(ReadModelDescription readModelDescription, ReadModelUpdate readModelUpdate,
                                                IReadModelContextFactory readModelContextFactory,
                                                Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken,
                                                      Task <ReadModelUpdateResult <TReadModel> > > updateReadModel, CancellationToken cancellationToken)
        {
            var readModelContext  = readModelContextFactory.Create(readModelUpdate.ReadModelId, true);
            var collection        = _mongoDatabase.GetCollection <TReadModel>(readModelDescription.RootCollectionName.Value);
            var readModelEnvelope = ReadModelEnvelope <TReadModel> .Empty(readModelUpdate.ReadModelId);

            var modelUpdateResult =
                await updateReadModel(readModelContext, readModelUpdate.DomainEvents, readModelEnvelope,
                                      cancellationToken).ConfigureAwait(false);

            readModelEnvelope = modelUpdateResult.Envelope;
            readModelEnvelope.ReadModel._id =
                ObjectIdGenerator.Instance.GenerateId(collection, readModelEnvelope.ReadModel);
            await collection.InsertOneAsync(
                readModelEnvelope.ReadModel,
                new InsertOneOptions { BypassDocumentValidation = true },
                cancellationToken);
        }
コード例 #7
0
        public async Task <Company> ExecuteQueryAsync(CompanyGetQuery query, CancellationToken cancellationToken)
        {
            ReadModelDescription readModelDescription = _readModelDescriptionProvider.GetReadModelDescription <CompanyReadModel>();
            string indexName = readModelDescription.IndexName.Value;

            await _elasticClient.FlushAsync(indexName,
                                            d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            await _elasticClient.RefreshAsync(indexName,
                                              d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            IGetResponse <CompanyReadModel> response = await _elasticClient.GetAsync <CompanyReadModel>(
                query.CompanyId.Value.ToString(),
                d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound))
                .Index(indexName), cancellationToken)
                                                       .ConfigureAwait(false);

            return(response.Source.ToCompany());
        }
コード例 #8
0
        private async Task UpdateReadModelAsync(ReadModelDescription readModelDescription,
                                                ReadModelUpdate readModelUpdate,
                                                IReadModelContextFactory readModelContextFactory,
                                                Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken, Task <ReadModelUpdateResult <TReadModel> > > updateReadModel,
                                                CancellationToken cancellationToken)
        {
            var collection = _mongoDatabase.GetCollection <TReadModel>(readModelDescription.RootCollectionName.Value);
            var filter     = Builders <TReadModel> .Filter.Eq(readmodel => readmodel._id, readModelUpdate.ReadModelId);

            var result = collection.Find(filter).FirstOrDefault();

            var isNew = result == null;

            var readModelEnvelope = !isNew
                    ? ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, result)
                    : ReadModelEnvelope <TReadModel> .Empty(readModelUpdate.ReadModelId);

            var readModelContext      = readModelContextFactory.Create(readModelUpdate.ReadModelId, isNew);
            var readModelUpdateResult = await updateReadModel(readModelContext, readModelUpdate.DomainEvents, readModelEnvelope, cancellationToken).ConfigureAwait(false);

            if (!readModelUpdateResult.IsModified)
            {
                return;
            }


            readModelEnvelope = readModelUpdateResult.Envelope;
            readModelEnvelope.ReadModel._version = readModelEnvelope.Version;

            await collection.ReplaceOneAsync <TReadModel>(
                x => x._id == readModelUpdate.ReadModelId,
                readModelEnvelope.ReadModel,
                new UpdateOptions()
            {
                IsUpsert = true
            },
                cancellationToken);
        }
        public async Task <int> ExecuteQueryAsync(CompanyGetByAddressQuery query, CancellationToken cancellationToken)
        {
            ReadModelDescription readModelDescription = _readModelDescriptionProvider.GetReadModelDescription <CompanyReadModel>();
            string indexName = readModelDescription.IndexName.Value;

            await _elasticClient.FlushAsync(indexName,
                                            d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            await _elasticClient.RefreshAsync(indexName,
                                              d => d.RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound)), cancellationToken)
            .ConfigureAwait(false);

            ISearchResponse <CompanyReadModel> searchResponse;

            if (query.Id != null)
            {
                searchResponse = await _elasticClient.SearchAsync <CompanyReadModel>(
                    d => d
                    .RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound))
                    .Index(indexName)
                    .Query(q => q.Match(m => m.Field(f => f.Address).Query(query.Address).MinimumShouldMatch("100%")) &&
                           !q.Match(m => m.Field(f => f.Id).Query(query.Id.Value.ToString()))), cancellationToken);
            }
            else
            {
                searchResponse = await _elasticClient.SearchAsync <CompanyReadModel>(
                    d => d
                    .RequestConfiguration(c => c.AllowedStatusCodes((int)HttpStatusCode.NotFound))
                    .Index(indexName)
                    .Query(q => q.Match(m => m.Field(f => f.Address).Query(query.Address).MinimumShouldMatch("100%"))), cancellationToken);
            }
            var count = searchResponse?.Documents?.Count;

            return(count ?? 0);
        }