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 `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. 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) .category(OptionCategory.DATABASE)
.description("The database vendor.") .description("The database vendor.")
.defaultValue("dev-file") .defaultValue("dev-file")
.expectedValues(Database::getLegacyStoreAliases) .expectedValues(Database::getDatabaseAliases)
.buildTime(true) .buildTime(true)
.build(); .build();

View file

@ -3,7 +3,6 @@ package org.keycloak.config;
public enum OptionCategory { public enum OptionCategory {
// ordered by name asc // ordered by name asc
CACHE("Cache", 10, ConfigSupportLevel.SUPPORTED), CACHE("Cache", 10, ConfigSupportLevel.SUPPORTED),
STORAGE("Storage", 15, ConfigSupportLevel.EXPERIMENTAL),
DATABASE("Database", 20, ConfigSupportLevel.SUPPORTED), DATABASE("Database", 20, ConfigSupportLevel.SUPPORTED),
TRANSACTION("Transaction",30, ConfigSupportLevel.SUPPORTED), TRANSACTION("Transaction",30, ConfigSupportLevel.SUPPORTED),
FEATURE("Feature", 40, 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.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Arrays.asList; 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() return DATABASES.entrySet().stream()
.filter(e -> e.getValue().isEnabledOnLegacyStore())
.map(Entry::getKey) .map(Entry::getKey)
.sorted() .sorted()
.collect(Collectors.toList()); .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 { public enum Vendor {
H2("h2", H2("h2",
Enabled.LEGACY_ONLY,
"org.h2.jdbcx.JdbcDataSource", "org.h2.jdbcx.JdbcDataSource",
"org.h2.Driver", "org.h2.Driver",
"org.hibernate.dialect.H2Dialect", "org.hibernate.dialect.H2Dialect",
@ -167,7 +153,6 @@ public final class Database {
"dev-mem", "dev-file" "dev-mem", "dev-file"
), ),
MYSQL("mysql", MYSQL("mysql",
Enabled.LEGACY_ONLY,
"com.mysql.cj.jdbc.MysqlXADataSource", "com.mysql.cj.jdbc.MysqlXADataSource",
"com.mysql.cj.jdbc.Driver", "com.mysql.cj.jdbc.Driver",
"org.hibernate.dialect.MySQLDialect", "org.hibernate.dialect.MySQLDialect",
@ -175,7 +160,6 @@ public final class Database {
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMySqlDatabase") asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMySqlDatabase")
), ),
MARIADB("mariadb", MARIADB("mariadb",
Enabled.LEGACY_ONLY,
"org.mariadb.jdbc.MariaDbDataSource", "org.mariadb.jdbc.MariaDbDataSource",
"org.mariadb.jdbc.Driver", "org.mariadb.jdbc.Driver",
"org.hibernate.dialect.MariaDBDialect", "org.hibernate.dialect.MariaDBDialect",
@ -183,7 +167,6 @@ public final class Database {
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMariaDBDatabase") asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMariaDBDatabase")
), ),
POSTGRES("postgresql", POSTGRES("postgresql",
Enabled.ENABLED,
"org.postgresql.xa.PGXADataSource", "org.postgresql.xa.PGXADataSource",
"org.postgresql.Driver", "org.postgresql.Driver",
"org.hibernate.dialect.PostgreSQLDialect", "org.hibernate.dialect.PostgreSQLDialect",
@ -191,17 +174,7 @@ public final class Database {
asList("liquibase.database.core.PostgresDatabase", "org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase"), asList("liquibase.database.core.PostgresDatabase", "org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase"),
"postgres" "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", MSSQL("mssql",
Enabled.LEGACY_ONLY,
"com.microsoft.sqlserver.jdbc.SQLServerXADataSource", "com.microsoft.sqlserver.jdbc.SQLServerXADataSource",
"com.microsoft.sqlserver.jdbc.SQLServerDriver", "com.microsoft.sqlserver.jdbc.SQLServerDriver",
"org.hibernate.dialect.SQLServerDialect", "org.hibernate.dialect.SQLServerDialect",
@ -210,7 +183,6 @@ public final class Database {
"mssql" "mssql"
), ),
ORACLE("oracle", ORACLE("oracle",
Enabled.LEGACY_ONLY,
"oracle.jdbc.xa.client.OracleXADataSource", "oracle.jdbc.xa.client.OracleXADataSource",
"oracle.jdbc.driver.OracleDriver", "oracle.jdbc.driver.OracleDriver",
"org.hibernate.dialect.OracleDialect", "org.hibernate.dialect.OracleDialect",
@ -219,7 +191,6 @@ public final class Database {
); );
final String databaseKind; final String databaseKind;
final Enabled enabled;
final String xaDriver; final String xaDriver;
final String nonXaDriver; final String nonXaDriver;
final Function<String, String> dialect; final Function<String, String> dialect;
@ -227,21 +198,20 @@ public final class Database {
final List<String> liquibaseTypes; final List<String> liquibaseTypes;
final String[] aliases; 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) { 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) { 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, List<String> liquibaseTypes,
String... aliases) { String... aliases) {
this.databaseKind = databaseKind; this.databaseKind = databaseKind;
this.enabled = enabled;
this.xaDriver = xaDriver; this.xaDriver = xaDriver;
this.nonXaDriver = nonXaDriver; this.nonXaDriver = nonXaDriver;
this.dialect = dialect; this.dialect = dialect;
@ -250,14 +220,6 @@ public final class Database {
this.aliases = aliases.length == 0 ? new String[] { databaseKind } : aliases; 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) { public boolean isOfKind(String dbKind) {
return databaseKind.equals(dbKind); return databaseKind.equals(dbKind);
} }
@ -267,18 +229,4 @@ public final class Database {
return databaseKind.toLowerCase(Locale.ROOT); 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.ClassInfo;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView; import org.jboss.jandex.IndexView;
import org.keycloak.config.StorageOptions;
import org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService; import org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService;
import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.BuildStep;
@ -30,10 +29,7 @@ import liquibase.servicelocator.LiquibaseService;
import liquibase.sqlgenerator.SqlGenerator; import liquibase.sqlgenerator.SqlGenerator;
import org.keycloak.quarkus.runtime.KeycloakRecorder; 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.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 { class LiquibaseProcessor {

View file

@ -4,18 +4,13 @@ import io.quarkus.datasource.common.runtime.DatabaseKind;
import io.smallrye.config.ConfigSourceInterceptorContext; import io.smallrye.config.ConfigSourceInterceptorContext;
import io.smallrye.config.ConfigValue; import io.smallrye.config.ConfigValue;
import org.keycloak.config.DatabaseOptions; import org.keycloak.config.DatabaseOptions;
import org.keycloak.config.StorageOptions;
import org.keycloak.config.database.Database; import org.keycloak.config.database.Database;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import java.util.Optional; import java.util.Optional;
import static java.util.Optional.of; 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.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.configuration.mappers.PropertyMapper.fromOption;
import static org.keycloak.quarkus.runtime.integration.QuarkusPlatform.addInitializationException; import static org.keycloak.quarkus.runtime.integration.QuarkusPlatform.addInitializationException;
@ -98,9 +93,6 @@ final class DatabasePropertyMappers {
Optional<String> url = Database.getDefaultUrl(value.get()); Optional<String> url = Database.getDefaultUrl(value.get());
if (url.isPresent()) { if (url.isPresent()) {
if (isJpaStore()) {
return Database.getDefaultUrl(getJpaStoreDbVendor().name().toLowerCase());
}
return url; return url;
} }
@ -108,11 +100,6 @@ final class DatabasePropertyMappers {
} }
private static Optional<String> getXaOrNonXaDriver(Optional<String> value, ConfigSourceInterceptorContext context) { 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"); ConfigValue xaEnabledConfigValue = context.proceed("kc.transaction-xa-enabled");
boolean isXaEnabled = xaEnabledConfigValue == null || Boolean.parseBoolean(xaEnabledConfigValue.getValue()); 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) { 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()); Optional<String> databaseKind = Database.getDatabaseKind(db.get());
if (databaseKind.isPresent()) { if (databaseKind.isPresent()) {
return databaseKind; return databaseKind;
} }
addInitializationException(invalidDatabaseVendor(db.get(), Database.getLegacyStoreAliases())); addInitializationException(invalidDatabaseVendor(db.get(), Database.getDatabaseAliases()));
return of("h2"); return of("h2");
} }
private static Optional<String> resolveDatabaseVendor(Optional<String> db, ConfigSourceInterceptorContext context) { private static Optional<String> resolveDatabaseVendor(Optional<String> db, ConfigSourceInterceptorContext context) {
if (isJpaStore()) {
return Optional.of(getJpaStoreDbVendor().name().toLowerCase());
}
if (db.isEmpty()) { if (db.isEmpty()) {
return of("dev-file"); return of("dev-file");
} }
@ -170,19 +149,11 @@ final class DatabasePropertyMappers {
} }
private static boolean isDevModeDatabase(ConfigSourceInterceptorContext context) { private static boolean isDevModeDatabase(ConfigSourceInterceptorContext context) {
if (isJpaStore()) {
return false;
}
String db = Configuration.getConfig().getConfigValue("kc.db").getValue(); String db = Configuration.getConfig().getConfigValue("kc.db").getValue();
return Database.getDatabaseKind(db).get().equals(DatabaseKind.H2); return Database.getDatabaseKind(db).get().equals(DatabaseKind.H2);
} }
private static Optional<String> transformDialect(Optional<String> db, ConfigSourceInterceptorContext context) { 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()); Optional<String> databaseKind = Database.getDatabaseKind(db.get());
if (databaseKind.isEmpty()) { if (databaseKind.isEmpty()) {
@ -198,13 +169,4 @@ final class DatabasePropertyMappers {
return Database.getDialect("dev-file"); 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; package org.keycloak.quarkus.runtime.configuration.mappers;
import org.keycloak.common.Profile;
import org.keycloak.config.FeatureOptions; 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 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 { final class FeaturePropertyMappers {
private FeaturePropertyMappers() { private FeaturePropertyMappers() {
@ -25,23 +13,10 @@ final class FeaturePropertyMappers {
return new PropertyMapper[] { return new PropertyMapper[] {
fromOption(FeatureOptions.FEATURES) fromOption(FeatureOptions.FEATURES)
.paramLabel("feature") .paramLabel("feature")
.transformer(FeaturePropertyMappers::transformFeatures)
.build(), .build(),
fromOption(FeatureOptions.FEATURES_DISABLED) fromOption(FeatureOptions.FEATURES_DISABLED)
.paramLabel("feature") .paramLabel("feature")
.build() .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(FeaturePropertyMappers.getMappers());
MAPPERS.addAll(LoggingPropertyMappers.getMappers()); MAPPERS.addAll(LoggingPropertyMappers.getMappers());
MAPPERS.addAll(TransactionPropertyMappers.getTransactionPropertyMappers()); MAPPERS.addAll(TransactionPropertyMappers.getTransactionPropertyMappers());
MAPPERS.addAll(StoragePropertyMappers.getMappers());
MAPPERS.addAll(ClassLoaderPropertyMappers.getMappers()); MAPPERS.addAll(ClassLoaderPropertyMappers.getMappers());
MAPPERS.addAll(SecurityPropertyMappers.getMappers()); MAPPERS.addAll(SecurityPropertyMappers.getMappers());
MAPPERS.addAll(ExportPropertyMappers.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; package org.keycloak.quarkus.runtime.configuration.mappers;
import io.smallrye.config.ConfigSourceInterceptorContext; import io.smallrye.config.ConfigSourceInterceptorContext;
import io.smallrye.config.ConfigValue;
import org.keycloak.config.StorageOptions;
import org.keycloak.config.TransactionOptions; import org.keycloak.config.TransactionOptions;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import static java.util.Optional.of; 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 static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.Optional; import java.util.Optional;
@ -31,11 +26,6 @@ public class TransactionPropertyMappers {
private static Optional<String> getQuarkusTransactionsValue(Optional<String> txValue, ConfigSourceInterceptorContext context) { private static Optional<String> getQuarkusTransactionsValue(Optional<String> txValue, ConfigSourceInterceptorContext context) {
boolean isXaEnabled = Boolean.parseBoolean(txValue.get()); 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) { if (isXaEnabled) {
return of("xa"); return of("xa");

View file

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

View file

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

View file

@ -13,69 +13,6 @@ Options:
--optimized Use this option to achieve an optimal startup time if you have previously --optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command. 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: Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, --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 --optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command. 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: Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, --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. This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google. 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: Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, --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. This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google. 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: Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, --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. This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google. 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: Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, --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. This option only takes effect if 'cache' is set to 'ispn'. Default: udp.
Possible values are: tcp, udp, kubernetes, ec2, azure, google. 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: Database:
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql, --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 --optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command. 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: Database:
--db-driver <driver> The fully qualified class name of the JDBC driver. If not set, a default --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 --optimized Use this option to achieve an optimal startup time if you have previously
built a server image using the 'build' command. 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: Database:
--db-password <password> --db-password <password>

View file

@ -33,7 +33,6 @@ import org.keycloak.config.HttpOptions;
import org.keycloak.config.LoggingOptions; import org.keycloak.config.LoggingOptions;
import org.keycloak.config.Option; import org.keycloak.config.Option;
import org.keycloak.config.SecurityOptions; import org.keycloak.config.SecurityOptions;
import org.keycloak.config.StorageOptions;
import org.keycloak.platform.Platform; import org.keycloak.platform.Platform;
import org.keycloak.quarkus.runtime.Environment; import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.cli.Picocli; import org.keycloak.quarkus.runtime.cli.Picocli;
@ -118,10 +117,6 @@ public class Keycloak {
addOptionIfNotSet(args, HttpOptions.HTTP_PORT); addOptionIfNotSet(args, HttpOptions.HTTP_PORT);
addOptionIfNotSet(args, HttpOptions.HTTPS_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(); boolean isFipsEnabled = ofNullable(getOptionValue(args, SecurityOptions.FIPS_MODE)).orElse(FipsMode.DISABLED).isFipsEnabled();
if (isFipsEnabled) { if (isFipsEnabled) {

View file

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