Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev UI - ArC - add interceptors page #18967

Merged
merged 1 commit into from
Jul 26, 2021
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 @@ -18,6 +18,7 @@
import io.quarkus.arc.processor.BeanDeploymentValidator;
import io.quarkus.arc.processor.BeanInfo;
import io.quarkus.arc.processor.BuildExtension;
import io.quarkus.arc.processor.InterceptorInfo;
import io.quarkus.arc.processor.ObserverInfo;
import io.quarkus.arc.runtime.ArcContainerSupplier;
import io.quarkus.arc.runtime.ArcRecorder;
Expand Down Expand Up @@ -92,14 +93,17 @@ public DevConsoleTemplateInfoBuildItem collectBeanInfo(ValidationPhaseBuildItem
CompletedApplicationClassPredicateBuildItem predicate) {
BeanDeploymentValidator.ValidationContext validationContext = validationPhaseBuildItem.getContext();
DevBeanInfos beanInfos = new DevBeanInfos();
for (BeanInfo beanInfo : validationContext.beans()) {
beanInfos.addBean(DevBeanInfo.from(beanInfo, predicate));
for (BeanInfo bean : validationContext.beans()) {
beanInfos.addBean(DevBeanInfo.from(bean, predicate));
}
for (BeanInfo beanInfo : validationContext.removedBeans()) {
beanInfos.addRemovedBean(DevBeanInfo.from(beanInfo, predicate));
for (BeanInfo bean : validationContext.removedBeans()) {
beanInfos.addRemovedBean(DevBeanInfo.from(bean, predicate));
}
for (ObserverInfo observerInfo : validationContext.get(BuildExtension.Key.OBSERVERS)) {
beanInfos.addObserver(DevObserverInfo.from(observerInfo, predicate));
for (ObserverInfo observer : validationContext.get(BuildExtension.Key.OBSERVERS)) {
beanInfos.addObserver(DevObserverInfo.from(observer, predicate));
}
for (InterceptorInfo interceptor : validationContext.get(BuildExtension.Key.INTERCEPTORS)) {
beanInfos.addInterceptor(DevInterceptorInfo.from(interceptor, predicate));
}
beanInfos.sort();
return new DevConsoleTemplateInfoBuildItem("devBeanInfos", beanInfos);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.quarkus.arc.deployment.devconsole;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.jboss.jandex.AnnotationInstance;
Expand All @@ -14,6 +16,7 @@
import io.quarkus.arc.deployment.CompletedApplicationClassPredicateBuildItem;
import io.quarkus.arc.processor.BeanInfo;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.arc.processor.InterceptorInfo;

public class DevBeanInfo implements Comparable<DevBeanInfo> {

Expand All @@ -29,6 +32,17 @@ public static DevBeanInfo from(BeanInfo bean, CompletedApplicationClassPredicate
Name scope = Name.from(bean.getScope().getDotName());
Name providerType = Name.from(bean.getProviderType());

List<String> interceptors;
List<InterceptorInfo> boundInterceptors = bean.getBoundInterceptors();
if (boundInterceptors.isEmpty()) {
interceptors = List.of();
} else {
interceptors = new ArrayList<>();
for (InterceptorInfo interceptor : boundInterceptors) {
interceptors.add(interceptor.getIdentifier());
}
}

if (bean.getTarget().isPresent()) {
AnnotationTarget target = bean.getTarget().get();
DevBeanKind kind;
Expand Down Expand Up @@ -56,15 +70,17 @@ public static DevBeanInfo from(BeanInfo bean, CompletedApplicationClassPredicate
} else {
throw new IllegalArgumentException("Invalid annotation target: " + target);
}
return new DevBeanInfo(kind, isApplicationBean, providerType, memberName, types, qualifiers, scope, declaringClass);
return new DevBeanInfo(kind, isApplicationBean, providerType, memberName, types, qualifiers, scope, declaringClass,
interceptors);
} else {
// Synthetic bean
return new DevBeanInfo(DevBeanKind.SYNTHETIC, false, providerType, null, types, qualifiers, scope, null);
return new DevBeanInfo(DevBeanKind.SYNTHETIC, false, providerType, null, types, qualifiers, scope, null,
interceptors);
}
}

public DevBeanInfo(DevBeanKind kind, boolean isApplicationBean, Name providerType, String memberName, Set<Name> types,
Set<Name> qualifiers, Name scope, Name declaringClass) {
Set<Name> qualifiers, Name scope, Name declaringClass, List<String> boundInterceptors) {
this.kind = kind;
this.isApplicationBean = isApplicationBean;
this.providerType = providerType;
Expand All @@ -73,6 +89,7 @@ public DevBeanInfo(DevBeanKind kind, boolean isApplicationBean, Name providerTyp
this.qualifiers = qualifiers;
this.scope = scope;
this.declaringClass = declaringClass;
this.interceptors = boundInterceptors;
}

private final DevBeanKind kind;
Expand All @@ -83,6 +100,7 @@ public DevBeanInfo(DevBeanKind kind, boolean isApplicationBean, Name providerTyp
private final Set<Name> qualifiers;
private final Name scope;
private final Name declaringClass;
private final List<String> interceptors;

public DevBeanKind getKind() {
return kind;
Expand Down Expand Up @@ -129,6 +147,10 @@ public Name getDeclaringClass() {
return declaringClass;
}

public List<String> getInterceptors() {
return interceptors;
}

@Override
public int compareTo(DevBeanInfo o) {
// Application beans should go first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ public class DevBeanInfos {
private final List<DevBeanInfo> beans;
private final List<DevBeanInfo> removedBeans;
private final List<DevObserverInfo> observers;
private final List<DevInterceptorInfo> interceptors;

public DevBeanInfos() {
beans = new ArrayList<>();
removedBeans = new ArrayList<>();
observers = new ArrayList<>();
interceptors = new ArrayList<>();
}

public List<DevBeanInfo> getRemovedBeans() {
Expand All @@ -28,6 +30,19 @@ public List<DevObserverInfo> getObservers() {
return observers;
}

public List<DevInterceptorInfo> getInterceptors() {
return interceptors;
}

public DevInterceptorInfo getInterceptor(String id) {
for (DevInterceptorInfo interceptor : interceptors) {
if (interceptor.getId().equals(id)) {
return interceptor;
}
}
return null;
}

void addBean(DevBeanInfo beanInfo) {
beans.add(beanInfo);
}
Expand All @@ -40,9 +55,14 @@ void addObserver(DevObserverInfo observer) {
observers.add(observer);
}

void addInterceptor(DevInterceptorInfo interceptor) {
interceptors.add(interceptor);
}

void sort() {
Collections.sort(beans);
Collections.sort(removedBeans);
Collections.sort(observers);
Collections.sort(interceptors);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package io.quarkus.arc.deployment.devconsole;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.enterprise.inject.spi.InterceptionType;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.deployment.CompletedApplicationClassPredicateBuildItem;
import io.quarkus.arc.processor.InterceptorInfo;

public class DevInterceptorInfo implements Comparable<DevInterceptorInfo> {

public static DevInterceptorInfo from(InterceptorInfo interceptor, CompletedApplicationClassPredicateBuildItem predicate) {
boolean isApplicationBean = predicate.test(interceptor.getBeanClass());
Set<Name> bindings = new HashSet<>();
for (AnnotationInstance binding : interceptor.getBindings()) {
bindings.add(Name.from(binding));
}
Map<InterceptionType, MethodInfo> intercepts = new HashMap<>();
if (interceptor.intercepts(InterceptionType.AROUND_INVOKE)) {
intercepts.put(InterceptionType.AROUND_INVOKE, interceptor.getAroundInvoke());
}
if (interceptor.intercepts(InterceptionType.AROUND_CONSTRUCT)) {
intercepts.put(InterceptionType.AROUND_CONSTRUCT, interceptor.getAroundInvoke());
}
if (interceptor.intercepts(InterceptionType.POST_CONSTRUCT)) {
intercepts.put(InterceptionType.POST_CONSTRUCT, interceptor.getPostConstruct());
}
if (interceptor.intercepts(InterceptionType.PRE_DESTROY)) {
intercepts.put(InterceptionType.PRE_DESTROY, interceptor.getPreDestroy());
}
return new DevInterceptorInfo(interceptor.getIdentifier(), Name.from(interceptor.getBeanClass()), bindings,
interceptor.getPriority(), intercepts,
isApplicationBean);
}

private final String id;
private final Name interceptorClass;
private final Set<Name> bindings;
private final int priority;
private final Map<InterceptionType, MethodInfo> intercepts;
private final boolean isApplicationBean;

DevInterceptorInfo(String id, Name interceptorClass, Set<Name> bindings, int priority,
Map<InterceptionType, MethodInfo> intercepts, boolean isApplicationBean) {
this.id = id;
this.interceptorClass = interceptorClass;
this.bindings = bindings;
this.priority = priority;
this.intercepts = intercepts;
this.isApplicationBean = isApplicationBean;
}

public String getId() {
return id;
}

public Name getInterceptorClass() {
return interceptorClass;
}

public Set<Name> getBindings() {
return bindings;
}

public int getPriority() {
return priority;
}

public Map<InterceptionType, MethodInfo> getIntercepts() {
return intercepts;
}

@Override
public int compareTo(DevInterceptorInfo o) {
// Application beans should go first
if (isApplicationBean == o.isApplicationBean) {
return interceptorClass.compareTo(o.interceptorClass);
}
return isApplicationBean ? -1 : 1;
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{#include main}
{#include main fluid=true}
{#style}
.annotation {
color: gray;
Expand Down Expand Up @@ -31,17 +31,23 @@
openInIDE($(this).text());
});
});

{/script}

{#title}Beans{/title}
{#body}
<div class="alert alert-primary alert-dismissible fade show" role="alert" data-timer="30000">
Beans are sorted by the bean class name in ascending order. However, application beans go first.
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Bean</th>
<th scope="col">Kind</th>
<th scope="col">Associated Interceptors</th>
</tr>
</thead>
<tbody>
Expand All @@ -54,6 +60,15 @@
<td>
{#bean-declaration bean/}
</td>
<td>
<ul>
{#for interceptorId in bean.interceptors}
{#set interceptor=info:devBeanInfos.getInterceptor(interceptorId)}
<li><span class="class-candidate">{interceptor.interceptorClass}</span> <span class="badge rounded-pill bg-info text-light larger-badge" title="Priority: {interceptor.priority}">{interceptor.priority}</span></li>
{/set}
{/for}
</ul>
</td>
{/for}
</tbody>
</table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@
<br>
<a href="{urlbase}/observers" class="badge badge-light">
<i class="fa fa-eye fa-fw"></i>
Observers <span class="badge badge-light">{info:arcContainer.observers.size}</span></a>
Observers <span class="badge badge-light">{info:devBeanInfos.observers.size}</span></a>
<br>
<a href="{urlbase}/interceptors" class="badge badge-light">
<i class="fa fa-traffic-light fa-fw"></i>
Interceptors <span class="badge badge-light">{info:devBeanInfos.interceptors.size}</span></a>
<br>
{#if config:property('quarkus.arc.dev-mode.monitoring-enabled') is "true"}
<a href="{urlbase}/events" class="badge badge-light">
<i class="far fa-eye"></i>
<i class="far fa-eye fa-fw"></i>
Fired Events</a>
<br>
<a href="{urlbase}/invocations" class="badge badge-light">
<i class="fas fa-project-diagram"></i>
<i class="fas fa-project-diagram fa-fw"></i>
Invocation Trees</a>
<br>
{/if}
<a href="{urlbase}/removed-beans" class="badge badge-light">
<i class="fa fa-trash-alt fa-fw"></i>
Removed Beans <span class="badge badge-light">{info:arcContainer.removedBeans.size}</span></a>
Removed Beans <span class="badge badge-light">{info:devBeanInfos.removedBeans.size}</span></a>
Loading