Skip to content

Commit

Permalink
feat: adaptations to switch from undertow to armeria http server and …
Browse files Browse the repository at this point in the history
…related changes in evitaDB project
  • Loading branch information
tpz committed Aug 6, 2024
1 parent c9b941f commit 2bc1ca1
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 36 deletions.
31 changes: 21 additions & 10 deletions EvitaDB.Client/Certificate/ClientCertificateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,26 @@ public class ClientCertificateManager
private string? ClientCertificateKeyPassword { get; }
private bool UseGeneratedCertificate { get; }
private bool TrustedServerCertificate { get; }
private bool UsingMtls { get; }

private ClientCertificateManager(string clientCertificateFolderPath, string? clientCertificatePath,
string? clientCertificateKeyPath, string? clientCertificateKeyPassword, bool useGeneratedCertificate,
bool trustedServerCertificate)
bool trustedServerCertificate, bool usingMtls)
{
ClientCertificateFolderPath = clientCertificateFolderPath;
ClientCertificatePath = clientCertificatePath;
ClientCertificateKeyPath = clientCertificateKeyPath;
ClientCertificateKeyPassword = clientCertificateKeyPassword;
UseGeneratedCertificate = useGeneratedCertificate;
TrustedServerCertificate = trustedServerCertificate;
UsingMtls = usingMtls;
}

private static async ValueTask<string> GetServerDirectoryPath(string host, int port, string clientCertificateFolderPath, bool useGeneratedCertificate)
private static async ValueTask<string> GetServerDirectoryPath(string host, int port, string clientCertificateFolderPath, bool useGeneratedCertificate, bool usingMtls)
{
if (useGeneratedCertificate)
{
return await GetCertificatesFromServer(host, port, clientCertificateFolderPath);
return await GetCertificatesFromServer(host, port, clientCertificateFolderPath, usingMtls);
}
return await IdentifyServerDirectory(host, port, clientCertificateFolderPath);
}
Expand All @@ -46,15 +48,16 @@ public class Builder
private string? ClientCertificateKeyPassword { get; set; }
private bool UseGeneratedCertificate { get; set; } = true;
private bool TrustedServerCertificate { get; set; }
private bool UsingMtls { get; set; }
private string? Host { get; set; }
private int Port { get; set; }

public async Task<ClientCertificateManager> Build()
{
string certificatePath = await GetServerDirectoryPath(Host!, Port, ClientCertificateFolderPath, UseGeneratedCertificate);
string certificatePath = await GetServerDirectoryPath(Host!, Port, ClientCertificateFolderPath, UseGeneratedCertificate, UsingMtls);
return new ClientCertificateManager(certificatePath, ClientCertificatePath,
ClientCertificateKeyPath, ClientCertificateKeyPassword, UseGeneratedCertificate,
TrustedServerCertificate);
TrustedServerCertificate, UsingMtls);
}

public Builder SetClientCertificateFolderPath(string? clientCertificateFolderPath)
Expand Down Expand Up @@ -94,10 +97,16 @@ public Builder SetTrustedServerCertificate(bool trustedServerCertificate)
TrustedServerCertificate = trustedServerCertificate;
return this;
}

public Builder SetUsingMtls(bool usingMtls)
{
UsingMtls = usingMtls;
return this;
}
}

private static async Task<string> GetCertificatesFromServer(string host, int systemApiPort,
string certificateClientFolderPath)
string certificateClientFolderPath, bool usingMtls)
{
string apiEndpoint = $"http://{host}:{systemApiPort}/system/";
string serverName = await GetServerName(apiEndpoint);
Expand All @@ -122,15 +131,17 @@ private static async Task<string> GetCertificatesFromServer(string host, int sys
try
{
await DownloadFile(apiEndpoint, serverSpecificDirectory, CertificateUtils.GeneratedCertificateFileName);
await DownloadFile(apiEndpoint, serverSpecificDirectory, CertificateUtils.GeneratedClientCertificateFileName);
await DownloadFile(apiEndpoint, serverSpecificDirectory, CertificateUtils.GeneratedClientCertificateKeyFileName);

if (usingMtls)
{
await DownloadFile(apiEndpoint, serverSpecificDirectory, CertificateUtils.GeneratedClientCertificateFileName);
await DownloadFile(apiEndpoint, serverSpecificDirectory, CertificateUtils.GeneratedClientCertificateKeyFileName);
}
return serverSpecificDirectory;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw new EvitaInvalidUsageException(ex.Message, "Failed to download certificates from the server", ex);
throw new EvitaInvalidUsageException(ex.Message, $"Failed to download {(usingMtls ? "client" : "")} certificates from the server", ex);
}
}

Expand Down
4 changes: 2 additions & 2 deletions EvitaDB.Client/Config/EvitaClientConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public record EvitaClientConfiguration(
string? TraceEndpointProtocol
)
{
private const int DefaultGrpcApiPort = 5556;
private const int DefaultSystemApiPort = 5557;
private const int DefaultGrpcApiPort = 5555;
private const int DefaultSystemApiPort = 5555;

public class Builder
{
Expand Down
1 change: 1 addition & 0 deletions EvitaDB.Client/EvitaClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public static async Task<EvitaClient> Create(EvitaClientConfiguration configurat
.SetUseGeneratedCertificate(configuration.UseGeneratedCertificate, configuration.Host,
configuration.SystemApiPort)
.SetTrustedServerCertificate(configuration.UsingTrustedRootCaCertificate)
.SetUsingMtls(configuration.MtlsEnabled)
.Build();
return new EvitaClient(configuration, certificateManager);
}
Expand Down
2 changes: 0 additions & 2 deletions EvitaDB.QueryValidator/evita-csharp-query-template.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,11 @@ public class DynamicClass
private static readonly EvitaClientConfiguration EvitaClientConfiguration =
Host == "localhost" ? new EvitaClientConfiguration.Builder()
.SetHost(Host)
.SetPort(5556)
.SetUseGeneratedCertificate(true)
.SetUsingTrustedRootCaCertificate(false)
.Build() :
new EvitaClientConfiguration.Builder()
.SetHost(Host)
.SetPort(5556)
.SetUseGeneratedCertificate(false)
.SetUsingTrustedRootCaCertificate(true)
.Build();
Expand Down
1 change: 0 additions & 1 deletion EvitaDB.Test/DemoSetupFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public class DemoSetupFixture : BaseSetupFixture
private static readonly EvitaClientConfiguration EvitaClientConfiguration =
new EvitaClientConfiguration.Builder()
.SetHost("demo.evitadb.io")
.SetPort(5556)
.SetUseGeneratedCertificate(false)
.SetUsingTrustedRootCaCertificate(true)
.Build();
Expand Down
2 changes: 1 addition & 1 deletion EvitaDB.Test/EvitaDB.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<PackageReference Include="Docker.DotNet" Version="3.125.15" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2"/>
<PackageReference Include="Testcontainers" Version="3.5.0" />
<PackageReference Include="Testcontainers" Version="3.9.0" />
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
39 changes: 20 additions & 19 deletions EvitaDB.Test/SetupFixture.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Net;
using Docker.DotNet;
using Docker.DotNet.Models;
using DotNet.Testcontainers.Builders;
Expand All @@ -11,13 +12,13 @@ namespace EvitaDB.Test;
public class SetupFixture : BaseSetupFixture
{
private readonly IList<EvitaTestSuite> _testSuites = new List<EvitaTestSuite>();
private const int GrpcPort = 5556;
private const int SystemApiPort = 5557;
private const string Host = "localhost";

private const int GrpcPort = 5555;
private const int SystemApiPort = 5555;
private const string Host = "127.0.0.1";
private const string ImageName = $"evitadb/evitadb:{ImageVersion}";
private const string ImageVersion = "canary";

public override Task<EvitaClient> GetClient()
{
if (Clients.TryDequeue(out EvitaClient? evitaClient))
Expand All @@ -26,9 +27,10 @@ public override Task<EvitaClient> GetClient()
evitaClient.Close();
return EvitaClient.Create(evitaClient.Configuration);
}

return InitializeEvitaContainerAndClientClient();
}

public override void ReturnClient(EvitaClient client)
{
Clients.Enqueue(client);
Expand All @@ -43,10 +45,7 @@ public override async Task InitializeAsync()
{
Filters = new Dictionary<string, IDictionary<string, bool>>
{
["reference"] = new Dictionary<string, bool>
{
[ImageName] = true,
},
["reference"] = new Dictionary<string, bool> { [ImageName] = true, },
}
});
if (images.Count > 0)
Expand Down Expand Up @@ -86,30 +85,32 @@ public override async Task DisposeAsync()
evitaClient.Close();
}
}

private async Task<EvitaClient> InitializeEvitaContainerAndClientClient(bool cacheCreatedEntitiesAndDestroySetupClient = false)

private async Task<EvitaClient> InitializeEvitaContainerAndClientClient(
bool cacheCreatedEntitiesAndDestroySetupClient = false)
{
IContainer container;
using (var consumer = Consume.RedirectStdoutAndStderrToConsole())
{
container = new ContainerBuilder()
.WithName($"evita-{Guid.NewGuid().ToString()}")
.WithEnvironment("EVITA_ARGS", "api.endpoints.rest.host=:5555 api.endpoints.rest.tlsMode=RELAXED api.endpoints.graphQL.host=:5555 api.endpoints.graphQL.tlsMode=RELAXED api.endpoints.gRPC.mTLS.enabled=false api.endpoints.gRPC.host=:5555 api.endpoints.gRPC.tlsMode=RELAXED api.endpoints.system.host=:5555 api.endpoints.observability.host=:5555 api.endpoints.lab.host=:5555")
// Set the image for the container to "evitadb/evitadb".
.WithImage(ImageName)
// Bind ports of the container.
.WithPortBinding(GrpcPort, true)
.WithPortBinding(SystemApiPort, true)
.WithWaitStrategy(
Wait.ForUnixContainer().UntilPortIsAvailable(GrpcPort).UntilPortIsAvailable(SystemApiPort))
Wait.ForUnixContainer().UntilPortIsAvailable(GrpcPort).UntilPortIsAvailable(SystemApiPort).AddCustomWaitStrategy(new CustomWaitStrategy())
)
.WithOutputConsumer(consumer)
// Build the container configuration.
.Build();

// Start the container.
try
{
await container.StartAsync()
.ConfigureAwait(false);
await container.StartAsync().ConfigureAwait(false);
}
catch (Exception e)
{
Expand All @@ -123,7 +124,7 @@ await container.StartAsync()
.SetPort(container.GetMappedPublicPort(GrpcPort))
.SetSystemApiPort(container.GetMappedPublicPort(SystemApiPort))
.Build();

// create a new evita client with the specified configuration
using (EvitaClient setupClient = await EvitaClient.Create(configuration))
{
Expand All @@ -134,10 +135,10 @@ await container.StartAsync()
}

EvitaClient client = await EvitaClient.Create(configuration);

_testSuites.Add(new EvitaTestSuite(client, container));
Clients.Enqueue(client);

return client;
}

Expand Down
2 changes: 1 addition & 1 deletion EvitaDB.Test/Tests/EvitaClientReadTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public void ShouldGetListWithExtraResults()
Data.ReferenceCategories,
FromRoot(Data.HierarchyReferenceRoot, EntityFetchAll())
),
FacetSummary(FacetStatisticsDepth.Impact)
FacetSummaryOfReference(Data.ReferenceRelatedProducts, FacetStatisticsDepth.Impact)
)
)
);
Expand Down
41 changes: 41 additions & 0 deletions EvitaDB.Test/Utils/CustomWaitStrategy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Net;
using System.Net.Http.Headers;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers;

namespace EvitaDB.Test.Utils;

public class CustomWaitStrategy : IWaitUntil
{
public async Task<bool> UntilAsync(IContainer container)
{
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
var httpClient = new HttpClient()
{
Timeout = TimeSpan.FromSeconds(5)
};
while (true)
{
try
{
var message =
new HttpRequestMessage(HttpMethod.Get,
$"http://{container.Hostname}:{container.GetMappedPublicPort(5555)}/system/server-name")
{
Version = new Version(2, 0),
Headers =
{
Accept = { MediaTypeWithQualityHeaderValue.Parse("application/json") },
UserAgent = { ProductInfoHeaderValue.Parse("EvitaDB.Test") }
}
};
await httpClient.SendAsync(message);
return true;
}
catch (Exception)
{
// wait
}
}
}
}

0 comments on commit 2bc1ca1

Please sign in to comment.