145 lines
6.1 KiB
Java
145 lines
6.1 KiB
Java
package org.gcube.keycloak.event;
|
|
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
|
|
import org.jboss.logging.Logger;
|
|
import org.keycloak.Config.Scope;
|
|
import org.keycloak.events.EventListenerProvider;
|
|
import org.keycloak.events.EventListenerProviderFactory;
|
|
import org.keycloak.models.ClientModel;
|
|
import org.keycloak.models.KeycloakSession;
|
|
import org.keycloak.models.KeycloakSessionFactory;
|
|
import org.keycloak.models.RealmModel;
|
|
|
|
/**
|
|
* @author <a href="mailto:marco.lettere@nubisware.com">Marco Lettere</a>
|
|
* @author <a href="mailto:mauro.mugnaini@nubisware.com">Mauro Mugnaini</a>
|
|
*/
|
|
public class OrchestratorEventPublisherProviderFactory implements EventListenerProviderFactory {
|
|
|
|
private static final Logger logger = Logger.getLogger(OrchestratorEventPublisherProviderFactory.class);
|
|
|
|
public static final String MASTER_REALM_NAME = "master";
|
|
public static final String ORCHESTRATOR_CLIENT_ID = "orchestrator";
|
|
public static final String KEYCLOAK_CLIENT_ID = "keycloak-client";
|
|
|
|
private static final int CHECK_DELAY = 60 * 1000; // One minute
|
|
|
|
public static URL ORCHESTRATOR_ENDPOINT;
|
|
public static URL KEYCLOAK_ENDPOINT;
|
|
public static String KEYCLOAK_CLIENT_SECRET;
|
|
|
|
protected Long lastEndpointCheck = new Long(0);
|
|
protected EventListenerProvider oepp;
|
|
|
|
public OrchestratorEventPublisherProviderFactory() {
|
|
logger.info("New OrchestratorEventPublisherProviderFactory has been created");
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
}
|
|
|
|
@Override
|
|
public synchronized EventListenerProvider create(KeycloakSession keycloakSession) {
|
|
Long now = System.currentTimeMillis();
|
|
Long elapsed = now - lastEndpointCheck;
|
|
if (oepp == null || elapsed > CHECK_DELAY) {
|
|
lastEndpointCheck = now;
|
|
ClientModel orchestratorClient = getClientInActualOrMasterRealm(keycloakSession, ORCHESTRATOR_CLIENT_ID);
|
|
URL newOrchestratorEndpoint;
|
|
if (orchestratorClient != null) {
|
|
logger.trace("Getting configured orchestrator endpoint address from client's base URL");
|
|
try {
|
|
newOrchestratorEndpoint = new URL(orchestratorClient.getBaseUrl());
|
|
} catch (MalformedURLException e) {
|
|
logger.errorf("Can't create new orchestrator endpoint address: %s", orchestratorClient.getBaseUrl(),
|
|
e);
|
|
oepp = new NoOpEventPublisherProvider();
|
|
return oepp;
|
|
}
|
|
} else {
|
|
logger.debugf("Can't go ahead without a configured '%f' client", ORCHESTRATOR_CLIENT_ID);
|
|
oepp = null;
|
|
return oepp;
|
|
}
|
|
ClientModel keycloakClient = getClientInActualOrMasterRealm(keycloakSession, KEYCLOAK_CLIENT_ID);
|
|
URL newKeycloakEndpoint;
|
|
String keycloakClientSecret;
|
|
if (keycloakClient != null) {
|
|
try {
|
|
logger.debug("Getting configured keycloak endpoint address from client's base URL");
|
|
newKeycloakEndpoint = new URL(keycloakClient.getBaseUrl());
|
|
// Only do it if URL has been configured properly
|
|
logger.debug("Getting configured keycloak client client-secret from client");
|
|
keycloakClientSecret = keycloakClient.getSecret();
|
|
} catch (MalformedURLException e) {
|
|
logger.errorf("Can't create new keycloak token address: %s", keycloakClient.getBaseUrl(), e);
|
|
oepp = new NoOpEventPublisherProvider();
|
|
return oepp;
|
|
}
|
|
} else {
|
|
logger.debugf("Can't go ahead without a configured '%f' client", KEYCLOAK_CLIENT_ID);
|
|
oepp = new NoOpEventPublisherProvider();
|
|
return oepp;
|
|
}
|
|
|
|
if (oepp == null || !newOrchestratorEndpoint.equals(ORCHESTRATOR_ENDPOINT)
|
|
|| !newKeycloakEndpoint.equals(KEYCLOAK_ENDPOINT)
|
|
|| !keycloakClientSecret.equals(KEYCLOAK_CLIENT_SECRET)) {
|
|
|
|
logger.info("Creating new orchestrator event publisher provider");
|
|
// Address and other fileds will be then read from static fields in this class by
|
|
// the createEventSender() called by the superclass' constructor, overridden in the impl.
|
|
ORCHESTRATOR_ENDPOINT = newOrchestratorEndpoint;
|
|
KEYCLOAK_ENDPOINT = newKeycloakEndpoint;
|
|
KEYCLOAK_CLIENT_SECRET = keycloakClientSecret;
|
|
oepp = new OrchestratorEventPublisherProvider();
|
|
}
|
|
|
|
} else {
|
|
logger.tracef("Next check is in %d millis", CHECK_DELAY - elapsed);
|
|
}
|
|
return oepp;
|
|
}
|
|
|
|
protected ClientModel getClientInActualOrMasterRealm(KeycloakSession keycloakSession, String clientId) {
|
|
logger.debug("Getting actual realm from session's context");
|
|
RealmModel realm = keycloakSession.getContext().getRealm();
|
|
logger.debugf("Trying getting '%s' client in current realm: '%s'", clientId, realm.getName());
|
|
ClientModel client = realm.getClientByClientId(clientId);
|
|
if (client == null) {
|
|
if (!MASTER_REALM_NAME.equals(realm.getName())) {
|
|
logger.debugf("Not found. Now trying getting '%s' in '%s' realm", clientId, MASTER_REALM_NAME);
|
|
realm = keycloakSession.realms().getRealmByName(MASTER_REALM_NAME);
|
|
client = realm.getClientByClientId(clientId);
|
|
if (client == null) {
|
|
logger.warnf("Cannot find '%s' client not even in '%s' realm", clientId, realm.getName(),
|
|
MASTER_REALM_NAME);
|
|
|
|
return null;
|
|
}
|
|
} else {
|
|
logger.trace("Not found.");
|
|
}
|
|
}
|
|
logger.debugf("Client '%f' found", clientId);
|
|
return client;
|
|
}
|
|
|
|
@Override
|
|
public String getId() {
|
|
return "orchestrator-event-publisher";
|
|
}
|
|
|
|
@Override
|
|
public void init(Scope scope) {
|
|
}
|
|
|
|
@Override
|
|
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
|
|
}
|
|
|
|
}
|