Skip to content

Commit

Permalink
v2.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
dhrovat committed Nov 8, 2024
1 parent 2c9b145 commit bb591e0
Show file tree
Hide file tree
Showing 19 changed files with 362 additions and 388 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Change Log

## 2024-11-08 2.4.1
- Improved how api requests are made (utilizing IHttpClientFactory)

## 2024-10-22 2.4.0
- CustomBet ICalculation and ICalculationFilter extended with new property Harmonization (extended with ICalculationV1 and ICalculationFilterV1)
- CustomBet ISelection extended with new property Odds (extended with ISelectionV1)
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ The SDK uses the following 3rd party libraries which must be added via the NuGet
- RabbitMQ.Client (6.5.0)

The package contains:
- DemoProject: A Visual Studio 2022 solution containing a demo project showing the basic usage of the SDK
- DemoProject: A solution containing a demo project showing the basic usage of the SDK
- libs: DLL file composing the Odds Feed SDK
- Odds Feed SDK Documentation.chm: A documentation file describing exposed entities
- Resources containing the log4net configuration needed by the Odds Feed SDK

For more information please contact [email protected] or visit https://iodocs.betradar.com/unifiedsdk/index.html
Expand Down
Binary file modified docs/docs/toc.pdf
Binary file not shown.
Binary file modified docs/sdkapi/toc.pdf
Binary file not shown.
Binary file modified docs/toc.pdf
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Sportradar.OddsFeed.SDKCore" Version="2.4.0" />
<PackageReference Include="Sportradar.OddsFeed.SDKCore" Version="2.4.0-rc1-feedsdk-2447" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ public void OnTimerWhenDataRouterManagerDisposedThenHandleDisposedException()
_dataRouterManager.UriExceptions.Add(new Tuple<string, Exception>("variant_market_descriptions.xml", new ObjectDisposedException("Drm disposed")));
_timer.FireOnce(TimeSpan.Zero);

var success = TestExecutionHelper.WaitToComplete(() => _cultures.Count == _dataRouterManager.GetCallCount(TestDataRouterManager.EndpointVariantDescriptions));
var success = TestExecutionHelper.WaitToComplete(() => _cultures.Count == _dataRouterManager.GetCallCount(TestDataRouterManager.EndpointVariantDescriptions), timeoutMs: 20000);

Assert.True(success);
}
Expand Down Expand Up @@ -845,19 +845,19 @@ public async Task LoadMarketDescriptionsWhenReloadingThenNoThrottlingHappens()
// public async Task GetAllWhenNoDataPresentThenReturnEmptyCollection()
// {
// Assert.Equal(0, _variantsListMemoryCache.Count());
//
//
// var result = await _variantsListCache.GetAllInvariantMarketDescriptionsAsync(_cultures);
//
//
// Assert.Empty(result);
// }
//
// [Fact]
// public async Task GetAllWhenDataPresentThenReturnAllCollection()
// {
// _ = await _variantsListCache.LoadMarketDescriptionsAsync();
//
//
// var result = await _variantsListCache.GetAllInvariantMarketDescriptionsAsync(_cultures);
//
//
// Assert.Equal(ScheduleData.VariantListCacheCount, result.Count());
// }
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ public void HttpClientFactoryIsSingleton()
[Fact]
public void HttpClientIsRegistered()
{
var service1 = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClient");
var service1A = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClient");
var service2 = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClient");
var service1 = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForNormal);
var service1A = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForNormal);
var service2 = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForNormal);
Assert.NotNull(service1);
Assert.NotNull(service1A);
Assert.NotNull(service2);
Expand All @@ -51,9 +51,9 @@ public void HttpClientIsRegistered()
[Fact]
public void HttpClientRecoveryIsRegistered()
{
var service1 = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientRecovery");
var service1A = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientRecovery");
var service2 = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientRecovery");
var service1 = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForRecovery);
var service1A = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForRecovery);
var service2 = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForRecovery);
Assert.NotNull(service1);
Assert.NotNull(service1A);
Assert.NotNull(service2);
Expand All @@ -64,9 +64,9 @@ public void HttpClientRecoveryIsRegistered()
[Fact]
public void HttpClientFastFailingIsRegistered()
{
var service1 = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientFastFailing");
var service1A = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientFastFailing");
var service2 = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientFastFailing");
var service1 = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForFastFailing);
var service1A = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForFastFailing);
var service2 = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForFastFailing);
Assert.NotNull(service1);
Assert.NotNull(service1A);
Assert.NotNull(service2);
Expand All @@ -77,9 +77,9 @@ public void HttpClientFastFailingIsRegistered()
[Fact]
public void HttpClientsHaveDifferentTimeouts()
{
var httpClientNormal = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClient");
var httpClientRecovery = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientRecovery");
var httpClientFastFailing = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("HttpClientFastFailing");
var httpClientNormal = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForNormal);
var httpClientRecovery = ServiceScope1.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForRecovery);
var httpClientFastFailing = ServiceScope2.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient(UofSdkBootstrap.HttpClientNameForFastFailing);
Assert.NotNull(httpClientNormal);
Assert.NotNull(httpClientRecovery);
Assert.NotNull(httpClientFastFailing);
Expand All @@ -93,9 +93,9 @@ public void HttpClientsHaveDifferentTimeouts()
}

[Fact]
public void SdkHttpClientInterfaceIsSingleton()
public void SdkHttpClientInterfaceIsTransient()
{
CheckSingletonType<ISdkHttpClient>();
CheckTransientType<ISdkHttpClient>();
}

[Fact]
Expand Down Expand Up @@ -168,12 +168,6 @@ public void SdkHttpClientFastFailingHasTimeoutConfigured()
Assert.Equal(UofConfig.Api.HttpClientFastFailingTimeout, sdkHttpClient.Timeout);
}

[Fact]
public void HttpDataFetcherIsSingleton()
{
CheckSingletonType<HttpDataFetcher>();
}

[Fact]
public void DataFetcherIsSingleton()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Microsoft.Extensions.DependencyInjection;
using Sportradar.OddsFeed.SDK.Api.Internal.ApiAccess;
using Sportradar.OddsFeed.SDK.Api.Internal.Config;
using Sportradar.OddsFeed.SDK.Common.Exceptions;
Expand All @@ -22,6 +23,7 @@ namespace Sportradar.OddsFeed.SDK.Tests.Entities.Rest;

public class HttpDataFetcherTests
{
private readonly ITestOutputHelper _outputHelper;
private readonly SdkHttpClient _sdkHttpClient;
private readonly HttpDataFetcher _httpDataFetcher;
private readonly Uri _badUri = new Uri("http://www.unexisting-url.com");
Expand All @@ -31,11 +33,20 @@ public class HttpDataFetcherTests

public HttpDataFetcherTests(ITestOutputHelper outputHelper)
{
_stubMessageHandler = new StubMessageHandler(outputHelper, 100, 50);
var httpClient = new HttpClient(_stubMessageHandler);
httpClient.DefaultRequestHeaders.Add(UofSdkBootstrap.HttpClientDefaultRequestHeaderForAccessToken, "aaa");
httpClient.DefaultRequestHeaders.Add(UofSdkBootstrap.HttpClientDefaultRequestHeaderForUserAgent, "UofSdk-Net");
_sdkHttpClient = new SdkHttpClient(httpClient);
_outputHelper = outputHelper;
const string httpClientName = "test";
_stubMessageHandler = new StubMessageHandler(_outputHelper, 100, 50);
var services = new ServiceCollection();
services.AddHttpClient(httpClientName)
.ConfigureHttpClient(configureClient =>
{
configureClient.Timeout = TimeSpan.FromSeconds(5);
configureClient.DefaultRequestHeaders.Add(UofSdkBootstrap.HttpClientDefaultRequestHeaderForAccessToken, "aaa");
configureClient.DefaultRequestHeaders.Add(UofSdkBootstrap.HttpClientDefaultRequestHeaderForUserAgent, "UofSdk-Net");
})
.ConfigurePrimaryHttpMessageHandler(() => _stubMessageHandler);
var serviceProvider = services.BuildServiceProvider();
_sdkHttpClient = new SdkHttpClient(serviceProvider.GetRequiredService<IHttpClientFactory>(), httpClientName);

_httpDataFetcher = new HttpDataFetcher(_sdkHttpClient, new Deserializer<response>());
}
Expand Down Expand Up @@ -90,7 +101,7 @@ public async Task ValidateConnectionWhenConnectionFailureTime()
Assert.Null(result);
Assert.IsType<CommunicationException>(e);
Assert.Null(e.InnerException);
Assert.Equal("Failed to execute request due to previous failures.", e.Message);
Assert.Equal("Failed to execute request due to previous failures", e.Message);
}

[Fact]
Expand Down Expand Up @@ -142,6 +153,23 @@ public async Task GetDataAsyncWhenWrongUrlThenThrowsHttpRequestException()
}
}

[Fact]
public async Task GetDataAsyncWhenTaskIsCanceled()
{
var httpDataFetcher = SetupHttpDataFetcherForTaskTimeout();

Stream result = null;
var ex = await Assert.ThrowsAsync<CommunicationException>(async () => result = await httpDataFetcher.GetDataAsync(_getUri));

Assert.Null(result);
Assert.IsType<CommunicationException>(ex);
Assert.Equal(HttpStatusCode.RequestTimeout, ex.ResponseCode);
if (ex.InnerException != null)
{
Assert.IsType<TaskCanceledException>(ex.InnerException);
}
}

[Fact]
public void GetDataWhenBadGatewayWithValidContent()
{
Expand Down Expand Up @@ -279,6 +307,23 @@ public async Task PostDataAsyncWhenWrongUrlThenThrowCommunicationException()
Assert.Null(e.InnerException);
}

[Fact]
public async Task PostDataAsyncWhenTaskIsCanceled()
{
var httpDataFetcher = SetupHttpDataFetcherForTaskTimeout();

HttpResponseMessage result = null;
var ex = await Assert.ThrowsAsync<CommunicationException>(async () => result = await httpDataFetcher.PostDataAsync(_getUri, new StringContent("test string")));

Assert.Null(result);
Assert.IsType<CommunicationException>(ex);
Assert.Equal(HttpStatusCode.RequestTimeout, ex.ResponseCode);
if (ex.InnerException != null)
{
Assert.IsType<TaskCanceledException>(ex.InnerException);
}
}

[Fact]
public async Task PostDataAsyncWhenValidContentWithResponseHeaders()
{
Expand Down Expand Up @@ -311,6 +356,25 @@ public async Task PostDataAsyncWhenValidContentWithMultipleSameResponseHeaders()
Assert.Equal("any-key", _httpDataFetcher.ResponseHeaders.First().Key);
}

private HttpDataFetcher SetupHttpDataFetcherForTaskTimeout()
{
const string httpClientName = "test";
var stubMessageHandler = new StubMessageHandler(_outputHelper, 1000);
var services = new ServiceCollection();
services.AddHttpClient(httpClientName)
.ConfigureHttpClient(configureClient =>
{
configureClient.Timeout = TimeSpan.FromMilliseconds(200);
configureClient.DefaultRequestHeaders.Add(UofSdkBootstrap.HttpClientDefaultRequestHeaderForAccessToken, "aaa");
configureClient.DefaultRequestHeaders.Add(UofSdkBootstrap.HttpClientDefaultRequestHeaderForUserAgent, "UofSdk-Net");
})
.ConfigurePrimaryHttpMessageHandler(() => stubMessageHandler);
var serviceProvider = services.BuildServiceProvider();
var sdkHttpClient = new SdkHttpClient(serviceProvider.GetRequiredService<IHttpClientFactory>(), httpClientName);
var httpDataFetcher = new HttpDataFetcher(sdkHttpClient, new Deserializer<response>());
return httpDataFetcher;
}

private HttpResponseMessage GetSuccessResponseMessage(HttpStatusCode httpStatusCode = HttpStatusCode.Accepted)
{
var response = GetResponse(httpStatusCode);
Expand All @@ -324,7 +388,7 @@ private response GetResponse(HttpStatusCode httpStatusCode = HttpStatusCode.Acce
return new response { action = "some-response-action", message = $"some-response-message {httpStatusCode}", response_code = response_code.ACCEPTED, response_codeSpecified = true };
}

public static string ObjectToXmlString<T>(T objectToSerialize)
private static string ObjectToXmlString<T>(T objectToSerialize)
{
var xmlSerializer = new XmlSerializer(typeof(T));

Expand Down
Loading

0 comments on commit bb591e0

Please sign in to comment.