diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcDevModeConfig.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcDevModeConfig.java index bfa6cd3d19ab6..0e175d57b02ba 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcDevModeConfig.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcDevModeConfig.java @@ -14,4 +14,10 @@ public class ArcDevModeConfig { @ConfigItem(defaultValue = "false") public boolean monitoringEnabled; + /** + * If set to true then the dependency graphs are generated and available in the Dev UI. + */ + @ConfigItem(defaultValue = "true") + public boolean generateDependencyGraphs; + } diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/ArcDevModeApiProcessor.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/ArcDevModeApiProcessor.java index 0c81148f2c0f7..894aa9827118a 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/ArcDevModeApiProcessor.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/ArcDevModeApiProcessor.java @@ -10,6 +10,7 @@ import java.util.Set; import java.util.stream.Collectors; +import io.quarkus.arc.deployment.ArcConfig; import io.quarkus.arc.deployment.CompletedApplicationClassPredicateBuildItem; import io.quarkus.arc.deployment.ValidationPhaseBuildItem; import io.quarkus.arc.processor.BeanDeploymentValidator; @@ -29,7 +30,7 @@ public class ArcDevModeApiProcessor { @BuildStep(onlyIf = IsDevelopment.class) - public void collectBeanInfo(ValidationPhaseBuildItem validationPhaseBuildItem, + public void collectBeanInfo(ArcConfig config, ValidationPhaseBuildItem validationPhaseBuildItem, CompletedApplicationClassPredicateBuildItem predicate, BuildProducer arcBeanInfoProducer) { BeanDeploymentValidator.ValidationContext validationContext = validationPhaseBuildItem.getContext(); @@ -63,35 +64,36 @@ public void collectBeanInfo(ValidationPhaseBuildItem validationPhaseBuildItem, } // Build dependency graphs - BeanResolver resolver = validationPhaseBuildItem.getBeanResolver(); - Collection beans = validationContext.get(BuildExtension.Key.BEANS); - Map> directDependents = new HashMap<>(); - List allInjectionPoints = new ArrayList<>(); - Map> declaringToProducers = validationContext.beans().producers() - .collect(Collectors.groupingBy(BeanInfo::getDeclaringBean)); - for (BeanInfo b : beans) { - if (b.hasInjectionPoint()) { - for (InjectionPointInfo ip : b.getAllInjectionPoints()) { - if (ip.getTargetBean().isPresent()) { - allInjectionPoints.add(ip); + Map> beanDependenciesMap = new HashMap<>(); + if (config.devMode.generateDependencyGraphs) { + BeanResolver resolver = validationPhaseBuildItem.getBeanResolver(); + Collection beans = validationContext.get(BuildExtension.Key.BEANS); + Map> directDependents = new HashMap<>(); + List allInjectionPoints = new ArrayList<>(); + Map> declaringToProducers = validationContext.beans().producers() + .collect(Collectors.groupingBy(BeanInfo::getDeclaringBean)); + for (BeanInfo b : beans) { + if (b.hasInjectionPoint()) { + for (InjectionPointInfo ip : b.getAllInjectionPoints()) { + if (ip.getTargetBean().isPresent()) { + allInjectionPoints.add(ip); + } } } } + for (BeanInfo bean : beans) { + DependencyGraph dependencyGraph = buildDependencyGraph(bean, validationContext, resolver, beanInfos, + allInjectionPoints, declaringToProducers, + directDependents); + beanInfos.addDependencyGraph(bean.getIdentifier(), dependencyGraph); + // id -> [dep1Id, dep2Id] + beanDependenciesMap.put(bean.getIdentifier(), + dependencyGraph.filterLinks(link -> link.type.equals("directDependency")).nodes.stream() + .map(DevBeanInfo::getId).filter(id -> !id.equals(bean.getIdentifier())) + .collect(Collectors.toList())); + } } - Map> beanDependenciesMap = new HashMap<>(); - - for (BeanInfo bean : beans) { - DependencyGraph dependencyGraph = buildDependencyGraph(bean, validationContext, resolver, beanInfos, - allInjectionPoints, declaringToProducers, - directDependents); - beanInfos.addDependencyGraph(bean.getIdentifier(), dependencyGraph); - // id -> [dep1Id, dep2Id] - beanDependenciesMap.put(bean.getIdentifier(), - dependencyGraph.filterLinks(link -> link.type.equals("directDependency")).nodes.stream() - .map(DevBeanInfo::getId).filter(id -> !id.equals(bean.getIdentifier())) - .collect(Collectors.toList())); - } // Set the global that could be used at runtime when generating the json payload for /q/arc/beans DevConsoleManager.setGlobal(DevBeanInfos.BEAN_DEPENDENCIES, beanDependenciesMap); diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DependencyGraph.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DependencyGraph.java index b5d706953a2f8..c7c0ae9f2cce2 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DependencyGraph.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DependencyGraph.java @@ -6,6 +6,8 @@ public class DependencyGraph { + static final DependencyGraph EMPTY = new DependencyGraph(Set.of(), Set.of()); + public final Set nodes; public final Set links; public final int maxLevel; diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DevBeanInfos.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DevBeanInfos.java index 3edf0324010e5..c01240a68f303 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DevBeanInfos.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/DevBeanInfos.java @@ -94,6 +94,9 @@ public DependencyGraph getDependencyGraph(String beanId) { if (maxLevel == null) { maxLevel = DEFAULT_MAX_DEPENDENCY_LEVEL; } + if (dependencyGraphs.isEmpty()) { + return DependencyGraph.EMPTY; + } DependencyGraph graph = dependencyGraphs.get(beanId); return graph.maxLevel <= maxLevel ? graph : graph.forLevel(maxLevel); }