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); }
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); } }
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); }
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()); }
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); }
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()); }
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); }