Skip to content

Commit 0dc4c63

Browse files
feat: support create ClientConfig from string and env (#179)
1 parent b69735e commit 0dc4c63

File tree

6 files changed

+150
-46
lines changed

6 files changed

+150
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### Features
44

55
1. [#175](https://github.com/InfluxCommunity/influxdb3-csharp/pull/175): Add QueryTimeout and WriteTimeout to ClientConfig.
6+
1. [#179](https://github.com/InfluxCommunity/influxdb3-csharp/pull/179): Allows create ClientConfig from ClientConfig(string connectionString) and ClientConfig(IDictionary env)
67

78
## 1.4.0 [2025-09-15]
89

Client.Test/Config/ClientConfigTest.cs

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Immutable;
44
using Grpc.Net.Compression;
55
using InfluxDB3.Client.Test.Config;
6+
using InfluxDB3.Client.Test.Utils;
67
using InfluxDB3.Client.Write;
78

89
namespace InfluxDB3.Client.Config.Test;
@@ -148,7 +149,7 @@ public void CreateFromEnvMinimal()
148149
{"INFLUX_HOST", "http://localhost:8086"},
149150
{"INFLUX_TOKEN", "my-token"},
150151
};
151-
SetEnv(env);
152+
TestUtils.SetEnv(env);
152153
var cfg = new ClientConfig(env);
153154
Assert.That(cfg, Is.Not.Null);
154155
cfg.Validate();
@@ -172,7 +173,7 @@ public void CreateFromEnvBasic()
172173
{"INFLUX_ORG", "my-org"},
173174
{"INFLUX_DATABASE", "my-database"},
174175
};
175-
SetEnv(env);
176+
TestUtils.SetEnv(env);
176177
var cfg = new ClientConfig(env);
177178
Assert.That(cfg, Is.Not.Null);
178179
cfg.Validate();
@@ -195,7 +196,7 @@ public void CreateFromEnvWithAuthScheme()
195196
{"INFLUX_TOKEN", "my-token"},
196197
{"INFLUX_AUTH_SCHEME", "my-scheme"},
197198
};
198-
SetEnv(env);
199+
TestUtils.SetEnv(env);
199200
var cfg = new ClientConfig(env);
200201
Assert.That(cfg, Is.Not.Null);
201202
cfg.Validate();
@@ -221,7 +222,7 @@ public void CreateFromEnvWithWriteOptions()
221222
{"INFLUX_GZIP_THRESHOLD", "64"},
222223
{"INFLUX_WRITE_NO_SYNC", "true"},
223224
};
224-
SetEnv(env);
225+
TestUtils.SetEnv(env);
225226
var cfg = new ClientConfig(env);
226227
Assert.That(cfg, Is.Not.Null);
227228
cfg.Validate();
@@ -247,7 +248,7 @@ public void CreateFromEnvWithWriteNoSyncOnly()
247248
{"INFLUX_TOKEN", "my-token"},
248249
{"INFLUX_WRITE_NO_SYNC", "true"},
249250
};
250-
SetEnv(env);
251+
TestUtils.SetEnv(env);
251252
var cfg = new ClientConfig(env);
252253
Assert.That(cfg, Is.Not.Null);
253254
cfg.Validate();
@@ -264,14 +265,6 @@ public void CreateFromEnvWithWriteNoSyncOnly()
264265
});
265266
}
266267

267-
private static void SetEnv(IDictionary<String, String> dict)
268-
{
269-
foreach (var entry in dict)
270-
{
271-
Environment.SetEnvironmentVariable(entry.Key, entry.Value, EnvironmentVariableTarget.Process);
272-
}
273-
}
274-
275268
[Test]
276269
public void DefaultQueryOptionsValue()
277270
{
@@ -299,19 +292,6 @@ public void CustomQueryOptions()
299292
[TearDown]
300293
public void Cleanup()
301294
{
302-
var envVars = new List<String>
303-
{
304-
ClientConfig.EnvInfluxHost,
305-
ClientConfig.EnvInfluxToken,
306-
ClientConfig.EnvInfluxOrg,
307-
ClientConfig.EnvInfluxDatabase,
308-
ClientConfig.EnvInfluxPrecision,
309-
ClientConfig.EnvInfluxGzipThreshold,
310-
ClientConfig.EnvInfluxWriteNoSync
311-
};
312-
foreach (var envVar in envVars)
313-
{
314-
Environment.SetEnvironmentVariable(envVar, null, EnvironmentVariableTarget.Process);
315-
}
295+
TestUtils.CleanupEnv();
316296
}
317297
}

Client.Test/InfluxDBClientTest.cs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3+
using InfluxDB3.Client.Config;
4+
using InfluxDB3.Client.Test.Utils;
35

46
// ReSharper disable ObjectCreationAsStatement
57
// ReSharper disable AssignNullToNotNullAttribute
@@ -34,7 +36,7 @@ public void CreateFromEnv()
3436
{"INFLUX_ORG", "my-org"},
3537
{"INFLUX_DATABASE", "my-database"},
3638
};
37-
SetEnv(env);
39+
TestUtils.SetEnv(env);
3840

3941
using var client = new InfluxDBClient();
4042

@@ -50,24 +52,9 @@ public void RequiredHost()
5052
Assert.That(ae.Message, Is.EqualTo("The URL of the InfluxDB server has to be defined"));
5153
}
5254

53-
private static void SetEnv(IDictionary<String, String> dict)
54-
{
55-
foreach (var entry in dict)
56-
{
57-
Environment.SetEnvironmentVariable(entry.Key, entry.Value, EnvironmentVariableTarget.Process);
58-
}
59-
}
60-
6155
[TearDown]
6256
public void Cleanup()
6357
{
64-
var env = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);
65-
foreach (var key in env.Keys)
66-
{
67-
if (((string)key).StartsWith("INFLUX_"))
68-
{
69-
Environment.SetEnvironmentVariable((string)key, null, EnvironmentVariableTarget.Process);
70-
}
71-
}
58+
TestUtils.CleanupEnv();
7259
}
7360
}

Client.Test/InfluxDBClientWriteTest.cs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
using System.Net;
55
using System.Threading;
66
using System.Threading.Tasks;
7+
using System.Web;
78
using InfluxDB3.Client.Config;
9+
using InfluxDB3.Client.Test.Utils;
810
using InfluxDB3.Client.Write;
911
using WireMock.Matchers;
1012
using WireMock.RequestBuilders;
@@ -559,6 +561,113 @@ public void TimeoutExceededByToken()
559561
TestWritePointsAsync(_client, cancellationToken);
560562
}
561563

564+
[Test]
565+
public async Task WriteFromUrl()
566+
{
567+
MockServer
568+
.Given(Request.Create().WithPath("/api/v3/write_lp").UsingPost())
569+
.RespondWith(Response.Create().WithStatusCode(204));
570+
571+
const string token = "my-token";
572+
const string org = "my-org";
573+
const string db = "my-database";
574+
const string precision = "nanosecond";
575+
const string authSchema = "Token";
576+
const bool writeNoSync = true;
577+
const int gzipThreshold = 2024;
578+
579+
var parameters = HttpUtility.ParseQueryString(string.Empty);
580+
parameters.Add("database", db);
581+
parameters.Add("token", token);
582+
parameters.Add("authScheme", authSchema);
583+
parameters.Add("org", org);
584+
parameters.Add("precision", precision);
585+
parameters.Add("writeNoSync", writeNoSync.ToString().ToLower());
586+
parameters.Add("gzipThreshold", gzipThreshold.ToString()); ;
587+
var uriBuilder = new UriBuilder(MockServerUrl);
588+
uriBuilder.Query = parameters.ToString()!;
589+
590+
var clientConfig = new ClientConfig(uriBuilder.Uri.ToString());
591+
Assert.That(clientConfig.WriteOptions!.GzipThreshold, Is.EqualTo(gzipThreshold)); ;
592+
593+
_client = new InfluxDBClient(clientConfig);
594+
await _client.WritePointAsync(PointData
595+
.Measurement("cpu")
596+
.SetTag("tag", "c")
597+
.SetField("field", 1)
598+
);
599+
600+
var requests = MockServer.LogEntries.ToList();
601+
using (Assert.EnterMultipleScope())
602+
{
603+
Assert.That(requests[0].RequestMessage.Query?["db"].First(), Is.EqualTo(db));
604+
Assert.That(requests[0].RequestMessage.Query?["org"].First(), Is.EqualTo(org));
605+
Assert.That(requests[0].RequestMessage.Query?["precision"].First(), Is.EqualTo(precision));
606+
Assert.That(requests[0].RequestMessage.Query?["no_sync"].First(), Is.EqualTo(writeNoSync.ToString().ToLower()));
607+
}
608+
var authHeader = requests[0].RequestMessage.Headers?["Authorization"].First().Split(" ");
609+
using (Assert.EnterMultipleScope())
610+
{
611+
Assert.That(authHeader?[0], Is.EqualTo(authSchema));
612+
Assert.That(authHeader?[1], Is.EqualTo(token));
613+
}
614+
}
615+
616+
[Test]
617+
public async Task WriteFromEnvVars()
618+
{
619+
MockServer
620+
.Given(Request.Create().WithPath("/api/v3/write_lp").UsingPost())
621+
.RespondWith(Response.Create().WithStatusCode(204));
622+
623+
const string token = "my-token";
624+
const string org = "my-org";
625+
const string db = "my-database";
626+
const string precision = "nanosecond";
627+
const string authSchema = "Token";
628+
const bool writeNoSync = true;
629+
const int gzipThreshold = 2024;
630+
631+
var dict = new Dictionary<string, string>()
632+
{
633+
{ ClientConfig.EnvInfluxHost, MockServerUrl },
634+
{ ClientConfig.EnvInfluxToken, token },
635+
{ ClientConfig.EnvInfluxOrg, org },
636+
{ ClientConfig.EnvInfluxDatabase, db },
637+
{ ClientConfig.EnvInfluxPrecision, precision },
638+
{ ClientConfig.EnvInfluxAuthScheme, authSchema },
639+
{ ClientConfig.EnvInfluxWriteNoSync, writeNoSync.ToString().ToLower() },
640+
{ ClientConfig.EnvInfluxGzipThreshold, gzipThreshold.ToString() }
641+
};
642+
643+
TestUtils.SetEnv(dict);
644+
645+
var clientConfig = new ClientConfig(dict);
646+
Assert.That(clientConfig.WriteOptions!.GzipThreshold, Is.EqualTo(gzipThreshold));
647+
648+
_client = new InfluxDBClient(clientConfig);
649+
await _client.WritePointAsync(PointData
650+
.Measurement("cpu")
651+
.SetTag("tag", "c")
652+
.SetField("field", 1)
653+
);
654+
655+
var requests = MockServer.LogEntries.ToList();
656+
using (Assert.EnterMultipleScope())
657+
{
658+
Assert.That(requests[0].RequestMessage.Query?["db"].First(), Is.EqualTo(db));
659+
Assert.That(requests[0].RequestMessage.Query?["org"].First(), Is.EqualTo(org));
660+
Assert.That(requests[0].RequestMessage.Query?["precision"].First(), Is.EqualTo(precision));
661+
Assert.That(requests[0].RequestMessage.Query?["no_sync"].First(), Is.EqualTo(writeNoSync.ToString().ToLower()));
662+
}
663+
var authHeader = requests[0].RequestMessage.Headers?["Authorization"].First().Split(" ");
664+
using (Assert.EnterMultipleScope())
665+
{
666+
Assert.That(authHeader?[0], Is.EqualTo(authSchema));
667+
Assert.That(authHeader?[1], Is.EqualTo(token));
668+
}
669+
}
670+
562671
private static void TestWriteRecordAsync(InfluxDBClient client, CancellationToken? cancellationToken = null)
563672
{
564673
Assert.ThrowsAsync<TaskCanceledException>(async () =>

Client.Test/Utils/TestUtils.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace InfluxDB3.Client.Test.Utils;
5+
6+
public static class TestUtils
7+
{
8+
public static void SetEnv(IDictionary<String, String> dict)
9+
{
10+
foreach (var entry in dict)
11+
{
12+
Environment.SetEnvironmentVariable(entry.Key, entry.Value, EnvironmentVariableTarget.Process);
13+
}
14+
}
15+
16+
public static void CleanupEnv()
17+
{
18+
var env = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);
19+
foreach (var key in env.Keys)
20+
{
21+
if (((string)key).StartsWith("INFLUX_"))
22+
{
23+
Environment.SetEnvironmentVariable((string)key, null, EnvironmentVariableTarget.Process);
24+
}
25+
}
26+
}
27+
}

Client/Config/ClientConfig.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public ClientConfig()
8484
/// <summary>
8585
/// Initializes a new instance of client configuration from connection string.
8686
/// </summary>
87-
internal ClientConfig(string connectionString)
87+
public ClientConfig(string connectionString)
8888
{
8989
var uri = new Uri(connectionString);
9090
Host = uri.GetLeftPart(UriPartial.Path);
@@ -102,7 +102,7 @@ internal ClientConfig(string connectionString)
102102
/// <summary>
103103
/// Initializes a new instance of client configuration from environment variables.
104104
/// </summary>
105-
internal ClientConfig(IDictionary env)
105+
public ClientConfig(IDictionary env)
106106
{
107107
Host = (string)env[EnvInfluxHost];
108108
Token = env[EnvInfluxToken] as string;

0 commit comments

Comments
 (0)