mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Require setting DB kind for additional datasources (#41087)
* Require setting DB kind for additional datasources Closes #41161 Signed-off-by: Martin Bartoš <mabartos@redhat.com> * refining build time check for db kind to be tolerant of existing usage Signed-off-by: Steve Hawkins <shawkins@redhat.com> --------- Signed-off-by: Martin Bartoš <mabartos@redhat.com> Signed-off-by: Steve Hawkins <shawkins@redhat.com> Co-authored-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
parent
71f510d115
commit
75ade9acef
@ -6,6 +6,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class DatabaseOptions {
|
public class DatabaseOptions {
|
||||||
|
|
||||||
@ -143,6 +144,13 @@ public class DatabaseOptions {
|
|||||||
DatabaseOptions.DB_URL.getKey(), "-full" // db-url-full
|
DatabaseOptions.DB_URL.getKey(), "-full" // db-url-full
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You can override some {@link OptionBuilder} methods for additional datasources in this map
|
||||||
|
*/
|
||||||
|
private static final Map<Option<?>, Consumer<OptionBuilder<?>>> DATASOURCES_OVERRIDES_OPTIONS = Map.of(
|
||||||
|
DatabaseOptions.DB, builder -> builder.defaultValue(Optional.empty()) // no default value for DB kind for datasources
|
||||||
|
);
|
||||||
|
|
||||||
private static final Map<String, Option<?>> cachedDatasourceOptions = new HashMap<>();
|
private static final Map<String, Option<?>> cachedDatasourceOptions = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
@ -179,6 +187,12 @@ public class DatabaseOptions {
|
|||||||
builder.description("Used for named <datasource>. " + parentOption.getDescription());
|
builder.description("Used for named <datasource>. " + parentOption.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// override some settings for options
|
||||||
|
var override = DATASOURCES_OVERRIDES_OPTIONS.get(parentOption);
|
||||||
|
if (override != null) {
|
||||||
|
override.accept(builder);
|
||||||
|
}
|
||||||
|
|
||||||
option = builder.build();
|
option = builder.build();
|
||||||
cachedDatasourceOptions.put(key.get(), option);
|
cachedDatasourceOptions.put(key.get(), option);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,12 +107,15 @@ import org.keycloak.provider.Spi;
|
|||||||
import org.keycloak.quarkus.runtime.Environment;
|
import org.keycloak.quarkus.runtime.Environment;
|
||||||
import org.keycloak.quarkus.runtime.KeycloakRecorder;
|
import org.keycloak.quarkus.runtime.KeycloakRecorder;
|
||||||
import org.keycloak.quarkus.runtime.cli.Picocli;
|
import org.keycloak.quarkus.runtime.cli.Picocli;
|
||||||
|
import org.keycloak.quarkus.runtime.cli.PropertyException;
|
||||||
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
||||||
import org.keycloak.quarkus.runtime.configuration.KeycloakConfigSourceProvider;
|
import org.keycloak.quarkus.runtime.configuration.KeycloakConfigSourceProvider;
|
||||||
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
||||||
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
|
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
|
||||||
|
import org.keycloak.quarkus.runtime.configuration.PropertyMappingInterceptor;
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
|
import org.keycloak.quarkus.runtime.configuration.mappers.WildcardPropertyMapper;
|
||||||
import org.keycloak.quarkus.runtime.integration.resteasy.KeycloakHandlerChainCustomizer;
|
import org.keycloak.quarkus.runtime.integration.resteasy.KeycloakHandlerChainCustomizer;
|
||||||
import org.keycloak.quarkus.runtime.integration.resteasy.KeycloakTracingCustomizer;
|
import org.keycloak.quarkus.runtime.integration.resteasy.KeycloakTracingCustomizer;
|
||||||
import org.keycloak.quarkus.runtime.logging.ClearMappedDiagnosticContextFilter;
|
import org.keycloak.quarkus.runtime.logging.ClearMappedDiagnosticContextFilter;
|
||||||
@ -171,6 +174,7 @@ import static org.keycloak.quarkus.runtime.configuration.Configuration.getOption
|
|||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalKcValue;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalKcValue;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
||||||
|
import static org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory.DEFAULT_PERSISTENCE_UNIT;
|
||||||
import static org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory.QUERY_PROPERTY_PREFIX;
|
import static org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory.QUERY_PROPERTY_PREFIX;
|
||||||
import static org.keycloak.representations.provider.ScriptProviderDescriptor.AUTHENTICATORS;
|
import static org.keycloak.representations.provider.ScriptProviderDescriptor.AUTHENTICATORS;
|
||||||
import static org.keycloak.representations.provider.ScriptProviderDescriptor.MAPPERS;
|
import static org.keycloak.representations.provider.ScriptProviderDescriptor.MAPPERS;
|
||||||
@ -370,6 +374,59 @@ class KeycloakProcessor {
|
|||||||
recorder.setDefaultUserProfileConfiguration(configuration.getDefaultConfig());
|
recorder.setDefaultUserProfileConfiguration(configuration.getDefaultConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BuildStep
|
||||||
|
@Produce(ValidatePersistenceUnitsBuildItem.class)
|
||||||
|
void checkPersistenceUnits(List<PersistenceXmlDescriptorBuildItem> descriptors) {
|
||||||
|
List<String> notSetPersistenceUnitsDBKinds = descriptors.stream()
|
||||||
|
.map(PersistenceXmlDescriptorBuildItem::getDescriptor)
|
||||||
|
.filter(descriptor -> !descriptor.getName().equals(DEFAULT_PERSISTENCE_UNIT)) // not default persistence unit
|
||||||
|
.map(KeycloakProcessor::getDatasourceNameFromPersistenceXml)
|
||||||
|
.filter(this::missingDbKind)
|
||||||
|
.map(datasourceName -> DatabaseOptions.getNamedKey(DatabaseOptions.DB, datasourceName).orElseThrow()).toList();
|
||||||
|
|
||||||
|
if (!notSetPersistenceUnitsDBKinds.isEmpty()) {
|
||||||
|
throwConfigError("Detected additional named datasources without a DB kind set, please specify: %s".formatted(String.join(",", notSetPersistenceUnitsDBKinds)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to find if DB kind is specified for the descriptor name.
|
||||||
|
* <p>
|
||||||
|
* Check it in order:
|
||||||
|
* <ol>
|
||||||
|
* <li> {@code db-kind-<descriptorName}
|
||||||
|
* <li> {@code quarkus.datasource."<descriptorName>".db-kind}
|
||||||
|
* <li> {@code quarkus.datasource.<descriptorName>.db-kind}
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
private boolean missingDbKind(String datasourceName) {
|
||||||
|
String key = NS_KEYCLOAK_PREFIX.concat(DatabaseOptions.getNamedKey(DatabaseOptions.DB, datasourceName).orElseThrow());
|
||||||
|
PropertyMappingInterceptor.disable();
|
||||||
|
try {
|
||||||
|
var from = Configuration.getConfigValue(key);
|
||||||
|
|
||||||
|
if (from.getValue() != null) {
|
||||||
|
return false; // user has directly specified
|
||||||
|
}
|
||||||
|
|
||||||
|
WildcardPropertyMapper<?> mapper = (WildcardPropertyMapper<?>)PropertyMappers.getMapper(key);
|
||||||
|
|
||||||
|
// quarkus properties
|
||||||
|
boolean missing = Configuration.getOptionalValue(mapper.getTo(datasourceName))
|
||||||
|
.or(() -> Configuration.getOptionalValue(mapper.getTo(datasourceName).replaceAll("\"", "")))
|
||||||
|
.isEmpty();
|
||||||
|
|
||||||
|
if (!missing) {
|
||||||
|
logger.warnf(
|
||||||
|
"You have set DB kind for '%s' datasource via a Quarkus property. This approach is deprecated and you should use the Keycloak 'db-kind-%s' property.",
|
||||||
|
datasourceName, datasourceName);
|
||||||
|
}
|
||||||
|
return missing;
|
||||||
|
} finally {
|
||||||
|
PropertyMappingInterceptor.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get datasource name obtained from the persistence.xml file based on this order:
|
* Get datasource name obtained from the persistence.xml file based on this order:
|
||||||
* <ol>
|
* <ol>
|
||||||
@ -423,6 +480,7 @@ class KeycloakProcessor {
|
|||||||
* @param descriptors
|
* @param descriptors
|
||||||
*/
|
*/
|
||||||
@BuildStep
|
@BuildStep
|
||||||
|
@Consume(ValidatePersistenceUnitsBuildItem.class)
|
||||||
@Record(ExecutionTime.RUNTIME_INIT)
|
@Record(ExecutionTime.RUNTIME_INIT)
|
||||||
void configurePersistenceUnits(HibernateOrmConfig config,
|
void configurePersistenceUnits(HibernateOrmConfig config,
|
||||||
List<PersistenceXmlDescriptorBuildItem> descriptors,
|
List<PersistenceXmlDescriptorBuildItem> descriptors,
|
||||||
@ -437,7 +495,7 @@ class KeycloakProcessor {
|
|||||||
for (PersistenceXmlDescriptorBuildItem item : descriptors) {
|
for (PersistenceXmlDescriptorBuildItem item : descriptors) {
|
||||||
ParsedPersistenceXmlDescriptor descriptor = (ParsedPersistenceXmlDescriptor) item.getDescriptor();
|
ParsedPersistenceXmlDescriptor descriptor = (ParsedPersistenceXmlDescriptor) item.getDescriptor();
|
||||||
|
|
||||||
if ("keycloak-default".equals(descriptor.getName())) {
|
if (DEFAULT_PERSISTENCE_UNIT.equals(descriptor.getName())) {
|
||||||
defaultUnitDescriptor = descriptor;
|
defaultUnitDescriptor = descriptor;
|
||||||
configureDefaultPersistenceUnitProperties(defaultUnitDescriptor, config, getDefaultDataSource(jdbcDataSources));
|
configureDefaultPersistenceUnitProperties(defaultUnitDescriptor, config, getDefaultDataSource(jdbcDataSources));
|
||||||
runtimeConfigured.produce(new HibernateOrmIntegrationRuntimeConfiguredBuildItem("keycloak", defaultUnitDescriptor.getName())
|
runtimeConfigured.produce(new HibernateOrmIntegrationRuntimeConfiguredBuildItem("keycloak", defaultUnitDescriptor.getName())
|
||||||
@ -627,7 +685,7 @@ class KeycloakProcessor {
|
|||||||
descriptors.stream()
|
descriptors.stream()
|
||||||
.map(PersistenceXmlDescriptorBuildItem::getDescriptor)
|
.map(PersistenceXmlDescriptorBuildItem::getDescriptor)
|
||||||
.map(PersistenceUnitDescriptor::getName)
|
.map(PersistenceUnitDescriptor::getName)
|
||||||
.filter(Predicate.not("keycloak-default"::equals))
|
.filter(Predicate.not(DEFAULT_PERSISTENCE_UNIT::equals))
|
||||||
.forEach((String unitName) -> {
|
.forEach((String unitName) -> {
|
||||||
NamedJpaConnectionProviderFactory factory = new NamedJpaConnectionProviderFactory();
|
NamedJpaConnectionProviderFactory factory = new NamedJpaConnectionProviderFactory();
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
package org.keycloak.quarkus.deployment;
|
||||||
|
|
||||||
|
import io.quarkus.builder.item.EmptyBuildItem;
|
||||||
|
|
||||||
|
public final class ValidatePersistenceUnitsBuildItem extends EmptyBuildItem {
|
||||||
|
}
|
||||||
@ -24,16 +24,6 @@ import java.util.Map;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import io.agroal.api.AgroalDataSource;
|
|
||||||
import io.quarkus.agroal.DataSource;
|
|
||||||
import io.quarkus.arc.Arc;
|
|
||||||
import io.quarkus.arc.InstanceHandle;
|
|
||||||
import io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrationRuntimeInitListener;
|
|
||||||
import io.quarkus.runtime.annotations.Recorder;
|
|
||||||
import io.vertx.core.Handler;
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
|
||||||
import liquibase.Scope;
|
|
||||||
import liquibase.servicelocator.ServiceLocator;
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.infinispan.protostream.SerializationContextInitializer;
|
import org.infinispan.protostream.SerializationContextInitializer;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
@ -56,6 +46,17 @@ import org.keycloak.theme.ClasspathThemeProviderFactory;
|
|||||||
import org.keycloak.truststore.TruststoreBuilder;
|
import org.keycloak.truststore.TruststoreBuilder;
|
||||||
import org.keycloak.userprofile.DeclarativeUserProfileProviderFactory;
|
import org.keycloak.userprofile.DeclarativeUserProfileProviderFactory;
|
||||||
|
|
||||||
|
import io.agroal.api.AgroalDataSource;
|
||||||
|
import io.quarkus.agroal.DataSource;
|
||||||
|
import io.quarkus.arc.Arc;
|
||||||
|
import io.quarkus.arc.InstanceHandle;
|
||||||
|
import io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrationRuntimeInitListener;
|
||||||
|
import io.quarkus.runtime.annotations.Recorder;
|
||||||
|
import io.vertx.core.Handler;
|
||||||
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
import liquibase.Scope;
|
||||||
|
import liquibase.servicelocator.ServiceLocator;
|
||||||
|
|
||||||
@Recorder
|
@Recorder
|
||||||
public class KeycloakRecorder {
|
public class KeycloakRecorder {
|
||||||
|
|
||||||
|
|||||||
@ -109,6 +109,7 @@ final class DatabasePropertyMappers {
|
|||||||
|
|
||||||
return appendDatasourceMappers(mappers, Map.of(
|
return appendDatasourceMappers(mappers, Map.of(
|
||||||
// Inherit options from the DB mappers
|
// Inherit options from the DB mappers
|
||||||
|
DatabaseOptions.DB, PropertyMapper.Builder::removeMapFrom,
|
||||||
DatabaseOptions.DB_POOL_INITIAL_SIZE, mapper -> mapper.mapFrom(DatabaseOptions.DB_POOL_INITIAL_SIZE),
|
DatabaseOptions.DB_POOL_INITIAL_SIZE, mapper -> mapper.mapFrom(DatabaseOptions.DB_POOL_INITIAL_SIZE),
|
||||||
DatabaseOptions.DB_POOL_MAX_SIZE, mapper -> mapper.mapFrom(DatabaseOptions.DB_POOL_MAX_SIZE)
|
DatabaseOptions.DB_POOL_MAX_SIZE, mapper -> mapper.mapFrom(DatabaseOptions.DB_POOL_MAX_SIZE)
|
||||||
));
|
));
|
||||||
|
|||||||
@ -379,6 +379,11 @@ public class PropertyMapper<T> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder<T> removeMapFrom() {
|
||||||
|
this.mapFrom = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder<T> mapFrom(Option<?> mapFrom) {
|
public Builder<T> mapFrom(Option<?> mapFrom) {
|
||||||
this.mapFrom = mapFrom.getKey();
|
this.mapFrom = mapFrom.getKey();
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public class WildcardPropertyMapper<T> extends PropertyMapper<T> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTo(String wildcardKey) {
|
public String getTo(String wildcardKey) {
|
||||||
return toPrefix + wildcardKey + toSuffix;
|
return toPrefix + wildcardKey + toSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,7 @@ import org.keycloak.quarkus.runtime.Environment;
|
|||||||
public class QuarkusJpaConnectionProviderFactory extends AbstractJpaConnectionProviderFactory implements ServerInfoAwareProviderFactory {
|
public class QuarkusJpaConnectionProviderFactory extends AbstractJpaConnectionProviderFactory implements ServerInfoAwareProviderFactory {
|
||||||
|
|
||||||
public static final String QUERY_PROPERTY_PREFIX = "kc.query.";
|
public static final String QUERY_PROPERTY_PREFIX = "kc.query.";
|
||||||
|
public static final String DEFAULT_PERSISTENCE_UNIT = "keycloak-default";
|
||||||
private static final Logger logger = Logger.getLogger(QuarkusJpaConnectionProviderFactory.class);
|
private static final Logger logger = Logger.getLogger(QuarkusJpaConnectionProviderFactory.class);
|
||||||
private static final String SQL_GET_LATEST_VERSION = "SELECT ID, VERSION FROM %sMIGRATION_MODEL ORDER BY UPDATE_TIME DESC";
|
private static final String SQL_GET_LATEST_VERSION = "SELECT ID, VERSION FROM %sMIGRATION_MODEL ORDER BY UPDATE_TIME DESC";
|
||||||
|
|
||||||
@ -165,7 +166,7 @@ public class QuarkusJpaConnectionProviderFactory extends AbstractJpaConnectionPr
|
|||||||
return instance.get();
|
return instance.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getEntityManagerFactory("keycloak-default").orElseThrow(() -> new IllegalStateException("Failed to resolve the default entity manager factory"));
|
return getEntityManagerFactory(DEFAULT_PERSISTENCE_UNIT).orElseThrow(() -> new IllegalStateException("Failed to resolve the default entity manager factory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -235,8 +235,8 @@ public class DatasourcesConfigurationTest extends AbstractConfigurationTest {
|
|||||||
|
|
||||||
ConfigArgsConfigSource.setCliArgs("");
|
ConfigArgsConfigSource.setCliArgs("");
|
||||||
initConfig();
|
initConfig();
|
||||||
assertConfig("db-dialect-clients", H2Dialect.class.getName());
|
assertConfigNull("db-dialect-clients");
|
||||||
assertExternalConfig("quarkus.datasource.\"clients\".jdbc.url", "jdbc:h2:file:test-dir/data/h2/keycloakdb-clients;;test=test;test1=test1;NON_KEYWORDS=VALUE;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=0");
|
assertConfigNull("quarkus.datasource.\"clients\".jdbc.url", true);
|
||||||
onAfter();
|
onAfter();
|
||||||
|
|
||||||
System.setProperty("kc.db-url-properties-users", "?test=test&test1=test1");
|
System.setProperty("kc.db-url-properties-users", "?test=test&test1=test1");
|
||||||
@ -293,6 +293,13 @@ public class DatasourcesConfigurationTest extends AbstractConfigurationTest {
|
|||||||
ConfigArgsConfigSource.setCliArgs("");
|
ConfigArgsConfigSource.setCliArgs("");
|
||||||
initConfig();
|
initConfig();
|
||||||
|
|
||||||
|
assertConfigNull("db-pool-initial-size-clients");
|
||||||
|
assertConfigNull("db-pool-min-size-clients");
|
||||||
|
assertConfig("db-pool-max-size-clients", "100");
|
||||||
|
|
||||||
|
ConfigArgsConfigSource.setCliArgs("--db-kind-clients=dev-mem");
|
||||||
|
initConfig();
|
||||||
|
|
||||||
assertConfigNull("db-pool-initial-size-clients");
|
assertConfigNull("db-pool-initial-size-clients");
|
||||||
assertConfig(Map.of(
|
assertConfig(Map.of(
|
||||||
"db-pool-min-size-clients", "1",
|
"db-pool-min-size-clients", "1",
|
||||||
@ -326,6 +333,12 @@ public class DatasourcesConfigurationTest extends AbstractConfigurationTest {
|
|||||||
|
|
||||||
ConfigArgsConfigSource.setCliArgs("--db-pool-initial-size-clients=10");
|
ConfigArgsConfigSource.setCliArgs("--db-pool-initial-size-clients=10");
|
||||||
initConfig();
|
initConfig();
|
||||||
|
assertConfigNull("db-pool-min-size-clients");
|
||||||
|
assertConfig("db-pool-initial-size-clients", "10");
|
||||||
|
onAfter();
|
||||||
|
|
||||||
|
ConfigArgsConfigSource.setCliArgs("--db-pool-initial-size-clients=10", "--db-kind-clients=dev-file");
|
||||||
|
initConfig();
|
||||||
assertConfig(Map.of(
|
assertConfig(Map.of(
|
||||||
"db-pool-min-size-clients", "1", // set 1 for H2
|
"db-pool-min-size-clients", "1", // set 1 for H2
|
||||||
"db-pool-initial-size-clients", "10"
|
"db-pool-initial-size-clients", "10"
|
||||||
|
|||||||
@ -20,14 +20,19 @@
|
|||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
|
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
|
||||||
version="3.0">
|
version="3.0">
|
||||||
<persistence-unit name="user-store" transaction-type="JTA">
|
<persistence-unit name="new-user-store" transaction-type="JTA">
|
||||||
<class>com.acme.provider.legacy.jpa.entity.Realm</class>
|
<class>com.acme.provider.legacy.jpa.entity.Realm</class>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
|
||||||
<!-- Sets the name of the datasource to be the same as the datasource name in quarkus.properties-->
|
<property name="jakarta.persistence.jtaDataSource" value="new-user-store" />
|
||||||
<property name="jakarta.persistence.jtaDataSource" value="user-store" />
|
|
||||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||||
<property name="hibernate.show_sql" value="false" />
|
<property name="hibernate.show_sql" value="false" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="client-store" transaction-type="JTA">
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|||||||
@ -15,7 +15,4 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
quarkus.datasource.user-store.db-kind=h2
|
quarkus.datasource.client-store.db-kind=h2
|
||||||
quarkus.datasource.user-store.username=sa
|
|
||||||
quarkus.datasource.user-store.jdbc.url=jdbc:h2:mem:user-store;DB_CLOSE_DELAY=-1
|
|
||||||
quarkus.datasource.user-store.jdbc.transactions=xa
|
|
||||||
|
|||||||
@ -26,19 +26,44 @@ import org.keycloak.it.junit5.extension.TestProvider;
|
|||||||
import com.acme.provider.legacy.jpa.entity.CustomJpaEntityProvider;
|
import com.acme.provider.legacy.jpa.entity.CustomJpaEntityProvider;
|
||||||
|
|
||||||
import io.quarkus.test.junit.main.Launch;
|
import io.quarkus.test.junit.main.Launch;
|
||||||
|
import org.keycloak.it.utils.KeycloakDistribution;
|
||||||
|
|
||||||
@DistributionTest
|
@DistributionTest
|
||||||
@RawDistOnly(reason = "Containers are immutable")
|
@RawDistOnly(reason = "Containers are immutable")
|
||||||
@Tag(DistributionTest.SMOKE)
|
@Tag(DistributionTest.SMOKE)
|
||||||
|
@TestProvider(CustomJpaEntityProvider.class)
|
||||||
public class CustomJpaEntityProviderDistTest {
|
public class CustomJpaEntityProviderDistTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestProvider(CustomJpaEntityProvider.class)
|
void dbKindSpecifiedInBuildTime(KeycloakDistribution dist) {
|
||||||
@Launch({ "start-dev", "--log-level=org.hibernate.jpa.internal.util.LogHelper:debug,org.keycloak.quarkus.deployment.KeycloakProcessor:debug" })
|
var result = dist.run("build", "--db=dev-file", "--db-kind-new-user-store=dev-mem");
|
||||||
|
result.assertMessage("Multiple datasources are specified: <default>, client-store, new-user-store");
|
||||||
|
result.assertMessage("You have set DB kind for 'client-store' datasource via a Quarkus property. This approach is deprecated and you should use the Keycloak 'db-kind-client-store' property.");
|
||||||
|
result.assertBuild();
|
||||||
|
|
||||||
|
result = dist.run("start", "--optimized", "--http-enabled=true", "--hostname-strict=false");
|
||||||
|
result.assertNoError("Detected additional named datasources. You need to explicitly set the DB kind for the datasource(s) to properly work as: db-kind-user-store");
|
||||||
|
|
||||||
|
// Remove once https://github.com/keycloak/keycloak/pull/41026 is solved
|
||||||
|
result.assertError("Datasource 'new-user-store' was deactivated automatically because its URL is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({"start-dev", "--db=dev-file"})
|
||||||
|
void notSpecifiedDbKind(CLIResult cliResult) {
|
||||||
|
// it is printed at build time and the check done at runtime
|
||||||
|
cliResult.assertNoMessage("Multiple datasources are specified: <default>, client-store, user-store");
|
||||||
|
cliResult.assertError("Detected additional named datasources without a DB kind set, please specify: db-kind-new-user-store");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({"start-dev", "--db=dev-file", "--log-level=org.hibernate.jpa.internal.util.LogHelper:debug,org.keycloak.quarkus.deployment.KeycloakProcessor:debug", "--db-kind-new-user-store=dev-mem", "--db-kind-client-store=dev-mem"})
|
||||||
void testUserManagedEntityNotAddedToDefaultPU(CLIResult cliResult) {
|
void testUserManagedEntityNotAddedToDefaultPU(CLIResult cliResult) {
|
||||||
cliResult.assertMessage("Multiple datasources are specified: <default>, user-store");
|
cliResult.assertMessage("Multiple datasources are specified: <default>, client-store, new-user-store");
|
||||||
cliResult.assertMessage("Datasource name 'user-store' is obtained from the 'jakarta.persistence.jtaDataSource' configuration property in persistence.xml file. Use 'user-store' name for datasource options like 'db-kind-user-store'.");
|
cliResult.assertMessage("Datasource name 'client-store' is obtained from the 'Persistence unit name' configuration property in persistence.xml file. Use 'client-store' name for datasource options like 'db-kind-client-store'.");
|
||||||
cliResult.assertStringCount("name: user-store", 1);
|
cliResult.assertMessage("Datasource name 'new-user-store' is obtained from the 'jakarta.persistence.jtaDataSource' configuration property in persistence.xml file. Use 'new-user-store' name for datasource options like 'db-kind-new-user-store'.");
|
||||||
|
cliResult.assertStringCount("name: new-user-store", 1);
|
||||||
|
cliResult.assertStringCount("name: client-store", 1);
|
||||||
cliResult.assertStringCount("com.acme.provider.legacy.jpa.entity.Realm", 1);
|
cliResult.assertStringCount("com.acme.provider.legacy.jpa.entity.Realm", 1);
|
||||||
cliResult.assertStartedDevMode();
|
cliResult.assertStartedDevMode();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,7 +85,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -87,7 +87,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -36,7 +36,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
|
|
||||||
Transaction:
|
Transaction:
|
||||||
|
|
||||||
|
|||||||
@ -80,7 +80,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -80,7 +80,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -80,7 +80,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -80,7 +80,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -122,7 +122,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -189,7 +189,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -170,7 +170,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -190,7 +190,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -169,7 +169,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -189,7 +189,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -167,7 +167,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -187,7 +187,7 @@ Database - additional datasources (Preview):
|
|||||||
Preview: Used for named <datasource>. The database vendor. In production mode
|
Preview: Used for named <datasource>. The database vendor. In production mode
|
||||||
the default value of 'dev-file' is deprecated, you should explicitly specify
|
the default value of 'dev-file' is deprecated, you should explicitly specify
|
||||||
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
the db instead. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres. Default: dev-file.
|
mysql, oracle, postgres.
|
||||||
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
--db-log-slow-queries-threshold-<datasource> <milliseconds>
|
||||||
Preview: Used for named <datasource>. Log SQL statements slower than the
|
Preview: Used for named <datasource>. Log SQL statements slower than the
|
||||||
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
configured threshold with logger org.hibernate.SQL_SLOW and log-level info.
|
||||||
|
|||||||
@ -85,6 +85,10 @@ public interface CLIResult extends LaunchResult {
|
|||||||
getErrorOutput(), not(containsString(msg)));
|
getErrorOutput(), not(containsString(msg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void assertWarning(String msg) {
|
||||||
|
assertError(msg); //seems that warnings are printed on stderr
|
||||||
|
}
|
||||||
|
|
||||||
default void assertExitCode(int code) {
|
default void assertExitCode(int code) {
|
||||||
assertThat("Exit codes do not match: ", exitCode(), is(code));
|
assertThat("Exit codes do not match: ", exitCode(), is(code));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user