Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for analyzers #357

Merged
merged 13 commits into from
Apr 28, 2022
Merged
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
- run:
name: Test
command:
dotnet test -c Release --filter "Feature!=StreamTransaction&RunningMode!=Cluster"
dotnet test -c Release --filter "Feature!=StreamTransaction&RunningMode!=Cluster&Feature!=Analyzer"

"test-arangodb-3_5":
working_directory: ~/arangodb-net-standard
Expand All @@ -80,7 +80,7 @@ jobs:
- run:
name: Test
command:
dotnet test -c Release --filter RunningMode!=Cluster
dotnet test -c Release --filter "RunningMode!=Cluster"

"test-arangodb-3_6":
working_directory: ~/arangodb-net-standard
Expand All @@ -99,7 +99,7 @@ jobs:
- run:
name: Test
command:
dotnet test -c Release --filter RunningMode!=Cluster
dotnet test -c Release --filter "RunningMode!=Cluster"

"test-arangodb-3_7":
working_directory: ~/arangodb-net-standard
Expand Down
152 changes: 152 additions & 0 deletions arangodb-net-standard.Test/AnalyzerApi/AnalyzerApiClientTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using ArangoDBNetStandard;
using ArangoDBNetStandard.AnalyzerApi;
using ArangoDBNetStandard.AnalyzerApi.Models;
using ArangoDBNetStandard.Transport;
using Moq;
using Xunit;

namespace ArangoDBNetStandardTest.IndexApi
{
public class AnalyzerApiClientTest : IClassFixture<AnalyzerApiClientTestFixture>, IAsyncLifetime
{
private AnalyzerApiClient _analyzerApi;
private ArangoDBClient _adb;

public AnalyzerApiClientTest(AnalyzerApiClientTestFixture fixture)
{
_adb = fixture.ArangoDBClient;
_analyzerApi = _adb.Analyzer;
}

public Task InitializeAsync()
{
return Task.CompletedTask;
}

public Task DisposeAsync()
{
return Task.CompletedTask;
}

[Fact]
[Trait("Feature", "Analyzer")]
public async Task GetAllAnalyzersAsync_ShouldSucceed()
{
var res = await _analyzerApi.GetAllAnalyzersAsync();
Assert.Equal(HttpStatusCode.OK, res.Code);
Assert.False(res.Error);
}

[Fact]
[Trait("Feature", "Analyzer")]
public async Task PostAnalyzerAsync_ShouldSucceed()
{
var res = await _analyzerApi.PostAnalyzerAsync(
new Analyzer()
{
Name = "text_sc",
Type = "identity",
Properties = new AnalyzerProperties()
{
Accent = false,
Case = "lower",
Locale = "sc",
Stemming = false,
StopWords = new List<string>()
},
Features = new List<string>()
{
"frequency",
"position",
"norm"
}
}
);
Assert.NotNull(res);
Assert.NotNull(res.Name);
}

[Fact]
[Trait("Feature", "Analyzer")]
public async Task PostAnalyzerAsync_ShouldThrow_WhenAnalyzerIsInvalid()
{
try
{
//This call should fail because...
var res = await _analyzerApi.PostAnalyzerAsync(
new Analyzer()
{
Name = "text_sc",
Type = "collection", //...invalid analyzer type
Properties = new AnalyzerProperties()
{
Accent = false,
Case = "lower",
Locale = "sc",
Stemming = false,
StopWords = new List<string>()
},
Features = new List<string>()
{
"frequency",
"position",
"norm"
}
}
);
}
catch (ApiErrorException ex)
{
Assert.NotNull(ex);
Assert.NotNull(ex.ApiError);
Assert.True(ex.ApiError.Error);
}
}

[Fact]
[Trait("Feature", "Analyzer")]
public async Task GetAnalyzerAsync_ShouldSucceed()
{
var allRes = await _analyzerApi.GetAllAnalyzersAsync();
var firstName = allRes.Result[0].Name;
var res = await _analyzerApi.GetAnalyzerAsync(firstName);
Assert.Equal(HttpStatusCode.OK, res.Code);
Assert.False(res.Error);
}

[Fact]
[Trait("Feature", "Analyzer")]
public async Task DeleteAnalyzerAsync_ShouldSucceed()
{
var name = "text_mu";
var createRes = await _analyzerApi.PostAnalyzerAsync(
new Analyzer()
{
Name = name,
Type = "identity",
Properties = new AnalyzerProperties()
{
Accent = false,
Case = "lower",
Locale = "mu",
Stemming = false,
StopWords = new List<string>()
},
Features = new List<string>()
{
"frequency",
"position",
"norm"
}
}
);
var res = await _analyzerApi.DeleteAnalyzerAsync(name);
Assert.Equal(HttpStatusCode.OK, res.Code);
Assert.False(res.Error);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using ArangoDBNetStandard;
using ArangoDBNetStandard.CollectionApi.Models;
using ArangoDBNetStandard.AnalyzerApi.Models;
using System;
using System.Threading.Tasks;

namespace ArangoDBNetStandardTest.IndexApi
{
public class AnalyzerApiClientTestFixture : ApiClientTestFixtureBase
{
public ArangoDBClient ArangoDBClient { get; internal set; }

public AnalyzerApiClientTestFixture()
{
}

public override async Task InitializeAsync()
{
await base.InitializeAsync();

Console.WriteLine("AnalyzerApiClientTestFixture.InitializeAsync() started.");
string dbName = nameof(AnalyzerApiClientTestFixture);
await CreateDatabase(dbName);
Console.WriteLine("Database " + dbName + " created successfully");
ArangoDBClient = GetArangoDBClient(dbName);
try
{
var dbRes = await ArangoDBClient.Database.GetCurrentDatabaseInfoAsync();
if (dbRes.Error)
throw new Exception("GetCurrentDatabaseInfoAsync failed: " + dbRes.Code.ToString());
else
{
Console.WriteLine("In database " + dbRes.Result.Name);
}
}
catch (ApiErrorException ex)
{
Console.WriteLine(ex.Message);
throw ex;
}

}
}
}
142 changes: 142 additions & 0 deletions arangodb-net-standard/AnalyzerApi/AnalyzerApiClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
using System.Net;
using System.Threading.Tasks;

using ArangoDBNetStandard.Serialization;
using ArangoDBNetStandard.Transport;
using ArangoDBNetStandard.AnalyzerApi.Models;
using System;

namespace ArangoDBNetStandard.AnalyzerApi
{
/// <summary>
/// A client for interacting with ArangoDB Analyzer endpoints,
/// implementing <see cref="IAnalyzerApiClient"/>.
/// </summary>
public class AnalyzerApiClient : ApiClientBase, IAnalyzerApiClient
{
/// <summary>
/// The transport client used to communicate with the ArangoDB host.
/// </summary>
protected IApiClientTransport _client;

/// <summary>
/// The root path of the API.
/// </summary>
protected readonly string _analyzerApiPath = "_api/analyzer";

/// <summary>
/// Creates an instance of <see cref="AnalyzerApiClient"/>
/// using the provided transport layer and the default JSON serialization.
/// </summary>
/// <param name="client">Transport client that the API client will use to communicate with ArangoDB</param>
public AnalyzerApiClient(IApiClientTransport client)
: base(new JsonNetApiClientSerialization())
{
_client = client;
}

/// <summary>
/// Creates an instance of <see cref="AnalyzerApiClient"/>
/// using the provided transport and serialization layers.
/// </summary>
/// <param name="client">Transport client that the API client will use to communicate with ArangoDB.</param>
/// <param name="serializer">Serializer to be used.</param>
public AnalyzerApiClient(IApiClientTransport client, IApiClientSerialization serializer)
: base(serializer)
{
_client = client;
}

/// <summary>
/// Fetch the list of available Analyzer definitions.
/// GET /_api/analyzer
/// </summary>
/// <returns></returns>
public virtual async Task<GetAllAnalyzersResponse> GetAllAnalyzersAsync()
{
string uri = _analyzerApiPath;
using (var response = await _client.GetAsync(uri).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
return DeserializeJsonFromStream<GetAllAnalyzersResponse>(stream);
}
throw await GetApiErrorException(response).ConfigureAwait(false);
}
}

/// <summary>
/// Creates a new Analyzer based on the provided definition
/// POST /_api/analyzer
/// </summary>
/// <param name="body">The properties of the new analyzer.</param>
/// <returns></returns>
public virtual async Task<Analyzer> PostAnalyzerAsync(Analyzer body)
{
if (body == null)
{
throw new ArgumentException("body is required", nameof(body));
}
var uri = _analyzerApiPath;
var content = GetContent(body, new ApiClientSerializationOptions(true, true));
using (var response = await _client.PostAsync(uri, content).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
return DeserializeJsonFromStream<Analyzer>(stream);
}
throw await GetApiErrorException(response).ConfigureAwait(false);
}
}

/// <summary>
/// Fetches the definition of the specified analyzer.
/// GET /_api/analyzer/{analyzer-name}
/// </summary>
/// <param name="analyzerName">The name of the analyzer</param>
/// <returns></returns>
public virtual async Task<GetAnalyzerResponse> GetAnalyzerAsync(string analyzerName)
{
if (string.IsNullOrEmpty(analyzerName))
{
throw new ArgumentException("Analyzer name is required", nameof(analyzerName));
}
string uri = _analyzerApiPath + '/' + WebUtility.UrlEncode(analyzerName);
using (var response = await _client.GetAsync(uri).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
return DeserializeJsonFromStream<GetAnalyzerResponse>(stream);
}
throw await GetApiErrorException(response).ConfigureAwait(false);
}
}

/// <summary>
/// Deletes an Analyzer.
/// DELETE /_api/analyzer/{analyzer-name}
/// </summary>
/// <param name="analyzerName">The name of the analyzer</param>
/// <returns></returns>
public virtual async Task<DeleteAnalyzerResponse> DeleteAnalyzerAsync(string analyzerName)
{
if (string.IsNullOrEmpty(analyzerName))
{
throw new ArgumentException("Analyzer name is required", nameof(analyzerName));
}
string uri = _analyzerApiPath + '/' + WebUtility.UrlEncode(analyzerName);
using (var response = await _client.DeleteAsync(uri).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
return DeserializeJsonFromStream<DeleteAnalyzerResponse>(stream);
}
throw await GetApiErrorException(response).ConfigureAwait(false);
}
}
}
}
Loading