Skip to content
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

feat(keycloak): add seeding data to configuration #800

Closed
Closed
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
81 changes: 81 additions & 0 deletions src/framework/Framework.Async/AsyncAggregateExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/********************************************************************************
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

namespace Org.Eclipse.TractusX.Portal.Backend.Framework.Async;

public static class AsyncAggregateExtensions
{
public static Task<TAccumulate> AggregateAsync<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, Task<TAccumulate>> accumulate, CancellationToken cancellationToken = default)
{
using var enumerator = source.GetEnumerator();
return AggregateAsync(enumerator, seed, accumulate, cancellationToken);
}

public static Task<TAccumulate> AggregateAsync<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, Task<TAccumulate>> accumulate, CancellationToken cancellationToken = default)
{
using var enumerator = source.GetEnumerator();
return AggregateAsync(enumerator, seed, accumulate, cancellationToken);
}

public static async Task<TResult> AggregateAsync<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, Task<TAccumulate>> accumulate, Func<TAccumulate, TResult> result, CancellationToken cancellationToken = default) =>
result(await AggregateAsync(source, seed, accumulate, cancellationToken));

public static async Task<TResult> AggregateAsync<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, Task<TAccumulate>> accumulate, Func<TAccumulate, TResult> result, CancellationToken cancellationToken = default) =>
result(await AggregateAsync(source, seed, accumulate, cancellationToken));

public static Task<TSource> AggregateAsync<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, CancellationToken, Task<TSource>> accumulate, CancellationToken cancellationToken = default)
{
using var enumerator = source.GetEnumerator();
if (!enumerator.MoveNext())
throw new InvalidOperationException("source must not be empty");

return AggregateAsync(enumerator, enumerator.Current, accumulate, cancellationToken);
}

public static Task<TSource> AggregateAsync<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, Task<TSource>> accumulate, CancellationToken cancellationToken = default)
{
using var enumerator = source.GetEnumerator();
if (!enumerator.MoveNext())
throw new InvalidOperationException("source must not be empty");

return AggregateAsync(enumerator, enumerator.Current, accumulate, cancellationToken);
}

private static async Task<TAccumulate> AggregateAsync<TSource, TAccumulate>(IEnumerator<TSource> enumerator, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, Task<TAccumulate>> accumulate, CancellationToken cancellationToken)
{
var accumulator = seed;
while (enumerator.MoveNext())
{
cancellationToken.ThrowIfCancellationRequested();
accumulator = await accumulate(accumulator, enumerator.Current, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}
return accumulator;
}

private static async Task<TAccumulate> AggregateAsync<TSource, TAccumulate>(IEnumerator<TSource> enumerator, TAccumulate seed, Func<TAccumulate, TSource, Task<TAccumulate>> accumulate, CancellationToken cancellationToken)
{
var accumulator = seed;
while (enumerator.MoveNext())
{
cancellationToken.ThrowIfCancellationRequested();
accumulator = await accumulate(accumulator, enumerator.Current).ConfigureAwait(ConfigureAwaitOptions.None);
}
return accumulator;
}
}
2 changes: 1 addition & 1 deletion src/framework/Framework.Async/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.Cors/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.DBAccess/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.IO/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.Linq/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
13 changes: 13 additions & 0 deletions src/framework/Framework.Linq/IfAnyExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,17 @@ public static bool IfAny<T, R>(this IEnumerable<T> source, Func<IEnumerable<T>,
returnValue = default;
return false;
}

public static async ValueTask<bool> IfAnyAwait<T>(this IEnumerable<T> source, Func<IEnumerable<T>, Task> process)
{
var enumerator = source.GetEnumerator();

if (enumerator.MoveNext())
{
await process(new IfAnyEnumerable<T>(source, enumerator)).ConfigureAwait(ConfigureAwaitOptions.None);
return true;
}

return false;
}
}
22 changes: 18 additions & 4 deletions src/framework/Framework.Linq/NullOrSequenceEqualExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Framework.Linq;

public static class NullOrSequenceEqualExtensions
{
public static bool NullOrContentEqual<T>(this IEnumerable<T>? items, IEnumerable<T>? others, IEqualityComparer<T>? comparer = null) where T : IComparable =>
public static bool NullOrContentEqual<T>(this IEnumerable<T>? items, IEnumerable<T>? others, IEqualityComparer<T>? comparer = null) where T : IComparable? =>
items == null && others == null ||
items != null && others != null &&
items.OrderBy(x => x).SequenceEqual(others.OrderBy(x => x), comparer);
items.Order().SequenceEqual(others.Order(), comparer);

public static bool NullOrContentEqual<K, V>(this IEnumerable<KeyValuePair<K, V>>? items, IEnumerable<KeyValuePair<K, V>>? others, IEqualityComparer<KeyValuePair<K, V>>? comparer = null) where K : IComparable where V : IComparable =>
public static bool NullOrContentEqual<K, V>(this IEnumerable<KeyValuePair<K, V>>? items, IEnumerable<KeyValuePair<K, V>>? others, IEqualityComparer<KeyValuePair<K, V>>? comparer = null) where K : IComparable where V : IComparable? =>
items == null && others == null ||
items != null && others != null &&
items.OrderBy(x => x.Key).SequenceEqual(others.OrderBy(x => x.Key), comparer);
Expand All @@ -37,6 +37,11 @@ public static bool NullOrContentEqual<K, V>(this IEnumerable<KeyValuePair<K, IEn
items == null && others == null ||
items != null && others != null &&
items.OrderBy(x => x.Key).SequenceEqual(others.OrderBy(x => x.Key), comparer ?? new EnumerableValueKeyValuePairEqualityComparer<K, V>());

public static bool NullOrNullableContentEqual<K, V>(this IEnumerable<KeyValuePair<K, IEnumerable<V>?>>? items, IEnumerable<KeyValuePair<K, IEnumerable<V>?>>? others, IEqualityComparer<KeyValuePair<K, IEnumerable<V>?>>? comparer = null) where V : IComparable =>
items == null && others == null ||
items != null && others != null &&
items.OrderBy(x => x.Key).SequenceEqual(others.OrderBy(x => x.Key), comparer ?? new NullableEnumerableValueKeyValuePairEqualityComparer<K, V>());
}

public class KeyValuePairEqualityComparer<K, V> : IEqualityComparer<KeyValuePair<K, V>> where K : IComparable where V : IComparable
Expand All @@ -50,7 +55,16 @@ public class EnumerableValueKeyValuePairEqualityComparer<K, V> : IEqualityCompar
{
public bool Equals(KeyValuePair<K, IEnumerable<V>> source, KeyValuePair<K, IEnumerable<V>> other) =>
Equals(source.Key, other.Key) &&
source.Value.NullOrContentEqual(other.Value);
source.Value.Order().SequenceEqual(other.Value.Order());

public int GetHashCode([DisallowNull] KeyValuePair<K, IEnumerable<V>> obj) => throw new NotImplementedException();
}

public class NullableEnumerableValueKeyValuePairEqualityComparer<K, V> : IEqualityComparer<KeyValuePair<K, IEnumerable<V>?>> where V : IComparable
{
public bool Equals(KeyValuePair<K, IEnumerable<V>?> source, KeyValuePair<K, IEnumerable<V>?> other) =>
Equals(source.Key, other.Key) &&
source.Value.NullOrContentEqual(other.Value);

public int GetHashCode([DisallowNull] KeyValuePair<K, IEnumerable<V>?> obj) => throw new NotImplementedException();
}
6 changes: 6 additions & 0 deletions src/framework/Framework.Linq/NullableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,10 @@ public static class NullableExtensions
{
public static bool IsNullOrEmpty<T>(this IEnumerable<T>? collection) =>
collection == null || !collection.Any();

public static IEnumerable<KeyValuePair<TKey, TValue>> FilterNotNullValues<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue?>> source) =>
source.Where(x => x.Value != null).Cast<KeyValuePair<TKey, TValue>>();

public static IEnumerable<T> FilterNotNull<T>(this IEnumerable<T?> source) =>
source.Where(x => x != null).Cast<T>();
}
2 changes: 1 addition & 1 deletion src/framework/Framework.Logging/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.Models/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.Seeding/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.Swagger/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.Token/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/framework/Framework.Web/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Project>
<PropertyGroup>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
31 changes: 20 additions & 11 deletions src/keycloak/Keycloak.ErrorHandling/FlurlErrorHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,54 @@
using Microsoft.Extensions.Logging;
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using System.Net;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Org.Eclipse.TractusX.Portal.Backend.Keycloak.ErrorHandling;

public static class FlurlErrorHandler
{
public static void ConfigureErrorHandler(ILogger logger, bool isDevelopment)
public static void ConfigureErrorHandler(ILogger logger)
{
FlurlHttp.Configure(settings => settings.OnError = (call) =>
{
var message = $"{call.HttpResponseMessage?.ReasonPhrase ?? "ReasonPhrase is null"}: {call.HttpRequestMessage.RequestUri}";

if (isDevelopment)
if (logger.IsEnabled(LogLevel.Debug))
{
LogDevelopmentError(logger, call);
LogDebug(logger, call);
}
else
{
logger.LogError(call.Exception, "{Message}", message);
}

if (call.HttpResponseMessage != null)
{
var errorContent = JsonSerializer.Deserialize<KeycloakErrorResponse>(call.HttpResponseMessage.Content.ReadAsStream())?.ErrorMessage;
if (!string.IsNullOrWhiteSpace(errorContent))
{
message = errorContent;
}
throw call.HttpResponseMessage.StatusCode switch
{
HttpStatusCode.NotFound => new KeycloakEntityNotFoundException(message, call.Exception),
HttpStatusCode.Conflict => new KeycloakEntityConflictException(message, call.Exception),
HttpStatusCode.BadRequest => new ArgumentException(message, call.Exception),
HttpStatusCode.BadRequest => new KeycloakNoSuccessException(message, call.Exception),
_ => new ServiceException(message, call.Exception, call.HttpResponseMessage.StatusCode),
};
}
throw new ServiceException(message, call.Exception);
});
}

private static void LogDevelopmentError(ILogger logger, FlurlCall call)
private static void LogDebug(ILogger logger, FlurlCall call)
{
var request = call.HttpRequestMessage == null ? "" : $"{call.HttpRequestMessage.Method} {call.HttpRequestMessage.RequestUri} HTTP/{call.HttpRequestMessage.Version}\n{call.HttpRequestMessage.Headers}\n";
var requestBody = call.RequestBody == null ? "\n" : call.RequestBody + "\n\n";
var response = call.HttpResponseMessage == null ? "" : call.HttpResponseMessage.ReasonPhrase + "\n";
var responseContent = call.HttpResponseMessage?.Content == null ? "" : call.HttpResponseMessage.Content.ReadAsStringAsync().Result + "\n";
logger.LogError(call.Exception, "{Request}{Body}{Response}{Content}", request, requestBody, response, responseContent);
logger.LogDebug(call.Exception, "{Request}{Body}{Response}{Content}", request, requestBody, response, responseContent);
}

public class KeycloakErrorResponse
{
[JsonPropertyName("errorMessage")]
public string? ErrorMessage { get; set; }
}
}
Loading
Loading