Skip to content

Commit

Permalink
feat(seeding): performance adjustments
Browse files Browse the repository at this point in the history
Refs: #1172
  • Loading branch information
Phil91 committed Nov 25, 2024
1 parent 210bfb3 commit 26ac07f
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 155 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public async Task UpdateClientScopeMapper(string instanceName, CancellationToken
{
var keycloak = keycloakFactory.CreateKeycloakClient(instanceName);
var realm = seedDataHandler.Realm;
var seederConfig = seedDataHandler.Configuration;
var seederConfig = seedDataHandler.GetSpecificConfiguration(ConfigurationKeys.ClientScopes);

var clients = await keycloak.GetClientsAsync(realm, null, true, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
foreach (var (clientName, mappingModels) in seedDataHandler.ClientScopeMappings)
Expand All @@ -60,15 +60,15 @@ public async Task UpdateClientScopeMapper(string instanceName, CancellationToken
}
}

private static async Task AddAndDeleteRoles(KeycloakClient keycloak, string realm, string clientScopeId, string clientId, IEnumerable<Role> roles, IEnumerable<Role> updateRoles, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task AddAndDeleteRoles(KeycloakClient keycloak, string realm, string clientScopeId, string clientId, IEnumerable<Role> roles, IEnumerable<Role> updateRoles, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
await updateRoles.ExceptBy(roles.Select(role => role.Name), roleModel => roleModel.Name)
.Where(x => seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, ModificationType.Create, x.Name))
.Where(x => seederConfig.ModificationAllowed(ModificationType.Create, x.Name))
.IfAnyAwait(rolesToAdd =>
keycloak.AddClientRolesScopeMappingToClientAsync(realm, clientScopeId, clientId, rolesToAdd, cancellationToken)).ConfigureAwait(false);

await roles.ExceptBy(updateRoles.Select(roleModel => roleModel.Name), role => role.Name)
.Where(x => seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, ModificationType.Delete, x.Name))
.Where(x => seederConfig.ModificationAllowed(ModificationType.Delete, x.Name))
.IfAnyAwait(rolesToDelete =>
keycloak.RemoveClientRolesFromClientScopeForClientAsync(realm, clientScopeId, clientId, rolesToDelete, cancellationToken)).ConfigureAwait(false);
}
Expand Down
47 changes: 25 additions & 22 deletions src/keycloak/Keycloak.Seeding/BusinessLogic/ClientScopesUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,31 @@ public async Task UpdateClientScopes(string instanceName, CancellationToken canc
{
var keycloak = keycloakFactory.CreateKeycloakClient(instanceName);
var realm = seedDataHandler.Realm;
var seederConfig = seedDataHandler.Configuration;
var seederConfig = seedDataHandler.GetSpecificConfiguration(ConfigurationKeys.ClientScopes);

var clientScopes = await keycloak.GetClientScopesAsync(realm, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
var seedClientScopes = seedDataHandler.ClientScopes;

await CheckAndExecute(ConfigurationKeys.ClientScopes, ModificationType.Delete, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, RemoveObsoleteClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ConfigurationKeys.ClientScopes, ModificationType.Create, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, CreateMissingClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ConfigurationKeys.ClientScopes, ModificationType.Update, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, UpdateExistingClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ModificationType.Delete, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, RemoveObsoleteClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ModificationType.Create, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, CreateMissingClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
await CheckAndExecute(ModificationType.Update, keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken, UpdateExistingClientScopes).ConfigureAwait(ConfigureAwaitOptions.None);
}

private static async Task CheckAndExecute(ConfigurationKeys configKey, ModificationType modificationType, KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken, Func<KeycloakClient, string, IEnumerable<ClientScope>, IEnumerable<ClientScopeModel>, KeycloakRealmSettings, CancellationToken, Task> executeLogic)
private static async Task CheckAndExecute(ModificationType modificationType, KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken, Func<KeycloakClient, string, IEnumerable<ClientScope>, IEnumerable<ClientScopeModel>, KeycloakSeederConfigModel, CancellationToken, Task> executeLogic)
{
if (!seederConfig.ModificationAllowed(configKey, modificationType))
if (!seederConfig.ModificationAllowed(modificationType))
{
return;
}

await executeLogic(keycloak, realm, clientScopes, seedClientScopes, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}

private static async Task RemoveObsoleteClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task RemoveObsoleteClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var deleteScope in clientScopes.ExceptBy(seedClientScopes.Select(x => x.Name), x => x.Name)
.Where(x => seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, ModificationType.Delete, x.Name)))
foreach (var deleteScope in clientScopes
.Where(x => seederConfig.ModificationAllowed(ModificationType.Delete, x.Name))
.ExceptBy(seedClientScopes.Select(x => x.Name), x => x.Name))
{
await keycloak.DeleteClientScopeAsync(
realm,
Expand All @@ -66,30 +67,30 @@ await keycloak.DeleteClientScopeAsync(
}
}

private static async Task CreateMissingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task CreateMissingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var addScope in seedClientScopes.ExceptBy(clientScopes.Select(x => x.Name), x => x.Name)
.Where(x => seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, ModificationType.Create, x.Name)))
.Where(x => seederConfig.ModificationAllowed(ModificationType.Create, x.Name)))
{
await keycloak.CreateClientScopeAsync(realm, CreateClientScope(null, addScope, true), cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}
}

private static async Task UpdateExistingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task UpdateExistingClientScopes(KeycloakClient keycloak, string realm, IEnumerable<ClientScope> clientScopes, IEnumerable<ClientScopeModel> seedClientScopes, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var (clientScope, update) in clientScopes
.Join(
seedClientScopes,
x => x.Name,
x => x.Name,
(clientScope, update) => (ClientScope: clientScope, Update: update))
.Where(x => seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, ModificationType.Update, x.Update.Name)))
.Where(x => seederConfig.ModificationAllowed(ModificationType.Update, x.Update.Name)))
{
await UpdateClientScopeWithProtocolMappers(keycloak, realm, clientScope, update, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}
}

private static async Task UpdateClientScopeWithProtocolMappers(KeycloakClient keycloak, string realm, ClientScope clientScope, ClientScopeModel update, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task UpdateClientScopeWithProtocolMappers(KeycloakClient keycloak, string realm, ClientScope clientScope, ClientScopeModel update, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
if (clientScope.Id == null)
throw new ConflictException($"clientScope.Id is null: {clientScope.Name}");
Expand All @@ -114,10 +115,11 @@ await keycloak.UpdateClientScopeAsync(
await UpdateExistingProtocolMappers(keycloak, realm, clientScope.Name, clientScope.Id, mappers, updateMappers, seederConfig, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None);
}

private static async Task DeleteObsoleteProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task DeleteObsoleteProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var mapper in mappers.ExceptBy(updateMappers.Select(x => x.Name), x => x.Name)
.Where(x => seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, clientScopeName, ConfigurationKeys.ProtocolMappers, ModificationType.Delete, x.Name)))
foreach (var mapper in mappers
.Where(x => seederConfig.ModificationAllowed(clientScopeName, ConfigurationKeys.ProtocolMappers, ModificationType.Delete, x.Name))
.ExceptBy(updateMappers.Select(x => x.Name), x => x.Name))
{
await keycloak.DeleteProtocolMapperAsync(
realm,
Expand All @@ -127,10 +129,11 @@ await keycloak.DeleteProtocolMapperAsync(
}
}

private static async Task CreateMissingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task CreateMissingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var update in updateMappers.ExceptBy(mappers.Select(x => x.Name), x => x.Name)
.Where(x => seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, clientScopeName, ConfigurationKeys.ProtocolMappers, ModificationType.Create, x.Name)))
foreach (var update in updateMappers
.Where(x => seederConfig.ModificationAllowed(clientScopeName, ConfigurationKeys.ProtocolMappers, ModificationType.Create, x.Name))
.ExceptBy(mappers.Select(x => x.Name), x => x.Name))
{
await keycloak.CreateProtocolMapperAsync(
realm,
Expand All @@ -140,14 +143,14 @@ await keycloak.CreateProtocolMapperAsync(
}
}

private static async Task UpdateExistingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakRealmSettings seederConfig, CancellationToken cancellationToken)
private static async Task UpdateExistingProtocolMappers(KeycloakClient keycloak, string realm, string clientScopeName, string clientScopeId, IEnumerable<ProtocolMapper> mappers, IEnumerable<ProtocolMapperModel> updateMappers, KeycloakSeederConfigModel seederConfig, CancellationToken cancellationToken)
{
foreach (var (mapper, update) in mappers.Join(
updateMappers,
x => x.Name,
x => x.Name,
(mapper, update) => (Mapper: mapper, Update: update))
.Where(x => !ProtocolMappersUpdater.CompareProtocolMapper(x.Mapper, x.Update) && seederConfig.ModificationAllowed(ConfigurationKeys.ClientScopes, clientScopeName, ConfigurationKeys.ProtocolMappers, ModificationType.Update, x.Update.Name)))
.Where(x => !ProtocolMappersUpdater.CompareProtocolMapper(x.Mapper, x.Update) && seederConfig.ModificationAllowed(clientScopeName, ConfigurationKeys.ProtocolMappers, ModificationType.Update, x.Update.Name)))
{
await keycloak.UpdateProtocolMapperAsync(
realm,
Expand Down
Loading

0 comments on commit 26ac07f

Please sign in to comment.