Skip to content

Commit

Permalink
Client Configuration (#123)
Browse files Browse the repository at this point in the history
Updated CryptoExchange.Net to version 8.3.0
Added support for loading client settings from IConfiguration
Added DI registration method for configuring Rest and Socket options at the same time
Added DisplayName and ImageUrl properties to HTXExchange class
Updated client constructors to accept IOptions from DI
Removed redundant HTXSocketClient constructor
  • Loading branch information
JKorf authored Nov 19, 2024
1 parent c382d48 commit d0c8b10
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 94 deletions.
102 changes: 102 additions & 0 deletions HTX.Net.UnitTests/HTXRestClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
using System.Net.Http;
using System.Collections.Generic;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using HTX.Net.Interfaces.Clients;
using CryptoExchange.Net.Objects;

namespace HTX.Net.UnitTests
{
Expand Down Expand Up @@ -83,5 +87,103 @@ public void CheckInterfaces()
CryptoExchange.Net.Testing.TestHelpers.CheckForMissingRestInterfaces<HTXRestClient>();
CryptoExchange.Net.Testing.TestHelpers.CheckForMissingSocketInterfaces<HTXSocketClient>();
}

[Test]
[TestCase(TradeEnvironmentNames.Live, "https://api.huobi.pro")]
[TestCase("", "https://api.huobi.pro")]
public void TestConstructorEnvironments(string environmentName, string expected)
{
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "HTX:Environment:Name", environmentName },
}).Build();

var collection = new ServiceCollection();
collection.AddHTX(configuration.GetSection("HTX"));
var provider = collection.BuildServiceProvider();

var client = provider.GetRequiredService<IHTXRestClient>();

var address = client.SpotApi.BaseAddress;

Assert.That(address, Is.EqualTo(expected));
}

[Test]
public void TestConstructorNullEnvironment()
{
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "HTX", null },
}).Build();

var collection = new ServiceCollection();
collection.AddHTX(configuration.GetSection("HTX"));
var provider = collection.BuildServiceProvider();

var client = provider.GetRequiredService<IHTXRestClient>();

var address = client.SpotApi.BaseAddress;

Assert.That(address, Is.EqualTo("https://api.huobi.pro"));
}

[Test]
public void TestConstructorApiOverwriteEnvironment()
{
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "HTX:Environment:Name", "test" },
{ "HTX:Rest:Environment:Name", "live" },
}).Build();

var collection = new ServiceCollection();
collection.AddHTX(configuration.GetSection("HTX"));
var provider = collection.BuildServiceProvider();

var client = provider.GetRequiredService<IHTXRestClient>();

var address = client.SpotApi.BaseAddress;

Assert.That(address, Is.EqualTo("https://api.huobi.pro"));
}

[Test]
public void TestConstructorConfiguration()
{
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "ApiCredentials:Key", "123" },
{ "ApiCredentials:Secret", "456" },
{ "Socket:ApiCredentials:Key", "456" },
{ "Socket:ApiCredentials:Secret", "789" },
{ "Rest:OutputOriginalData", "true" },
{ "Socket:OutputOriginalData", "false" },
{ "Rest:Proxy:Host", "host" },
{ "Rest:Proxy:Port", "80" },
{ "Socket:Proxy:Host", "host2" },
{ "Socket:Proxy:Port", "81" },
}).Build();

var collection = new ServiceCollection();
collection.AddHTX(configuration);
var provider = collection.BuildServiceProvider();

var restClient = provider.GetRequiredService<IHTXRestClient>();
var socketClient = provider.GetRequiredService<IHTXSocketClient>();

Assert.That(((BaseApiClient)restClient.SpotApi).OutputOriginalData, Is.True);
Assert.That(((BaseApiClient)socketClient.SpotApi).OutputOriginalData, Is.False);
Assert.That(((BaseApiClient)restClient.SpotApi).AuthenticationProvider.ApiKey, Is.EqualTo("123"));
Assert.That(((BaseApiClient)socketClient.SpotApi).AuthenticationProvider.ApiKey, Is.EqualTo("456"));
Assert.That(((BaseApiClient)restClient.SpotApi).ClientOptions.Proxy.Host, Is.EqualTo("host"));
Assert.That(((BaseApiClient)restClient.SpotApi).ClientOptions.Proxy.Port, Is.EqualTo(80));
Assert.That(((BaseApiClient)socketClient.SpotApi).ClientOptions.Proxy.Host, Is.EqualTo("host2"));
Assert.That(((BaseApiClient)socketClient.SpotApi).ClientOptions.Proxy.Port, Is.EqualTo(81));
}
}
}
9 changes: 5 additions & 4 deletions HTX.Net.UnitTests/HTXRestIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Text;
using System.Threading.Tasks;
using HTX.Net.Enums;
using Microsoft.Extensions.Options;

namespace HTX.Net.UnitTests
{
Expand All @@ -28,11 +29,11 @@ public override HTXRestClient GetClient(ILoggerFactory loggerFactory)
var sec = Environment.GetEnvironmentVariable("APISECRET");

Authenticated = key != null && sec != null;
return new HTXRestClient(null, loggerFactory, opts =>
return new HTXRestClient(null, loggerFactory, Options.Create(new Objects.Options.HTXRestOptions
{
opts.OutputOriginalData = true;
opts.ApiCredentials = Authenticated ? new ApiCredentials(key, sec) : null;
});
OutputOriginalData = true,
ApiCredentials = Authenticated ? new ApiCredentials(key, sec) : null
}));
}

[Test]
Expand Down
21 changes: 9 additions & 12 deletions HTX.Net/Clients/HTXRestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using CryptoExchange.Net.Clients;
using HTX.Net.Interfaces.Clients.UsdtFuturesApi;
using HTX.Net.Clients.UsdtFutures;
using Microsoft.Extensions.Options;

namespace HTX.Net.Clients
{
Expand All @@ -26,26 +27,24 @@ public class HTXRestClient : BaseRestClient, IHTXRestClient
/// Create a new instance of the HTXRestClient using provided options
/// </summary>
/// <param name="optionsDelegate">Option configuration delegate</param>
public HTXRestClient(Action<HTXRestOptions>? optionsDelegate = null) : this(null, null, optionsDelegate)
public HTXRestClient(Action<HTXRestOptions>? optionsDelegate = null)
: this(null, null, Options.Create(ApplyOptionsDelegate(optionsDelegate)))
{
}

/// <summary>
/// Create a new instance of the HTXRestClient
/// </summary>
/// <param name="optionsDelegate">Option configuration delegate</param>
/// <param name="options">Option configuration delegate</param>
/// <param name="loggerFactory">The logger factory</param>
/// <param name="httpClient">Http client for this client</param>
public HTXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, Action<HTXRestOptions>? optionsDelegate = null)
public HTXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, IOptions<HTXRestOptions> options)
: base(loggerFactory, "HTX")
{
var options = HTXRestOptions.Default.Copy();
if (optionsDelegate != null)
optionsDelegate(options);
Initialize(options);
Initialize(options.Value);

SpotApi = AddApiClient(new HTXRestClientSpotApi(_logger, httpClient, options));
UsdtFuturesApi = AddApiClient(new HTXRestClientUsdtFuturesApi(_logger, httpClient, options));
SpotApi = AddApiClient(new HTXRestClientSpotApi(_logger, httpClient, options.Value));
UsdtFuturesApi = AddApiClient(new HTXRestClientUsdtFuturesApi(_logger, httpClient, options.Value));
}
#endregion

Expand All @@ -56,9 +55,7 @@ public HTXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, Acti
/// <param name="optionsDelegate">Option configuration delegate</param>
public static void SetDefaultOptions(Action<HTXRestOptions> optionsDelegate)
{
var options = HTXRestOptions.Default.Copy();
optionsDelegate(options);
HTXRestOptions.Default = options;
HTXRestOptions.Default = ApplyOptionsDelegate(optionsDelegate);
}

/// <inheritdoc />
Expand Down
27 changes: 9 additions & 18 deletions HTX.Net/Clients/HTXSocketClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using HTX.Net.Interfaces.Clients.SpotApi;
using HTX.Net.Interfaces.Clients.UsdtFuturesApi;
using HTX.Net.Objects.Options;
using Microsoft.Extensions.Options;

namespace HTX.Net.Clients
{
Expand All @@ -19,35 +20,27 @@ public class HTXSocketClient : BaseSocketClient, IHTXSocketClient
#endregion

#region ctor
/// <summary>
/// Create a new instance of the HTXSocketClient
/// </summary>
/// <param name="loggerFactory">The logger factory</param>
public HTXSocketClient(ILoggerFactory? loggerFactory = null) : this((x) => { }, loggerFactory)
{
}

/// <summary>
/// Create a new instance of the HTXSocketClient
/// </summary>
/// <param name="optionsDelegate">Option configuration delegate</param>
public HTXSocketClient(Action<HTXSocketOptions> optionsDelegate) : this(optionsDelegate, null)
public HTXSocketClient(Action<HTXSocketOptions>? optionsDelegate = null)
: this(Options.Create(ApplyOptionsDelegate(optionsDelegate)), null)
{
}

/// <summary>
/// Create a new instance of the HTXSocketClient
/// </summary>
/// <param name="loggerFactory">The logger factory</param>
/// <param name="optionsDelegate">Option configuration delegate</param>
public HTXSocketClient(Action<HTXSocketOptions> optionsDelegate, ILoggerFactory? loggerFactory = null) : base(loggerFactory, "HTX")
/// <param name="options">Option configuration</param>
public HTXSocketClient(IOptions<HTXSocketOptions> options, ILoggerFactory? loggerFactory = null) : base(loggerFactory, "HTX")
{
var options = HTXSocketOptions.Default.Copy();
optionsDelegate(options);
Initialize(options);
Initialize(options.Value);

SpotApi = AddApiClient(new HTXSocketClientSpotApi(_logger, options));
UsdtFuturesApi = AddApiClient(new HTXSocketClientUsdtFuturesApi(_logger, options));
SpotApi = AddApiClient(new HTXSocketClientSpotApi(_logger, options.Value));
UsdtFuturesApi = AddApiClient(new HTXSocketClientUsdtFuturesApi(_logger, options.Value));
}
#endregion

Expand All @@ -58,9 +51,7 @@ public HTXSocketClient(Action<HTXSocketOptions> optionsDelegate, ILoggerFactory?
/// <param name="optionsDelegate">Option configuration delegate</param>
public static void SetDefaultOptions(Action<HTXSocketOptions> optionsDelegate)
{
var options = HTXSocketOptions.Default.Copy();
optionsDelegate(options);
HTXSocketOptions.Default = options;
HTXSocketOptions.Default = ApplyOptionsDelegate(optionsDelegate);
}

/// <inheritdoc />
Expand Down
Loading

0 comments on commit d0c8b10

Please sign in to comment.