use of io.quarkus.deployment.annotations.Record in project keycloak by keycloak.
the class KeycloakProcessor method initializeMetrics.
/**
* <p>Initialize metrics and health endpoints.
*
* <p>The only reason for manually registering these endpoints is that by default they run as blocking hence
* running in a different thread than the worker thread started by {@link QuarkusRequestFilter}.
* See https://github.com/quarkusio/quarkus/issues/12990.
*
* <p>By doing this, custom health checks such as {@link org.keycloak.quarkus.runtime.services.health.KeycloakReadyHealthCheck} is
* executed within an active {@link org.keycloak.models.KeycloakSession}, making possible to use it when calculating the
* status.
*
* @param routes
*/
@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void initializeMetrics(KeycloakRecorder recorder, BuildProducer<RouteBuildItem> routes, NonApplicationRootPathBuildItem nonAppRootPath) {
final Handler<RoutingContext> healthHandler = (isHealthEnabled()) ? new SmallRyeHealthHandler() : new NotFoundHandler();
Handler<RoutingContext> metricsHandler;
if (isMetricsEnabled()) {
String rootPath = nonAppRootPath.getNormalizedHttpRootPath();
metricsHandler = recorder.createMetricsHandler(rootPath.concat(DEFAULT_METRICS_ENDPOINT).replace("//", "/"));
} else {
metricsHandler = new NotFoundHandler();
}
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT).handler(healthHandler).build());
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/live")).handler(healthHandler).build());
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/ready")).handler(healthHandler).build());
routes.produce(RouteBuildItem.builder().route(DEFAULT_METRICS_ENDPOINT).handler(metricsHandler).build());
}
use of io.quarkus.deployment.annotations.Record in project keycloak by keycloak.
the class LiquibaseProcessor method configure.
@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void configure(KeycloakRecorder recorder, List<JdbcDataSourceBuildItem> jdbcDataSources, CombinedIndexBuildItem indexBuildItem) {
DotName liquibaseServiceName = DotName.createSimple(LiquibaseService.class.getName());
Map<String, List<String>> services = new HashMap<>();
IndexView index = indexBuildItem.getIndex();
JdbcDataSourceBuildItem dataSourceBuildItem = jdbcDataSources.get(0);
String dbKind = dataSourceBuildItem.getDbKind();
for (Class<?> c : Arrays.asList(liquibase.diff.compare.DatabaseObjectComparator.class, liquibase.parser.NamespaceDetails.class, liquibase.precondition.Precondition.class, Database.class, liquibase.change.Change.class, liquibase.snapshot.SnapshotGenerator.class, liquibase.changelog.ChangeLogHistoryService.class, liquibase.datatype.LiquibaseDataType.class, liquibase.executor.Executor.class, SqlGenerator.class)) {
List<String> impls = new ArrayList<>();
services.put(c.getName(), impls);
Set<ClassInfo> classes = new HashSet<>();
if (c.isInterface()) {
classes.addAll(index.getAllKnownImplementors(DotName.createSimple(c.getName())));
} else {
classes.addAll(index.getAllKnownSubclasses(DotName.createSimple(c.getName())));
}
filterImplementations(c, dbKind, classes);
for (ClassInfo found : classes) {
if (Modifier.isAbstract(found.flags()) || Modifier.isInterface(found.flags()) || !found.hasNoArgsConstructor() || !Modifier.isPublic(found.flags())) {
continue;
}
AnnotationInstance annotationInstance = found.classAnnotation(liquibaseServiceName);
if (annotationInstance == null || !annotationInstance.value("skip").asBoolean()) {
impls.add(found.name().toString());
}
}
}
services.put(LockService.class.getName(), Arrays.asList(DummyLockService.class.getName()));
services.put(ChangeLogParser.class.getName(), Arrays.asList(XMLChangeLogSAXParser.class.getName()));
recorder.configureLiquibase(services);
}
use of io.quarkus.deployment.annotations.Record in project keycloak by keycloak.
the class KeycloakProcessor method configureProviders.
/**
* <p>Load the built-in provider factories during build time so we don't spend time looking up them at runtime. By loading
* providers at this stage we are also able to perform a more dynamic configuration based on the default providers.
*
* <p>User-defined providers are going to be loaded at startup</p>
*
* @param recorder
*/
@Consume(RuntimeConfigSetupCompleteBuildItem.class)
@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
KeycloakSessionFactoryPreInitBuildItem configureProviders(KeycloakRecorder recorder) {
Profile.setInstance(new QuarkusProfile());
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<>();
for (Entry<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> entry : loadFactories(preConfiguredProviders).entrySet()) {
checkProviders(entry.getKey(), entry.getValue(), defaultProviders);
for (Entry<Class<? extends Provider>, Map<String, ProviderFactory>> value : entry.getValue().entrySet()) {
for (ProviderFactory factory : value.getValue().values()) {
factories.computeIfAbsent(entry.getKey(), key -> new HashMap<>()).computeIfAbsent(entry.getKey().getProviderClass(), aClass -> new HashMap<>()).put(factory.getId(), factory.getClass());
}
}
}
recorder.configSessionFactory(factories, defaultProviders, preConfiguredProviders, Environment.isRebuild());
return new KeycloakSessionFactoryPreInitBuildItem();
}
use of io.quarkus.deployment.annotations.Record in project keycloak by keycloak.
the class CLusteringBuildSteps method configureInfinispan.
@Consume(KeycloakSessionFactoryPreInitBuildItem.class)
@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
void configureInfinispan(KeycloakRecorder recorder, BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItems, ShutdownContextBuildItem shutdownContext) {
String configFile = getConfigValue("kc.spi-connections-infinispan-quarkus-config-file").getValue();
if (configFile != null) {
Path configPath = Paths.get(configFile);
String path;
if (configPath.toFile().exists()) {
path = configPath.toFile().getAbsolutePath();
} else {
path = configPath.getFileName().toString();
}
InputStream url = FileLookupFactory.newInstance().lookupFile(path, KeycloakProcessor.class.getClassLoader());
if (url == null) {
throw new IllegalArgumentException("Could not load cluster configuration file at [" + configPath + "]");
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url))) {
String config = reader.lines().collect(Collectors.joining("\n"));
syntheticBeanBuildItems.produce(SyntheticBeanBuildItem.configure(CacheManagerFactory.class).scope(ApplicationScoped.class).unremovable().setRuntimeInit().runtimeValue(recorder.createCacheInitializer(config, shutdownContext)).done());
} catch (Exception cause) {
throw new RuntimeException("Failed to read clustering configuration from [" + url + "]", cause);
}
} else {
throw new IllegalArgumentException("Option 'configFile' needs to be specified");
}
}
Aggregations