Skip to content

Commit

Permalink
NCBC-1646: Add FTS index management API support
Browse files Browse the repository at this point in the history
MOTIVATION
----------
Full text search indexes can be managed via a REST interface and should
be exposed via the SDK. Primarily to support create, get, delete and get
document counts.

MODIFICATIONS
-------------
- Add System.ComponentModel.Primitives nuget dependency for netstandard
  1.5 / 2.0
- Add ISearchIndexManager with method definitions, plus supporting class
  and enums
- Add interface to ClusterManager with implementations
- Add integration tests to verify behaviour (note partition tests are
  currently ignored)

RESULT
------
FTS indexes can be managed using the ClusterManager class with options
to create, get, delete and get document counts.

Also includes experimental support to control ingestion, query and plan
freeze modes; plus support for getting partition indexes and partition
index document counts.

Change-Id: I88c4e6ccbd1bfac378d80e1429f4b8d273684de7
Reviewed-on: http://review.couchbase.org/92051
Tested-by: Build Bot <build@couchbase.com>
Reviewed-by: Jeffry Morris <jeffrymorris@gmail.com>
Reviewed-on: http://review.couchbase.org/93245
Tested-by: Jeffry Morris <jeffrymorris@gmail.com>
  • Loading branch information
MikeGoldsmith authored and jeffrymorris committed Apr 24, 2018
1 parent 15d402b commit e12c6d9
Show file tree
Hide file tree
Showing 12 changed files with 1,059 additions and 5 deletions.
207 changes: 206 additions & 1 deletion Src/Couchbase.IntegrationTests/Management/ClusterManagerTests.cs
@@ -1,7 +1,10 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Couchbase.Core;
using Couchbase.Core.Buckets;
using Couchbase.Core.Version;
using Couchbase.IntegrationTests.Utils;
using Couchbase.Management;
using NUnit.Framework;
Expand Down Expand Up @@ -296,6 +299,209 @@ public void Can_Upsert_List_And_Remove_User()
Assert.IsTrue(removeResult.Success);
}

#region FTS Index Management

[Test]
public async Task Can_List_All_FTS_Indexes()
{
var result = await _clusterManager.GetAllSearchIndexDefinitionsAsync(CancellationToken.None);
Assert.IsTrue(result.Success);
}

[Test]
public async Task Can_Create_Get_and_Delete_FTS_Index()
{
var definition = new SearchIndexDefinition("test-index", "default");

try
{
var createResult = await _clusterManager.CreateSearchIndexAsync(definition);
Assert.IsTrue(createResult.Success);
Assert.IsNull(createResult.Value);

var getResult = await _clusterManager.GetSearchIndexDefinitionAsync(definition.IndexName);
Assert.IsTrue(getResult.Success);
Assert.IsNotEmpty(getResult.Value);

// wait a second to give the index to register
await Task.Delay(TimeSpan.FromSeconds(1));

var countResult = await _clusterManager.GetSearchIndexDocumentCountAsync(definition.IndexName);
Assert.IsTrue(countResult.Success);
Assert.IsTrue(countResult.Value > 0);
}
finally
{
var deleteResult = await _clusterManager.DeleteSearchIndexAsync(definition.IndexName);
Assert.IsTrue(deleteResult.Success);
}
}

[TestCase(SearchIndexIngestionMode.Pause)]
[TestCase(SearchIndexIngestionMode.Resume)]
public async Task Can_Set_SearchIndex_IngestionMode(SearchIndexIngestionMode mode)
{
if (ClusterVersionProvider.Instance.GetVersion(_cluster) < new ClusterVersion(new Version(5, 0)))
{
Assert.Ignore("Requires Couchbase Server 5 or greater");
}

var definition = new SearchIndexDefinition("ingestion-index", "default");

try
{
var createResult = await _clusterManager.CreateSearchIndexAsync(definition);
Assert.IsTrue(createResult.Success);
Assert.IsNull(createResult.Value);

var pauseIngestionResult = await _clusterManager.SetSearchIndexIngestionModeAsync(definition.IndexName, mode);
Assert.IsTrue(pauseIngestionResult.Success);
}
finally
{
var deleteResult = await _clusterManager.DeleteSearchIndexAsync(definition.IndexName);
Assert.IsTrue(deleteResult.Success);
}
}

[TestCase(SearchIndexQueryMode.Allow)]
[TestCase(SearchIndexQueryMode.Disallow)]
public async Task Can_Set_SearchIndex_QueryMode(SearchIndexQueryMode mode)
{
if (ClusterVersionProvider.Instance.GetVersion(_cluster) < new ClusterVersion(new Version(5, 0)))
{
Assert.Ignore("Requires Couchbase Server 5 or greater");
}

var definition = new SearchIndexDefinition("index-index", "default");

try
{
var createResult = await _clusterManager.CreateSearchIndexAsync(definition);
Assert.IsTrue(createResult.Success);
Assert.IsNull(createResult.Value);

var pauseIngestionResult = await _clusterManager.SetSearchIndexQueryModeAsync(definition.IndexName, mode);
Assert.IsTrue(pauseIngestionResult.Success);
}
finally
{
var deleteResult = await _clusterManager.DeleteSearchIndexAsync(definition.IndexName);
Assert.IsTrue(deleteResult.Success);
}
}

[TestCase(SearchIndexPlanFreezeMode.Freeze)]
[TestCase(SearchIndexPlanFreezeMode.Unfreeze)]
public async Task Can_Set_SearchIndex_PlanFreezeMode(SearchIndexPlanFreezeMode mode)
{
if (ClusterVersionProvider.Instance.GetVersion(_cluster) < new ClusterVersion(new Version(5, 0)))
{
Assert.Ignore("Requires Couchbase Server 5 or greater");
}

var definition = new SearchIndexDefinition("plan-index", "default");

try
{
var createResult = await _clusterManager.CreateSearchIndexAsync(definition);
Assert.IsTrue(createResult.Success);
Assert.IsNull(createResult.Value);

var pauseIngestionResult = await _clusterManager.SetSearchIndexPlanModeAsync(definition.IndexName, mode);
Assert.IsTrue(pauseIngestionResult.Success);
}
finally
{
var deleteResult = await _clusterManager.DeleteSearchIndexAsync(definition.IndexName);
Assert.IsTrue(deleteResult.Success);
}
}

[Test]
public async Task Can_Get_All_SearchIndex_Statistics()
{
var getResult = await _clusterManager.GetSearchIndexStatisticsAsync();
Assert.IsTrue(getResult.Success);
Assert.IsNotEmpty(getResult.Value);
}

[Test]
public async Task Can_Get_SearchIndex_Statistics()
{
var definition = new SearchIndexDefinition("statistics-index", "default");

try
{
var createResult = await _clusterManager.CreateSearchIndexAsync(definition);
Assert.IsTrue(createResult.Success);
Assert.IsNull(createResult.Value);

var getResult = await _clusterManager.GetSearchIndexStatisticsAsync(definition.IndexName);
Assert.IsTrue(getResult.Success);
Assert.IsNotEmpty(getResult.Value);
}
finally
{
var deleteResult = await _clusterManager.DeleteSearchIndexAsync(definition.IndexName);
Assert.IsTrue(deleteResult.Success);
}
}

[Test]
public async Task Can_Get_All_SearchIndex_Partition_Information()
{
var getResult = await _clusterManager.GetAllSearchIndexPartitionInfoAsync();
Assert.IsTrue(getResult.Success);
Assert.IsNotEmpty(getResult.Value);
}

[Test, Ignore("Requires partitions in search index")]
public async Task Can_Get_SearchIndex_Partition_Information()
{
var definition = new SearchIndexDefinition("partition-index", "default");

try
{
var createResult = await _clusterManager.CreateSearchIndexAsync(definition);
Assert.IsTrue(createResult.Success);
Assert.IsNull(createResult.Value);

var getResult = await _clusterManager.GetSearchIndexPartitionInfoAsync(definition.IndexName);
Assert.IsTrue(getResult.Success);
Assert.IsNotEmpty(getResult.Value);
}
finally
{
var deleteResult = await _clusterManager.DeleteSearchIndexAsync(definition.IndexName);
Assert.IsTrue(deleteResult.Success);
}
}

[Test, Ignore("Requires partitions in search index")]
public async Task Can_Get_SearchIndex_Partition_Count()
{
var definition = new SearchIndexDefinition("partition-index", "default");

try
{
var createResult = await _clusterManager.CreateSearchIndexAsync(definition);
Assert.IsTrue(createResult.Success);
Assert.IsNull(createResult.Value);

var getResult = await _clusterManager.GetSearchIndexPartitionDocumentCountAsync(definition.IndexName);
Assert.IsTrue(getResult.Success);
Assert.IsInstanceOf<int>(getResult.Value);
}
finally
{
var deleteResult = await _clusterManager.DeleteSearchIndexAsync(definition.IndexName);
Assert.IsTrue(deleteResult.Success);
}
}

#endregion

[OneTimeTearDown]
public void OneTimeTearDown()
{
Expand Down Expand Up @@ -327,4 +533,3 @@ public void OneTimeTearDown()
* ************************************************************/

#endregion

1 change: 1 addition & 0 deletions Src/Couchbase/Couchbase.csproj
Expand Up @@ -51,6 +51,7 @@

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.5' Or '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.0" />
<PackageReference Include="System.ComponentModel.Primitives" Version="4.3.0" />
<PackageReference Include="System.Globalization.Extensions" Version="4.3.0" />
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
<PackageReference Include="System.Net.Primitives" Version="4.3.0" />
Expand Down

0 comments on commit e12c6d9

Please sign in to comment.