From 971d4bd26880508d92fa9b49172dc6c942d2ff74 Mon Sep 17 00:00:00 2001 From: Stephan Schnabel Date: Mon, 13 Mar 2023 10:54:58 +0100 Subject: [PATCH] Read model names without lookup by using context object --- .../metrics/MicrometerEventListener.java | 42 ++++++------- .../metrics/MicrometerEventListenerTest.java | 63 ++++++++++++------- 2 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java index fba4baf..85aaf96 100644 --- a/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java +++ b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java @@ -1,7 +1,5 @@ package io.kokuwa.keycloak.metrics; -import java.util.Optional; - import org.jboss.logging.Logger; import org.keycloak.events.Event; import org.keycloak.events.EventListenerProvider; @@ -33,7 +31,7 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose registry.counter("keycloak_event_user", "realm", toBlank(replace ? getRealmName(event.getRealmId()) : event.getRealmId()), "type", toBlank(event.getType()), - "client", toBlank(replace ? getClientId(event.getRealmId(), event.getClientId()) : event.getClientId()), + "client", toBlank(replace ? getClientId(event.getClientId()) : event.getClientId()), "error", toBlank(event.getError())) .increment(); } @@ -51,27 +49,25 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose @Override public void close() {} + private String getRealmName(String id) { + var model = session.getContext().getRealm(); + if (id == null || id.equals(model.getId())) { + return model.getName(); + } + log.warnv("Failed to resolve realmName for id {0}", id); + return id; + } + + private String getClientId(String id) { + var model = session.getContext().getClient(); + if (id == null || id.equals(model.getId())) { + return model.getClientId(); + } + log.warnv("Failed to resolve clientId for id {0}", id); + return id; + } + private String toBlank(Object value) { return value == null ? "" : value.toString(); } - - private String getRealmName(String realmId) { - var model = session.realms().getRealm(realmId); - if (model == null) { - log.warnv("Failed to resolve realm with id", realmId); - return realmId; - } - return model.getName(); - } - - private String getClientId(String realmId, String clientId) { - var model = Optional.ofNullable(session.realms().getRealm(realmId)) - .map(realm -> realm.getClientById(clientId)) - .orElse(null); - if (model == null) { - log.warnv("Failed to resolve client with id {} in realm {}", clientId, realmId); - return clientId; - } - return model.getClientId(); - } } diff --git a/src/test/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerTest.java b/src/test/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerTest.java index a195957..c15f62c 100644 --- a/src/test/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerTest.java +++ b/src/test/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerTest.java @@ -7,6 +7,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Map; +import java.util.TreeMap; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -22,9 +23,9 @@ import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; +import org.keycloak.models.KeycloakContext; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.RealmProvider; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; @@ -44,12 +45,12 @@ public class MicrometerEventListenerTest { @Mock KeycloakSession session; @Mock - RealmProvider realmProvider; - @Mock RealmModel realmModel; @Mock ClientModel clientModel; @Mock + KeycloakContext context; + @Mock MeterRegistry registry; @Mock Counter counter; @@ -77,10 +78,12 @@ public class MicrometerEventListenerTest { var clientName = UUID.randomUUID().toString(); var type = EventType.LOGIN; - when(session.realms()).thenReturn(realmProvider); - when(realmProvider.getRealm(realmId)).thenReturn(realmModel); + when(session.getContext()).thenReturn(context); + when(context.getRealm()).thenReturn(realmModel); + when(context.getClient()).thenReturn(clientModel); + when(realmModel.getId()).thenReturn(realmId); when(realmModel.getName()).thenReturn(realmName); - when(realmModel.getClientById(clientId)).thenReturn(clientModel); + when(clientModel.getId()).thenReturn(clientId); when(clientModel.getClientId()).thenReturn(clientName); listener(true).onEvent(toEvent(realmId, clientId, type, null)); @@ -98,10 +101,12 @@ public class MicrometerEventListenerTest { var type = EventType.LOGIN_ERROR; var error = UUID.randomUUID().toString(); - when(session.realms()).thenReturn(realmProvider); - when(realmProvider.getRealm(realmId)).thenReturn(realmModel); + when(session.getContext()).thenReturn(context); + when(context.getRealm()).thenReturn(realmModel); + when(context.getClient()).thenReturn(clientModel); + when(realmModel.getId()).thenReturn(realmId); when(realmModel.getName()).thenReturn(realmName); - when(realmModel.getClientById(clientId)).thenReturn(clientModel); + when(clientModel.getId()).thenReturn(clientId); when(clientModel.getClientId()).thenReturn(clientName); listener(true).onEvent(toEvent(realmId, clientId, type, error)); @@ -112,11 +117,17 @@ public class MicrometerEventListenerTest { @Test void replaceFieldsEmpty() { - when(session.realms()).thenReturn(realmProvider); - when(realmProvider.getRealm(any())).thenReturn(null); + var realmName = UUID.randomUUID().toString(); + var clientName = UUID.randomUUID().toString(); + + when(session.getContext()).thenReturn(context); + when(context.getRealm()).thenReturn(realmModel); + when(context.getClient()).thenReturn(clientModel); + when(realmModel.getName()).thenReturn(realmName); + when(clientModel.getClientId()).thenReturn(clientName); listener(true).onEvent(toEvent(null, null, null, null)); - assertEvent("", "", "", ""); + assertEvent(realmName, clientName, "", ""); } @DisplayName("replace(false) - without error") @@ -182,8 +193,9 @@ public class MicrometerEventListenerTest { var resource = ResourceType.USER; var operation = OperationType.CREATE; - when(session.realms()).thenReturn(realmProvider); - when(realmProvider.getRealm(realmId)).thenReturn(realmModel); + when(session.getContext()).thenReturn(context); + when(context.getRealm()).thenReturn(realmModel); + when(realmModel.getId()).thenReturn(realmId); when(realmModel.getName()).thenReturn(realmName); listener(true).onEvent(toAdminEvent(realmId, resource, operation, null), false); @@ -200,8 +212,9 @@ public class MicrometerEventListenerTest { var operation = OperationType.CREATE; var error = UUID.randomUUID().toString(); - when(session.realms()).thenReturn(realmProvider); - when(realmProvider.getRealm(realmId)).thenReturn(realmModel); + when(session.getContext()).thenReturn(context); + when(context.getRealm()).thenReturn(realmModel); + when(realmModel.getId()).thenReturn(realmId); when(realmModel.getName()).thenReturn(realmName); listener(true).onEvent(toAdminEvent(realmId, resource, operation, error), false); @@ -212,11 +225,14 @@ public class MicrometerEventListenerTest { @Test void replaceFieldsEmpty() { - when(session.realms()).thenReturn(realmProvider); - when(realmProvider.getRealm(any())).thenReturn(null); + var realmName = UUID.randomUUID().toString(); + + when(session.getContext()).thenReturn(context); + when(context.getRealm()).thenReturn(realmModel); + when(realmModel.getName()).thenReturn(realmName); listener(true).onEvent(toAdminEvent(null, null, null, null), false); - assertAdminEvent("", "", "", ""); + assertAdminEvent(realmName, "", "", ""); } @DisplayName("replace(false) - without error") @@ -277,8 +293,13 @@ public class MicrometerEventListenerTest { verify(registry).counter(anyString(), any(String[].class)); verify(counter).increment(); assertEquals(metric, metricCaptor.getValue(), "metric"); - assertEquals(tags, IntStream + var expectedTags = new TreeMap<>(tags); + var actualTags = IntStream .range(0, tagsCaptor.getValue().length / 2).mapToObj(i -> i * 2) - .collect(Collectors.toMap(i -> tagsCaptor.getValue()[i], i -> tagsCaptor.getValue()[i + 1])), "tags"); + .collect(Collectors.toMap( + i -> tagsCaptor.getValue()[i], + i -> tagsCaptor.getValue()[i + 1], + (i, j) -> i, TreeMap::new)); + assertEquals(expectedTags, actualTags, "tags"); } } -- 2.47.2