keycloak-event-listener-mqtt/src/main/scala/net/dergrimm/keycloak/providers/events/mqtt/MqttEventListenerProviderFactory.scala
2024-02-18 17:11:38 +01:00

106 lines
3.4 KiB
Scala

package net.dergrimm.keycloak.providers.events.mqtt
import java.util.logging
import org.keycloak.Config
import org.keycloak.events.EventListenerProvider
import org.keycloak.events.EventListenerProviderFactory
import org.keycloak.events.EventType
import org.keycloak.events.admin.OperationType
import org.keycloak.models.KeycloakSession
import org.keycloak.models.KeycloakSessionFactory
import scala.collection.immutable
import akka.stream.alpakka.mqtt.MqttConnectionSettings
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence
import scala.concurrent.duration.FiniteDuration
import java.util.concurrent.TimeUnit
import akka.stream.alpakka.mqtt.scaladsl.MqttSink
import akka.actor.ActorSystem
object MqttEventListenerProviderFactory:
private val PLUGIN_ID = "mqtt"
private val PUBLISHER_ID = "keycloak"
implicit val system: ActorSystem = ActorSystem()
class MqttEventListenerProviderFactory(
var data: MqttEventListenerProviderFactoryData
) extends EventListenerProviderFactory:
private final val logger =
logging.Logger.getLogger(
classOf[MqttEventListenerProviderFactory].getName()
)
def this() = this(null)
override def create(session: KeycloakSession): MqttEventListenerProvider =
MqttEventListenerProvider(
session,
excludedEvents = data.excludedEvents,
excludedAdminEvents = data.excludedAdminOperations,
mqttOptions = data.mqttOptions,
mqttSink = data.mqttSink
)
override def init(config: Config.Scope): Unit =
val excludes = config.getArray("excludeEvents")
val excludedEvents =
if excludes != null then
Some(
immutable.HashSet.from(excludes.map(EventType.valueOf))
)
else None
val excludesOperations = config.getArray("excludesOperations")
val excludedAdminOperations =
if excludesOperations != null then
Some(
immutable.HashSet.from(excludesOperations.map(OperationType.valueOf))
)
else None
val uri = config.get("serverUri")
if uri == null then
throw new IllegalArgumentException("MQTT server URI is null")
val credentials =
val username = config.get("username")
val password = config.get("password")
if username != null && password != null then
Some(Credentials(username, password))
else None
val cleanSession = config.getBoolean("cleanSession", true)
val connectionTimeout =
FiniteDuration(config.getLong("connectionTimeout", 10), TimeUnit.SECONDS)
val mqttOptions = MqttOptions.fromConfig(config)
var connectionSettings = MqttConnectionSettings(
uri,
"net.dergrimm.keycloak.providers.events.mqtt",
new MemoryPersistence
).withCleanSession(cleanSession)
.withConnectionTimeout(connectionTimeout)
credentials match
case Some(creds) =>
connectionSettings = connectionSettings.withAuth(
username = creds.username,
password = creds.password
)
case None => {}
val sink = MqttSink(connectionSettings, mqttOptions.qos)
data = MqttEventListenerProviderFactoryData(
excludedEvents = excludedEvents,
excludedAdminOperations = excludedAdminOperations,
mqttOptions,
sink
)
override def postInit(factory: KeycloakSessionFactory): Unit = {}
override def close(): Unit = {}
override def getId(): String = MqttEventListenerProviderFactory.PLUGIN_ID