
io.quarkus.vertx.http.deployment.devmode.ArcDevProcessor Maven / Gradle / Ivy
package io.quarkus.vertx.http.deployment.devmode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.quarkus.arc.InjectableBean;
import io.quarkus.arc.deployment.ArcConfig;
import io.quarkus.arc.deployment.ValidationPhaseBuildItem;
import io.quarkus.arc.deployment.ValidationPhaseBuildItem.ValidationErrorBuildItem;
import io.quarkus.arc.deployment.devconsole.ArcDevConsoleProcessor;
import io.quarkus.arc.processor.BeanInfo;
import io.quarkus.arc.processor.BuildExtension;
import io.quarkus.arc.processor.DecoratorInfo;
import io.quarkus.arc.processor.InterceptorInfo;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.runtime.devmode.ArcDevRecorder;
public class ArcDevProcessor {
@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep(onlyIf = IsDevelopment.class)
void registerRoutes(ArcConfig arcConfig, ArcDevRecorder recorder,
BuildProducer routes,
BuildProducer displayableEndpoints,
NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem,
ValidationPhaseBuildItem validationPhase,
BuildProducer errors) {
List removed = new ArrayList<>();
Collection removedInterceptors = validationPhase.getContext()
.get(BuildExtension.Key.REMOVED_INTERCEPTORS);
if (removedInterceptors != null) {
removed.addAll(removedInterceptors);
}
Collection removedDecorators = validationPhase.getContext().get(BuildExtension.Key.REMOVED_DECORATORS);
if (removedDecorators != null) {
removed.addAll(removedDecorators);
}
List removedInterceptorsDecorators;
if (removed.isEmpty()) {
removedInterceptorsDecorators = Collections.emptyList();
} else {
removedInterceptorsDecorators = new ArrayList<>();
for (BeanInfo r : removed) {
removedInterceptorsDecorators.add(new String[] { r.isInterceptor() ? InjectableBean.Kind.INTERCEPTOR.toString()
: InjectableBean.Kind.DECORATOR.toString(), r.getImplClazz().name().toString() });
}
}
String basePath = "arc";
String beansPath = basePath + "/beans";
String removedBeansPath = basePath + "/removed-beans";
String observersPath = basePath + "/observers";
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.route(basePath)
.displayOnNotFoundPage("CDI Overview")
.handler(recorder.createSummaryHandler(getConfigProperties(arcConfig),
nonApplicationRootPathBuildItem.getNonApplicationRootPath(),
removedInterceptorsDecorators.size()))
.build());
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.route(beansPath)
.displayOnNotFoundPage("Active CDI Beans")
.handler(recorder.createBeansHandler(ArcDevConsoleProcessor.BEAN_DEPENDENCIES)).build());
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.route(removedBeansPath)
.displayOnNotFoundPage("Removed CDI Beans")
.handler(recorder.createRemovedBeansHandler(removedInterceptorsDecorators)).build());
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.route(observersPath)
.displayOnNotFoundPage("Active CDI Observers")
.handler(recorder.createObserversHandler()).build());
}
// Note that we can't turn ArcConfig into BUILD_AND_RUN_TIME_FIXED because it's referencing IndexDependencyConfig
// And we can't split the config due to compatibility reasons
private Map getConfigProperties(ArcConfig arcConfig) {
Map props = new HashMap<>();
props.put("quarkus.arc.remove-unused-beans", arcConfig.removeUnusedBeans);
props.put("quarkus.arc.unremovable-types", arcConfig.unremovableTypes.map(Object::toString).orElse(""));
props.put("quarkus.arc.detect-unused-false-positives", "" + arcConfig.detectUnusedFalsePositives);
props.put("quarkus.arc.transform-unproxyable-classes", "" + arcConfig.transformUnproxyableClasses);
props.put("quarkus.arc.auto-inject-fields", "" + arcConfig.autoInjectFields);
props.put("quarkus.arc.auto-producer-methods", "" + arcConfig.autoProducerMethods);
props.put("quarkus.arc.selected-alternatives", "" + arcConfig.selectedAlternatives.map(Object::toString).orElse(""));
props.put("quarkus.arc.exclude-types", "" + arcConfig.excludeTypes.map(Object::toString).orElse(""));
return props;
}
// NOTE: we can't add this build step to the ArC extension as it would cause a cyclic dependency
@BuildStep
@Record(value = ExecutionTime.STATIC_INIT, optional = true)
DevConsoleRouteBuildItem eventsEndpoint(ArcDevRecorder recorder) {
return DevConsoleRouteBuildItem.builder().ga("io.quarkus", "quarkus-arc").path("events").method("POST")
.handler(recorder.events()).build();
}
// NOTE: we can't add this build step to the ArC extension as it would cause a cyclic dependency
@BuildStep
@Record(value = ExecutionTime.STATIC_INIT, optional = true)
DevConsoleRouteBuildItem invocationsEndpoint(ArcDevRecorder recorder) {
return DevConsoleRouteBuildItem.builder().ga("io.quarkus", "quarkus-arc").path("invocations").method("POST")
.handler(recorder.invocations()).build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy