Merge pull request #989 from patriot1burke/master

provider events
This commit is contained in:
Bill Burke 2015-02-23 12:11:30 -05:00
commit 1a43309333
13 changed files with 79 additions and 99 deletions

View file

@ -1,6 +1,7 @@
package org.keycloak.models;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderEventManager;
import org.keycloak.provider.ProviderFactory;
import java.util.List;
@ -9,7 +10,7 @@ import java.util.List;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface KeycloakSessionFactory {
public interface KeycloakSessionFactory extends ProviderEventManager {
KeycloakSession create();
<T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz);

View file

@ -1,31 +0,0 @@
package org.keycloak.models;
import java.util.LinkedList;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class RealmListenerHelper {
protected LinkedList<RealmProvider.RealmCreationListener> list = new LinkedList<RealmProvider.RealmCreationListener>();
public void registerListener(RealmProvider.RealmCreationListener listener) {
synchronized (list) {
list.add(listener);
}
}
public void unregisterListener(RealmProvider.RealmCreationListener listener) {
synchronized (list) {
list.remove(listener);
}
}
public void executeCreationListeners(RealmModel realm) {
synchronized (list) {
for (RealmProvider.RealmCreationListener listener : list) {
listener.created(realm);
}
}
}
}

View file

@ -1,6 +1,7 @@
package org.keycloak.models;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderEvent;
import java.util.List;
@ -9,16 +10,14 @@ import java.util.List;
* @version $Revision: 1 $
*/
public interface RealmProvider extends Provider {
public interface RealmCreationListener {
void created(RealmModel realm);
public interface RealmCreationEvent extends ProviderEvent {
RealmModel getCreatedRealm();
}
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
RealmModel createRealm(String name);
RealmModel createRealm(String id, String name);
void registerListener(RealmCreationListener listener);
void unregisterListener(RealmCreationListener listener);
RealmModel getRealm(String id);
RealmModel getRealmByName(String name);

View file

@ -0,0 +1,8 @@
package org.keycloak.provider;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface ProviderEvent {
}

View file

@ -0,0 +1,9 @@
package org.keycloak.provider;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface ProviderEventListener {
void onEvent(ProviderEvent event);
}

View file

@ -0,0 +1,16 @@
package org.keycloak.provider;
import org.keycloak.provider.ProviderEvent;
import org.keycloak.provider.ProviderEventListener;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface ProviderEventManager {
void register(ProviderEventListener listener);
void unregister(ProviderEventListener listener);
void publish(ProviderEvent event);
}

View file

@ -50,17 +50,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
session.getTransaction().enlistAfterCompletion(getTransaction());
}
@Override
public void registerListener(RealmCreationListener listener) {
getDelegate().registerListener(listener);
}
@Override
public void unregisterListener(RealmCreationListener listener) {
getDelegate().unregisterListener(listener);
}
@Override
public boolean isEnabled() {
return cache.isEnabled();

View file

@ -38,16 +38,6 @@ public class NoCacheRealmProvider implements CacheRealmProvider {
return delegate;
}
@Override
public void registerListener(RealmCreationListener listener) {
getDelegate().registerListener(listener);
}
@Override
public void unregisterListener(RealmCreationListener listener) {
getDelegate().unregisterListener(listener);
}
@Override
public void registerRealmInvalidation(String id) {
}

View file

@ -3,7 +3,6 @@ package org.keycloak.models.jpa;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmListenerHelper;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RoleModel;
@ -26,24 +25,11 @@ import java.util.List;
public class JpaRealmProvider implements RealmProvider {
private final KeycloakSession session;
protected EntityManager em;
protected RealmListenerHelper listeners;
public JpaRealmProvider(KeycloakSession session, EntityManager em, RealmListenerHelper listeners) {
public JpaRealmProvider(KeycloakSession session, EntityManager em) {
this.session = session;
this.em = em;
this.listeners = listeners;
}
@Override
public void registerListener(RealmCreationListener listener) {
listeners.registerListener(listener);
}
@Override
public void unregisterListener(RealmCreationListener listener) {
listeners.unregisterListener(listener);
}
@Override
@ -58,8 +44,13 @@ public class JpaRealmProvider implements RealmProvider {
realm.setId(id);
em.persist(realm);
em.flush();
RealmModel model = new RealmAdapter(session, em, realm);
listeners.executeCreationListeners(model);
final RealmModel model = new RealmAdapter(session, em, realm);
session.getKeycloakSessionFactory().publish(new RealmCreationEvent() {
@Override
public RealmModel getCreatedRealm() {
return model;
}
});
return model;
}

View file

@ -3,7 +3,6 @@ package org.keycloak.models.jpa;
import org.keycloak.Config;
import org.keycloak.connections.jpa.JpaConnectionProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmListenerHelper;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RealmProviderFactory;
@ -15,8 +14,6 @@ import javax.persistence.EntityManager;
*/
public class JpaRealmProviderFactory implements RealmProviderFactory {
protected RealmListenerHelper listeners = new RealmListenerHelper();
@Override
public void init(Config.Scope config) {
}
@ -29,7 +26,7 @@ public class JpaRealmProviderFactory implements RealmProviderFactory {
@Override
public RealmProvider create(KeycloakSession session) {
EntityManager em = session.getProvider(JpaConnectionProvider.class).getEntityManager();
return new JpaRealmProvider(session, em, listeners);
return new JpaRealmProvider(session, em);
}
@Override

View file

@ -8,7 +8,6 @@ import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmListenerHelper;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RoleModel;
@ -28,12 +27,10 @@ public class MongoRealmProvider implements RealmProvider {
private final MongoStoreInvocationContext invocationContext;
private final KeycloakSession session;
protected RealmListenerHelper listeners;
public MongoRealmProvider(KeycloakSession session, MongoStoreInvocationContext invocationContext, RealmListenerHelper listeners) {
public MongoRealmProvider(KeycloakSession session, MongoStoreInvocationContext invocationContext) {
this.session = session;
this.invocationContext = invocationContext;
this.listeners = listeners;
}
@Override
@ -41,18 +38,6 @@ public class MongoRealmProvider implements RealmProvider {
// TODO
}
@Override
public void registerListener(RealmCreationListener listener) {
listeners.registerListener(listener);
}
@Override
public void unregisterListener(RealmCreationListener listener) {
listeners.unregisterListener(listener);
}
@Override
public RealmModel createRealm(String name) {
return createRealm(KeycloakModelUtils.generateId(), name);
@ -66,8 +51,13 @@ public class MongoRealmProvider implements RealmProvider {
getMongoStore().insertEntity(newRealm, invocationContext);
RealmModel model = new RealmAdapter(session, newRealm, invocationContext);
listeners.executeCreationListeners(model);
final RealmModel model = new RealmAdapter(session, newRealm, invocationContext);
session.getKeycloakSessionFactory().publish(new RealmCreationEvent() {
@Override
public RealmModel getCreatedRealm() {
return model;
}
});
return model;
}

View file

@ -4,7 +4,6 @@ import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.connections.mongo.MongoConnectionProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmListenerHelper;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RealmProviderFactory;
@ -16,7 +15,6 @@ import org.keycloak.models.RealmProviderFactory;
public class MongoRealmProviderFactory implements RealmProviderFactory {
protected static final Logger logger = Logger.getLogger(MongoRealmProviderFactory.class);
protected RealmListenerHelper listeners = new RealmListenerHelper();
@Override
public String getId() {
@ -30,7 +28,7 @@ public class MongoRealmProviderFactory implements RealmProviderFactory {
@Override
public RealmProvider create(KeycloakSession session) {
MongoConnectionProvider connection = session.getProvider(MongoConnectionProvider.class);
return new MongoRealmProvider(session, connection.getInvocationContext(), listeners);
return new MongoRealmProvider(session, connection.getInvocationContext());
}
@Override

View file

@ -4,7 +4,11 @@ import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderEvent;
import org.keycloak.provider.ProviderEventListener;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderManager;
import org.keycloak.provider.Spi;
@ -16,6 +20,7 @@ import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory {
@ -23,6 +28,24 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory {
private Map<Class<? extends Provider>, String> provider = new HashMap<Class<? extends Provider>, String>();
private Map<Class<? extends Provider>, Map<String, ProviderFactory>> factoriesMap = new HashMap<Class<? extends Provider>, Map<String, ProviderFactory>>();
protected CopyOnWriteArrayList<ProviderEventListener> listeners = new CopyOnWriteArrayList<ProviderEventListener>();
@Override
public void register(ProviderEventListener listener) {
listeners.add(listener);
}
@Override
public void unregister(ProviderEventListener listener) {
listeners.remove(listener);
}
@Override
public void publish(ProviderEvent event) {
for (ProviderEventListener listener : listeners) {
listener.onEvent(event);
}
}
public void init() {
ProviderManager pm = new ProviderManager(getClass().getClassLoader(), Config.scope().getArray("providers"));