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

ArC bean resolution - handle qualifier default values correctly #20097

Merged
merged 2 commits into from
Sep 15, 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 @@ -36,10 +36,13 @@
import io.grpc.Channel;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanDiscoveryFinishedBuildItem;
import io.quarkus.arc.deployment.InjectionPointTransformerBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.arc.processor.Annotations;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.arc.processor.InjectionPointInfo;
import io.quarkus.arc.processor.InjectionPointsTransformer;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
Expand Down Expand Up @@ -277,6 +280,39 @@ public void validateInjectedServiceInterfaces(CombinedIndexBuildItem index,
}
}

@BuildStep
InjectionPointTransformerBuildItem transformInjectionPoints() {
return new InjectionPointTransformerBuildItem(new InjectionPointsTransformer() {

@Override
public void transform(TransformationContext ctx) {
// If annotated with @GrpcClient and no explicit value is used, i.e. @GrpcClient(),
// then we need to determine the service name from the annotated element and transform the injection point
AnnotationInstance clientAnnotation = Annotations.find(ctx.getQualifiers(), GrpcDotNames.GRPC_CLIENT);
if (clientAnnotation != null && clientAnnotation.value() == null) {
String clientName = null;
if (ctx.getTarget().kind() == Kind.FIELD) {
clientName = clientAnnotation.target().asField().name();
} else if (ctx.getTarget().kind() == Kind.METHOD_PARAMETER) {
MethodParameterInfo param = clientAnnotation.target().asMethodParameter();
// We don't need to check if parameter names are recorded - that's validated elsewhere
clientName = param.method().parameterName(param.position());
}
if (clientName != null) {
ctx.transform().remove(GrpcDotNames::isGrpcClient)
.add(GrpcDotNames.GRPC_CLIENT, AnnotationValue.createStringValue("value", clientName)).done();
}
}
}

@Override
public boolean appliesTo(Type requiredType) {
return true;
}

});
}

private DeploymentException invalidInjectionPoint(InjectionPointInfo injectionPoint) {
return new DeploymentException(
injectionPoint.getRequiredType() + " cannot be injected into " + injectionPoint.getTargetInfo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.function.BiFunction;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;

import io.grpc.BindableService;
Expand Down Expand Up @@ -60,4 +61,8 @@ public class GrpcDotNames {
static final MethodDescriptor GET_STUB_CONFIGURATOR = MethodDescriptor.ofMethod(GrpcClientConfigProvider.class,
"getStubConfigurator", BiFunction.class);

static boolean isGrpcClient(AnnotationInstance instance) {
return instance.name().equals(GRPC_CLIENT);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ static boolean hasQualifier(BeanDeployment beanDeployment, AnnotationInstance re
ClassInfo requiredClazz = beanDeployment.getQualifier(requiredQualifier.name());
List<AnnotationValue> values = new ArrayList<>();
Set<String> nonBindingFields = beanDeployment.getQualifierNonbindingMembers(requiredQualifier.name());
for (AnnotationValue val : requiredQualifier.values()) {
for (AnnotationValue val : requiredQualifier.valuesWithDefaults(beanDeployment.getBeanArchiveIndex())) {
if (!requiredClazz.method(val.name()).hasAnnotation(DotNames.NONBINDING)
&& !nonBindingFields.contains(val.name())) {
values.add(val);
Expand All @@ -695,7 +695,7 @@ static boolean hasQualifier(BeanDeployment beanDeployment, AnnotationInstance re
// Must have the same annotation member value for each member which is not annotated @Nonbinding
boolean matches = true;
for (AnnotationValue value : values) {
if (!value.equals(qualifier.value(value.name()))) {
if (!value.equals(qualifier.valueWithDefault(beanDeployment.getBeanArchiveIndex(), value.name()))) {
matches = false;
break;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkus.arc.test.qualifiers.defaultvalues;

public interface Animal {

int noOfLeg();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.arc.test.qualifiers.defaultvalues;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.TYPE })
public @interface AnimalQualifier {

String value() default "";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkus.arc.test.qualifiers.defaultvalues;

import javax.enterprise.context.Dependent;

@Dependent
@AnimalQualifier("cat")
public class Cat implements Animal {

@Override
public int noOfLeg() {
return 4;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkus.arc.test.qualifiers.defaultvalues;

import javax.enterprise.context.Dependent;

@Dependent
@AnimalQualifier
public class Owl implements Animal {

@Override
public int noOfLeg() {
return 2;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkus.arc.test.qualifiers.defaultvalues;

import static org.junit.jupiter.api.Assertions.assertEquals;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

public class QualifierDefaultValuesTest {

@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(Consumer.class, Animal.class, AnimalQualifier.class, Cat.class,
Owl.class);

@Test
public void testDefaultValues() {
Consumer consumer = Arc.container().instance(Consumer.class).get();
assertEquals(2, consumer.animal.noOfLeg());
}

@Dependent
public static class Consumer {

@Inject
@AnimalQualifier
Animal animal;

}

}