Skip to content

Commit b96a118

Browse files
committed
Persistence-related fixes and improvements
Add a configuration option to use message persistence. The default is to not use persistence; if set to "true" in-memory persistence will be used. Fix the client using the default file persistence for admin messages, resulting in errors in deployments where temporary files could not be opened - typically in containers. Document deployment steps for quarkus-based versions of Keycloak. Change-Id: I8430b4b9c8aad536a6f53090a1a14aea7fad5546
1 parent 894a411 commit b96a118

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
A Keycloak SPI that publishes events to a MQTT broker.
44

5+
This SPI has been deployed successfully on a containerized Keycloak 15.0.2
6+
and on a Keycloak 19.0 server on a kubernetes cluster. It should therefore
7+
work properly on any version of Keycloak above 15.0.2.
8+
59
# Build
610

711
```
@@ -10,6 +14,8 @@ mvn clean install
1014

1115
# Deploy
1216

17+
## Keycloak on Wildfly
18+
1319
* Copy target/event-listener-mqtt-jar-with-dependencies.jar to {KEYCLOAK_HOME}/standalone/deployments
1420
* Edit standalone.xml to configure the MQTT service settings. Find the following
1521
section in the configuration:
@@ -29,11 +35,27 @@ And add below:
2935
<property name="username" value="mqtt_user"/>
3036
<property name="password" value="mqtt_password"/>
3137
<property name="topic" value="my_topic"/>
38+
<property name="usePersistence" value="true">
3239
</properties>
3340
</provider>
3441
</spi>
3542
```
3643
Leave username and password out if the service allows anonymous write access.
3744
If unset, the default message topic is "keycloak/events".
45+
By default, the SPI won't use persistence. If set to true, messages will be persisted in memory.
3846

3947
* Restart the keycloak server.
48+
49+
## Keycloak on Quarkus
50+
51+
* Copy the jar archive to /opt/keycloak/providers/ in the keycloak container.
52+
* run keycloak with the following options:
53+
54+
```
55+
kc.sh start
56+
--spi-events-listener-mqtt-server-uri "tcp://your.mqtt.server:port" \
57+
--spi-events-listener-mqtt-username mqtt_user \
58+
--spi-events-listener-mqtt-password mqtt_password \
59+
--spi-events-listener-mqtt-topic my_topic
60+
--spi-events-listener-mqtt-user-persistence true
61+
```

src/main/java/org/softwarefactory/keycloak/providers/events/mqtt/MQTTEventListenerProvider.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@ public class MQTTEventListenerProvider implements EventListenerProvider {
4747
private String password;
4848
public static final String publisherId = "keycloak";
4949
public String TOPIC;
50+
public boolean usePersistence;
5051

51-
public MQTTEventListenerProvider(Set<EventType> excludedEvents, Set<OperationType> excludedAdminOperations, String serverUri, String username, String password, String topic) {
52+
public MQTTEventListenerProvider(Set<EventType> excludedEvents, Set<OperationType> excludedAdminOperations, String serverUri, String username, String password, String topic, boolean usePersistence) {
5253
this.excludedEvents = excludedEvents;
5354
this.excludedAdminOperations = excludedAdminOperations;
5455
this.serverUri = serverUri;
5556
this.username = username;
5657
this.password = password;
5758
this.TOPIC = topic;
59+
this.usePersistence = usePersistence;
5860
}
5961

6062
@Override
@@ -65,7 +67,10 @@ public void onEvent(Event event) {
6567
} else {
6668
String stringEvent = toString(event);
6769
try {
68-
MemoryPersistence persistence = new MemoryPersistence();
70+
MemoryPersistence persistence = null;
71+
if (this.usePersistence == true) {
72+
persistence = new MemoryPersistence();
73+
}
6974
MqttClient client = new MqttClient(this.serverUri ,publisherId, persistence);
7075
MqttConnectOptions options = new MqttConnectOptions();
7176
options.setAutomaticReconnect(true);
@@ -84,7 +89,7 @@ public void onEvent(Event event) {
8489
client.disconnect();
8590
} catch(Exception e) {
8691
// ?
87-
System.out.println("UH OH!! " + e.toString());
92+
System.out.println("Caught the following error: " + e.toString());
8893
e.printStackTrace();
8994
return;
9095
}
@@ -99,7 +104,11 @@ public void onEvent(AdminEvent event, boolean includeRepresentation) {
99104
} else {
100105
String stringEvent = toString(event);
101106
try {
102-
MqttClient client = new MqttClient(this.serverUri ,publisherId);
107+
MemoryPersistence persistence = null;
108+
if (this.usePersistence == true) {
109+
persistence = new MemoryPersistence();
110+
}
111+
MqttClient client = new MqttClient(this.serverUri ,publisherId, persistence);
103112
MqttConnectOptions options = new MqttConnectOptions();
104113
options.setAutomaticReconnect(true);
105114
options.setCleanSession(true);
@@ -117,7 +126,7 @@ public void onEvent(AdminEvent event, boolean includeRepresentation) {
117126
client.disconnect();
118127
} catch(Exception e) {
119128
// ?
120-
System.out.println("UH OH!! " + e.toString());
129+
System.out.println("Caught the following error: " + e.toString());
121130
e.printStackTrace();
122131
return;
123132
}

src/main/java/org/softwarefactory/keycloak/providers/events/mqtt/MQTTEventListenerProviderFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ public class MQTTEventListenerProviderFactory implements EventListenerProviderFa
4040
private String username;
4141
private String password;
4242
private String topic;
43+
private boolean usePersistence;
4344

4445
@Override
4546
public EventListenerProvider create(KeycloakSession session) {
46-
return new MQTTEventListenerProvider(excludedEvents, excludedAdminOperations, serverUri, username, password, topic);
47+
return new MQTTEventListenerProvider(excludedEvents, excludedAdminOperations, serverUri, username, password, topic, usePersistence);
4748
}
4849

4950
@Override
@@ -68,6 +69,7 @@ public void init(Config.Scope config) {
6869
username = config.get("username", null);
6970
password = config.get("password", null);
7071
topic = config.get("topic", "keycloak/events");
72+
usePersistence = config.getBoolean("usePersistence", false);
7173
}
7274

7375
@Override

0 commit comments

Comments
 (0)