Remove quarkus options related to map store
Signed-off-by: vramik <vramik@redhat.com> Closes #24098
This commit is contained in:
parent
6d7a99dc6f
commit
71b6757c2f
23 changed files with 14 additions and 1353 deletions
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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");
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue