KEYCLOAK-17991 Introduce preview feature for map storage

This commit is contained in:
Hynek Mlnarik 2021-05-04 10:01:33 +02:00 committed by Hynek Mlnařík
parent 253dee077e
commit 98a88e3e8b
12 changed files with 53 additions and 10 deletions

View file

@ -55,7 +55,8 @@ public class Profile {
UPLOAD_SCRIPTS(DEPRECATED),
WEB_AUTHN(Type.DEFAULT, Type.PREVIEW),
CLIENT_POLICIES(Type.PREVIEW),
CIBA(Type.PREVIEW);
CIBA(Type.PREVIEW),
MAP_STORAGE(Type.EXPERIMENTAL);
private Type typeProject;
private Type typeProduct;

View file

@ -21,7 +21,7 @@ public class ProfileTest {
@Test
public void checkDefaultsKeycloak() {
Assert.assertEquals("community", Profile.getName());
assertEquals(Profile.getDisabledFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DOCKER, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.UPLOAD_SCRIPTS, Profile.Feature.CLIENT_POLICIES, Profile.Feature.CIBA);
assertEquals(Profile.getDisabledFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DOCKER, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.UPLOAD_SCRIPTS, Profile.Feature.CLIENT_POLICIES, Profile.Feature.CIBA, Profile.Feature.MAP_STORAGE);
assertEquals(Profile.getPreviewFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.CLIENT_POLICIES, Profile.Feature.CIBA);
assertEquals(Profile.getDeprecatedFeatures(), Profile.Feature.UPLOAD_SCRIPTS);
@ -37,7 +37,7 @@ public class ProfileTest {
Profile.init();
Assert.assertEquals("product", Profile.getName());
assertEquals(Profile.getDisabledFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DOCKER, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.UPLOAD_SCRIPTS, Profile.Feature.WEB_AUTHN, Profile.Feature.CLIENT_POLICIES, Profile.Feature.CIBA);
assertEquals(Profile.getDisabledFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.DOCKER, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.UPLOAD_SCRIPTS, Profile.Feature.WEB_AUTHN, Profile.Feature.CLIENT_POLICIES, Profile.Feature.CIBA, Profile.Feature.MAP_STORAGE);
assertEquals(Profile.getPreviewFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.OPENSHIFT_INTEGRATION, Profile.Feature.WEB_AUTHN, Profile.Feature.CLIENT_POLICIES, Profile.Feature.CIBA);
assertEquals(Profile.getDeprecatedFeatures(), Profile.Feature.UPLOAD_SCRIPTS);

View file

@ -13,6 +13,8 @@
embed-server
/system-property=keycloak.profile.feature.map_storage:add(value=enabled)
/subsystem=keycloak-server/spi=authorizationPersister:add(default-provider=map)
/subsystem=keycloak-server/spi=client:add(default-provider=map)
/subsystem=keycloak-server/spi=clientScope:add(default-provider=map)

View file

@ -26,6 +26,7 @@ import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.store.AuthorizationStoreFactory;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.common.Profile;
import org.keycloak.component.AmphibianProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.map.authorization.entity.MapPermissionTicketEntity;
@ -38,12 +39,13 @@ import org.keycloak.models.map.storage.MapStorage;
import org.keycloak.models.map.storage.MapStorageProvider;
import org.keycloak.models.map.storage.MapStorageProviderFactory;
import org.keycloak.models.map.storage.MapStorageSpi;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
import static org.keycloak.models.utils.KeycloakModelUtils.getComponentFactory;
/**
* @author mhajas
*/
public class MapAuthorizationStoreFactory<K> implements AmphibianProviderFactory<StoreFactory>, AuthorizationStoreFactory {
public class MapAuthorizationStoreFactory<K> implements AmphibianProviderFactory<StoreFactory>, AuthorizationStoreFactory, EnvironmentDependentProviderFactory {
public static final String PROVIDER_ID = AbstractMapProviderFactory.PROVIDER_ID;
@ -98,4 +100,9 @@ public class MapAuthorizationStoreFactory<K> implements AmphibianProviderFactory
public String getHelpText() {
return "Authorization store provider";
}
@Override
public boolean isSupported() {
return Profile.isFeatureEnabled(Profile.Feature.MAP_STORAGE);
}
}

View file

@ -17,6 +17,7 @@
package org.keycloak.models.map.common;
import org.keycloak.Config.Scope;
import org.keycloak.common.Profile;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.map.storage.MapStorage;
import org.keycloak.models.map.storage.MapStorageProvider;
@ -24,6 +25,7 @@ import org.keycloak.models.map.storage.MapStorageProviderFactory;
import org.keycloak.models.map.storage.MapStorageSpi;
import org.keycloak.component.AmphibianProviderFactory;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
import org.keycloak.provider.Provider;
import org.jboss.logging.Logger;
import static org.keycloak.models.utils.KeycloakModelUtils.getComponentFactory;
@ -32,7 +34,7 @@ import static org.keycloak.models.utils.KeycloakModelUtils.getComponentFactory;
*
* @author hmlnarik
*/
public abstract class AbstractMapProviderFactory<T extends Provider, K, V extends AbstractEntity<K>, M> implements AmphibianProviderFactory<T> {
public abstract class AbstractMapProviderFactory<T extends Provider, K, V extends AbstractEntity<K>, M> implements AmphibianProviderFactory<T>, EnvironmentDependentProviderFactory {
public static final String PROVIDER_ID = "map";
@ -74,4 +76,9 @@ public abstract class AbstractMapProviderFactory<T extends Provider, K, V extend
// Implementation of the map storage SPI
this.storageConfigScope = config.scope(CONFIG_STORAGE);
}
@Override
public boolean isSupported() {
return Profile.isFeatureEnabled(Profile.Feature.MAP_STORAGE);
}
}

View file

@ -21,6 +21,7 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.common.Profile;
import org.keycloak.common.Version;
import org.keycloak.common.util.Base64Url;
import org.keycloak.common.util.RandomString;
@ -30,8 +31,9 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ServerInfoProvider;
import org.keycloak.models.ServerInfoProviderFactory;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
public class MapServerInfoProviderFactory implements ServerInfoProviderFactory {
public class MapServerInfoProviderFactory implements ServerInfoProviderFactory, EnvironmentDependentProviderFactory {
public static final String PROVIDER_ID = "map";
@ -72,6 +74,11 @@ public class MapServerInfoProviderFactory implements ServerInfoProviderFactory {
public void close() {
}
@Override
public boolean isSupported() {
return Profile.isFeatureEnabled(Profile.Feature.MAP_STORAGE);
}
private static final ServerInfoProvider INSTANCE = new ServerInfoProvider() {
private final MigrationModel INSTANCE = new MigrationModel() {

View file

@ -22,6 +22,7 @@ import org.keycloak.authorization.model.PermissionTicket;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.common.Profile;
import org.keycloak.component.ComponentModelScope;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.ClientModel;
@ -49,6 +50,7 @@ import org.keycloak.models.map.storage.MapStorageProviderFactory;
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
import org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity;
import org.keycloak.models.map.storage.StringKeyConvertor;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.sessions.RootAuthenticationSessionModel;
import java.util.Collections;
@ -59,7 +61,7 @@ import java.util.Map;
*
* @author hmlnarik
*/
public class ConcurrentHashMapStorageProviderFactory implements AmphibianProviderFactory<MapStorageProvider>,MapStorageProviderFactory {
public class ConcurrentHashMapStorageProviderFactory implements AmphibianProviderFactory<MapStorageProvider>, MapStorageProviderFactory, EnvironmentDependentProviderFactory {
public static final String PROVIDER_ID = "concurrenthashmap";
@ -262,4 +264,8 @@ public class ConcurrentHashMapStorageProviderFactory implements AmphibianProvide
return Collections.emptyList();
}
@Override
public boolean isSupported() {
return Profile.isFeatureEnabled(Profile.Feature.MAP_STORAGE);
}
}

View file

@ -17,6 +17,7 @@
package org.keycloak.models.map.userSession;
import org.keycloak.Config.Scope;
import org.keycloak.common.Profile;
import org.keycloak.component.AmphibianProviderFactory;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.KeycloakSession;
@ -31,6 +32,7 @@ import org.keycloak.models.map.storage.MapStorageProvider;
import org.keycloak.models.map.storage.MapStorageProviderFactory;
import org.keycloak.models.map.storage.MapStorageSpi;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
import org.keycloak.provider.ProviderEvent;
import org.keycloak.provider.ProviderEventListener;
import static org.keycloak.models.utils.KeycloakModelUtils.getComponentFactory;
@ -38,7 +40,7 @@ import static org.keycloak.models.utils.KeycloakModelUtils.getComponentFactory;
/**
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
*/
public class MapUserSessionProviderFactory<UK, CK> implements AmphibianProviderFactory<UserSessionProvider>, UserSessionProviderFactory, ProviderEventListener {
public class MapUserSessionProviderFactory<UK, CK> implements AmphibianProviderFactory<UserSessionProvider>, UserSessionProviderFactory, ProviderEventListener, EnvironmentDependentProviderFactory {
public static final String CONFIG_STORAGE_USER_SESSIONS = "storage-user-sessions";
public static final String CONFIG_STORAGE_CLIENT_SESSIONS = "storage-client-sessions";
@ -105,4 +107,9 @@ public class MapUserSessionProviderFactory<UK, CK> implements AmphibianProviderF
provider.removeUserSessions(userRemovedEvent.getRealm(), userRemovedEvent.getUser());
}
}
@Override
public boolean isSupported() {
return Profile.isFeatureEnabled(Profile.Feature.MAP_STORAGE);
}
}

View file

@ -1185,6 +1185,8 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<keycloak.profile.feature.map_storage>enabled</keycloak.profile.feature.map_storage>
<keycloak.mapStorage.provider>concurrenthashmap</keycloak.mapStorage.provider>
<keycloak.realm.provider>map</keycloak.realm.provider>
<keycloak.client.provider>map</keycloak.client.provider>
<keycloak.clientScope.provider>map</keycloak.clientScope.provider>

View file

@ -80,7 +80,7 @@
},
"mapStorage": {
"provider": "${keycloak.mapStorage.provider:concurrenthashmap}",
"provider": "${keycloak.mapStorage.provider:}",
"concurrenthashmap": {
"dir": "${project.build.directory:target}",
"keyType.realms": "string",

View file

@ -24,6 +24,7 @@
<jdbc.mvn.artifactId>h2</jdbc.mvn.artifactId>
<jdbc.mvn.version>${h2.version}</jdbc.mvn.version>
<log4j.configuration>file:${project.build.directory}/dependency/log4j.properties</log4j.configuration>
<keycloak.profile.feature.map_storage>disabled</keycloak.profile.feature.map_storage>
</properties>
<dependencies>
@ -108,6 +109,7 @@
<keycloak.connectionsJpa.default.password>${keycloak.connectionsJpa.password}</keycloak.connectionsJpa.default.password>
<keycloak.connectionsJpa.default.url>${keycloak.connectionsJpa.url}</keycloak.connectionsJpa.default.url>
<log4j.configuration>file:${project.build.directory}/test-classes/log4j.properties</log4j.configuration> <!-- for the logging to properly work with tests in the 'other' module -->
<keycloak.profile.feature.map_storage>${keycloak.profile.feature.map_storage}</keycloak.profile.feature.map_storage>
</systemPropertyVariables>
</configuration>
</plugin>
@ -194,6 +196,7 @@
<profile>
<id>map+infinispan</id>
<properties>
<keycloak.profile.feature.map_storage>enabled</keycloak.profile.feature.map_storage>
<keycloak.model.parameters>Infinispan,Jpa,Map,ConcurrentHashMapStorage</keycloak.model.parameters>
</properties>
</profile>
@ -201,6 +204,7 @@
<profile>
<id>map</id>
<properties>
<keycloak.profile.feature.map_storage>enabled</keycloak.profile.feature.map_storage>
<keycloak.model.parameters>Jpa,Map,ConcurrentHashMapStorage</keycloak.model.parameters>
</properties>
</profile>

View file

@ -54,7 +54,7 @@
},
"mapStorage": {
"provider": "${keycloak.mapStorage.provider:concurrenthashmap}",
"provider": "${keycloak.mapStorage.provider:}",
"concurrenthashmap": {
"dir": "${project.build.directory:target}"
}