public async Task HandleFailureInReindexScriptAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version22Index = new VersionedEmployeeIndex(_configuration, 22) { DiscardIndexesOnReindex = false }; await version22Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); IEmployeeRepository version1Repository = new EmployeeRepository(_configuration); var utcNow = SystemClock.UtcNow; var employee = await version1Repository.AddAsync(EmployeeGenerator.Generate(createdUtc: utcNow), o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); using (new DisposableAction(() => version22Index.DeleteAsync().GetAwaiter().GetResult())) { await version22Index.ConfigureAsync(); await version22Index.ReindexAsync(); var aliasResponse = await _client.Indices.GetAliasAsync(version1Index.Name); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key); } } }
public async Task CanReindexVersionedIndexWithCorrectMappingsAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2) { DiscardIndexesOnReindex = false }; await version2Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); IEmployeeRepository version1Repository = new EmployeeRepository(_configuration); var utcNow = SystemClock.UtcNow; var employee = await version1Repository.AddAsync(EmployeeGenerator.Generate(createdUtc: utcNow), o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { await version2Index.ConfigureAsync(); await version2Index.ReindexAsync(); var existsResponse = await _client.Indices.ExistsAsync(version1Index.VersionedName); _logger.LogRequest(existsResponse); Assert.True(existsResponse.ApiCall.Success); Assert.True(existsResponse.Exists); var mappingResponse = await _client.Indices.GetMappingAsync <Employee>(m => m.Index(version1Index.VersionedName)); _logger.LogRequest(mappingResponse); Assert.True(mappingResponse.IsValid); var mappingsV1 = mappingResponse.Indices[version1Index.VersionedName]; Assert.NotNull(mappingsV1); existsResponse = await _client.Indices.ExistsAsync(version2Index.VersionedName); _logger.LogRequest(existsResponse); Assert.True(existsResponse.ApiCall.Success); Assert.True(existsResponse.Exists); string version1Mappings = ToJson(mappingsV1); mappingResponse = await _client.Indices.GetMappingAsync <Employee>(m => m.Index(version2Index.VersionedName)); _logger.LogRequest(mappingResponse); Assert.True(mappingResponse.IsValid); var mappingsV2 = mappingResponse.Indices[version2Index.VersionedName]; Assert.NotNull(mappingsV2); string version2Mappings = ToJson(mappingsV2); Assert.Equal(version1Mappings, version2Mappings); } } }
public async Task MaintainWillCreateAliasOnVersionedIndexAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2); await version2Index.DeleteAsync(); // Indexes don't exist yet so the current version will be the index version. Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); Assert.Equal(2, await version2Index.GetCurrentVersionAsync()); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); Assert.True(_client.IndexExists(version1Index.VersionedName).Exists); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { await version2Index.ConfigureAsync(); Assert.True(_client.IndexExists(version2Index.VersionedName).Exists); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); // delete all aliases await _configuration.Cache.RemoveAllAsync(); await DeleteAliasesAsync(version1Index.VersionedName); await DeleteAliasesAsync(version2Index.VersionedName); await _client.RefreshAsync(Indices.All); var aliasesResponse = await _client.GetAliasAsync(a => a.Index($"{version1Index.VersionedName},{version2Index.VersionedName}")); Assert.Equal(0, aliasesResponse.Indices.SelectMany(i => i.Value).Count()); // Indexes exist but no alias so the oldest index version will be used. Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); await version1Index.MaintainAsync(); aliasesResponse = await _client.GetAliasAsync(a => a.Index(version1Index.VersionedName)); Assert.Equal(1, aliasesResponse.Indices.Single().Value.Count); aliasesResponse = await _client.GetAliasAsync(a => a.Index(version2Index.VersionedName)); Assert.Equal(0, aliasesResponse.Indices.Single().Value.Count); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); } } }
public async Task CanCreateAndDeleteVersionedIndex() { var index = new VersionedEmployeeIndex(_configuration, 1); await index.ConfigureAsync(); var existsResponse = await _client.Indices.ExistsAsync(index.VersionedName); _logger.LogRequest(existsResponse); Assert.True(existsResponse.ApiCall.Success); Assert.True(existsResponse.Exists); await _client.AssertSingleIndexAlias(index.VersionedName, index.Name); await index.DeleteAsync(); existsResponse = await _client.Indices.ExistsAsync(index.VersionedName); _logger.LogRequest(existsResponse); Assert.True(existsResponse.ApiCall.Success); Assert.False(existsResponse.Exists); Assert.Equal(0, await _client.GetAliasIndexCount(index.Name)); }
public async Task CanResumeReindexAsync() { const int numberOfEmployeesToCreate = 2000; var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2); await version2Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); IEmployeeRepository version1Repository = new EmployeeRepository(_configuration); await version1Repository.AddAsync(EmployeeGenerator.GenerateEmployees(numberOfEmployeesToCreate), o => o.ImmediateConsistency()); var countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.Name)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(numberOfEmployeesToCreate, countResponse.Count); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { await version2Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version2Index.VersionedName)).Exists); // Throw error before second repass. await Assert.ThrowsAsync <ApplicationException>(async() => await version2Index.ReindexAsync((progress, message) => { _logger.LogInformation("Reindex Progress {0}%: {1}", progress, message); if (progress == 91) { throw new ApplicationException("Random Error"); } return(Task.CompletedTask); })); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); // Add a document and ensure it resumes from this document. await version1Repository.AddAsync(EmployeeGenerator.Generate(ObjectId.GenerateNewId(SystemClock.UtcNow.AddMinutes(1)).ToString()), o => o.ImmediateConsistency()); await version2Index.ReindexAsync(); var aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version2Index.VersionedName, aliasResponse.Indices.First().Key); Assert.Equal(2, await version1Index.GetCurrentVersionAsync()); Assert.Equal(2, await version2Index.GetCurrentVersionAsync()); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(numberOfEmployeesToCreate + 1, countResponse.Count); Assert.False((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); } } }
public async Task CanReindexVersionedIndexWithDeletedDocsAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2); await version2Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); IEmployeeRepository repository = new EmployeeRepository(_configuration); var employee = await repository.AddAsync(EmployeeGenerator.Default, o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { await version2Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version2Index.VersionedName)).Exists); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); // alias should still point to the old version until reindex var aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); _logger.LogRequest(aliasResponse); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key); var countdown = new AsyncCountdownEvent(1); var reindexTask = version2Index.ReindexAsync(async(progress, message) => { _logger.LogInformation($"Reindex Progress {progress}%: {message}"); if (progress == 91) { countdown.Signal(); await Task.Delay(1000); } }); // Wait until the first reindex pass is done. await countdown.WaitAsync(); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); await repository.RemoveAllAsync(o => o.ImmediateConsistency()); // Resume after everythings been indexed. await reindexTask; aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); _logger.LogRequest(aliasResponse); Assert.True(aliasResponse.IsValid, aliasResponse.GetErrorMessage()); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version2Index.VersionedName, aliasResponse.Indices.First().Key); Assert.Equal(2, await version1Index.GetCurrentVersionAsync()); Assert.Equal(2, await version2Index.GetCurrentVersionAsync()); var countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.ApiCall.HttpStatusCode == 404, countResponse.GetErrorMessage()); Assert.Equal(0, countResponse.Count); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid, countResponse.GetErrorMessage()); Assert.Equal(1, countResponse.Count); Assert.Equal(employee, await repository.GetByIdAsync(employee.Id)); Assert.False((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); } } }
public async Task CanReindexVersionedIndexWithDataInBothIndexesAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2); await version2Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); IEmployeeRepository version1Repository = new EmployeeRepository(_configuration); var employee = await version1Repository.AddAsync(EmployeeGenerator.Default, o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { await version2Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version2Index.VersionedName)).Exists); // swap the alias so we write to v1 and v2 and try to reindex. await _client.Indices.BulkAliasAsync(x => x .Remove(a => a.Alias(version1Index.Name).Index(version1Index.VersionedName)) .Add(a => a.Alias(version2Index.Name).Index(version2Index.VersionedName))); IEmployeeRepository version2Repository = new EmployeeRepository(_configuration); await version2Repository.AddAsync(EmployeeGenerator.Generate(), o => o.ImmediateConsistency()); var countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(1, countResponse.Count); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(1, countResponse.Count); // swap back the alias await _client.Indices.BulkAliasAsync(x => x .Remove(a => a.Alias(version2Index.Name).Index(version2Index.VersionedName)) .Add(a => a.Alias(version1Index.Name).Index(version1Index.VersionedName))); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); // alias should still point to the old version until reindex var aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key); await version2Index.ReindexAsync(); aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version2Index.VersionedName, aliasResponse.Indices.First().Key); Assert.Equal(2, await version1Index.GetCurrentVersionAsync()); Assert.Equal(2, await version2Index.GetCurrentVersionAsync()); await _client.Indices.RefreshAsync(Indices.All); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(2, countResponse.Count); Assert.False((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); } } }
public async Task CanReindexVersionedIndexWithReindexScriptAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version20Index = new VersionedEmployeeIndex(_configuration, 20) { DiscardIndexesOnReindex = false }; await version20Index.DeleteAsync(); var version21Index = new VersionedEmployeeIndex(_configuration, 21) { DiscardIndexesOnReindex = false }; await version21Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); IEmployeeRepository version1Repository = new EmployeeRepository(version1Index); var utcNow = SystemClock.UtcNow; var employee = await version1Repository.AddAsync(EmployeeGenerator.Generate(createdUtc: utcNow), o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); using (new DisposableAction(() => version20Index.DeleteAsync().GetAwaiter().GetResult())) { await version20Index.ConfigureAsync(); await version20Index.ReindexAsync(); IEmployeeRepository version20Repository = new EmployeeRepository(version20Index); var result = await version20Repository.GetByIdAsync(employee.Id); Assert.Equal("scripted", result.CompanyName); using (new DisposableAction(() => version21Index.DeleteAsync().GetAwaiter().GetResult())) { await version21Index.ConfigureAsync(); await version21Index.ReindexAsync(); IEmployeeRepository version21Repository = new EmployeeRepository(version21Index); result = await version21Repository.GetByIdAsync(employee.Id); Assert.Equal("typed script", result.CompanyName); } } } using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); IEmployeeRepository version1Repository = new EmployeeRepository(version1Index); var utcNow = SystemClock.UtcNow; var employee = await version1Repository.AddAsync(EmployeeGenerator.Generate(createdUtc: utcNow), o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); using (new DisposableAction(() => version21Index.DeleteAsync().GetAwaiter().GetResult())) { await version21Index.ConfigureAsync(); await version21Index.ReindexAsync(); IEmployeeRepository version21Repository = new EmployeeRepository(version21Index); var result = await version21Repository.GetByIdAsync(employee.Id); Assert.Equal("typed script", result.CompanyName); } } }
public async Task CanReindexVersionedIndexAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2); await version2Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); var indexes = _client.GetIndicesPointingToAlias(version1Index.Name); Assert.Single(indexes); var aliasResponse = await _client.Indices.GetAliasAsync(version1Index.Name); _logger.LogRequest(aliasResponse); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key); IEmployeeRepository version1Repository = new EmployeeRepository(_configuration); var employee = await version1Repository.AddAsync(EmployeeGenerator.Default, o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); var countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.Name)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(1, countResponse.Count); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { await version2Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version2Index.VersionedName)).Exists); // Make sure we can write to the index still. Should go to the old index until after the reindex is complete. IEmployeeRepository version2Repository = new EmployeeRepository(_configuration); await version2Repository.AddAsync(EmployeeGenerator.Generate(), o => o.ImmediateConsistency()); countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(2, countResponse.Count); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(0, countResponse.Count); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); // alias should still point to the old version until reindex aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key); await version2Index.ReindexAsync(); aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version2Index.VersionedName, aliasResponse.Indices.First().Key); Assert.Equal(2, await version1Index.GetCurrentVersionAsync()); Assert.Equal(2, await version2Index.GetCurrentVersionAsync()); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(2, countResponse.Count); Assert.False((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); employee = await version2Repository.AddAsync(EmployeeGenerator.Default, o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.Name)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(3, countResponse.Count); } } }
public async Task CanHandleReindexFailureAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2); await version2Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); Assert.True((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists); IEmployeeRepository version1Repository = new EmployeeRepository(_configuration); await version1Repository.AddAsync(EmployeeGenerator.Generate(), o => o.ImmediateConsistency()); var countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.Name)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(1, countResponse.Count); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { //Create invalid mappings var response = await _client.Indices.CreateAsync(version2Index.VersionedName, d => d.Map <Employee>(map => map .Dynamic(false) .Properties(p => p .Number(f => f.Name(e => e.Id)) ))); _logger.LogRequest(response); Assert.True((await _client.Indices.ExistsAsync(version2Index.VersionedName)).Exists); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); await version2Index.ReindexAsync(); await version2Index.Configuration.Client.Indices.RefreshAsync(Indices.All); var aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.True(aliasResponse.Indices.ContainsKey(version1Index.VersionedName)); var indexResponse = await _client.Cat.IndicesAsync(d => d.Index(Indices.Index("employees-*"))); Assert.NotNull(indexResponse.Records.FirstOrDefault(r => r.Index == version1Index.VersionedName)); Assert.NotNull(indexResponse.Records.FirstOrDefault(r => r.Index == version2Index.VersionedName)); Assert.NotNull(indexResponse.Records.FirstOrDefault(r => r.Index == $"{version2Index.VersionedName}-error")); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(1, countResponse.Count); countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(0, countResponse.Count); countResponse = await _client.CountAsync <object>(d => d.Index($"{version2Index.VersionedName}-error")); _logger.LogRequest(countResponse); Assert.True(countResponse.IsValid); Assert.Equal(1, countResponse.Count); } } }
public async Task CanReindexVersionedIndexWithUpdatedDocsAsync() { var version1Index = new VersionedEmployeeIndex(_configuration, 1); await version1Index.DeleteAsync(); var version2Index = new VersionedEmployeeIndex(_configuration, 2); await version2Index.DeleteAsync(); using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) { await version1Index.ConfigureAsync(); Assert.True(_client.IndexExists(version1Index.VersionedName).Exists); var repository = new EmployeeRepository(version1Index.Employee); var employee = await repository.AddAsync(EmployeeGenerator.Default, o => o.ImmediateConsistency()); Assert.NotNull(employee?.Id); using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) { await version2Index.ConfigureAsync(); Assert.True(_client.IndexExists(version2Index.VersionedName).Exists); Assert.Equal(1, await version2Index.GetCurrentVersionAsync()); // alias should still point to the old version until reindex var aliasResponse = await _client.GetAliasAsync(descriptor => descriptor.Name(version2Index.Name)); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key); var countdown = new AsyncCountdownEvent(1); var reindexTask = version2Index.ReindexAsync((progress, message) => { _logger.LogInformation($"Reindex Progress {progress}%: {message}"); if (progress == 91) { countdown.Signal(); SystemClock.Sleep(1000); } return(Task.CompletedTask); }); // Wait until the first reindex pass is done. await countdown.WaitAsync(); Assert.Equal(1, await version1Index.GetCurrentVersionAsync()); await repository.AddAsync(EmployeeGenerator.Generate(createdUtc: SystemClock.UtcNow)); employee.Name = "Updated"; await repository.SaveAsync(employee); // Resume after everythings been indexed. await reindexTask; aliasResponse = await _client.GetAliasAsync(descriptor => descriptor.Name(version2Index.Name)); Assert.True(aliasResponse.IsValid); Assert.Equal(1, aliasResponse.Indices.Count); Assert.Equal(version2Index.VersionedName, aliasResponse.Indices.First().Key); Assert.Equal(2, await version1Index.GetCurrentVersionAsync()); Assert.Equal(2, await version2Index.GetCurrentVersionAsync()); await _client.RefreshAsync(Indices.All); var countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName)); _logger.LogTrace(countResponse.GetRequest()); Assert.True(countResponse.IsValid); Assert.Equal(2, countResponse.Count); var result = await repository.GetByIdAsync(employee.Id); Assert.Equal(ToJson(employee), ToJson(result)); Assert.False((await _client.IndexExistsAsync(version1Index.VersionedName)).Exists); } } }