keycloak-d4science-spi-parent/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherP...

127 lines
5.3 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.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 OrchestratorEventPublisherProvider oepp;
public OrchestratorEventPublisherProviderFactory() {
logger.info("New OrchestratorEventPublisherProviderFactory has been created");
}
@Override
public void close() {
}
@Override
public synchronized OrchestratorEventPublisherProvider 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);
ClientModel keycloakClient = getClientInActualOrMasterRealm(keycloakSession, KEYCLOAK_CLIENT_ID);
logger.debug("Getting configured orchestrator endpoint address from client's base URL");
String orchestratorAddress = orchestratorClient.getBaseUrl();
logger.debug("Getting configured keycloak endpoint address from client's base URL");
String keycloakAddress = keycloakClient.getBaseUrl();
logger.debug("Getting configured keycloak client client-secret from client");
String keycloakClientSecret = keycloakClient.getSecret();
URL newOrchestratorEndpoint;
URL newKeycloakEndpoint;
try {
newOrchestratorEndpoint = new URL(orchestratorAddress);
} catch (MalformedURLException e) {
logger.errorf("Can't create new orchestrator endpoint address: %s",
orchestratorAddress, e);
oepp = null;
return null;
}
try {
newKeycloakEndpoint = new URL(keycloakAddress);
} catch (MalformedURLException e) {
logger.errorf("Can't create new keycloak token address: %s", keycloakAddress, e);
oepp = null;
return null;
}
if (oepp == null || !newOrchestratorEndpoint.equals(ORCHESTRATOR_ENDPOINT)
|| !newKeycloakEndpoint.equals(KEYCLOAK_ENDPOINT)
|| !keycloakClientSecret.equals(KEYCLOAK_CLIENT_SECRET)) {
logger.infof("Creating new orchestrator event publisher provider for endpoint: %s",
orchestratorAddress);
// 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.debugf("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) {
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;
}
}
return client;
}
@Override
public String getId() {
return "orchestrator-event-publisher";
}
@Override
public void init(Scope scope) {
}
@Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
}
}