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

Route annotations with the same values share a single handler instance #10782

Merged
merged 1 commit into from
Jul 16, 2020
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 @@ -4,36 +4,34 @@
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;

import io.vertx.core.buffer.Buffer;

/**
* Describe a request handler.
*/
public class HandlerDescriptor {
class HandlerDescriptor {

private final MethodInfo method;

public HandlerDescriptor(MethodInfo method) {
HandlerDescriptor(MethodInfo method) {
this.method = method;
}

public Type getReturnType() {
Type getReturnType() {
return method.returnType();
}

public boolean isReturningVoid() {
boolean isReturningVoid() {
return method.returnType().kind().equals(Type.Kind.VOID);
}

public boolean isReturningUni() {
boolean isReturningUni() {
return method.returnType().name().equals(DotNames.UNI);
}

public boolean isReturningMulti() {
boolean isReturningMulti() {
return method.returnType().name().equals(DotNames.MULTI);
}

public Type getContentType() {
Type getContentType() {
if (isReturningVoid()) {
return null;
}
Expand All @@ -46,23 +44,23 @@ public Type getContentType() {
return getReturnType();
}

public boolean isContentTypeString() {
boolean isContentTypeString() {
Type type = getContentType();
if (type == null) {
return false;
}
return type.name().equals(io.quarkus.arc.processor.DotNames.STRING);
}

public boolean isContentTypeBuffer() {
boolean isContentTypeBuffer() {
Type type = getContentType();
if (type == null) {
return false;
}
return type.name().equals(DotNames.BUFFER);
}

public boolean isContentTypeRxBuffer() {
boolean isContentTypeRxBuffer() {
Type type = getContentType();
if (type == null) {
return false;
Expand All @@ -71,7 +69,7 @@ public boolean isContentTypeRxBuffer() {
.equals(DotName.createSimple(io.vertx.reactivex.core.buffer.Buffer.class.getName()));
}

public boolean isContentTypeMutinyBuffer() {
boolean isContentTypeMutinyBuffer() {
Type type = getContentType();
if (type == null) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,6 @@ void addAdditionalRoutes(
Map<RouteMatcher, MethodInfo> matchers = new HashMap<>();

for (AnnotatedRouteHandlerBuildItem businessMethod : routeHandlerBusinessMethods) {
String handlerClass = generateHandler(new HandlerDescriptor(businessMethod.getMethod()),
businessMethod.getBean(), businessMethod.getMethod(), classOutput, transformedAnnotations);
reflectiveClasses.produce(new ReflectiveClassBuildItem(false, false, handlerClass));
Handler<RoutingContext> routingHandler = recorder.createHandler(handlerClass);

AnnotationInstance routeBaseAnnotation = businessMethod.getRouteBase();
String pathPrefix = null;
String[] baseProduces = null;
Expand All @@ -227,7 +222,22 @@ void addAdditionalRoutes(
}
}

// Route annotations with the same values share a single handler instance
// @Route string value -> handler
Map<String, Handler<RoutingContext>> routeHandlers = new HashMap<>();

for (AnnotationInstance route : businessMethod.getRoutes()) {
String routeString = route.toString(true);
Handler<RoutingContext> routeHandler = routeHandlers.get(routeString);
if (routeHandler == null) {
String handlerClass = generateHandler(new HandlerDescriptor(businessMethod.getMethod()),
businessMethod.getBean(), businessMethod.getMethod(), classOutput, transformedAnnotations,
routeString);
reflectiveClasses.produce(new ReflectiveClassBuildItem(false, false, handlerClass));
routeHandler = recorder.createHandler(handlerClass);
routeHandlers.put(routeString, routeHandler);
}

AnnotationValue regexValue = route.value(VALUE_REGEX);
AnnotationValue pathValue = route.value(VALUE_PATH);
AnnotationValue orderValue = route.valueWithDefault(index, VALUE_ORDER);
Expand Down Expand Up @@ -296,13 +306,14 @@ void addAdditionalRoutes(
throw new IllegalStateException("Unkown type " + typeString);
}
}
routeProducer.produce(new RouteBuildItem(routeFunction, routingHandler, handlerType));
routeProducer.produce(new RouteBuildItem(routeFunction, routeHandler, handlerType));
}
}

for (AnnotatedRouteFilterBuildItem filterMethod : routeFilterBusinessMethods) {
String handlerClass = generateHandler(new HandlerDescriptor(filterMethod.getMethod()),
filterMethod.getBean(), filterMethod.getMethod(), classOutput, transformedAnnotations);
filterMethod.getBean(), filterMethod.getMethod(), classOutput, transformedAnnotations,
filterMethod.getRouteFilter().toString(true));
reflectiveClasses.produce(new ReflectiveClassBuildItem(false, false, handlerClass));
Handler<RoutingContext> routingHandler = recorder.createHandler(handlerClass);
AnnotationValue priorityValue = filterMethod.getRouteFilter().value();
Expand Down Expand Up @@ -393,7 +404,7 @@ private void validateRouteMethod(BeanInfo bean, MethodInfo method, TransformedAn
}

private String generateHandler(HandlerDescriptor desc, BeanInfo bean, MethodInfo method, ClassOutput classOutput,
TransformedAnnotationsBuildItem transformedAnnotations) {
TransformedAnnotationsBuildItem transformedAnnotations, String hashSuffix) {

String baseName;
if (bean.getImplClazz().enclosingClass() != null) {
Expand All @@ -410,7 +421,7 @@ private String generateHandler(HandlerDescriptor desc, BeanInfo bean, MethodInfo
sigBuilder.append(i.name().toString());
}
String generatedName = targetPackage.replace('.', '/') + "/" + baseName + HANDLER_SUFFIX + "_" + method.name() + "_"
+ HashUtil.sha1(sigBuilder.toString());
+ HashUtil.sha1(sigBuilder.toString() + hashSuffix);

ClassCreator invokerCreator = ClassCreator.builder().classOutput(classOutput).className(generatedName)
.interfaces(RouteHandler.class).build();
Expand Down