Skip to content

Commit 5084ca4

Browse files
author
Alexander Furer
committed
fixes #117
1 parent 52f4ff7 commit 5084ca4

File tree

2 files changed

+74
-32
lines changed

2 files changed

+74
-32
lines changed

grpc-spring-boot-starter-demo/src/test/java/org/lognet/springboot/grpc/OrderedInterceptorsTest.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import org.lognet.springboot.grpc.demo.DemoApp;
1515
import org.springframework.boot.test.context.SpringBootTest;
1616
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
17+
import org.springframework.boot.test.context.TestConfiguration;
1718
import org.springframework.context.annotation.Bean;
18-
import org.springframework.context.annotation.Configuration;
1919
import org.springframework.core.Ordered;
2020
import org.springframework.core.annotation.Order;
2121
import org.springframework.test.context.junit4.SpringRunner;
@@ -55,12 +55,12 @@ protected GreeterGrpc.GreeterFutureStub beforeGreeting(GreeterGrpc.GreeterFuture
5555

5656
@Override
5757
protected void afterGreeting() {
58-
assertThat(calledInterceptors).containsExactly(1, 2, 3, 4,5,6, 10, 100);
58+
assertThat(calledInterceptors).containsExactly(1, 2, 3, 4,5,6, 7,10,10, 100);
5959
}
6060

6161

6262

63-
@Configuration
63+
@TestConfiguration
6464
public static class TheConfiguration {
6565

6666

@@ -155,6 +155,34 @@ public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
155155
}
156156
}
157157

158+
@Bean
159+
@GRpcGlobalInterceptor
160+
@Order(7)
161+
public ServerInterceptor mySeventhInterceptor(){
162+
return new ServerInterceptor() {
163+
@Override
164+
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
165+
calledInterceptors.add(7);
166+
return next.startCall(call, headers);
167+
168+
}
169+
};
170+
}
171+
172+
@Bean
173+
@GRpcGlobalInterceptor
174+
@Order
175+
public ServerInterceptor myOrderedMethodFactoryBeanInterceptor(){
176+
return new ServerInterceptor() {
177+
@Override
178+
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
179+
calledInterceptors.add(10);
180+
return next.startCall(call, headers);
181+
182+
}
183+
};
184+
}
185+
158186
@Bean
159187
@GRpcGlobalInterceptor
160188
public ServerInterceptor myInterceptor(){

grpc-spring-boot-starter/src/main/java/org/lognet/springboot/grpc/GRpcServerRunner.java

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package org.lognet.springboot.grpc;
22

3-
import io.grpc.*;
3+
import io.grpc.BindableService;
4+
import io.grpc.Server;
5+
import io.grpc.ServerBuilder;
6+
import io.grpc.ServerInterceptor;
7+
import io.grpc.ServerInterceptors;
8+
import io.grpc.ServerServiceDefinition;
49
import io.grpc.health.v1.HealthCheckResponse;
510
import io.grpc.protobuf.services.ProtoReflectionService;
611
import io.grpc.services.HealthStatusManager;
@@ -11,20 +16,22 @@
1116
import org.springframework.beans.factory.DisposableBean;
1217
import org.springframework.beans.factory.annotation.Autowired;
1318
import org.springframework.beans.factory.config.BeanDefinition;
19+
import org.springframework.beans.factory.support.RootBeanDefinition;
1420
import org.springframework.boot.CommandLineRunner;
1521
import org.springframework.context.support.AbstractApplicationContext;
1622
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
17-
import org.springframework.core.annotation.AnnotationUtils;
18-
import org.springframework.core.annotation.Order;
1923
import org.springframework.core.type.AnnotatedTypeMetadata;
2024

2125
import java.lang.annotation.Annotation;
22-
import java.lang.reflect.Method;
23-
import java.util.*;
24-
import java.util.concurrent.TimeUnit;
26+
import java.util.ArrayList;
27+
import java.util.Collection;
28+
import java.util.Comparator;
29+
import java.util.List;
30+
import java.util.Map;
31+
import java.util.Optional;
2532
import java.util.concurrent.CountDownLatch;
33+
import java.util.concurrent.TimeUnit;
2634
import java.util.function.Consumer;
27-
import java.util.function.Function;
2835
import java.util.stream.Collectors;
2936
import java.util.stream.Stream;
3037

@@ -90,7 +97,7 @@ public void run(String... args) throws Exception {
9097

9198
configurator.accept(serverBuilder);
9299
server = serverBuilder.build().start();
93-
applicationContext.publishEvent(new GRpcServerInitializedEvent(applicationContext,server));
100+
applicationContext.publishEvent(new GRpcServerInitializedEvent(applicationContext, server));
94101

95102
log.info("gRPC Server started, listening on port {}.", server.getPort());
96103
startDaemonAwaitThread();
@@ -103,8 +110,7 @@ private ServerServiceDefinition bindInterceptors(ServerServiceDefinition service
103110
.map(interceptorClass -> {
104111
try {
105112
return 0 < applicationContext.getBeanNamesForType(interceptorClass).length ?
106-
applicationContext.getBean(interceptorClass) :
107-
interceptorClass.newInstance();
113+
applicationContext.getBean(interceptorClass) : interceptorClass.newInstance();
108114
} catch (Exception e) {
109115
throw new BeanCreationException("Failed to create interceptor instance.", e);
110116
}
@@ -120,26 +126,34 @@ private ServerServiceDefinition bindInterceptors(ServerServiceDefinition service
120126
}
121127

122128
private Comparator<Object> serverInterceptorOrderComparator() {
123-
Function<Object,Boolean> isOrderAnnotated = obj->{
124-
Order ann = obj instanceof Method ? AnnotationUtils.findAnnotation((Method) obj, Order.class) :
125-
AnnotationUtils.findAnnotation(obj.getClass(), Order.class);
126-
return ann != null;
127-
};
128-
return AnnotationAwareOrderComparator.INSTANCE.thenComparing((o1, o2) -> {
129-
boolean p1 = isOrderAnnotated.apply(o1);
130-
boolean p2 = isOrderAnnotated.apply(o2);
131-
return p1 && !p2 ? -1 : p2 && !p1 ? 1 : 0;
132-
}).reversed();
129+
return new AnnotationAwareOrderComparator()
130+
.withSourceProvider(o -> {
131+
List<Object> sources = new ArrayList<>(2);
132+
final Optional<RootBeanDefinition> rootBeanDefinition = Stream.of(applicationContext.getBeanNamesForType(o.getClass()))
133+
.findFirst()
134+
.map(name -> applicationContext.getBeanFactory().getBeanDefinition(name))
135+
.filter(RootBeanDefinition.class::isInstance)
136+
.map(RootBeanDefinition.class::cast);
137+
138+
rootBeanDefinition.map(RootBeanDefinition::getResolvedFactoryMethod)
139+
.ifPresent(sources::add);
140+
141+
rootBeanDefinition.map(RootBeanDefinition::getTargetType)
142+
.filter(t -> t != o.getClass())
143+
.ifPresent(sources::add);
144+
145+
return sources.toArray();
146+
}).reversed();
133147
}
134148

135149
private void startDaemonAwaitThread() {
136-
Thread awaitThread = new Thread(()->{
137-
try {
138-
latch.await();
139-
} catch (InterruptedException e) {
140-
log.error("gRPC server awaiter interrupted.", e);
141-
}
142-
});
150+
Thread awaitThread = new Thread(() -> {
151+
try {
152+
latch.await();
153+
} catch (InterruptedException e) {
154+
log.error("gRPC server awaiter interrupted.", e);
155+
}
156+
});
143157
awaitThread.setName("grpc-server-awaiter");
144158
awaitThread.setDaemon(false);
145159
awaitThread.start();
@@ -148,9 +162,9 @@ private void startDaemonAwaitThread() {
148162
@Override
149163
public void destroy() throws Exception {
150164

151-
Optional.ofNullable(server).ifPresent(s->{
165+
Optional.ofNullable(server).ifPresent(s -> {
152166
log.info("Shutting down gRPC server ...");
153-
s.getServices().forEach(def->healthStatusManager.clearStatus(def.getServiceDescriptor().getName()));
167+
s.getServices().forEach(def -> healthStatusManager.clearStatus(def.getServiceDescriptor().getName()));
154168
s.shutdown();
155169
int shutdownGrace = gRpcServerProperties.getShutdownGrace();
156170
try {

0 commit comments

Comments
 (0)