Skip to content

feat: create Client from connection string or environment variables #46

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

Merged
merged 9 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .markdownlint.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{
"MD013": false,
"MD024": false,
"MD024": {
"siblings_only": true
},
"MD033": {
"allowed_elements": [ "a", "img", "p" ]
},
"MD041": false,
}
}
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### Features

1. [#36](https://github.com/InfluxCommunity/influxdb3-csharp/pull/46): Add client creation from connection string
and environment variables.
1. [#52](https://github.com/InfluxCommunity/influxdb3-csharp/pull/52): Add structured query support

### Docs
Expand Down
198 changes: 198 additions & 0 deletions Client.Test/Config/ClientConfigTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
using System;
using System.Collections.Generic;
using InfluxDB3.Client.Write;

namespace InfluxDB3.Client.Config.Test;

public class ClientConfigTest
{
[Test]
public void RequiredConfig()
{
var ae = Assert.Throws<ArgumentNullException>(() => { new InfluxDBClient((ClientConfig)null); });

Assert.That(ae, Is.Not.Null);
Assert.That(ae.Message, Is.EqualTo("Value cannot be null. (Parameter 'config')"));
}

[Test]
public void CreateFromConnectionStringMinimal()
{
var cfg = new ClientConfig("http://localhost:8086?token=my-token");
Assert.That(cfg, Is.Not.Null);
cfg.Validate();
Assert.Multiple(() =>
{
Assert.That(cfg.Host, Is.EqualTo("http://localhost:8086/"));
Assert.That(cfg.Token, Is.EqualTo("my-token"));
Assert.That(cfg.Organization, Is.EqualTo(null));
Assert.That(cfg.Database, Is.EqualTo(null));
Assert.That(cfg.WriteOptions, Is.EqualTo(null));
});
}

[Test]
public void CreateFromConnectionStringBasic()
{
var cfg = new ClientConfig("http://localhost:8086?token=my-token&org=my-org&database=my-database");
Assert.That(cfg, Is.Not.Null);
cfg.Validate();
Assert.Multiple(() =>
{
Assert.That(cfg.Host, Is.EqualTo("http://localhost:8086/"));
Assert.That(cfg.Token, Is.EqualTo("my-token"));
Assert.That(cfg.Organization, Is.EqualTo("my-org"));
Assert.That(cfg.Database, Is.EqualTo("my-database"));
Assert.That(cfg.WriteOptions, Is.EqualTo(null));
});
}

[Test]
public void CreateFromConnectionStringWithWriteOptions()
{
var cfg = new ClientConfig("http://localhost:8086?token=my-token&org=my-org&database=my-database&precision=s&gzipThreshold=64");
Assert.That(cfg, Is.Not.Null);
cfg.Validate();
Assert.Multiple(() =>
{
Assert.That(cfg.Host, Is.EqualTo("http://localhost:8086/"));
Assert.That(cfg.Token, Is.EqualTo("my-token"));
Assert.That(cfg.Organization, Is.EqualTo("my-org"));
Assert.That(cfg.Database, Is.EqualTo("my-database"));
Assert.That(cfg.WriteOptions.Precision, Is.EqualTo(WritePrecision.S));
Assert.That(cfg.WriteOptions.GzipThreshold, Is.EqualTo(64));
});
}

[Test]
public void CreateFromConnectionStringPrecisions()
{
var precisions = new[]
{
("ns", WritePrecision.Ns),
("us", WritePrecision.Us),
("ms", WritePrecision.Ms),
("s", WritePrecision.S),
};
foreach (var precision in precisions)
{
var cfg = new ClientConfig($"http://localhost:8086?token=my-token&precision={precision.Item1}");
Assert.That(cfg, Is.Not.Null);
cfg.Validate();
Assert.Multiple(() =>
{
Assert.That(cfg.Host, Is.EqualTo("http://localhost:8086/"));
Assert.That(cfg.Token, Is.EqualTo("my-token"));
Assert.That(cfg.WriteOptions.Precision, Is.EqualTo(precision.Item2));
});
}
}

[Test]
public void CreateFromConnectionStringInvalidPrecision()
{
var ae = Assert.Throws<ArgumentException>(() => { new ClientConfig("http://localhost:8086?token=my-token&precision=xs"); });

Assert.That(ae, Is.Not.Null);
Assert.That(ae.Message, Is.EqualTo("Unsupported precision 'xs'"));
}

[Test]
public void CreateFromEnvMinimal()
{
var env = new Dictionary<String, String>
{
{"INFLUX_HOST", "http://localhost:8086"},
{"INFLUX_TOKEN", "my-token"},
};
SetEnv(env);
var cfg = new ClientConfig(env);
Assert.That(cfg, Is.Not.Null);
cfg.Validate();
Assert.Multiple(() =>
{
Assert.That(cfg.Host, Is.EqualTo("http://localhost:8086/"));
Assert.That(cfg.Token, Is.EqualTo("my-token"));
Assert.That(cfg.Organization, Is.EqualTo(null));
Assert.That(cfg.Database, Is.EqualTo(null));
Assert.That(cfg.WriteOptions, Is.EqualTo(null));
});
}

[Test]
public void CreateFromEnvBasic()
{
var env = new Dictionary<String, String>
{
{"INFLUX_HOST", "http://localhost:8086"},
{"INFLUX_TOKEN", "my-token"},
{"INFLUX_ORG", "my-org"},
{"INFLUX_DATABASE", "my-database"},
};
SetEnv(env);
var cfg = new ClientConfig(env);
Assert.That(cfg, Is.Not.Null);
cfg.Validate();
Assert.Multiple(() =>
{
Assert.That(cfg.Host, Is.EqualTo("http://localhost:8086/"));
Assert.That(cfg.Token, Is.EqualTo("my-token"));
Assert.That(cfg.Organization, Is.EqualTo("my-org"));
Assert.That(cfg.Database, Is.EqualTo("my-database"));
Assert.That(cfg.WriteOptions, Is.EqualTo(null));
});
}

[Test]
public void CreateFromEnvWithWriteOptions()
{
var env = new Dictionary<String, String>
{
{"INFLUX_HOST", "http://localhost:8086"},
{"INFLUX_TOKEN", "my-token"},
{"INFLUX_ORG", "my-org"},
{"INFLUX_DATABASE", "my-database"},
{"INFLUX_PRECISION", "s"},
{"INFLUX_GZIP_THRESHOLD", "64"},
};
SetEnv(env);
var cfg = new ClientConfig(env);
Assert.That(cfg, Is.Not.Null);
cfg.Validate();
Assert.Multiple(() =>
{
Assert.That(cfg.Host, Is.EqualTo("http://localhost:8086/"));
Assert.That(cfg.Token, Is.EqualTo("my-token"));
Assert.That(cfg.Organization, Is.EqualTo("my-org"));
Assert.That(cfg.Database, Is.EqualTo("my-database"));
Assert.That(cfg.WriteOptions.Precision, Is.EqualTo(WritePrecision.S));
Assert.That(cfg.WriteOptions.GzipThreshold, Is.EqualTo(64));
});
}

private static void SetEnv(IDictionary<String, String> dict)
{
foreach (var entry in dict)
{
Environment.SetEnvironmentVariable(entry.Key, entry.Value, EnvironmentVariableTarget.Process);
}
}

[TearDown]
public void Cleanup()
{
var envVars = new List<String>
{
ClientConfig.EnvInfluxHost,
ClientConfig.EnvInfluxToken,
ClientConfig.EnvInfluxOrg,
ClientConfig.EnvInfluxDatabase,
ClientConfig.EnvInfluxPrecision,
ClientConfig.EnvInfluxGzipThreshold
};
foreach (var envVar in envVars)
{
Environment.SetEnvironmentVariable(envVar, null, EnvironmentVariableTarget.Process);
}
}
}
54 changes: 46 additions & 8 deletions Client.Test/InfluxDBClientTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

// ReSharper disable ObjectCreationAsStatement
// ReSharper disable AssignNullToNotNullAttribute
Expand All @@ -10,26 +11,63 @@ public class InfluxDBClientTest
[Test]
public void Create()
{
using var client = new InfluxDBClient("http://localhost:8086", organization: "org", database: "database");
using var client = new InfluxDBClient("http://localhost:8086", token: "my-token", organization: "my-org", database: "my-database");

Assert.That(client, Is.Not.Null);
}

[Test]
public void RequiredHost()
public void CreateFromConnectionString()
{
var ae = Assert.Throws<ArgumentException>(() => { new InfluxDBClient(host: null); });
using var client = new InfluxDBClient("http://localhost:8086?token=my-token&org=my-org&database=my-db");

Assert.That(ae, Is.Not.Null);
Assert.That(ae.Message, Is.EqualTo("The URL of the InfluxDB server has to be defined."));
Assert.That(client, Is.Not.Null);
}

[Test]
public void RequiredConfigs()
public void CreateFromEnv()
{
var ae = Assert.Throws<ArgumentException>(() => { new InfluxDBClient(null); });
var env = new Dictionary<String, String>
{
{"INFLUX_HOST", "http://localhost:8086"},
{"INFLUX_TOKEN", "my-token"},
{"INFLUX_ORG", "my-org"},
{"INFLUX_DATABASE", "my-database"},
};
SetEnv(env);

using var client = new InfluxDBClient();

Assert.That(client, Is.Not.Null);
}

[Test]
public void RequiredHost()
{
var ae = Assert.Throws<ArgumentException>(() => { new InfluxDBClient(host: null, token: ""); });

Assert.That(ae, Is.Not.Null);
Assert.That(ae.Message, Is.EqualTo("The configuration of the client has to be defined."));
Assert.That(ae.Message, Is.EqualTo("The URL of the InfluxDB server has to be defined"));
}

private static void SetEnv(IDictionary<String, String> dict)
{
foreach (var entry in dict)
{
Environment.SetEnvironmentVariable(entry.Key, entry.Value, EnvironmentVariableTarget.Process);
}
}

[TearDown]
public void Cleanup()
{
var env = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);
foreach (var key in env.Keys)
{
if (((string)key).StartsWith("INFLUX_"))
{
Environment.SetEnvironmentVariable((string)key, null, EnvironmentVariableTarget.Process);
}
}
}
}
Loading