17
17
package org .springframework .boot .web .embedded .netty ;
18
18
19
19
import java .net .ConnectException ;
20
+ import java .net .SocketAddress ;
20
21
import java .time .Duration ;
21
22
import java .util .Arrays ;
22
23
24
+ import io .netty .channel .Channel ;
23
25
import org .awaitility .Awaitility ;
24
26
import org .junit .jupiter .api .Test ;
25
27
import org .mockito .InOrder ;
28
+ import reactor .core .CoreSubscriber ;
29
+ import reactor .core .Disposable ;
26
30
import reactor .core .publisher .Mono ;
31
+ import reactor .netty .DisposableChannel ;
32
+ import reactor .netty .DisposableServer ;
27
33
import reactor .netty .http .server .HttpServer ;
28
34
import reactor .test .StepVerifier ;
29
35
34
40
import org .springframework .boot .web .server .Ssl ;
35
41
import org .springframework .http .MediaType ;
36
42
import org .springframework .http .client .reactive .ReactorClientHttpConnector ;
43
+ import org .springframework .http .server .reactive .ReactorHttpHandlerAdapter ;
37
44
import org .springframework .web .reactive .function .BodyInserters ;
38
45
import org .springframework .web .reactive .function .client .WebClient ;
39
46
52
59
*/
53
60
class NettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactoryTests {
54
61
55
- @ Override
56
- protected NettyReactiveWebServerFactory getFactory () {
57
- return new NettyReactiveWebServerFactory (0 );
58
- }
59
-
60
62
@ Test
61
63
void exceptionIsThrownWhenPortIsAlreadyInUse () {
62
64
AbstractReactiveWebServerFactory factory = getFactory ();
@@ -68,6 +70,14 @@ void exceptionIsThrownWhenPortIsAlreadyInUse() {
68
70
.satisfies (this ::portMatchesRequirement ).withCauseInstanceOf (Throwable .class );
69
71
}
70
72
73
+ @ Test
74
+ void getPortWhenDisposableServerPortOperationIsUnsupportedReturnsMinusOne () {
75
+ NettyReactiveWebServerFactory factory = new NoPortNettyReactiveWebServerFactory (0 );
76
+ this .webServer = factory .getWebServer (new EchoHandler ());
77
+ this .webServer .start ();
78
+ assertThat (this .webServer .getPort ()).isEqualTo (-1 );
79
+ }
80
+
71
81
private void portMatchesRequirement (PortInUseException exception ) {
72
82
assertThat (exception .getPort ()).isEqualTo (this .webServer .getPort ());
73
83
}
@@ -143,4 +153,102 @@ protected Mono<String> testSslWithAlias(String alias) {
143
153
.retrieve ().bodyToMono (String .class );
144
154
}
145
155
156
+ @ Override
157
+ protected NettyReactiveWebServerFactory getFactory () {
158
+ return new NettyReactiveWebServerFactory (0 );
159
+ }
160
+
161
+ static class NoPortNettyReactiveWebServerFactory extends NettyReactiveWebServerFactory {
162
+
163
+ NoPortNettyReactiveWebServerFactory (int port ) {
164
+ super (port );
165
+ }
166
+
167
+ @ Override
168
+ NettyWebServer createNettyWebServer (HttpServer httpServer , ReactorHttpHandlerAdapter handlerAdapter ,
169
+ Duration lifecycleTimeout , Shutdown shutdown ) {
170
+ return new NoPortNettyWebServer (httpServer , handlerAdapter , lifecycleTimeout , shutdown );
171
+ }
172
+
173
+ }
174
+
175
+ static class NoPortNettyWebServer extends NettyWebServer {
176
+
177
+ NoPortNettyWebServer (HttpServer httpServer , ReactorHttpHandlerAdapter handlerAdapter , Duration lifecycleTimeout ,
178
+ Shutdown shutdown ) {
179
+ super (httpServer , handlerAdapter , lifecycleTimeout , shutdown );
180
+ }
181
+
182
+ @ Override
183
+ DisposableServer startHttpServer () {
184
+ return new NoPortDisposableServer (super .startHttpServer ());
185
+ }
186
+
187
+ }
188
+
189
+ static class NoPortDisposableServer implements DisposableServer {
190
+
191
+ private final DisposableServer delegate ;
192
+
193
+ NoPortDisposableServer (DisposableServer delegate ) {
194
+ this .delegate = delegate ;
195
+ }
196
+
197
+ @ Override
198
+ public SocketAddress address () {
199
+ return this .delegate .address ();
200
+ }
201
+
202
+ @ Override
203
+ public String host () {
204
+ return this .delegate .host ();
205
+ }
206
+
207
+ @ Override
208
+ public String path () {
209
+ return this .delegate .path ();
210
+ }
211
+
212
+ @ Override
213
+ public Channel channel () {
214
+ return this .delegate .channel ();
215
+ }
216
+
217
+ @ Override
218
+ public void dispose () {
219
+ this .delegate .dispose ();
220
+ }
221
+
222
+ @ Override
223
+ public void disposeNow () {
224
+ this .delegate .disposeNow ();
225
+ }
226
+
227
+ @ Override
228
+ public void disposeNow (Duration timeout ) {
229
+ this .delegate .disposeNow (timeout );
230
+ }
231
+
232
+ @ Override
233
+ public CoreSubscriber <Void > disposeSubscriber () {
234
+ return this .delegate .disposeSubscriber ();
235
+ }
236
+
237
+ @ Override
238
+ public boolean isDisposed () {
239
+ return this .delegate .isDisposed ();
240
+ }
241
+
242
+ @ Override
243
+ public Mono <Void > onDispose () {
244
+ return this .delegate .onDispose ();
245
+ }
246
+
247
+ @ Override
248
+ public DisposableChannel onDispose (Disposable onDispose ) {
249
+ return this .delegate .onDispose (onDispose );
250
+ }
251
+
252
+ }
253
+
146
254
}
0 commit comments