Skip to content

Commit 2aa3363

Browse files
committed
ClientRSocketFactoryConfigurer refactoring
1 parent 027fd78 commit 2aa3363

File tree

6 files changed

+65
-100
lines changed

6 files changed

+65
-100
lines changed

spring-messaging/src/main/java/org/springframework/messaging/rsocket/ClientRSocketFactoryConfigurer.java

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818
import io.rsocket.RSocketFactory;
1919

2020
/**
21-
* Strategy to apply some configuration to a
22-
* {@link io.rsocket.RSocketFactory.ClientRSocketFactory ClientRSocketFactory}.
23-
* It is given to {@link RSocketRequester.Builder} to initialize the
24-
* {@code RSocketFactory} that's used to connect.
21+
* Strategy to apply configuration to a client side {@code RSocketFactory}.
22+
* that's being prepared by {@link RSocketRequester.Builder} to connect
23+
* to a server.
2524
*
2625
* @author Rossen Stoyanchev
2726
* @since 5.2
@@ -30,17 +29,7 @@
3029
public interface ClientRSocketFactoryConfigurer {
3130

3231
/**
33-
* This method is invoked by {@link RSocketRequester.Builder} immediately
34-
* before the call to {@link #configure}, and can be used by implementations
35-
* of this interface that need access to the configured
36-
* {@code RSocketStrategies}.
37-
*/
38-
default void configureWithStrategies(RSocketStrategies strategies) {
39-
}
40-
41-
/**
42-
* Configure the given {@code ClientRSocketFactory}.
43-
* @param rsocketFactory the factory to configure
32+
* Apply configuration to the given {@code ClientRSocketFactory}.
4433
*/
4534
void configure(RSocketFactory.ClientRSocketFactory rsocketFactory);
4635

spring-messaging/src/main/java/org/springframework/messaging/rsocket/DefaultRSocketRequesterBuilder.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ final class DefaultRSocketRequesterBuilder implements RSocketRequester.Builder {
5555

5656
private List<Consumer<RSocketStrategies.Builder>> strategiesConfigurers = new ArrayList<>();
5757

58-
private List<ClientRSocketFactoryConfigurer> rsocketFactoryConfigurers = new ArrayList<>();
58+
private List<ClientRSocketFactoryConfigurer> rsocketConfigurers = new ArrayList<>();
5959

6060

6161
@Override
@@ -85,7 +85,7 @@ public RSocketRequester.Builder rsocketStrategies(Consumer<RSocketStrategies.Bui
8585

8686
@Override
8787
public RSocketRequester.Builder rsocketFactory(ClientRSocketFactoryConfigurer configurer) {
88-
this.rsocketFactoryConfigurers.add(configurer);
88+
this.rsocketConfigurers.add(configurer);
8989
return this;
9090
}
9191

@@ -118,10 +118,7 @@ private Mono<RSocketRequester> doConnect(ClientTransport transport) {
118118
rsocketFactory.frameDecoder(PayloadDecoder.ZERO_COPY);
119119
}
120120

121-
this.rsocketFactoryConfigurers.forEach(configurer -> {
122-
configurer.configureWithStrategies(rsocketStrategies);
123-
configurer.configure(rsocketFactory);
124-
});
121+
this.rsocketConfigurers.forEach(configurer -> configurer.configure(rsocketFactory));
125122

126123
return rsocketFactory.transport(transport)
127124
.start()

spring-messaging/src/main/java/org/springframework/messaging/rsocket/RSocketRequester.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,12 @@ interface Builder {
164164

165165
/**
166166
* Callback to configure the {@code ClientRSocketFactory} directly.
167-
* <p>See static factory method
168-
* {@link RSocketMessageHandler#clientResponder(Object...)} for
169-
* configuring a client side responder with annotated methods.
170-
* <p><strong>Note:</strong> Do not set {@link #dataMimeType(MimeType)}
171-
* and {@link #metadataMimeType(MimeType)} directly on the
172-
* {@code ClientRSocketFactory}. Use the shortcuts on this builder
173-
* instead since the created {@code RSocketRequester} needs to be aware
174-
* of those settings.
175-
* @see RSocketMessageHandler#clientResponder(Object...)
167+
* <p>Do not set {@link #dataMimeType(MimeType)} and
168+
* {@link #metadataMimeType(MimeType)} directly on the
169+
* {@code ClientRSocketFactory}. Use methods on this builder instead
170+
* so the {@code RSocketRequester} will have access to them.
171+
* <p>For configuring client side responding, see
172+
* {@link RSocketMessageHandler#clientResponder(RSocketStrategies, Object...)}.
176173
*/
177174
RSocketRequester.Builder rsocketFactory(ClientRSocketFactoryConfigurer configurer);
178175

spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketMessageHandler.java

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
import io.rsocket.ConnectionSetupPayload;
2626
import io.rsocket.RSocket;
27-
import io.rsocket.RSocketFactory;
2827
import io.rsocket.SocketAcceptor;
2928
import io.rsocket.frame.FrameType;
3029
import reactor.core.publisher.Mono;
@@ -344,18 +343,15 @@ public SocketAcceptor serverResponder() {
344343
}
345344

346345
/**
347-
* Return an adapter for a client side
348-
* {@link io.rsocket.RSocketFactory.ClientRSocketFactory#acceptor(BiFunction)
349-
* acceptor} that delegate to this {@link RSocketMessageHandler} for
350-
* handling.
351-
* <p>The initial {@link ConnectionSetupPayload} can be processed with a
352-
* {@link ConnectMapping @ConnectionMapping} method but, unlike the
353-
* server side, such a method is merely a callback and cannot prevent the
354-
* connection unless the method throws an error immediately. Such a method
355-
* can also start requests to the server but must do so decoupled from
356-
* handling and from the current thread.
357-
* <p>Subsequent stream requests can be handled with
358-
* {@link MessageMapping MessageMapping} methods.
346+
* Return an adapter for a client side responder that can be used to set
347+
* {@link io.rsocket.RSocketFactory.ClientRSocketFactory#acceptor(Function)}.
348+
* The responder delegates requests to this {@code RSocketMessageHandler}
349+
* for handling via {@code @MessageMapping} methods.
350+
* <p>The initial {@link ConnectionSetupPayload} can be accessed through a
351+
* {@link ConnectMapping @ConnectionMapping} method, but such a method is
352+
* only a callback just before the connection is made and cannot "accept"
353+
* or prevent the connection. Such a method can also start requests to the
354+
* server but must do so decoupled from handling and the current thread.
359355
*/
360356
public BiFunction<ConnectionSetupPayload, RSocket, RSocket> clientResponder() {
361357
return (setupPayload, sendingRSocket) -> {
@@ -375,17 +371,13 @@ private MessagingRSocket createResponder(ConnectionSetupPayload setupPayload, RS
375371
MimeType metaMimeType = StringUtils.hasText(s) ? MimeTypeUtils.parseMimeType(s) : this.defaultMetadataMimeType;
376372
Assert.notNull(metaMimeType, "No `metadataMimeType` in ConnectionSetupPayload and no default value");
377373

378-
RSocketStrategies strategies = getRSocketStrategies();
379-
RSocketRequester requester = RSocketRequester.wrap(rsocket, dataMimeType, metaMimeType, strategies);
380-
381-
Assert.state(this.metadataExtractor != null,
382-
() -> "No MetadataExtractor. Was afterPropertiesSet not called?");
374+
RSocketRequester requester = RSocketRequester.wrap(
375+
rsocket, dataMimeType, metaMimeType, this.strategies);
383376

384-
Assert.state(getRouteMatcher() != null,
385-
() -> "No RouteMatcher. Was afterPropertiesSet not called?");
377+
Assert.state(getRouteMatcher() != null, () -> "No RouteMatcher. Was afterPropertiesSet not called?");
386378

387-
return new MessagingRSocket(dataMimeType, metaMimeType, this.metadataExtractor, requester,
388-
this, getRouteMatcher(), strategies);
379+
return new MessagingRSocket(dataMimeType, metaMimeType, this.metadataExtractor,
380+
requester, this, getRouteMatcher(), this.strategies);
389381
}
390382

391383
private boolean isDataMimeTypeSupported(MimeType dataMimeType) {
@@ -399,39 +391,39 @@ private boolean isDataMimeTypeSupported(MimeType dataMimeType) {
399391
return false;
400392
}
401393

402-
public static ClientRSocketFactoryConfigurer clientResponder(Object... handlers) {
403-
return new ResponderConfigurer(handlers);
404-
}
405-
406-
407-
private static final class ResponderConfigurer implements ClientRSocketFactoryConfigurer {
408-
409-
private final List<Object> handlers = new ArrayList<>();
410-
411-
@Nullable
412-
private RSocketStrategies strategies;
413-
414-
415-
private ResponderConfigurer(Object... handlers) {
416-
Assert.notEmpty(handlers, "No handlers");
417-
for (Object obj : handlers) {
418-
this.handlers.add(obj instanceof Class ? BeanUtils.instantiateClass((Class<?>) obj) : obj);
419-
}
420-
}
394+
/**
395+
* Static factory method for a configurer of a client side responder with
396+
* annotated handler methods. This is intended to be passed into
397+
* {@link RSocketRequester.Builder#rsocketFactory(ClientRSocketFactoryConfigurer)}.
398+
* <p>In effect a shortcut to create and initialize
399+
* {@code RSocketMessageHandler} with the given strategies and handlers,
400+
* and use {@link #clientResponder()} to obtain the responder.
401+
* For more advanced scenarios, e.g. discovering handlers through a custom
402+
* stereotype annotation, consider declaring {@code RSocketMessageHandler}
403+
* as a bean, and then obtain the responder from it.
404+
* @param strategies the strategies to set on the created
405+
* {@code RSocketMessageHandler}
406+
* @param candidateHandlers a list of Objects and/or Classes with annotated
407+
* handler methods; used to call {@link #setHandlers(List)} with
408+
* on the created {@code RSocketMessageHandler}
409+
* @return a configurer that may be passed into
410+
* {@link RSocketRequester.Builder#rsocketFactory(ClientRSocketFactoryConfigurer)}
411+
*/
412+
public static ClientRSocketFactoryConfigurer clientResponder(
413+
RSocketStrategies strategies, Object... candidateHandlers) {
421414

422-
@Override
423-
public void configureWithStrategies(RSocketStrategies strategies) {
424-
this.strategies = strategies;
415+
Assert.notEmpty(candidateHandlers, "No handlers");
416+
List<Object> handlers = new ArrayList<>(candidateHandlers.length);
417+
for (Object obj : candidateHandlers) {
418+
handlers.add(obj instanceof Class ? BeanUtils.instantiateClass((Class<?>) obj) : obj);
425419
}
426420

427-
@Override
428-
public void configure(RSocketFactory.ClientRSocketFactory factory) {
421+
return rsocketFactory -> {
429422
RSocketMessageHandler handler = new RSocketMessageHandler();
430-
handler.setHandlers(this.handlers);
431-
handler.setRSocketStrategies(this.strategies);
423+
handler.setHandlers(handlers);
424+
handler.setRSocketStrategies(strategies);
432425
handler.afterPropertiesSet();
433-
factory.acceptor(handler.clientResponder());
434-
}
426+
rsocketFactory.acceptor(handler.clientResponder());
427+
};
435428
}
436-
437429
}

spring-messaging/src/test/java/org/springframework/messaging/rsocket/DefaultRSocketRequesterBuilderTests.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ public void shouldApplyCustomizations() {
9999

100100
verify(this.transport).connect(anyInt());
101101
verify(rsocketStrategiesConfigurer).accept(any(RSocketStrategies.Builder.class));
102-
assertThat(this.rsocketFactoryConfigurer.rsocketStrategies()).isNotNull();
103102
assertThat(this.rsocketFactoryConfigurer.rsocketFactory()).isNotNull();
104103
}
105104

@@ -194,25 +193,14 @@ public void dispose() {
194193

195194
static class TestRSocketFactoryConfigurer implements ClientRSocketFactoryConfigurer {
196195

197-
private RSocketStrategies strategies;
198-
199196
private RSocketFactory.ClientRSocketFactory rsocketFactory;
200197

201198

202-
public RSocketStrategies rsocketStrategies() {
203-
return this.strategies;
204-
}
205-
206-
public RSocketFactory.ClientRSocketFactory rsocketFactory() {
199+
RSocketFactory.ClientRSocketFactory rsocketFactory() {
207200
return this.rsocketFactory;
208201
}
209202

210203

211-
@Override
212-
public void configureWithStrategies(RSocketStrategies strategies) {
213-
this.strategies = strategies;
214-
}
215-
216204
@Override
217205
public void configure(RSocketFactory.ClientRSocketFactory rsocketFactory) {
218206
this.rsocketFactory = rsocketFactory;

spring-messaging/src/test/java/org/springframework/messaging/rsocket/RSocketServerToClientIntegrationTests.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,17 @@ private static void connectAndRunTest(String connectionRoute) {
106106
ServerController serverController = context.getBean(ServerController.class);
107107
serverController.reset();
108108

109+
RSocketStrategies strategies = context.getBean(RSocketStrategies.class);
110+
ClientRSocketFactoryConfigurer clientResponderConfigurer =
111+
RSocketMessageHandler.clientResponder(strategies, new ClientHandler());
112+
109113
RSocketRequester requester = null;
110114
try {
111115
requester = RSocketRequester.builder()
112-
.rsocketFactory(factory -> {
113-
factory.metadataMimeType("text/plain");
114-
factory.setupPayload(ByteBufPayload.create("", connectionRoute));
115-
})
116-
.rsocketFactory(RSocketMessageHandler.clientResponder(new ClientHandler()))
117-
.rsocketStrategies(context.getBean(RSocketStrategies.class))
116+
.metadataMimeType(MimeTypeUtils.TEXT_PLAIN)
117+
.rsocketStrategies(strategies)
118+
.rsocketFactory(clientResponderConfigurer)
119+
.rsocketFactory(factory -> factory.setupPayload(ByteBufPayload.create("", connectionRoute)))
118120
.connectTcp("localhost", server.address().getPort())
119121
.block();
120122

0 commit comments

Comments
 (0)