Skip to content

Commit 2c9457d

Browse files
committed
Allow filtering of global server interceptors
This commit adds support for filtering the server-side global interceptors. Resolves #208 Signed-off-by: Chris Bono <[email protected]>
1 parent 94b9ef9 commit 2c9457d

File tree

11 files changed

+312
-72
lines changed

11 files changed

+312
-72
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2024-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.grpc.server;
18+
19+
import io.grpc.Server;
20+
import io.grpc.ServerServiceDefinition;
21+
22+
/**
23+
* Marker interface for {@link GrpcServerFactory} that is to be handled by the servlet
24+
* container.
25+
*
26+
* @author Chris Bono
27+
*/
28+
public class ServletGrpcServerFactory implements GrpcServerFactory {
29+
30+
/**
31+
* Default instance of marker interface.
32+
*/
33+
public static ServletGrpcServerFactory INSTANCE = new ServletGrpcServerFactory();
34+
35+
@Override
36+
public Server createServer() {
37+
throw new UnsupportedOperationException("Marker interface only");
38+
}
39+
40+
@Override
41+
public void addService(ServerServiceDefinition service) {
42+
throw new UnsupportedOperationException("Marker interface only");
43+
}
44+
45+
}

spring-grpc-core/src/main/java/org/springframework/grpc/server/service/DefaultGrpcServiceConfigurer.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import org.springframework.context.ApplicationContext;
2424
import org.springframework.grpc.internal.ApplicationContextBeanLookupUtils;
2525
import org.springframework.grpc.server.GlobalServerInterceptor;
26+
import org.springframework.grpc.server.GrpcServerFactory;
2627
import org.springframework.lang.Nullable;
28+
import org.springframework.util.Assert;
2729

2830
import io.grpc.BindableService;
2931
import io.grpc.ServerInterceptor;
@@ -42,8 +44,12 @@ public class DefaultGrpcServiceConfigurer implements GrpcServiceConfigurer, Init
4244

4345
private List<ServerInterceptor> globalInterceptors;
4446

45-
public DefaultGrpcServiceConfigurer(ApplicationContext applicationContext) {
47+
private ServerInterceptorFilter interceptorFilter;
48+
49+
public DefaultGrpcServiceConfigurer(ApplicationContext applicationContext,
50+
@Nullable ServerInterceptorFilter interceptorFilter) {
4651
this.applicationContext = applicationContext;
52+
this.interceptorFilter = interceptorFilter;
4753
}
4854

4955
@Override
@@ -52,8 +58,10 @@ public void afterPropertiesSet() {
5258
}
5359

5460
@Override
55-
public ServerServiceDefinition configure(ServerServiceDefinitionSpec serviceDefinitionSpec) {
56-
return bindInterceptors(serviceDefinitionSpec.service(), serviceDefinitionSpec.serviceInfo());
61+
public ServerServiceDefinition configure(ServerServiceDefinitionSpec serviceSpec, GrpcServerFactory serverFactory) {
62+
Assert.notNull(serviceSpec, () -> "serviceSpec must not be null");
63+
Assert.notNull(serverFactory, () -> "serverFactory must not be null");
64+
return bindInterceptors(serviceSpec.service(), serviceSpec.serviceInfo(), serverFactory);
5765
}
5866

5967
private List<ServerInterceptor> findGlobalInterceptors() {
@@ -62,13 +70,18 @@ private List<ServerInterceptor> findGlobalInterceptors() {
6270
}
6371

6472
private ServerServiceDefinition bindInterceptors(BindableService bindableService,
65-
@Nullable GrpcServiceInfo serviceInfo) {
73+
@Nullable GrpcServiceInfo serviceInfo, GrpcServerFactory serverFactory) {
6674
var serviceDef = bindableService.bindService();
75+
76+
// Add and filter global interceptors first
77+
List<ServerInterceptor> allInterceptors = new ArrayList<>(this.globalInterceptors);
78+
if (this.interceptorFilter != null) {
79+
allInterceptors
80+
.removeIf(interceptor -> !this.interceptorFilter.filter(interceptor, serviceDef, serverFactory));
81+
}
6782
if (serviceInfo == null) {
68-
return ServerInterceptors.interceptForward(serviceDef, this.globalInterceptors);
83+
return ServerInterceptors.interceptForward(serviceDef, allInterceptors);
6984
}
70-
// Add global interceptors first
71-
List<ServerInterceptor> allInterceptors = new ArrayList<>(this.globalInterceptors);
7285
// Add interceptors by type
7386
Arrays.stream(serviceInfo.interceptors())
7487
.forEachOrdered(

spring-grpc-core/src/main/java/org/springframework/grpc/server/service/GrpcServiceConfigurer.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.grpc.server.service;
1818

19+
import org.springframework.grpc.server.GrpcServerFactory;
20+
1921
import io.grpc.ServerServiceDefinition;
2022

2123
/**
@@ -29,12 +31,14 @@
2931
public interface GrpcServiceConfigurer {
3032

3133
/**
32-
* Configure and bind a gRPC service spec resulting in a service definition that can
34+
* Configure and bind a gRPC server spec resulting in a service definition that can
3335
* then be added to a gRPC server.
3436
* @param serviceSpec the spec containing the info about the service
35-
* @return bound and configured service definition that is ready to be added to the
37+
* @param serverFactory the factory that provides the server that the service will be
38+
* added to
39+
* @return bound and configured service definition that is ready to be added to a
3640
* server
3741
*/
38-
ServerServiceDefinition configure(ServerServiceDefinitionSpec serviceSpec);
42+
ServerServiceDefinition configure(ServerServiceDefinitionSpec serviceSpec, GrpcServerFactory serverFactory);
3943

4044
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.grpc.server.service;
17+
18+
import org.springframework.grpc.server.GrpcServerFactory;
19+
20+
import io.grpc.ServerInterceptor;
21+
import io.grpc.ServerServiceDefinition;
22+
23+
/**
24+
* Strategy to determine whether a global {@link ServerInterceptor server interceptor}
25+
* should be applied to {@link ServerServiceDefinition gRPC service}.
26+
*
27+
* @author Chris Bono
28+
*/
29+
@FunctionalInterface
30+
public interface ServerInterceptorFilter {
31+
32+
/**
33+
* Determine whether an interceptor should be applied to a service when the service is
34+
* running on a server provided by the given server factory.
35+
* @param interceptor the server interceptor under consideration.
36+
* @param service the service being added.
37+
* @param serverFactory the server factory in use.
38+
* @return {@code true} if the interceptor should be included; {@code false}
39+
* otherwise.
40+
*/
41+
boolean filter(ServerInterceptor interceptor, ServerServiceDefinition service, GrpcServerFactory serverFactory);
42+
43+
}

0 commit comments

Comments
 (0)