8000 fix: combining / removing static and initialization logic by shawkins · Pull Request #46918 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.jar.JarFile;
import java.util.logging.Handler;

import jakarta.inject.Singleton;
import jakarta.persistence.Entity;
import jakarta.persistence.PersistenceUnitTransactionType;

Expand Down Expand Up @@ -93,6 +94,7 @@
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import org.keycloak.quarkus.runtime.configuration.mappers.WildcardPropertyMapper;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.integration.resteasy.KeycloakHandlerChainCustomizer;
import org.keycloak.quarkus.runtime.integration.resteasy.KeycloakTracingCustomizer;
import org.keycloak.quarkus.runtime.logging.ClearMappedDiagnosticContextFilter;
Expand Down Expand Up @@ -127,6 +129,7 @@
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem;
import io.quarkus.arc.deployment.BuildTimeConditionBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.datasource.deployment.spi.DevServicesDatasourceResultBuildItem;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
Expand Down Expand Up @@ -681,7 +684,7 @@ private void configureDefaultPersistenceUnitEntities(ParsedPersistenceXmlDescrip
@Consume(ConfigBuildItem.class)
@Consume(CryptoProviderInitBuildItem.class)
@Produce(KeycloakSessionFactoryPreInitBuildItem.class)
void configureKeycloakSessionFactory(KeycloakRecorder recorder, List<PersistenceXmlDescriptorBuildItem> descriptors) {
SyntheticBeanBuildItem configureKeycloakSessionFactory(KeycloakRecorder recorder, List<PersistenceXmlDescriptorBuildItem> descriptors) {
Map<Spi, Map<Class<? extends Provider>, Map<String, Class<? extends ProviderFactory>>>> factories = new HashMap<>();
Map<Class<? extends Provider>, String> defaultProviders = new HashMap<>();
Map<String, ProviderFactory> preConfiguredProviders = new HashMap<>();
Expand Down Expand Up @@ -709,7 +712,10 @@ void configureKeycloakSessionFactory(KeycloakRecorder recorder, List<Persistence
}
}

recorder.configSessionFactory(factories, defaultProviders, preConfiguredProviders, loadThemesFromClassPath());
return SyntheticBeanBuildItem.configure(QuarkusKeycloakSessionFactory.class).scope(Singleton.class)
.unremovable()
.runtimeValue(recorder.createSessionFactory(factories, defaultProviders, preConfiguredProviders,
loadThemesFromClassPath())).done();
}

private List<ClasspathThemeProviderFactory.ThemesRepresentation> loadThemesFromClassPath() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;

import io.quarkus.arc.Arc;
Expand Down Expand Up @@ -146,7 +147,8 @@ public static void start(Picocli picocli, AbstractNonServerCommand command, Exec
public int run(String... args) throws Exception {
if (COMMAND != null) {
QuarkusKeycloakApplication application = Arc.container().instance(QuarkusKeycloakApplication.class).get();
COMMAND.onStart(application);
QuarkusKeycloakSessionFactory sessionFactory = Arc.container().instance(QuarkusKeycloakSessionFactory.class).get();
COMMAND.onStart(application, sessionFactory);
}
if (isTestLaunchMode() || isNonServerMode()) {
// in test mode we exit immediately
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrationRuntimeInitListener;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
Expand Down Expand Up @@ -156,12 +157,12 @@ public void configureLiquibase(Map<String, List<String>> services) {
}
}

public void configSessionFactory(
public RuntimeValue<QuarkusKeycloakSessionFactory> createSessionFactory(
Map<Spi, Map<Class<? extends Provider>, Map<String, Class<? extends ProviderFactory>>>> factories,
Map<Class<? extends Provider>, String> defaultProviders,
Map<String, ProviderFactory> preConfiguredProviders,
List<ClasspathThemeProviderFactory.ThemesRepresentation> themes) {
QuarkusKeycloakSessionFactory.setInstance(new QuarkusKeycloakSessionFactory(factories, defaultProviders, preConfiguredProviders, themes));
return new RuntimeValue<QuarkusKeycloakSessionFactory>(new Quar 8BD0 kusKeycloakSessionFactory(factories, defaultProviders, preConfiguredProviders, themes));
}

public void setDefaultUserProfileConfiguration(UPConfig configuration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.keycloak.common.util.Environment;
import org.keycloak.config.OptionCategory;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;

import picocli.CommandLine;
Expand All @@ -44,7 +45,7 @@ public boolean isHiddenCategory(OptionCategory category) {
return super.isHiddenCategory(category) || hidden.contains(category);
}

public void onStart(QuarkusKeycloakApplication application) {
public void onStart(QuarkusKeycloakApplication application, QuarkusKeycloakSessionFactory sessionFactory) {
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@
import org.keycloak.common.util.IoUtils;
import org.keycloak.config.BootstrapAdminOptions;
import org.keycloak.config.OptionCategory;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;
import org.keycloak.services.resources.KeycloakApplication;

import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
Expand Down Expand Up @@ -99,9 +98,8 @@ private String getFromEnv(String envVar) {
}

@Override
public void onStart(QuarkusKeycloakApplication application) {
public void onStart(QuarkusKeycloakApplication application, QuarkusKeycloakSessionFactory sessionFactory) {
//BootstrapAdmin bootstrap = spec.commandLine().getParent().getCommand();
KeycloakSessionFactory sessionFactory = KeycloakApplication.getSessionFactory();
KeycloakModelUtils.runJobInTransaction(sessionFactory, session -> application
.createTemporaryMasterRealmAdminService(clientId, clientSecret, /* bootstrap.expiration, */ session));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@
import org.keycloak.common.util.IoUtils;
import org.keycloak.config.BootstrapAdminOptions;
import org.keycloak.config.OptionCategory;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;
import org.keycloak.services.resources.KeycloakApplication;

import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
Expand Down Expand Up @@ -99,9 +98,8 @@ private String getFromEnv(String envVar) {
}

@Override
public void onStart(QuarkusKeycloakApplication application) {
public void onStart(QuarkusKeycloakApplication application, QuarkusKeycloakSessionFactory sessionFactory) {
//BootstrapAdmin bootstrap = spec.commandLine().getParent().getCommand();
KeycloakSessionFactory sessionFactory = KeycloakApplication.getSessionFactory();
KeycloakModelUtils.runJobInTransaction(sessionFactory, session -> application
.createTemporaryMasterRealmAdminUser(username, password, /* bootstrap.expiration, */ session));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,19 @@
import org.keycloak.models.KeycloakSession;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderManagerRegistry;
import org.keycloak.provider.Spi;
import org.keycloak.quarkus.runtime.themes.QuarkusJarThemeProviderFactory;
import org.keycloak.services.DefaultKeycloakSessionFactory;
import org.keycloak.services.resources.admin.fgap.AdminPermissions;
import org.keycloak.theme.ClasspathThemeProviderFactory;

public final class QuarkusKeycloakSessionFactory extends DefaultKeycloakSessionFactory {

public static QuarkusKeycloakSessionFactory getInstance() {
if (INSTANCE == null) {
INSTANCE = new QuarkusKeycloakSessionFactory();
}

return INSTANCE;
}

public static void setInstance(QuarkusKeycloakSessionFactory instance) {
INSTANCE = instance;
}

private static QuarkusKeycloakSessionFactory INSTANCE;

public QuarkusKeycloakSessionFactory(
Map<Spi, Map<Class<? extends Provider>, Map<String, Class<? extends ProviderFactory>>>> factories,
Map<Class<? extends Provider>, String> defaultProviders,
Map<String, ProviderFactory> preConfiguredProviders,
List<ClasspathThemeProviderFactory.ThemesRepresentation> themes) {
this.provider = defaultProviders;
serverStartupTimestamp = System.currentTimeMillis();
spis = factories.keySet();

for (Spi spi : spis) {
Expand All @@ -79,17 +62,6 @@ public QuarkusKeycloakSessionFactory(
}
}

private QuarkusKeycloakSessionFactory() {
}

@Override
public void init() {
initProviderFactories();
AdminPermissions.registerListener(this);
Comment thread
mabartos marked this conversation as resolved.
Resolved
// make the session factory ready for hot deployment
ProviderManagerRegistry.SINGLETON.setDeployer(this);
}

private ProviderFactory lookupProviderFactory(Class<? extends ProviderFactory> factoryClazz) {
ProviderFactory factory;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.inject.Disposes;
import jakarta.inject.Inject;

import org.keycloak.models.KeycloakSession;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.transaction.TransactionalSessionHandler;
import org.keycloak.utils.KeycloakSessionUtil;

Expand All @@ -31,9 +33,12 @@
@Unremovable
public class KeycloakBeanProducer implements TransactionalSessionHandler {

@Inject
QuarkusKeycloakSessionFactory factory;

@RequestScoped
public KeycloakSession getKeycloakSession() {
return create();
return factory.create();
}

void dispose(@Disposes KeycloakSession session) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@
import org.keycloak.quarkus.runtime.configuration.PropertyMappingInterceptor;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory;
import org.keycloak.services.DefaultKeycloakSessionFactory;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.managers.ApplianceBootstrap;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.utils.StringUtil;

import io.quarkus.arc.Arc;
import io.quarkus.runtime.Quarkus;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
Expand All @@ -43,10 +45,11 @@

import static org.keycloak.common.util.Environment.isDevMode;
import static org.keycloak.common.util.Environment.isNonServerMode;
import static org.keycloak.quarkus.runtime.Environment.isTestLaunchMode;

@ApplicationPath("/")
@Blocking
public class QuarkusKeycloakApplication extends KeycloakApplication<QuarkusKeycloakSessionFactory> {
public class QuarkusKeycloakApplication extends KeycloakApplication {

private static final String KEYCLOAK_ADMIN_ENV_VAR = "KEYCLOAK_ADMIN";
private static final String KEYCLOAK_ADMIN_PASSWORD_ENV_VAR = "KEYCLOAK_ADMIN_PASSWORD";
Expand Down Expand Up @@ -75,13 +78,8 @@ void onShutdownEvent(@Observes ShutdownEvent event) {
}

@Override
public QuarkusKeycloakSessionFactory createSessionFactory() {
return QuarkusKeycloakSessionFactory.getInstance();
}

@Override
protected void initKeycloakSessionFactory(QuarkusKeycloakSessionFactory quarkusKeycloakSessionFactory) {
quarkusKeycloakSessionFactory.init();
public DefaultKeycloakSessionFactory createSessionFactory() {
return Arc.container().instance(QuarkusKeycloakSessionFactory.class).get();
}

@Override
Expand Down Expand Up @@ -116,11 +114,11 @@ protected boolean supportsAsyncInitialization() {
.map(Boolean::parseBoolean)
.orElse(Boolean.TRUE);
// skip async bootstrap in dev and non-server mode
return !isDevMode() && !isNonServerMode() && asyncBootstrap;
return !isDevMode() && !isNonServerMode() && !isTestLaunchMode() && asyncBootstrap;
}

@Override
protected int getTransactionTimeout(QuarkusKeycloakSessionFactory sessionFactory) {
protected int getTransactionTimeout(DefaultKeycloakSessionFactory sessionFactory) {
return ((QuarkusJpaConnectionProviderFactory) sessionFactory.getProviderFactory(JpaConnectionProvider.class)).getMigrationTransactionTimeout();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.keycloak.quarkus.runtime.services;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;

import org.jboss.logging.Logger;
import org.jboss.resteasy.reactive.server.ServerRequestFilter;
Expand All @@ -22,6 +23,9 @@ public class BootstrapFilter {
private boolean ready;
private volatile boolean warningLogged;

@Inject
QuarkusKeycloakSessionFactory factory;

public BootstrapFilter() {
startup = System.currentTimeMillis();
}
Expand All @@ -32,7 +36,7 @@ public Response filter(ContainerRequestContext ignored) {
// JVM branch prediction may optimize this code and saves on reading a static volatile field
return null;
}
if (KeycloakApplication.isBootstrapCompleted()) {
10BC8 if (factory.isBootstrapCompleted()) {
// Return null to continue the request chain normally
ready = true;
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
package org.keycloak.quarkus.runtime.services.health;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;

import io.smallrye.health.api.AsyncHealthCheck;
import io.smallrye.mutiny.Uni;
Expand All @@ -37,16 +38,19 @@ public class BoostrapReadyHealthCheck implements AsyncHealthCheck {
private static final HealthCheckResponse UP = builder().up().build();
private boolean bootstrapCompleted;

@Inject
QuarkusKeycloakSessionFactory factory;

@Override
public Uni<HealthCheckResponse> call() {
// JVM branch prediction may optimize this code and saves on reading a static volatile field
if (bootstrapCompleted) {
return ready();
}
if (KeycloakApplication.isBootstrapCompleted()) {
if (factory.isBootstrapCompleted()) {
bootstrapCompleted = true;
return ready();
}
}
return Uni.createFrom().item(builder().down().build());
}

Expand Down
B368
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Inject;

import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.connections.infinispan.InfinispanConnectionProviderFactory;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;

import io.smallrye.health.api.AsyncHealthCheck;
import org.eclipse.microprofile.health.Readiness;
Expand All @@ -32,6 +33,8 @@ public class KeycloakClusterReadyHealthCheckProducer {

private AsyncHealthCheck instance;
private boolean ready;
@Inject
QuarkusKeycloakSessionFactory sessionFactory;

@Produces
@Readiness
Expand All @@ -41,14 +44,13 @@ public AsyncHealthCheck createHealthCheck() {
// JVM branch prediction may optimize this code and saves on reading a static volatile field
return instance;
}
if (!KeycloakApplication.isBootstrapCompleted()) {
if (!sessionFactory.isBootstrapCompleted()) {
return null;
}
synchronized (this) {
if (ready) {
return instance;
}
var sessionFactory = KeycloakApplication.getSessionFactory();
var factory = (InfinispanConnectionProviderFactory) sessionFactory.getProviderFactory(InfinispanConnectionProvider.class);
if (factory.isClusterHealthSupported()) {
instance = new KeycloakClusterReadyHealthCheck(factory);
Expand Down
Loading
Loading
0