Skip to content
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>10.8.7</Version>
<Version>10.8.8</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<Title>OData Provider</Title>
<Description>The Odata Provider lets you fetch and map data from or to any OData endpoint.</Description>
Expand Down
71 changes: 44 additions & 27 deletions src/ODataSourceReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace Dynamicweb.DataIntegration.Providers.ODataProvider;

Expand Down Expand Up @@ -238,26 +239,7 @@

if (parameters != null && parameters.Count > 0)
{
StringBuilder stringBuilder = new StringBuilder(string.Empty);
foreach (KeyValuePair<string, string> parameter in parameters)
{
stringBuilder.Append("&" + parameter.Key + "=" + WebUtility.UrlEncode(parameter.Value));
}

if (stringBuilder.Length > 0)
{
if (!result.Contains("?"))
{
return $"{result}?{stringBuilder.Remove(0, 1)}";
}

if (!result.EndsWith("?"))
{
return $"{result}{stringBuilder}";
}

return $"{result}{stringBuilder.Remove(0, 1)}";
}
return BuildURLWithParameters(parameters, result);
}

return result;
Expand Down Expand Up @@ -381,7 +363,7 @@
foreach (var group in groups)
{
var filters = GetFilterAsParameters(mapping, group.Conditionals);
result.AddRange(filters);
result.AddRange(filters);
}
}
else
Expand All @@ -406,8 +388,8 @@
if (filterAsParameters.Any())
{
var groupFilter = string.Join($" {group.ConditionalOperator} ", filterAsParameters);
result += $"({groupFilter}){prependOperator}";
}
result += $"({groupFilter}){prependOperator}";
}
}
if (!string.IsNullOrEmpty(result) && result.Length > prependOperator.Length)
{
Expand All @@ -427,7 +409,7 @@

private List<string> GetFilterAsParameters(Mapping mapping, IEnumerable<MappingConditional> mappingConditionals)
{
List<string> result = new();
List<string> result = new();
if (mappingConditionals.Any())
{
foreach (var item in mappingConditionals)
Expand All @@ -436,7 +418,7 @@
if (!string.IsNullOrEmpty(itemFilter))
{
result.Add(itemFilter);
}
}
}
}
return result;
Expand Down Expand Up @@ -644,11 +626,11 @@
if (endpointAuthentication.IsTokenBased())
{
string token = GetToken(_endpoint, endpointAuthentication);
task = RetryHelper.RetryOnExceptionAsync<Exception>(10, async () => { _httpRestClient.GetAsync(url, HandleStream, token, (Dictionary<string, string>)headers).Wait(new CancellationTokenSource(_timeoutInMilliseconds).Token); }, _logger);

Check warning on line 629 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 629 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
}
else
{
task = RetryHelper.RetryOnExceptionAsync<Exception>(10, async () => { _httpRestClient.GetAsync(url, HandleStream, endpointAuthentication, (Dictionary<string, string>)headers).Wait(new CancellationTokenSource(_timeoutInMilliseconds).Token); }, _logger);

Check warning on line 633 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 633 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
}
if (task.IsCanceled)
{
Expand Down Expand Up @@ -739,22 +721,57 @@
if (url.Contains('?'))
{
bool urlContainsTop = url.Contains("$top=", StringComparison.OrdinalIgnoreCase);
if (new Uri(url).Query.Any() && !urlContainsTop)
if (new Uri(url).Query.Length != 0 && !urlContainsTop)
{
return $"{url}&$top=1";
}
else if (!urlContainsTop)
{
return $"{url}$top=1";
}
return url;
else
{
var paramsCollection = HttpUtility.ParseQueryString(url);
if (paramsCollection is null)
return url;

var paramsAsDictionary = paramsCollection.AllKeys.ToDictionary(k => k, k => paramsCollection[k]);
paramsAsDictionary["$top"] = "1";
return BuildURLWithParameters(paramsAsDictionary, url[..url.IndexOf('?')]);
}
}
else
{
return $"{url}?$top=1";
}
}

private static string BuildURLWithParameters(IDictionary<string, string> parameters, string url)
{
StringBuilder stringBuilder = new(string.Empty);
foreach (KeyValuePair<string, string> parameter in parameters)
{
stringBuilder.Append("&" + parameter.Key + "=" + WebUtility.UrlEncode(parameter.Value));
}

if (stringBuilder.Length > 0)
{
if (!url.Contains('?'))
{
return $"{url}?{stringBuilder.Remove(0, 1)}";
}

if (!url.EndsWith('?'))
{
return $"{url}{stringBuilder}";
}

return $"{url}{stringBuilder.Remove(0, 1)}";
}

return url;
}

private bool CheckIfEndpointIsReadyForUse(string url)
{
string checkUrl = GetEndpointUrlWithTop(url);
Expand All @@ -765,11 +782,11 @@
if (endpointAuthentication.IsTokenBased())
{
string token = GetToken(_endpoint, endpointAuthentication);
task = RetryHelper.RetryOnExceptionAsync<Exception>(10, async () => { _httpRestClient.GetAsync(checkUrl, HandleResponse, token, (Dictionary<string, string>)GetAllHeaders()).Wait(new CancellationTokenSource(_timeoutInMilliseconds).Token); }, _logger);

Check warning on line 785 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 785 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
}
else
{
task = RetryHelper.RetryOnExceptionAsync<Exception>(10, async () => { _httpRestClient.GetAsync(checkUrl, HandleResponse, endpointAuthentication, (Dictionary<string, string>)GetAllHeaders()).Wait(new CancellationTokenSource(_timeoutInMilliseconds).Token); }, _logger);

Check warning on line 789 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 789 in src/ODataSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
}
if (task.IsCanceled)
{
Expand Down