|
17 | 17 | package org.springframework.grpc.autoconfigure.server; |
18 | 18 |
|
19 | 19 | import static org.assertj.core.api.Assertions.assertThat; |
| 20 | +import static org.junit.jupiter.params.provider.Arguments.arguments; |
20 | 21 | import static org.mockito.ArgumentMatchers.any; |
21 | 22 | import static org.mockito.ArgumentMatchers.anyInt; |
22 | 23 | import static org.mockito.Mockito.inOrder; |
|
26 | 27 | import java.time.Duration; |
27 | 28 | import java.util.List; |
28 | 29 | import java.util.concurrent.TimeUnit; |
| 30 | +import java.util.function.Function; |
| 31 | +import java.util.stream.Stream; |
29 | 32 |
|
30 | 33 | import org.assertj.core.api.InstanceOfAssertFactories; |
31 | 34 | import org.junit.jupiter.api.BeforeEach; |
32 | 35 | import org.junit.jupiter.api.Nested; |
33 | 36 | import org.junit.jupiter.api.Test; |
| 37 | +import org.junit.jupiter.params.ParameterizedTest; |
| 38 | +import org.junit.jupiter.params.provider.Arguments; |
| 39 | +import org.junit.jupiter.params.provider.MethodSource; |
34 | 40 | import org.mockito.InOrder; |
35 | 41 | import org.mockito.MockedStatic; |
36 | 42 | import org.mockito.Mockito; |
|
45 | 51 | import org.springframework.context.annotation.Bean; |
46 | 52 | import org.springframework.context.annotation.Configuration; |
47 | 53 | import org.springframework.core.annotation.Order; |
48 | | -import org.springframework.grpc.server.DefaultGrpcServerFactory; |
49 | 54 | import org.springframework.grpc.server.GrpcServerFactory; |
50 | 55 | import org.springframework.grpc.server.InProcessGrpcServerFactory; |
51 | 56 | import org.springframework.grpc.server.NettyGrpcServerFactory; |
@@ -83,13 +88,23 @@ void prepareForTest() { |
83 | 88 | when(service.bindService()).thenReturn(serviceDefinition); |
84 | 89 | } |
85 | 90 |
|
86 | | - private AbstractApplicationContextRunner<?, ?, ?> contextRunner() { |
| 91 | + private ApplicationContextRunner contextRunner() { |
87 | 92 | // NOTE: we use noop server lifecycle to avoid startup |
88 | 93 | ApplicationContextRunner runner = new ApplicationContextRunner(); |
89 | 94 | return contextRunner(runner); |
90 | 95 | } |
91 | 96 |
|
92 | | - private AbstractApplicationContextRunner<?, ?, ?> contextRunner(AbstractApplicationContextRunner<?, ?, ?> runner) { |
| 97 | + private ApplicationContextRunner contextRunner(ApplicationContextRunner runner) { |
| 98 | + return runner |
| 99 | + .withConfiguration(AutoConfigurations.of(GrpcServerAutoConfiguration.class, |
| 100 | + GrpcServerFactoryAutoConfiguration.class, SslAutoConfiguration.class)) |
| 101 | + .withBean("shadedNettyGrpcServerLifecycle", GrpcServerLifecycle.class, Mockito::mock) |
| 102 | + .withBean("nettyGrpcServerLifecycle", GrpcServerLifecycle.class, Mockito::mock) |
| 103 | + .withBean("inProcessGrpcServerLifecycle", GrpcServerLifecycle.class, Mockito::mock) |
| 104 | + .withBean(BindableService.class, () -> service); |
| 105 | + } |
| 106 | + |
| 107 | + private WebApplicationContextRunner webContextRunner(WebApplicationContextRunner runner) { |
93 | 108 | return runner |
94 | 109 | .withConfiguration(AutoConfigurations.of(GrpcServerAutoConfiguration.class, |
95 | 110 | GrpcServerFactoryAutoConfiguration.class, SslAutoConfiguration.class)) |
@@ -294,7 +309,7 @@ void shadedNettyServerFactoryAutoConfiguredAsExpected() { |
294 | 309 | @Test |
295 | 310 | void serverFactoryAutoConfiguredInWebAppWhenServletDisabled() { |
296 | 311 | serverFactoryAutoConfiguredAsExpected( |
297 | | - this.contextRunner(new WebApplicationContextRunner()) |
| 312 | + this.webContextRunner(new WebApplicationContextRunner()) |
298 | 313 | .withPropertyValues("spring.grpc.server.host=myhost", "spring.grpc.server.port=6160") |
299 | 314 | .withPropertyValues("spring.grpc.server.servlet.enabled=false"), |
300 | 315 | GrpcServerFactory.class, "myhost:6160", "shadedNettyGrpcServerLifecycle"); |
@@ -395,6 +410,74 @@ void nettyServerFactoryAutoConfiguredWithSsl() { |
395 | 410 | NettyGrpcServerFactory.class, "myhost:6160", "nettyGrpcServerLifecycle"); |
396 | 411 | } |
397 | 412 |
|
| 413 | + @Nested |
| 414 | + class WithAllFactoriesServiceFilterAutoConfig { |
| 415 | + |
| 416 | + static Stream<Arguments> serverFactoryProvider() { |
| 417 | + return Stream.of(arguments( |
| 418 | + (Function<ApplicationContextRunner, ApplicationContextRunner>) (contextRunner) -> contextRunner, |
| 419 | + ShadedNettyGrpcServerFactory.class), |
| 420 | + arguments( |
| 421 | + (Function<ApplicationContextRunner, ApplicationContextRunner>) ( |
| 422 | + contextRunner) -> contextRunner.withClassLoader(new FilteredClassLoader( |
| 423 | + io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder.class)), |
| 424 | + NettyGrpcServerFactory.class), |
| 425 | + arguments( |
| 426 | + (Function<ApplicationContextRunner, ApplicationContextRunner>) ( |
| 427 | + contextRunner) -> contextRunner |
| 428 | + .withPropertyValues("spring.grpc.server.inprocess.name=foo") |
| 429 | + .withClassLoader(new FilteredClassLoader(NettyServerBuilder.class, |
| 430 | + io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder.class)), |
| 431 | + InProcessGrpcServerFactory.class)); |
| 432 | + } |
| 433 | + |
| 434 | + @ParameterizedTest(name = "whenNoServiceFilterThenFactoryUsesNoFilter w/ factory {1}") |
| 435 | + @MethodSource("serverFactoryProvider") |
| 436 | + void whenNoServiceFilterThenFactoryUsesNoFilter( |
| 437 | + Function<ApplicationContextRunner, ApplicationContextRunner> serverFactoryContextCustomizer, |
| 438 | + Class<?> expectedServerFactoryType) { |
| 439 | + GrpcServerAutoConfigurationTests.this.contextRunner() |
| 440 | + .withPropertyValues("spring.grpc.server.port=0") |
| 441 | + .with(serverFactoryContextCustomizer) |
| 442 | + .run((context) -> assertThat(context).getBean(GrpcServerFactory.class) |
| 443 | + .isInstanceOf(expectedServerFactoryType) |
| 444 | + .extracting("serviceFilter") |
| 445 | + .isNull()); |
| 446 | + } |
| 447 | + |
| 448 | + @ParameterizedTest(name = "whenUniqueServiceFilterThenFactoryUsesFilter w/ factory {1}") |
| 449 | + @MethodSource("serverFactoryProvider") |
| 450 | + void whenUniqueServiceFilterThenFactoryUsesFilter( |
| 451 | + Function<ApplicationContextRunner, ApplicationContextRunner> serverFactoryContextCustomizer, |
| 452 | + Class<?> expectedServerFactoryType) { |
| 453 | + ServerServiceDefinitionFilter serviceFilter = mock(); |
| 454 | + GrpcServerAutoConfigurationTests.this.contextRunner() |
| 455 | + .withPropertyValues("spring.grpc.server.port=0") |
| 456 | + .withBean(ServerServiceDefinitionFilter.class, () -> serviceFilter) |
| 457 | + .with(serverFactoryContextCustomizer) |
| 458 | + .run((context) -> assertThat(context).getBean(GrpcServerFactory.class) |
| 459 | + .isInstanceOf(expectedServerFactoryType) |
| 460 | + .extracting("serviceFilter") |
| 461 | + .isSameAs(serviceFilter)); |
| 462 | + } |
| 463 | + |
| 464 | + @ParameterizedTest(name = "whenMultipleServiceFiltersThenThrowsException w/ factory {1}") |
| 465 | + @MethodSource("serverFactoryProvider") |
| 466 | + void whenMultipleServiceFiltersThenThrowsException( |
| 467 | + Function<ApplicationContextRunner, ApplicationContextRunner> serverFactoryContextCustomizer, |
| 468 | + Class<?> ignored) { |
| 469 | + GrpcServerAutoConfigurationTests.this.contextRunnerWithLifecyle() |
| 470 | + .withPropertyValues("spring.grpc.server.port=0") |
| 471 | + .withBean("filter1", ServerServiceDefinitionFilter.class, Mockito::mock) |
| 472 | + .withBean("filter2", ServerServiceDefinitionFilter.class, Mockito::mock) |
| 473 | + .with(serverFactoryContextCustomizer) |
| 474 | + .run((context) -> assertThat(context).hasFailed() |
| 475 | + .getFailure() |
| 476 | + .hasMessageContaining("expected single matching bean but found 2: filter1,filter2")); |
| 477 | + } |
| 478 | + |
| 479 | + } |
| 480 | + |
398 | 481 | @Nested |
399 | 482 | class WithGrpcServiceConfigurerAutoConfig { |
400 | 483 |
|
|
0 commit comments