Remove quarkus options related to map store

Signed-off-by: vramik <vramik@redhat.com>

Closes #24098
This commit is contained in:
vramik 2023-11-03 12:38:01 +01:00 committed by Alexander Schwartz
parent 6d7a99dc6f
commit 71b6757c2f
23 changed files with 14 additions and 1353 deletions

View file

@ -154,3 +154,6 @@ some user profile classes and some validator related classes (but not builtin va
`keycloak-server-spi` module. However, the packages for java classes remain the same. You might be affected in some corner cases, such as when you
are overriding the built-in implementation with your own `UserProfileProvider` implementation However, note that `UserProfileProvider` is an unsupported SPI.
= Removal of the `storage` configuration setting
Since this release, it is no longer possible to use `--storage` related CLI options due to the announced discontinuation of the Map Store.

View file

@ -19,7 +19,7 @@ public class DatabaseOptions {
.category(OptionCategory.DATABASE)
.description("The database vendor.")
.defaultValue("dev-file")
.expectedValues(Database::getLegacyStoreAliases)
.expectedValues(Database::getDatabaseAliases)
.buildTime(true)
.build();

View file

@ -3,7 +3,6 @@ package org.keycloak.config;
public enum OptionCategory {
// ordered by name asc
CACHE("Cache", 10, ConfigSupportLevel.SUPPORTED),
STORAGE("Storage", 15, ConfigSupportLevel.EXPERIMENTAL),
DATABASE("Database", 20, ConfigSupportLevel.SUPPORTED),
TRANSACTION("Transaction",30, ConfigSupportLevel.SUPPORTED),
FEATURE("Feature", 40, ConfigSupportLevel.SUPPORTED),

View file

@ -1,361 +0,0 @@
/*
* Copyright 2022 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.config;
import static java.util.function.Predicate.not;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.config.database.Database;
public class StorageOptions {
public enum StorageType {
jpa("jpa"),
chm("concurrenthashmap"),
hotrod("hotrod"),
file("file");
private final String provider;
StorageType(String provider) {
this.provider = provider;
}
public String getProvider() {
return provider;
}
}
public static final Option<StorageType> STORAGE = new OptionBuilder<>("storage", StorageType.class)
.category(OptionCategory.STORAGE)
.description("Sets the default storage mechanism for all areas.")
.defaultValue(Optional.empty())
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_PROVIDER = new OptionBuilder<>("storage-provider", StorageType.class)
.category(OptionCategory.STORAGE)
.buildTime(true)
.build();
public static final Option<String> STORAGE_EVENT_STORE_PROVIDER = new OptionBuilder<>("storage-event-store-provider", String.class)
.category(OptionCategory.STORAGE)
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_EVENT_ADMIN_STORE = new OptionBuilder<>("storage-area-event-admin", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("admin events"))
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_EVENT_AUTH_STORE = new OptionBuilder<>("storage-area-event-auth", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("authentication and authorization events"))
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_EXCEPTION_CONVERTER = new OptionBuilder<>("storage-exception-converter", StorageType.class)
.category(OptionCategory.STORAGE)
.buildTime(true)
.build();
public static final Option<String> STORAGE_REALM_PROVIDER = new OptionBuilder<>("storage-realm-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_REALM_STORE = new OptionBuilder<>("storage-area-realm", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("realms"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_CLIENT_PROVIDER = new OptionBuilder<>("storage-client-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_CLIENT_STORE = new OptionBuilder<>("storage-area-client", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("clients"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_CLIENT_SCOPE_PROVIDER = new OptionBuilder<>("storage-client-scope-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_CLIENT_SCOPE_STORE = new OptionBuilder<>("storage-area-client-scope", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("client scopes"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_GROUP_PROVIDER = new OptionBuilder<>("storage-group-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_GROUP_STORE = new OptionBuilder<>("storage-area-group", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("groups"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_ROLE_PROVIDER = new OptionBuilder<>("storage-role-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_ROLE_STORE = new OptionBuilder<>("storage-area-role", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("roles"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_USER_PROVIDER = new OptionBuilder<>("storage-user-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_USER_STORE = new OptionBuilder<>("storage-area-user", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("users"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_DEPLOYMENT_STATE_PROVIDER = new OptionBuilder<>("storage-deployment-state-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED = new OptionBuilder<>("storage-deployment-state-version-seed", String.class)
.category(OptionCategory.STORAGE)
.description("Secret that serves as a seed to mask the version number of Keycloak in URLs. Need to be identical across all servers in the cluster. Will default to a random number generated when starting the server which is secure but will lead to problems when a loadbalancer without sticky sessions is used or nodes are restarted.")
.buildTime(false)
.build();
public static final Option<String> STORAGE_AUTH_SESSION_PROVIDER = new OptionBuilder<>("storage-auth-session-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_AUTH_SESSION_STORE = new OptionBuilder<>("storage-area-auth-session", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("authentication sessions"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_USER_SESSION_PROVIDER = new OptionBuilder<>("storage-user-session-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_USER_SESSION_STORE = new OptionBuilder<>("storage-area-user-session", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("user and client sessions"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_LOGIN_FAILURE_PROVIDER = new OptionBuilder<>("storage-login-failure-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_LOGIN_FAILURE_STORE = new OptionBuilder<>("storage-area-login-failure", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("login failures"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_AUTHORIZATION_PROVIDER = new OptionBuilder<>("storage-authorization-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_AUTHORIZATION_STORE = new OptionBuilder<>("storage-area-authorization", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("authorizations"))
.buildTime(true)
.build();
public static final Option<String> STORAGE_USER_SESSION_PERSISTER = new OptionBuilder<>("storage-user-session-persister", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_GLOBAL_LOCK_PROVIDER = new OptionBuilder<>("storage-global-lock-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_CACHE_REALM_ENABLED = new OptionBuilder<>("cache-realm-enabled", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_CACHE_USER_ENABLED = new OptionBuilder<>("cache-user-enabled", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_ADMIN_CACHE_CLEAR_USER = new OptionBuilder<>("cache-clear-user", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_ADMIN_CACHE_CLEAR_REALM = new OptionBuilder<>("cache-clear-realm", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_ADMIN_CACHE_CLEAR_KEYS = new OptionBuilder<>("cache-clear-keys", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_SINGLE_USE_OBJECT_PROVIDER = new OptionBuilder<>("storage-single-use-object-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<StorageType> STORAGE_SINGLE_USE_OBJECT_STORE = new OptionBuilder<>("storage-area-single-use-object", StorageType.class)
.category(OptionCategory.STORAGE)
.description(descriptionForStorageAreas("single use objects"))
.buildTime(true)
.expectedValues(Stream.of(StorageType.values()).filter(not(StorageType.file::equals)).toArray(StorageType[]::new))
.build();
public static final Option<String> STORAGE_PUBLIC_KEY_STORAGE_STORE = new OptionBuilder<>("storage-public-key-storage", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_CACHE_AUTHORIZATION_ENABLED = new OptionBuilder<>("cache-authorization-enabled", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_LEGACY_SESSION_SUPPORT = new OptionBuilder<>("storage-legacy-session-support", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_ADMIN_USER_STORAGE = new OptionBuilder<>("storage-admin-user-storage", String.class)
.category(OptionCategory.STORAGE)
.hidden()
.buildTime(true)
.build();
public static final Option<String> STORAGE_HOTROD_HOST = new OptionBuilder<>("storage-hotrod-host", String.class)
.category(OptionCategory.STORAGE)
.description("Sets the host of the Infinispan server.")
.build();
public static final Option<Integer> STORAGE_HOTROD_PORT = new OptionBuilder<>("storage-hotrod-port", Integer.class)
.category(OptionCategory.STORAGE)
.description("Sets the port of the Infinispan server.")
.build();
public static final Option<String> STORAGE_HOTROD_USERNAME = new OptionBuilder<>("storage-hotrod-username", String.class)
.category(OptionCategory.STORAGE)
.description("Sets the username of the Infinispan user.")
.build();
public static final Option<String> STORAGE_HOTROD_PASSWORD = new OptionBuilder<>("storage-hotrod-password", String.class)
.category(OptionCategory.STORAGE)
.description("Sets the password of the Infinispan user.")
.build();
public static final Option<Boolean> STORAGE_HOTROD_CACHE_CONFIGURE = new OptionBuilder<>("storage-hotrod-cache-configure", Boolean.class)
.category(OptionCategory.STORAGE)
.defaultValue(true)
.description("When set to true, Keycloak will create and configure Infinispan caches on startup.")
.hidden()
.build();
public static final Option<String> STORAGE_HOTROD_CACHE_REINDEX = new OptionBuilder<>("storage-hotrod-cache-reindex", String.class)
.category(OptionCategory.STORAGE)
.defaultValue(Optional.empty())
.expectedValues(StorageOptions::getExpectedCacheNames)
.description("List of cache names that should be indexed on Keycloak startup. When set to `all`, all caches are reindexed. By default no caches are reindexed.")
.hidden()
.build();
public static final Option<String> STORAGE_FILE_DIR= new OptionBuilder<>("storage-file-dir", String.class)
.category(OptionCategory.STORAGE)
.description("Root directory for file map store.")
.build();
public static final Option<String> STORAGE_JPA_DB = new OptionBuilder<>("storage-jpa-db", String.class)
.category(OptionCategory.STORAGE)
.defaultValue(Database.Vendor.POSTGRES.name().toLowerCase())
.expectedValues(Database::getAvailableMapStoreAliases)
.description("The database vendor for jpa map storage.")
.buildTime(true)
.build();
private static String descriptionForStorageAreas(String areaAsText) {
return "Sets a storage mechanism for " + areaAsText + ".";
}
private static String storageAreas() {
return String.join(",", Arrays.stream(StorageType.values()).map(StorageType::name).collect(Collectors.joining(", ")));
}
private static List<String> getExpectedCacheNames() {
return Collections.emptyList();
}
public static Optional<Database.Vendor> getDatabaseVendor(String databaseKind) {
return Stream.of(Database.Vendor.values())
.filter(Database.Vendor::isEnabledOnNewStore)
.filter(v -> v.isOfKind(databaseKind))
.findFirst();
}
}

View file

@ -26,7 +26,6 @@ import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
@ -97,30 +96,17 @@ public final class Database {
}
/**
* @return List of aliases of databases enabled on legacy store.
* @return List of aliases of databases
*/
public static List<String> getLegacyStoreAliases() {
public static List<String> getDatabaseAliases() {
return DATABASES.entrySet().stream()
.filter(e -> e.getValue().isEnabledOnLegacyStore())
.map(Entry::getKey)
.sorted()
.collect(Collectors.toList());
}
/**
* @return List of aliases of databases enabled on jpa map store.
*/
public static List<String> getAvailableMapStoreAliases() {
return Stream.of(Database.Vendor.values())
.filter(Database.Vendor::isEnabledOnNewStore)
.map(v -> v.aliases)// may be replaced by Database.Vendor::getAliases if we add the getter into Database.Vendor
.flatMap(Stream::of)
.collect(Collectors.toList());
}
public enum Vendor {
H2("h2",
Enabled.LEGACY_ONLY,
"org.h2.jdbcx.JdbcDataSource",
"org.h2.Driver",
"org.hibernate.dialect.H2Dialect",
@ -167,7 +153,6 @@ public final class Database {
"dev-mem", "dev-file"
),
MYSQL("mysql",
Enabled.LEGACY_ONLY,
"com.mysql.cj.jdbc.MysqlXADataSource",
"com.mysql.cj.jdbc.Driver",
"org.hibernate.dialect.MySQLDialect",
@ -175,7 +160,6 @@ public final class Database {
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMySqlDatabase")
),
MARIADB("mariadb",
Enabled.LEGACY_ONLY,
"org.mariadb.jdbc.MariaDbDataSource",
"org.mariadb.jdbc.Driver",
"org.hibernate.dialect.MariaDBDialect",
@ -183,7 +167,6 @@ public final class Database {
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMariaDBDatabase")
),
POSTGRES("postgresql",
Enabled.ENABLED,
"org.postgresql.xa.PGXADataSource",
"org.postgresql.Driver",
"org.hibernate.dialect.PostgreSQLDialect",
@ -191,17 +174,7 @@ public final class Database {
asList("liquibase.database.core.PostgresDatabase", "org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase"),
"postgres"
),
COCKROACH(POSTGRES.databaseKind, //needs to be aligned with https://quarkus.io/guides/datasource#default-datasource
Enabled.MAP_STORE_ONLY,
POSTGRES.xaDriver,
POSTGRES.nonXaDriver,
"org.hibernate.dialect.CockroachDialect",
"jdbc:postgresql://${kc.db-url-host:localhost}:${kc.db-url-port:26257}/${kc.db-url-database:keycloak}${kc.db-url-properties:}",
List.of("liquibase.database.core.CockroachDatabase"),
"cockroach"
),
MSSQL("mssql",
Enabled.LEGACY_ONLY,
"com.microsoft.sqlserver.jdbc.SQLServerXADataSource",
"com.microsoft.sqlserver.jdbc.SQLServerDriver",
"org.hibernate.dialect.SQLServerDialect",
@ -210,7 +183,6 @@ public final class Database {
"mssql"
),
ORACLE("oracle",
Enabled.LEGACY_ONLY,
"oracle.jdbc.xa.client.OracleXADataSource",
"oracle.jdbc.driver.OracleDriver",
"org.hibernate.dialect.OracleDialect",
@ -219,7 +191,6 @@ public final class Database {
);
final String databaseKind;
final Enabled enabled;
final String xaDriver;
final String nonXaDriver;
final Function<String, String> dialect;
@ -227,21 +198,20 @@ public final class Database {
final List<String> liquibaseTypes;
final String[] aliases;
Vendor(String databaseKind, Enabled enabled, String xaDriver, String nonXaDriver, String dialect, String defaultUrl, List<String> liquibaseTypes,
Vendor(String databaseKind, String xaDriver, String nonXaDriver, String dialect, String defaultUrl, List<String> liquibaseTypes,
String... aliases) {
this(databaseKind, enabled, xaDriver, nonXaDriver, alias -> dialect, alias -> defaultUrl, liquibaseTypes, aliases);
this(databaseKind, xaDriver, nonXaDriver, alias -> dialect, alias -> defaultUrl, liquibaseTypes, aliases);
}
Vendor(String databaseKind, Enabled enabled, String xaDriver, String nonXaDriver, String dialect, Function<String, String> defaultUrl,
Vendor(String databaseKind, String xaDriver, String nonXaDriver, String dialect, Function<String, String> defaultUrl,
List<String> liquibaseTypes, String... aliases) {
this(databaseKind, enabled, xaDriver, nonXaDriver, alias -> dialect, defaultUrl, liquibaseTypes, aliases);
this(databaseKind, xaDriver, nonXaDriver, alias -> dialect, defaultUrl, liquibaseTypes, aliases);
}
Vendor(String databaseKind, Enabled enabled, String xaDriver, String nonXaDriver, Function<String, String> dialect, Function<String, String> defaultUrl,
Vendor(String databaseKind, String xaDriver, String nonXaDriver, Function<String, String> dialect, Function<String, String> defaultUrl,
List<String> liquibaseTypes,
String... aliases) {
this.databaseKind = databaseKind;
this.enabled = enabled;
this.xaDriver = xaDriver;
this.nonXaDriver = nonXaDriver;
this.dialect = dialect;
@ -250,14 +220,6 @@ public final class Database {
this.aliases = aliases.length == 0 ? new String[] { databaseKind } : aliases;
}
public boolean isEnabledOnLegacyStore() {
return enabled.legacyStore;
}
public boolean isEnabledOnNewStore() {
return enabled.jpaMapStore;
}
public boolean isOfKind(String dbKind) {
return databaseKind.equals(dbKind);
}
@ -267,18 +229,4 @@ public final class Database {
return databaseKind.toLowerCase(Locale.ROOT);
}
}
private static class Enabled {
final static Enabled LEGACY_ONLY = new Enabled(true, false);
final static Enabled MAP_STORE_ONLY = new Enabled(false, true);
final static Enabled ENABLED = new Enabled(true, true);
final boolean legacyStore;
final boolean jpaMapStore;
private Enabled(boolean legacyStore, boolean jpaMapStore) {
this.legacyStore = legacyStore;
this.jpaMapStore = jpaMapStore;
}
}
}

View file

@ -16,7 +16,6 @@ import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.keycloak.config.StorageOptions;
import org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService;
import io.quarkus.deployment.annotations.BuildStep;
@ -30,10 +29,7 @@ import liquibase.servicelocator.LiquibaseService;
import liquibase.sqlgenerator.SqlGenerator;
import org.keycloak.quarkus.runtime.KeycloakRecorder;
import static org.keycloak.config.StorageOptions.STORAGE;
import static org.keycloak.quarkus.deployment.KeycloakProcessor.getDefaultDataSource;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
class LiquibaseProcessor {

View file

@ -4,18 +4,13 @@ import io.quarkus.datasource.common.runtime.DatabaseKind;
import io.smallrye.config.ConfigSourceInterceptorContext;
import io.smallrye.config.ConfigValue;
import org.keycloak.config.DatabaseOptions;
import org.keycloak.config.StorageOptions;
import org.keycloak.config.database.Database;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import java.util.Optional;
import static java.util.Optional.of;
import static org.keycloak.config.StorageOptions.STORAGE;
import static org.keycloak.config.StorageOptions.STORAGE_JPA_DB;
import static org.keycloak.quarkus.runtime.Messages.invalidDatabaseVendor;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getRawValue;
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import static org.keycloak.quarkus.runtime.integration.QuarkusPlatform.addInitializationException;
@ -98,9 +93,6 @@ final class DatabasePropertyMappers {
Optional<String> url = Database.getDefaultUrl(value.get());
if (url.isPresent()) {
if (isJpaStore()) {
return Database.getDefaultUrl(getJpaStoreDbVendor().name().toLowerCase());
}
return url;
}
@ -108,11 +100,6 @@ final class DatabasePropertyMappers {
}
private static Optional<String> getXaOrNonXaDriver(Optional<String> value, ConfigSourceInterceptorContext context) {
if (isJpaStore()) {
// always use XA driver with jpa map store
return Database.getDriver(getJpaStoreDbVendor().name().toLowerCase(), true);
}
ConfigValue xaEnabledConfigValue = context.proceed("kc.transaction-xa-enabled");
boolean isXaEnabled = xaEnabledConfigValue == null || Boolean.parseBoolean(xaEnabledConfigValue.getValue());
@ -126,26 +113,18 @@ final class DatabasePropertyMappers {
}
private static Optional<String> toDatabaseKind(Optional<String> db, ConfigSourceInterceptorContext context) {
if (isJpaStore()) {
return Database.getDatabaseKind(getJpaStoreDbVendor().name().toLowerCase());
}
Optional<String> databaseKind = Database.getDatabaseKind(db.get());
if (databaseKind.isPresent()) {
return databaseKind;
}
addInitializationException(invalidDatabaseVendor(db.get(), Database.getLegacyStoreAliases()));
addInitializationException(invalidDatabaseVendor(db.get(), Database.getDatabaseAliases()));
return of("h2");
}
private static Optional<String> resolveDatabaseVendor(Optional<String> db, ConfigSourceInterceptorContext context) {
if (isJpaStore()) {
return Optional.of(getJpaStoreDbVendor().name().toLowerCase());
}
if (db.isEmpty()) {
return of("dev-file");
}
@ -170,19 +149,11 @@ final class DatabasePropertyMappers {
}
private static boolean isDevModeDatabase(ConfigSourceInterceptorContext context) {
if (isJpaStore()) {
return false;
}
String db = Configuration.getConfig().getConfigValue("kc.db").getValue();
return Database.getDatabaseKind(db).get().equals(DatabaseKind.H2);
}
private static Optional<String> transformDialect(Optional<String> db, ConfigSourceInterceptorContext context) {
if (isJpaStore()) {
return Database.getDialect(getJpaStoreDbVendor().name().toLowerCase());
}
Optional<String> databaseKind = Database.getDatabaseKind(db.get());
if (databaseKind.isEmpty()) {
@ -198,13 +169,4 @@ final class DatabasePropertyMappers {
return Database.getDialect("dev-file");
}
private static boolean isJpaStore() {
String storage = getRawValue(NS_KEYCLOAK_PREFIX.concat(STORAGE.getKey()));
return storage != null && StorageOptions.StorageType.jpa.name().equals(storage);
}
private static Database.Vendor getJpaStoreDbVendor() {
String storageJpaDb = getRawValue(NS_KEYCLOAK_PREFIX.concat(STORAGE_JPA_DB.getKey()));
return StorageOptions.getDatabaseVendor(storageJpaDb).orElse(Database.Vendor.POSTGRES);
}
}

View file

@ -1,21 +1,9 @@
package org.keycloak.quarkus.runtime.configuration.mappers;
import org.keycloak.common.Profile;
import org.keycloak.config.FeatureOptions;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import static java.util.Optional.of;
import static org.keycloak.config.StorageOptions.STORAGE;
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import io.smallrye.config.ConfigSourceInterceptorContext;
final class FeaturePropertyMappers {
private FeaturePropertyMappers() {
@ -25,23 +13,10 @@ final class FeaturePropertyMappers {
return new PropertyMapper[] {
fromOption(FeatureOptions.FEATURES)
.paramLabel("feature")
.transformer(FeaturePropertyMappers::transformFeatures)
.build(),
fromOption(FeatureOptions.FEATURES_DISABLED)
.paramLabel("feature")
.build()
};
}
private static Optional<String> transformFeatures(Optional<String> features, ConfigSourceInterceptorContext context) {
if (Configuration.getOptionalValue(NS_KEYCLOAK_PREFIX.concat(STORAGE.getKey())).isEmpty()) {
return features;
}
Set<String> featureSet = new HashSet<>(List.of(features.orElse("").split(",")));
featureSet.add(Profile.Feature.MAP_STORAGE.getKey());
return of(String.join(",", featureSet));
}
}

View file

@ -36,7 +36,6 @@ public final class PropertyMappers {
MAPPERS.addAll(FeaturePropertyMappers.getMappers());
MAPPERS.addAll(LoggingPropertyMappers.getMappers());
MAPPERS.addAll(TransactionPropertyMappers.getTransactionPropertyMappers());
MAPPERS.addAll(StoragePropertyMappers.getMappers());
MAPPERS.addAll(ClassLoaderPropertyMappers.getMappers());
MAPPERS.addAll(SecurityPropertyMappers.getMappers());
MAPPERS.addAll(ExportPropertyMappers.getMappers());

View file

@ -1,423 +0,0 @@
/*
* Copyright 2022 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.quarkus.runtime.configuration.mappers;
import static java.util.Optional.of;
import static java.util.function.Predicate.not;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.Optional;
import java.util.stream.Stream;
import org.keycloak.config.StorageOptions;
import org.keycloak.config.StorageOptions.StorageType;
import io.smallrye.config.ConfigSourceInterceptorContext;
final class StoragePropertyMappers {
private StoragePropertyMappers(){}
public static PropertyMapper[] getMappers() {
return new PropertyMapper[] {
fromOption(StorageOptions.STORAGE)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_PROVIDER)
.to("kc.spi-map-storage-provider")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_EVENT_STORE_PROVIDER)
.mapFrom("storage")
.to("kc.spi-events-store-provider")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_EVENT_ADMIN_STORE)
.mapFrom("storage")
.to("kc.spi-events-store-map-storage-admin-events-provider")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_EVENT_AUTH_STORE)
.mapFrom("storage")
.to("kc.spi-events-store-map-storage-auth-events-provider")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_REALM_PROVIDER)
.to("kc.spi-realm-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_REALM_STORE)
.to("kc.spi-realm-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_CLIENT_PROVIDER)
.to("kc.spi-client-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_CLIENT_STORE)
.to("kc.spi-client-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_CLIENT_SCOPE_PROVIDER)
.to("kc.spi-client-scope-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_CLIENT_SCOPE_STORE)
.to("kc.spi-client-scope-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_GROUP_PROVIDER)
.to("kc.spi-group-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_GROUP_STORE)
.to("kc.spi-group-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_ROLE_PROVIDER)
.to("kc.spi-role-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_ROLE_STORE)
.to("kc.spi-role-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_USER_PROVIDER)
.to("kc.spi-user-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_USER_STORE)
.to("kc.spi-user-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_DEPLOYMENT_STATE_PROVIDER)
.to("kc.spi-deployment-state-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED)
.to("kc.spi-deployment-state-map-resources-version-seed")
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_AUTH_SESSION_PROVIDER)
.to("kc.spi-authentication-sessions-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getCacheStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_AUTH_SESSION_STORE)
.to("kc.spi-authentication-sessions-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_USER_SESSION_PROVIDER)
.to("kc.spi-user-sessions-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getCacheStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_USER_SESSION_STORE)
.to("kc.spi-user-sessions-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_LOGIN_FAILURE_PROVIDER)
.to("kc.spi-login-failure-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getCacheStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_LOGIN_FAILURE_STORE)
.to("kc.spi-login-failure-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_USER_SESSION_PERSISTER)
.to("kc.spi-user-session-persister-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getUserSessionPersisterStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_AUTHORIZATION_PROVIDER)
.to("kc.spi-authorization-persister-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_AUTHORIZATION_STORE)
.to("kc.spi-authorization-persister-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_GLOBAL_LOCK_PROVIDER)
.to("kc.spi-global-lock-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getGlobalLockProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_GLOBAL_LOCK_PROVIDER)
.to("kc.spi-global-lock-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProvider)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_CACHE_REALM_ENABLED)
.to("kc.spi-realm-cache-default-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isCacheAreaEnabledForStorage)
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_CACHE_AUTHORIZATION_ENABLED)
.to("kc.spi-authorization-cache-default-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isCacheAreaEnabledForStorage)
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_CACHE_USER_ENABLED)
.to("kc.spi-user-cache-default-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isCacheAreaEnabledForStorage)
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_SINGLE_USE_OBJECT_PROVIDER)
.to("kc.spi-single-use-object-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::getCacheStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_SINGLE_USE_OBJECT_STORE)
.to("kc.spi-single-use-object-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProviderSingleUseObjects)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_PUBLIC_KEY_STORAGE_STORE)
.to("kc.spi-public-key-storage-map-storage-provider")
.mapFrom("storage")
.transformer(StoragePropertyMappers::resolveMapStorageProviderPublicKeyStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_EXCEPTION_CONVERTER)
.to("kc.spi-exception-converter-jpa-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isLegacyStoreEnabled)
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_ADMIN_CACHE_CLEAR_REALM)
.to("kc.spi-admin-realm-restapi-extension-clear-realm-cache-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isLegacyStoreEnabled)
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_ADMIN_CACHE_CLEAR_USER)
.to("kc.spi-admin-realm-restapi-extension-clear-user-cache-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isLegacyStoreEnabled)
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_ADMIN_CACHE_CLEAR_KEYS)
.to("kc.spi-admin-realm-restapi-extension-clear-keys-cache-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isLegacyStoreEnabled)
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_LEGACY_SESSION_SUPPORT)
.to("kc.spi-legacy-session-support-default-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isLegacyStoreEnabled)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_ADMIN_USER_STORAGE)
.to("kc.spi-admin-realm-restapi-extension-user-storage-enabled")
.mapFrom("storage")
.transformer(StoragePropertyMappers::isLegacyStoreEnabled)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_HOTROD_HOST)
.to("kc.spi-connections-hot-rod-default-host")
.paramLabel("host")
.build(),
fromOption(StorageOptions.STORAGE_HOTROD_PORT)
.to("kc.spi-connections-hot-rod-default-port")
.paramLabel("port")
.build(),
fromOption(StorageOptions.STORAGE_HOTROD_USERNAME)
.to("kc.spi-connections-hot-rod-default-username")
.paramLabel("username")
.build(),
fromOption(StorageOptions.STORAGE_HOTROD_PASSWORD)
.to("kc.spi-connections-hot-rod-default-password")
.paramLabel("password")
.build(),
fromOption(StorageOptions.STORAGE_HOTROD_CACHE_CONFIGURE)
.to("kc.spi-connections-hot-rod-default-configure-remote-caches")
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build(),
fromOption(StorageOptions.STORAGE_HOTROD_CACHE_REINDEX)
.to("kc.spi-connections-hot-rod-default-reindex-caches")
.paramLabel("[cache1,cache2,...]|all")
.build(),
fromOption(StorageOptions.STORAGE_FILE_DIR)
.to("kc.spi-map-storage-file-dir")
.mapFrom("storage")
.paramLabel("dir")
.build(),
fromOption(StorageOptions.STORAGE_JPA_DB)
.to("kc.spi-map-storage-jpa-db")
.mapFrom("storage")
.paramLabel("type")
.build()
};
}
private static Optional<String> getAreaStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
if (storage.isEmpty()) {
return of("jpa");
}
if (Stream.of(StorageType.values()).map(Enum::name).anyMatch(storage.get()::equals)) {
return of("map");
}
return storage;
}
private static Optional<String> getCacheStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
if (storage.isEmpty()) {
return of("infinispan");
}
if (Stream.of(StorageType.values()).map(Enum::name).anyMatch(storage.get()::equals)) {
return of("map");
}
return storage;
}
private static Optional<String> getGlobalLockProvider(Optional<String> storage, ConfigSourceInterceptorContext context) {
try {
if (storage.isPresent()) {
StorageType storageType = StorageType.valueOf(storage.get());
switch (storageType) {
case hotrod:
return Optional.of(storageType.getProvider());
case jpa:
return Optional.of("map");
default:
return Optional.of("none");
}
}
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Invalid storage provider: " + storage.orElse(null), iae);
}
return of("dblock");
}
private static Optional<String> getUserSessionPersisterStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
return of(storage.isEmpty() ? "jpa" : "disabled");
}
private static Optional<String> isLegacyStoreEnabled(Optional<String> value, ConfigSourceInterceptorContext context) {
if (value.isEmpty()) {
return of(Boolean.TRUE.toString());
}
return of(Boolean.FALSE.toString());
}
private static Optional<String> resolveMapStorageProvider(Optional<String> value, ConfigSourceInterceptorContext context) {
try {
if (value.isPresent()) {
return of(value.map(StorageType::valueOf).map(StorageType::getProvider)
.orElse(StorageType.chm.getProvider()));
}
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Invalid storage provider: " + value.orElse(null), iae);
}
return value;
}
private static Optional<String> resolveMapStorageProviderSingleUseObjects(Optional<String> value, ConfigSourceInterceptorContext context) {
try {
if (value.isPresent()) {
return of(value.map(StorageType::valueOf)
.filter(not(StorageType.file::equals))
.map(StorageType::getProvider)
.orElse(StorageType.chm.getProvider()));
}
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Invalid storage provider: " + value.orElse(null), iae);
}
return value;
}
private static Optional<String> resolveMapStorageProviderPublicKeyStorage(Optional<String> value, ConfigSourceInterceptorContext context) {
try {
if (value.isPresent()) {
// there is only one public key storage provider available
return of(StorageType.chm.getProvider());
}
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Invalid storage provider: " + value.orElse(null), iae);
}
return value;
}
private static Optional<String> isCacheAreaEnabledForStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
return of(storage.isEmpty() ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
}
}

View file

@ -1,15 +1,10 @@
package org.keycloak.quarkus.runtime.configuration.mappers;
import io.smallrye.config.ConfigSourceInterceptorContext;
import io.smallrye.config.ConfigValue;
import org.keycloak.config.StorageOptions;
import org.keycloak.config.TransactionOptions;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import static java.util.Optional.of;
import static org.keycloak.config.StorageOptions.STORAGE;
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.Optional;
@ -31,11 +26,6 @@ public class TransactionPropertyMappers {
private static Optional<String> getQuarkusTransactionsValue(Optional<String> txValue, ConfigSourceInterceptorContext context) {
boolean isXaEnabled = Boolean.parseBoolean(txValue.get());
ConfigValue storage = context.proceed(NS_KEYCLOAK_PREFIX.concat(STORAGE.getKey()));
if (storage != null && StorageOptions.StorageType.jpa.name().equals(storage.getValue())) {
isXaEnabled = true;
}
if (isXaEnabled) {
return of("xa");

View file

@ -41,7 +41,7 @@ public class BuildAndStartDistTest {
void testBuildAndStart(KeycloakDistribution dist) {
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
// start using based on the build options set via CLI
CLIResult cliResult = rawDist.run("build", "--http-relative-path=/auth");
CLIResult cliResult = rawDist.run("build");
cliResult.assertBuild();
cliResult = rawDist.run("start", "--http-enabled=true", "--hostname-strict=false", OPTIMIZED_BUILD_OPTION_LONG);
cliResult.assertNoBuild();

View file

@ -92,7 +92,6 @@ public class HelpCommandDistTest {
void testStartOptimizedHelpAll(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertHelp(cliResult);
cliResult.assertNoMessage("--storage ");
}
@Test
@ -114,7 +113,6 @@ public class HelpCommandDistTest {
void testStartHelpAll(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertHelp(cliResult);
cliResult.assertMessage("--storage");
}
@Test

View file

@ -13,69 +13,6 @@ Options:
--optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command.
Storage (Experimental):
--storage <type> Experimental: Sets the default storage mechanism for all areas. Possible
values are: jpa, chm, hotrod, file.
--storage-area-auth-session <type>
Experimental: Sets a storage mechanism for authentication sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-area-authorization <type>
Experimental: Sets a storage mechanism for authorizations. Possible values
are: jpa, chm, hotrod, file.
--storage-area-client <type>
Experimental: Sets a storage mechanism for clients. Possible values are: jpa,
chm, hotrod, file.
--storage-area-client-scope <type>
Experimental: Sets a storage mechanism for client scopes. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-admin <type>
Experimental: Sets a storage mechanism for admin events. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-auth <type>
Experimental: Sets a storage mechanism for authentication and authorization
events. Possible values are: jpa, chm, hotrod, file.
--storage-area-group <type>
Experimental: Sets a storage mechanism for groups. Possible values are: jpa,
chm, hotrod, file.
--storage-area-login-failure <type>
Experimental: Sets a storage mechanism for login failures. Possible values
are: jpa, chm, hotrod, file.
--storage-area-realm <type>
Experimental: Sets a storage mechanism for realms. Possible values are: jpa,
chm, hotrod, file.
--storage-area-role <type>
Experimental: Sets a storage mechanism for roles. Possible values are: jpa,
chm, hotrod, file.
--storage-area-single-use-object <type>
Experimental: Sets a storage mechanism for single use objects. Possible values
are: jpa, chm, hotrod.
--storage-area-user <type>
Experimental: Sets a storage mechanism for users. Possible values are: jpa,
chm, hotrod, file.
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
--storage-jpa-db <type>
Experimental: The database vendor for jpa map storage. Possible values are:
postgres, cockroach. Default: postgres.
Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,

View file

@ -13,69 +13,6 @@ Options:
--optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command.
Storage (Experimental):
--storage <type> Experimental: Sets the default storage mechanism for all areas. Possible
values are: jpa, chm, hotrod, file.
--storage-area-auth-session <type>
Experimental: Sets a storage mechanism for authentication sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-area-authorization <type>
Experimental: Sets a storage mechanism for authorizations. Possible values
are: jpa, chm, hotrod, file.
--storage-area-client <type>
Experimental: Sets a storage mechanism for clients. Possible values are: jpa,
chm, hotrod, file.
--storage-area-client-scope <type>
Experimental: Sets a storage mechanism for client scopes. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-admin <type>
Experimental: Sets a storage mechanism for admin events. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-auth <type>
Experimental: Sets a storage mechanism for authentication and authorization
events. Possible values are: jpa, chm, hotrod, file.
--storage-area-group <type>
Experimental: Sets a storage mechanism for groups. Possible values are: jpa,
chm, hotrod, file.
--storage-area-login-failure <type>
Experimental: Sets a storage mechanism for login failures. Possible values
are: jpa, chm, hotrod, file.
--storage-area-realm <type>
Experimental: Sets a storage mechanism for realms. Possible values are: jpa,
chm, hotrod, file.
--storage-area-role <type>
Experimental: Sets a storage mechanism for roles. Possible values are: jpa,
chm, hotrod, file.
--storage-area-single-use-object <type>
Experimental: Sets a storage mechanism for single use objects. Possible values
are: jpa, chm, hotrod.
--storage-area-user <type>
Experimental: Sets a storage mechanism for users. Possible values are: jpa,
chm, hotrod, file.
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
--storage-jpa-db <type>
Experimental: The database vendor for jpa map storage. Possible values are:
postgres, cockroach. Default: postgres.
Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,

View file

@ -29,69 +29,6 @@ Cache:
This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google.
Storage (Experimental):
--storage <type> Experimental: Sets the default storage mechanism for all areas. Possible
values are: jpa, chm, hotrod, file.
--storage-area-auth-session <type>
Experimental: Sets a storage mechanism for authentication sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-area-authorization <type>
Experimental: Sets a storage mechanism for authorizations. Possible values
are: jpa, chm, hotrod, file.
--storage-area-client <type>
Experimental: Sets a storage mechanism for clients. Possible values are: jpa,
chm, hotrod, file.
--storage-area-client-scope <type>
Experimental: Sets a storage mechanism for client scopes. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-admin <type>
Experimental: Sets a storage mechanism for admin events. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-auth <type>
Experimental: Sets a storage mechanism for authentication and authorization
events. Possible values are: jpa, chm, hotrod, file.
--storage-area-group <type>
Experimental: Sets a storage mechanism for groups. Possible values are: jpa,
chm, hotrod, file.
--storage-area-login-failure <type>
Experimental: Sets a storage mechanism for login failures. Possible values
are: jpa, chm, hotrod, file.
--storage-area-realm <type>
Experimental: Sets a storage mechanism for realms. Possible values are: jpa,
chm, hotrod, file.
--storage-area-role <type>
Experimental: Sets a storage mechanism for roles. Possible values are: jpa,
chm, hotrod, file.
--storage-area-single-use-object <type>
Experimental: Sets a storage mechanism for single use objects. Possible values
are: jpa, chm, hotrod.
--storage-area-user <type>
Experimental: Sets a storage mechanism for users. Possible values are: jpa,
chm, hotrod, file.
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
--storage-jpa-db <type>
Experimental: The database vendor for jpa map storage. Possible values are:
postgres, cockroach. Default: postgres.
Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,

View file

@ -29,69 +29,6 @@ Cache:
This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google.
Storage (Experimental):
--storage <type> Experimental: Sets the default storage mechanism for all areas. Possible
values are: jpa, chm, hotrod, file.
--storage-area-auth-session <type>
Experimental: Sets a storage mechanism for authentication sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-area-authorization <type>
Experimental: Sets a storage mechanism for authorizations. Possible values
are: jpa, chm, hotrod, file.
--storage-area-client <type>
Experimental: Sets a storage mechanism for clients. Possible values are: jpa,
chm, hotrod, file.
--storage-area-client-scope <type>
Experimental: Sets a storage mechanism for client scopes. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-admin <type>
Experimental: Sets a storage mechanism for admin events. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-auth <type>
Experimental: Sets a storage mechanism for authentication and authorization
events. Possible values are: jpa, chm, hotrod, file.
--storage-area-group <type>
Experimental: Sets a storage mechanism for groups. Possible values are: jpa,
chm, hotrod, file.
--storage-area-login-failure <type>
Experimental: Sets a storage mechanism for login failures. Possible values
are: jpa, chm, hotrod, file.
--storage-area-realm <type>
Experimental: Sets a storage mechanism for realms. Possible values are: jpa,
chm, hotrod, file.
--storage-area-role <type>
Experimental: Sets a storage mechanism for roles. Possible values are: jpa,
chm, hotrod, file.
--storage-area-single-use-object <type>
Experimental: Sets a storage mechanism for single use objects. Possible values
are: jpa, chm, hotrod.
--storage-area-user <type>
Experimental: Sets a storage mechanism for users. Possible values are: jpa,
chm, hotrod, file.
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
--storage-jpa-db <type>
Experimental: The database vendor for jpa map storage. Possible values are:
postgres, cockroach. Default: postgres.
Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,

View file

@ -30,69 +30,6 @@ Cache:
This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google.
Storage (Experimental):
--storage <type> Experimental: Sets the default storage mechanism for all areas. Possible
values are: jpa, chm, hotrod, file.
--storage-area-auth-session <type>
Experimental: Sets a storage mechanism for authentication sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-area-authorization <type>
Experimental: Sets a storage mechanism for authorizations. Possible values
are: jpa, chm, hotrod, file.
--storage-area-client <type>
Experimental: Sets a storage mechanism for clients. Possible values are: jpa,
chm, hotrod, file.
--storage-area-client-scope <type>
Experimental: Sets a storage mechanism for client scopes. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-admin <type>
Experimental: Sets a storage mechanism for admin events. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-auth <type>
Experimental: Sets a storage mechanism for authentication and authorization
events. Possible values are: jpa, chm, hotrod, file.
--storage-area-group <type>
Experimental: Sets a storage mechanism for groups. Possible values are: jpa,
chm, hotrod, file.
--storage-area-login-failure <type>
Experimental: Sets a storage mechanism for login failures. Possible values
are: jpa, chm, hotrod, file.
--storage-area-realm <type>
Experimental: Sets a storage mechanism for realms. Possible values are: jpa,
chm, hotrod, file.
--storage-area-role <type>
Experimental: Sets a storage mechanism for roles. Possible values are: jpa,
chm, hotrod, file.
--storage-area-single-use-object <type>
Experimental: Sets a storage mechanism for single use objects. Possible values
are: jpa, chm, hotrod.
--storage-area-user <type>
Experimental: Sets a storage mechanism for users. Possible values are: jpa,
chm, hotrod, file.
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
--storage-jpa-db <type>
Experimental: The database vendor for jpa map storage. Possible values are:
postgres, cockroach. Default: postgres.
Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,

View file

@ -30,69 +30,6 @@ Cache:
This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google.
Storage (Experimental):
--storage <type> Experimental: Sets the default storage mechanism for all areas. Possible
values are: jpa, chm, hotrod, file.
--storage-area-auth-session <type>
Experimental: Sets a storage mechanism for authentication sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-area-authorization <type>
Experimental: Sets a storage mechanism for authorizations. Possible values
are: jpa, chm, hotrod, file.
--storage-area-client <type>
Experimental: Sets a storage mechanism for clients. Possible values are: jpa,
chm, hotrod, file.
--storage-area-client-scope <type>
Experimental: Sets a storage mechanism for client scopes. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-admin <type>
Experimental: Sets a storage mechanism for admin events. Possible values are:
jpa, chm, hotrod, file.
--storage-area-event-auth <type>
Experimental: Sets a storage mechanism for authentication and authorization
events. Possible values are: jpa, chm, hotrod, file.
--storage-area-group <type>
Experimental: Sets a storage mechanism for groups. Possible values are: jpa,
chm, hotrod, file.
--storage-area-login-failure <type>
Experimental: Sets a storage mechanism for login failures. Possible values
are: jpa, chm, hotrod, file.
--storage-area-realm <type>
Experimental: Sets a storage mechanism for realms. Possible values are: jpa,
chm, hotrod, file.
--storage-area-role <type>
Experimental: Sets a storage mechanism for roles. Possible values are: jpa,
chm, hotrod, file.
--storage-area-single-use-object <type>
Experimental: Sets a storage mechanism for single use objects. Possible values
are: jpa, chm, hotrod.
--storage-area-user <type>
Experimental: Sets a storage mechanism for users. Possible values are: jpa,
chm, hotrod, file.
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod, file.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
--storage-jpa-db <type>
Experimental: The database vendor for jpa map storage. Possible values are:
postgres, cockroach. Default: postgres.
Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,

View file

@ -15,25 +15,6 @@ Options:
--optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command.
Storage (Experimental):
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
Database:
--db-driver <driver> The fully qualified class name of the JDBC driver. If not set, a default

View file

@ -15,25 +15,6 @@ Options:
--optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command.
Storage (Experimental):
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-file-dir <dir>
Experimental: Root directory for file map store.
--storage-hotrod-host <host>
Experimental: Sets the host of the Infinispan server.
--storage-hotrod-password <password>
Experimental: Sets the password of the Infinispan user.
--storage-hotrod-port <port>
Experimental: Sets the port of the Infinispan server.
--storage-hotrod-username <username>
Experimental: Sets the username of the Infinispan user.
Database:
--db-password <password>

View file

@ -33,7 +33,6 @@ import org.keycloak.config.HttpOptions;
import org.keycloak.config.LoggingOptions;
import org.keycloak.config.Option;
import org.keycloak.config.SecurityOptions;
import org.keycloak.config.StorageOptions;
import org.keycloak.platform.Platform;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.cli.Picocli;
@ -118,10 +117,6 @@ public class Keycloak {
addOptionIfNotSet(args, HttpOptions.HTTP_PORT);
addOptionIfNotSet(args, HttpOptions.HTTPS_PORT);
if (getOptionValue(args, DatabaseOptions.DB) == null) {
addOptionIfNotSet(args, StorageOptions.STORAGE, StorageOptions.StorageType.chm);
}
boolean isFipsEnabled = ofNullable(getOptionValue(args, SecurityOptions.FIPS_MODE)).orElse(FipsMode.DISABLED).isFipsEnabled();
if (isFipsEnabled) {

View file

@ -52,11 +52,7 @@ public class TimeOffsetTest extends AbstractAdminTest {
setTimeOffset(5);
// legacy store requires manual trigger of expired events removal
String eventStoreProvider = testingClient.server().fetch(session -> Config.getProvider(EventStoreSpi.NAME), String.class);
if (eventStoreProvider.equals(JpaEventStoreProviderFactory.ID)) {
testingClient.testing().clearExpiredEvents();
}
testingClient.server().run(session -> {
EventStoreProvider provider = session.getProvider(EventStoreProvider.class);