Allow to conditionally bootstrap the default persistence unit

Closes #12662
This commit is contained in:
Pedro Igor 2022-06-23 10:54:16 -03:00 committed by Bruno Oliveira da Silva
parent c5d5659100
commit c972ec4383
10 changed files with 120 additions and 2 deletions

View file

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

View file

@ -0,0 +1,29 @@
/*
* 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;
public class StorageOptions {
public static final Option<Boolean> DEFAULT_PERSISTENCE_UNIT_ENABLED = new OptionBuilder<>("storage-default-persistence-unit-enabled", Boolean.class)
.category(OptionCategory.STORAGE)
.defaultValue(true)
.runtimes(Option.Runtime.OPERATOR)
.buildTime(true)
.build();
}

View file

@ -58,7 +58,10 @@ public class JpaUtils {
public static EntityManagerFactory createEntityManagerFactory(KeycloakSession session, String unitName, Map<String, Object> properties, boolean jta) { public static EntityManagerFactory createEntityManagerFactory(KeycloakSession session, String unitName, Map<String, Object> properties, boolean jta) {
PersistenceUnitTransactionType txType = jta ? PersistenceUnitTransactionType.JTA : PersistenceUnitTransactionType.RESOURCE_LOCAL; PersistenceUnitTransactionType txType = jta ? PersistenceUnitTransactionType.JTA : PersistenceUnitTransactionType.RESOURCE_LOCAL;
List<ParsedPersistenceXmlDescriptor> persistenceUnits = PersistenceXmlParser.locatePersistenceUnits(properties); List<ParsedPersistenceXmlDescriptor> persistenceUnits = new ArrayList<>(PersistenceXmlParser.locatePersistenceUnits(properties));
persistenceUnits.add(PersistenceXmlParser.locateIndividualPersistenceUnit(JpaUtils.class.getClassLoader().getResource("default-persistence.xml")));
for (ParsedPersistenceXmlDescriptor persistenceUnit : persistenceUnits) { for (ParsedPersistenceXmlDescriptor persistenceUnit : persistenceUnits) {
if (persistenceUnit.getName().equals(unitName)) { if (persistenceUnit.getName().equals(unitName)) {
List<Class<?>> providedEntities = getProvidedEntities(session); List<Class<?>> providedEntities = getProvidedEntities(session);

View file

@ -83,7 +83,7 @@
<class>org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity</class> <class>org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity</class> <class>org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserRoleMappingEntity</class> <class>org.keycloak.storage.jpa.entity.FederatedUserRoleMappingEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes> <exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties> <properties>

View file

@ -0,0 +1,32 @@
/*
* 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.deployment;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalBooleanValue;
import java.util.function.BooleanSupplier;
import org.keycloak.quarkus.runtime.Environment;
public class IsDefaultPersistenceUnitEnabled implements BooleanSupplier {
@Override
public boolean getAsBoolean() {
return getOptionalBooleanValue("kc.storage-default-persistence-unit-enabled").get();
}
}

View file

@ -79,6 +79,7 @@ import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.RoutingContext;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
@ -227,6 +228,14 @@ class KeycloakProcessor {
} }
} }
@BuildStep(onlyIf = IsDefaultPersistenceUnitEnabled.class)
void produceDefaultPersistenceUnit(BuildProducer<PersistenceXmlDescriptorBuildItem> producer) {
ParsedPersistenceXmlDescriptor descriptor = PersistenceXmlParser.locateIndividualPersistenceUnit(
Thread.currentThread().getContextClassLoader().getResource("default-persistence.xml"));
producer.produce(new PersistenceXmlDescriptorBuildItem(descriptor));
}
private void configureJpaProperties(ParsedPersistenceXmlDescriptor descriptor, HibernateOrmConfig config, private void configureJpaProperties(ParsedPersistenceXmlDescriptor descriptor, HibernateOrmConfig config,
List<JdbcDataSourceBuildItem> jdbcDataSources) { List<JdbcDataSourceBuildItem> jdbcDataSources) {
Properties unitProperties = descriptor.getProperties(); Properties unitProperties = descriptor.getProperties();

View file

@ -431,6 +431,10 @@ public final class Picocli {
argGroupBuilder.addArg(optBuilder.build()); argGroupBuilder.addArg(optBuilder.build());
} }
if (argGroupBuilder.args().isEmpty()) {
continue;
}
cSpec.addArgGroup(argGroupBuilder.build()); cSpec.addArgGroup(argGroupBuilder.build());
} }
} }

View file

@ -32,6 +32,7 @@ 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());
} }
public static ConfigValue getValue(ConfigSourceInterceptorContext context, String name) { public static ConfigValue getValue(ConfigSourceInterceptorContext context, String name) {

View file

@ -0,0 +1,39 @@
/*
* 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 org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import org.keycloak.config.StorageOptions;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import io.smallrye.config.ConfigSourceInterceptorContext;
final class StoragePropertyMappers {
private StoragePropertyMappers(){}
public static PropertyMapper[] getMappers() {
return new PropertyMapper[] {
fromOption(StorageOptions.DEFAULT_PERSISTENCE_UNIT_ENABLED)
.to("kc.spi-connections-jpa-quarkus-enabled")
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
.build()
};
}
}