Skip to content
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
46 changes: 1 addition & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The aim of this module is to send those Events and AdminEvents to another server

## Compilation

Java 8 is required (Java 9+ is not supported yet).
Java 21 is required.

### Build and Tests
This project 2 modules, one with the event emitter code (could contain unit tests) and one for integration tests using a parent inherited from Keycloak tests for simplifying the
Expand All @@ -15,13 +15,6 @@ POM content.
The integration tests rely on the arquillian-based Keycloak test framework. As Keycloak does not publish publicly
the related jars for testing, one needs to manually build them so that they are available for maven for testing.

For building these tests-jars, you need to:
* clone the official Keycloak repository (https://github.com/keycloak/keycloak)
* checkout the tag of the Keycloak version related to the version of the event-emitter module
* execute `mvn clean install -DskipTests` in the Keycloak repository to build the jars and put them in your maven repository

Once these test-jars are built, the event-emitter module can be built.

### Binary
The build produces the JAR of the module, along with a TAR.GZ file that contains the dependencies to be installed
with the module.
Expand All @@ -40,43 +33,6 @@ tar -zxf keycloak-event-emitter-<version>-dist.tar.gz --directory <PATH_TO_KEYCL
chmod -R 755 <PATH_TO_KEYCLOAK>/modules/system/layers/event-emitter
```

For enabling the newly created layer, edit __layers.conf__:
```Bash
layers=keycloak,event-emitter
```


## Enable & Configure

In __standalone.xml__, add the new module and configure it

```xml
<!--[...]-->
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<web-context>auth</web-context>
<providers>
<!--[...]-->
<provider>module:io.cloudtrust.keycloak.eventemitter</provider>
<!--[...]-->
</providers>
<!--[...]-->
<spi name="eventsListener">
<provider name="event-emitter" enabled="true">
<properties>
<property name="format" value="JSON"/>
<property name="targetUri" value="http://localhost:8888/event/receiver"/>
<property name="bufferCapacity" value="10"/>
<property name="keycloakId" value="1"/>
<property name="datacenterId" value="1"/>
<property name="connectTimeoutMillis" value="500"/>
<property name="connectionRequestTimeoutMillis" value="500"/>
<property name="socketTimeoutMillis" value="500"/>
</properties>
</provider>
</spi>
<!--[...]-->
</subsystem>
```

Configuration parameters:
* format: JSON or FLATBUFFER
Expand Down
11 changes: 3 additions & 8 deletions keycloak-event-emitter-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
<parent>
<groupId>io.cloudtrust</groupId>
<artifactId>kc-cloudtrust-testsuite</artifactId>
<version>20.0.0</version>
<version>26.0.0-SNAPSHOT</version>
<relativePath />
</parent>

<artifactId>keycloak-event-emitter-tests</artifactId>
<version>20.1.1-SNAPSHOT</version>
<version>26.0.0-SNAPSHOT</version>

<properties>
<apache-cxf.version>3.4.1</apache-cxf.version>
<gson.version>2.9.0</gson.version>
<gson.version>2.12.1</gson.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
</properties>

Expand Down Expand Up @@ -60,11 +60,6 @@
<artifactId>system-lambda</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package flatbuffers.events;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.events.EventType;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;

import java.util.Arrays;
import java.util.List;

public class TypesTest {
protected <E extends Enum<E>> void validateNames(Class<E> enumClass, String[] flatbufferTypes) {
List<String> enumNames = Arrays.stream(enumClass.getEnumConstants()).map(Enum::name).toList();
int flatLen = flatbufferTypes.length - ("UNKNOWN".equals(flatbufferTypes[flatbufferTypes.length-1]) ? 1 : 0);
for(int i=0; i<Math.max(enumNames.size(), flatLen); i++) {
String valueEnum = i<enumNames.size() ? enumNames.get(i) : "<missing>";
String valueFlatb = i<flatbufferTypes.length ? flatbufferTypes[i] : "<missing>";
Assertions.assertEquals(valueEnum, valueFlatb);
}
Assertions.assertEquals(enumNames.size(), flatLen);
}

/**
* This test checks that the list of EventType defined in flatbuffers matches the list defined by the current
* Keycloak version. If it is not the case, it means that the file events.fbs needs to be updated according
* to the new EventType file defined in the root GitHub repository of the correct version.
*/
@Test
void testEventTypesAreUpToDate() {
validateNames(EventType.class, flatbuffers.events.EventType.names);
}

/**
* This test checks that the list of OperationType defined in flatbuffers matches the list defined by the current
* Keycloak version. If it is not the case, it means that the file events.fbs needs to be updated according
* to the new OperationType file defined in the root GitHub repository of the correct version.
*/
@Test
void testOperationTypesAreUpToDate() {
validateNames(OperationType.class, flatbuffers.events.OperationType.names);
}

/**
* This test checks that the list of ResourceType defined in flatbuffers matches the list defined by the current
* Keycloak version. If it is not the case, it means that the file events.fbs needs to be updated according
* to the new ResourceType file defined in the root GitHub repository of the correct version.
*/
@Test
void testResourceTypesAreUpToDate() {
validateNames(ResourceType.class, flatbuffers.events.ResourceType.names);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package io.cloudtrust.keycloak;
package io.cloudtrust.keycloak.eventemitter;

import io.cloudtrust.keycloak.eventemitter.EventEmitterProviderFactory;
import io.cloudtrust.keycloak.eventemitter.kafkaemitter.KafkaEventEmitterProviderFactory;
import io.cloudtrust.keycloak.test.AbstractInKeycloakTest;
import io.cloudtrust.keycloak.test.http.HttpServerManager;
import io.cloudtrust.keycloak.test.pages.LoginPage;
import io.cloudtrust.keycloak.test.pages.WebPage;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.StatusCodes;
import jakarta.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
import org.jboss.logging.Logger;
import org.junit.jupiter.api.AfterAll;
Expand All @@ -21,7 +22,6 @@
import org.keycloak.representations.idm.UserRepresentation;
import org.xnio.streams.ChannelInputStream;

import javax.ws.rs.core.Response;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.LinkedList;
Expand Down Expand Up @@ -97,7 +97,7 @@ public String toString() {

private void setupTestRealm(RealmResource testRealm) {
RealmRepresentation realm = testRealm.toRepresentation();
realm.getEventsListeners().add(EventEmitterProviderFactory.PROVIDER_ID);
realm.getEventsListeners().add(KafkaEventEmitterProviderFactory.PROVIDER_ID);
testRealm.update(realm);

CredentialRepresentation credentialPass = new CredentialRepresentation();
Expand All @@ -118,5 +118,4 @@ private void setupTestRealm(RealmResource testRealm) {
}
}
}

}
Loading