diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ComponentUtil.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ComponentUtil.java index 969eacbd8a..0d103124dc 100644 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/ComponentUtil.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ComponentUtil.java @@ -25,6 +25,8 @@ import org.keycloak.provider.Provider; import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderFactory; import org.keycloak.representations.idm.ComponentRepresentation; +import org.keycloak.storage.OnCreateComponent; +import org.keycloak.storage.UserStorageProviderFactory; import java.util.HashMap; import java.util.List; @@ -88,6 +90,9 @@ public class ComponentUtil { public static void notifyCreated(KeycloakSession session, RealmModel realm, ComponentModel model) { ComponentFactory factory = getComponentFactory(session, model); factory.onCreate(session, realm, model); + if (factory instanceof UserStorageProviderFactory) { + ((OnCreateComponent)session.userStorageManager()).onCreate(session, realm, model); + } } public static void notifyUpdated(KeycloakSession session, RealmModel realm, ComponentModel model) { ComponentFactory factory = getComponentFactory(session, model); diff --git a/server-spi-private/src/main/java/org/keycloak/storage/OnCreateComponent.java b/server-spi-private/src/main/java/org/keycloak/storage/OnCreateComponent.java new file mode 100644 index 0000000000..e01dce877b --- /dev/null +++ b/server-spi-private/src/main/java/org/keycloak/storage/OnCreateComponent.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.keycloak.storage; + +import org.keycloak.component.ComponentModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; + +/** + * Callback for component creation. Only hardcoded classes like UserStorageManager implement it. In future we + * may allow anybody to implement this interface. + * + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface OnCreateComponent { + void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model); +} diff --git a/server-spi/src/main/java/org/keycloak/component/ComponentFactory.java b/server-spi/src/main/java/org/keycloak/component/ComponentFactory.java index da2f029195..50b16e420a 100644 --- a/server-spi/src/main/java/org/keycloak/component/ComponentFactory.java +++ b/server-spi/src/main/java/org/keycloak/component/ComponentFactory.java @@ -50,6 +50,7 @@ public interface ComponentFactory ex } + default void onUpdate(KeycloakSession session, RealmModel realm, ComponentModel model) { diff --git a/services/src/main/java/org/keycloak/services/managers/UserStorageSyncManager.java b/services/src/main/java/org/keycloak/services/managers/UserStorageSyncManager.java index b1114fabe2..cec46f2d6f 100755 --- a/services/src/main/java/org/keycloak/services/managers/UserStorageSyncManager.java +++ b/services/src/main/java/org/keycloak/services/managers/UserStorageSyncManager.java @@ -75,7 +75,6 @@ public class UserStorageSyncManager { }); } - private class Holder { ExecutionResult result; } diff --git a/services/src/main/java/org/keycloak/storage/UserStorageManager.java b/services/src/main/java/org/keycloak/storage/UserStorageManager.java index ccaf8651b4..cbb6018c69 100755 --- a/services/src/main/java/org/keycloak/storage/UserStorageManager.java +++ b/services/src/main/java/org/keycloak/storage/UserStorageManager.java @@ -19,6 +19,7 @@ package org.keycloak.storage; import org.jboss.logging.Logger; import org.keycloak.common.util.reflections.Types; +import org.keycloak.component.ComponentFactory; import org.keycloak.component.ComponentModel; import org.keycloak.models.ClientModel; import org.keycloak.models.FederatedIdentityModel; @@ -36,6 +37,8 @@ import org.keycloak.models.UserProvider; import org.keycloak.models.cache.CachedUserModel; import org.keycloak.models.cache.OnUserCache; import org.keycloak.models.cache.UserCache; +import org.keycloak.models.utils.ComponentUtil; +import org.keycloak.services.managers.UserStorageSyncManager; import org.keycloak.storage.federated.UserFederatedStorageProvider; import org.keycloak.storage.user.ImportedUserValidation; import org.keycloak.storage.user.UserBulkUpdateProvider; @@ -57,7 +60,7 @@ import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction; * @author Bill Burke * @version $Revision: 1 $ */ -public class UserStorageManager implements UserProvider, OnUserCache { +public class UserStorageManager implements UserProvider, OnUserCache, OnCreateComponent { private static final Logger logger = Logger.getLogger(UserStorageManager.class); @@ -606,6 +609,7 @@ public class UserStorageManager implements UserProvider, OnUserCache { if (!component.getProviderType().equals(UserStorageProvider.class.getName())) return; localStorage().preRemove(realm, component); if (getFederatedStorage() != null) getFederatedStorage().preRemove(realm, component); + new UserStorageSyncManager().notifyToRefreshPeriodicSync(session, realm, new UserStorageProviderModel(component), true); } @@ -627,5 +631,14 @@ public class UserStorageManager implements UserProvider, OnUserCache { public void close() { } + @Override + public void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model) { + ComponentFactory factory = ComponentUtil.getComponentFactory(session, model); + if (!(factory instanceof UserStorageProviderFactory)) return; + new UserStorageSyncManager().notifyToRefreshPeriodicSync(session, realm, new UserStorageProviderModel(model), false); + + } + + }