Skip to content

Commit

Permalink
Read model names without lookup by using context object (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
sschnabe authored Mar 13, 2023
1 parent 4e0c4af commit 579d0a9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -33,7 +31,7 @@ public void onEvent(Event event) {
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();
}
Expand All @@ -51,27 +49,25 @@ public void onEvent(AdminEvent event, boolean includeRepresentation) {
@Override
public void close() {}

private String toBlank(Object value) {
return value == null ? "" : value.toString();
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 getRealmName(String realmId) {
var model = session.realms().getRealm(realmId);
if (model == null) {
log.warnv("Failed to resolve realm with id", realmId);
return realmId;
private String getClientId(String id) {
var model = session.getContext().getClient();
if (id == null || id.equals(model.getId())) {
return model.getClientId();
}
return model.getName();
log.warnv("Failed to resolve clientId for id {0}", id);
return id;
}

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();
private String toBlank(Object value) {
return value == null ? "" : value.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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;
Expand All @@ -22,9 +23,9 @@
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;
Expand All @@ -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;
Expand Down Expand Up @@ -77,10 +78,12 @@ void replaceWithoutError() {
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));
Expand All @@ -98,10 +101,12 @@ void replaceWithError() {
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));
Expand All @@ -112,11 +117,17 @@ void replaceWithError() {
@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")
Expand Down Expand Up @@ -182,8 +193,9 @@ void replaceWithoutError() {
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);
Expand All @@ -200,8 +212,9 @@ void replaceWithError() {
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);
Expand All @@ -212,11 +225,14 @@ void replaceWithError() {
@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")
Expand Down Expand Up @@ -277,8 +293,13 @@ private void assertCounter(String metric, Map<String, String> tags) {
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");
}
}

0 comments on commit 579d0a9

Please sign in to comment.