Skip to content

Commit

Permalink
Check for duplicate services - mutiny and plain; from quarkusio#44326
Browse files Browse the repository at this point in the history
  • Loading branch information
alesj committed Nov 15, 2024
1 parent 45fa5d3 commit 29169fa
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ void discoverBindableServices(BuildProducer<BindableServiceBuildItem> bindables,
IndexView index = combinedIndexBuildItem.getIndex();
Collection<ClassInfo> bindableServices = index.getAllKnownImplementors(GrpcDotNames.BINDABLE_SERVICE);

Map<String, Set<String>> implBase = new HashMap<>();

for (ClassInfo service : bindableServices) {
if (service.interfaceNames().contains(GrpcDotNames.MUTINY_BEAN)) {
// Ignore the generated beans
Expand All @@ -235,6 +237,9 @@ void discoverBindableServices(BuildProducer<BindableServiceBuildItem> bindables,
if (Modifier.isAbstract(service.flags())) {
continue;
}

fillBaseImpls(index, implBase, service);

BindableServiceBuildItem item = new BindableServiceBuildItem(service.name());
Set<String> blockingMethods = gatherBlockingOrVirtualMethodNames(service, index, false);
Set<String> virtualMethods = gatherBlockingOrVirtualMethodNames(service, index, true);
Expand All @@ -248,6 +253,40 @@ void discoverBindableServices(BuildProducer<BindableServiceBuildItem> bindables,
}
}

private static void fillBaseImpls(IndexView index, Map<String, Set<String>> implBase, ClassInfo serviceClass) {
AnnotationInstance grpcAnnotation = serviceClass.annotation(GrpcDotNames.GRPC_SERVICE);
if (grpcAnnotation == null) {
return;
}

// mutiny vs plain
// org.acme.example.MutinyGreeterGrpc$GreeterImplBase
// org.acme.example.GreeterGrpc$GreeterImplBase

DotName biClass = findImplBase(serviceClass, index);
String[] split = biClass.toString().split("\\$"); // find inner class
String serviceNameIB = split[1].replace("ImplBase", "");
String prefix = split[0].startsWith("Mutiny") ? "" : "."; // do we have some package
String serviceNameGrpc = split[0].replace(prefix + "Mutiny" + serviceNameIB + "Grpc", prefix + serviceNameIB + "Grpc");

Set<String> existing = implBase.compute(serviceNameIB, (k, v) -> v == null ? new HashSet<>() : v);
if (!existing.add(serviceNameGrpc)) {
throw new IllegalArgumentException("Duplicate service impl: " + existing);
}
}

private static DotName findImplBase(ClassInfo classInfo, IndexView index) {
if (classInfo == null) {
throw new IllegalArgumentException("No ImplBase found");
}
DotName name = classInfo.name();
if (name.toString().endsWith("ImplBase")) {
return name;
}
Type superClazz = index.getClassByName(name).superClassType();
return findImplBase(superClazz != null ? index.getClassByName(superClazz.name()) : null, index);
}

/**
* Generate list of {@link ClassInfo} with {@code service} as the first element and the class implementing
* {@code io.grpc.BindableService} (for example via the protobuf generated {@code *ImplBase}) as the last one.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.quarkus.grpc.server;

Check failure on line 1 in extensions/grpc/deployment/src/test/java/io/quarkus/grpc/server/DuplicateServiceTest.java

View workflow job for this annotation

GitHub Actions / Build summary for 29169fa1c168addacb3da20433270057773bfbc4

JVM Tests - JDK 17

org.opentest4j.AssertionFailedError: The build was expected to fail at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:693) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Raw output
org.opentest4j.AssertionFailedError: The build was expected to fail
	at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:693)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Check failure on line 1 in extensions/grpc/deployment/src/test/java/io/quarkus/grpc/server/DuplicateServiceTest.java

View workflow job for this annotation

GitHub Actions / Build summary for 29169fa1c168addacb3da20433270057773bfbc4

JVM Tests - JDK 17 Windows

org.opentest4j.AssertionFailedError: The build was expected to fail at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:693) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Raw output
org.opentest4j.AssertionFailedError: The build was expected to fail
	at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:693)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Check failure on line 1 in extensions/grpc/deployment/src/test/java/io/quarkus/grpc/server/DuplicateServiceTest.java

View workflow job for this annotation

GitHub Actions / Build summary for 29169fa1c168addacb3da20433270057773bfbc4

JVM Tests - JDK 21

org.opentest4j.AssertionFailedError: The build was expected to fail at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:693) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Raw output
org.opentest4j.AssertionFailedError: The build was expected to fail
	at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:693)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

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

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.google.protobuf.EmptyProto;

import io.grpc.testing.integration.Messages;
import io.quarkus.grpc.server.services.BlockingMutinyTestService;
import io.quarkus.grpc.server.services.BlockingTestService;
import io.quarkus.test.QuarkusUnitTest;

public class DuplicateServiceTest {

@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addPackage(EmptyProto.class.getPackage())
.addPackage(Messages.SimpleRequest.class.getPackage())
.addClasses(BlockingTestService.class,
BlockingMutinyTestService.class))
.assertException(t -> {
System.out.println("t = " + t);
});

@Test
void testDuplicateService() {
fail("Should not be called");
}

}

0 comments on commit 29169fa

Please sign in to comment.