Read model names without lookup by using context object #8

Merged
sschnabe merged 1 commit from model into main 2023-03-13 11:06:35 +01:00
2 changed files with 61 additions and 44 deletions
Showing only changes of commit 971d4bd268 - Show all commits

View file

@ -1,7 +1,5 @@
package io.kokuwa.keycloak.metrics; package io.kokuwa.keycloak.metrics;
import java.util.Optional;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.events.Event; import org.keycloak.events.Event;
import org.keycloak.events.EventListenerProvider; import org.keycloak.events.EventListenerProvider;
@ -33,7 +31,7 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose
registry.counter("keycloak_event_user", registry.counter("keycloak_event_user",
"realm", toBlank(replace ? getRealmName(event.getRealmId()) : event.getRealmId()), "realm", toBlank(replace ? getRealmName(event.getRealmId()) : event.getRealmId()),
"type", toBlank(event.getType()), "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())) "error", toBlank(event.getError()))
.increment(); .increment();
} }
@ -51,27 +49,25 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose
@Override @Override
public void close() {} 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) { private String toBlank(Object value) {
return value == null ? "" : value.toString(); 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();
}
} }

View file

@ -7,6 +7,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; 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.OperationType;
import org.keycloak.events.admin.ResourceType; import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakContext;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Captor; import org.mockito.Captor;
import org.mockito.Mock; import org.mockito.Mock;
@ -44,12 +45,12 @@ public class MicrometerEventListenerTest {
@Mock @Mock
KeycloakSession session; KeycloakSession session;
@Mock @Mock
RealmProvider realmProvider;
@Mock
RealmModel realmModel; RealmModel realmModel;
@Mock @Mock
ClientModel clientModel; ClientModel clientModel;
@Mock @Mock
KeycloakContext context;
@Mock
MeterRegistry registry; MeterRegistry registry;
@Mock @Mock
Counter counter; Counter counter;
@ -77,10 +78,12 @@ public class MicrometerEventListenerTest {
var clientName = UUID.randomUUID().toString(); var clientName = UUID.randomUUID().toString();
var type = EventType.LOGIN; var type = EventType.LOGIN;
when(session.realms()).thenReturn(realmProvider); when(session.getContext()).thenReturn(context);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel); when(context.getRealm()).thenReturn(realmModel);
when(context.getClient()).thenReturn(clientModel);
when(realmModel.getId()).thenReturn(realmId);
when(realmModel.getName()).thenReturn(realmName); when(realmModel.getName()).thenReturn(realmName);
when(realmModel.getClientById(clientId)).thenReturn(clientModel); when(clientModel.getId()).thenReturn(clientId);
when(clientModel.getClientId()).thenReturn(clientName); when(clientModel.getClientId()).thenReturn(clientName);
listener(true).onEvent(toEvent(realmId, clientId, type, null)); listener(true).onEvent(toEvent(realmId, clientId, type, null));
@ -98,10 +101,12 @@ public class MicrometerEventListenerTest {
var type = EventType.LOGIN_ERROR; var type = EventType.LOGIN_ERROR;
var error = UUID.randomUUID().toString(); var error = UUID.randomUUID().toString();
when(session.realms()).thenReturn(realmProvider); when(session.getContext()).thenReturn(context);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel); when(context.getRealm()).thenReturn(realmModel);
when(context.getClient()).thenReturn(clientModel);
when(realmModel.getId()).thenReturn(realmId);
when(realmModel.getName()).thenReturn(realmName); when(realmModel.getName()).thenReturn(realmName);
when(realmModel.getClientById(clientId)).thenReturn(clientModel); when(clientModel.getId()).thenReturn(clientId);
when(clientModel.getClientId()).thenReturn(clientName); when(clientModel.getClientId()).thenReturn(clientName);
listener(true).onEvent(toEvent(realmId, clientId, type, error)); listener(true).onEvent(toEvent(realmId, clientId, type, error));
@ -112,11 +117,17 @@ public class MicrometerEventListenerTest {
@Test @Test
void replaceFieldsEmpty() { void replaceFieldsEmpty() {
when(session.realms()).thenReturn(realmProvider); var realmName = UUID.randomUUID().toString();
when(realmProvider.getRealm(any())).thenReturn(null); 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)); listener(true).onEvent(toEvent(null, null, null, null));
assertEvent("", "", "", ""); assertEvent(realmName, clientName, "", "");
} }
@DisplayName("replace(false) - without error") @DisplayName("replace(false) - without error")
@ -182,8 +193,9 @@ public class MicrometerEventListenerTest {
var resource = ResourceType.USER; var resource = ResourceType.USER;
var operation = OperationType.CREATE; var operation = OperationType.CREATE;
when(session.realms()).thenReturn(realmProvider); when(session.getContext()).thenReturn(context);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel); when(context.getRealm()).thenReturn(realmModel);
when(realmModel.getId()).thenReturn(realmId);
when(realmModel.getName()).thenReturn(realmName); when(realmModel.getName()).thenReturn(realmName);
listener(true).onEvent(toAdminEvent(realmId, resource, operation, null), false); listener(true).onEvent(toAdminEvent(realmId, resource, operation, null), false);
@ -200,8 +212,9 @@ public class MicrometerEventListenerTest {
var operation = OperationType.CREATE; var operation = OperationType.CREATE;
var error = UUID.randomUUID().toString(); var error = UUID.randomUUID().toString();
when(session.realms()).thenReturn(realmProvider); when(session.getContext()).thenReturn(context);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel); when(context.getRealm()).thenReturn(realmModel);
when(realmModel.getId()).thenReturn(realmId);
when(realmModel.getName()).thenReturn(realmName); when(realmModel.getName()).thenReturn(realmName);
listener(true).onEvent(toAdminEvent(realmId, resource, operation, error), false); listener(true).onEvent(toAdminEvent(realmId, resource, operation, error), false);
@ -212,11 +225,14 @@ public class MicrometerEventListenerTest {
@Test @Test
void replaceFieldsEmpty() { void replaceFieldsEmpty() {
when(session.realms()).thenReturn(realmProvider); var realmName = UUID.randomUUID().toString();
when(realmProvider.getRealm(any())).thenReturn(null);
when(session.getContext()).thenReturn(context);
when(context.getRealm()).thenReturn(realmModel);
when(realmModel.getName()).thenReturn(realmName);
listener(true).onEvent(toAdminEvent(null, null, null, null), false); listener(true).onEvent(toAdminEvent(null, null, null, null), false);
assertAdminEvent("", "", "", ""); assertAdminEvent(realmName, "", "", "");
} }
@DisplayName("replace(false) - without error") @DisplayName("replace(false) - without error")
@ -277,8 +293,13 @@ public class MicrometerEventListenerTest {
verify(registry).counter(anyString(), any(String[].class)); verify(registry).counter(anyString(), any(String[].class));
verify(counter).increment(); verify(counter).increment();
assertEquals(metric, metricCaptor.getValue(), "metric"); 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) .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");
} }
} }