Lenient adapt non-Publisher subscription result

Closes gh-1213
This commit is contained in:
rstoyanchev
2025-05-16 08:48:13 +01:00
parent ce9472fdd9
commit 518617dd34
3 changed files with 45 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ import reactor.core.publisher.Mono;
import org.springframework.core.ReactiveAdapter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.util.Assert;
/**
* Helper to adapt a result Object to {@link Mono} or {@link Flux} through
@@ -90,7 +89,8 @@ public abstract class ReactiveAdapterRegistryHelper {
/**
* Return a {@link Flux} for the given result Object, adapting to a
* {@link Publisher} first if necessary via {@link ReactiveAdapterRegistry}.
* {@link Publisher} via {@link ReactiveAdapterRegistry} or wrapping it as
* {@code Flux} if necessary.
* @param result the result Object to adapt
* @return a {@link Flux}, possibly empty if the result is {@code null}
*/
@@ -102,8 +102,7 @@ public abstract class ReactiveAdapterRegistryHelper {
return Flux.from(publisher);
}
ReactiveAdapter adapter = registry.getAdapter(result.getClass());
Assert.state(adapter != null, "Expected Publisher for a subscription");
return Flux.from(adapter.toPublisher(result));
return ((adapter != null) ? Flux.from(adapter.toPublisher(result)) : Flux.just(result));
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2024 the original author or authors.
* Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -104,6 +104,26 @@ class GraphQlSseHandlerTests {
""");
}
@Test // gh-1213
void shouldHandleNonPublisherValue() {
SerializableGraphQlRequest request = initRequest(
"subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } }");
GraphQlSseHandler handler = createHandler(env -> BookSource.getBook(1L));
MockServerHttpResponse response = handleRequest(this.httpRequest, handler, request);
assertThat(response.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue();
assertThat(response.getBodyAsString().block()).isEqualTo("""
event:next
data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}}
event:complete
data:{}
""");
}
@Test
void shouldWriteEventsAndTerminalError() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2024 the original author or authors.
* Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -111,6 +111,25 @@ class GraphQlSseHandlerTests {
""");
}
@Test // gh-1213
void shouldHandleNonPublisherValue() throws Exception {
GraphQlSseHandler handler = createSseHandler(env -> BookSource.getBook(1L));
MockHttpServletRequest request = createServletRequest("""
{ "query": "subscription TestSubscription { bookSearch { id name } }" }
""");
MockHttpServletResponse response = handleAndAwait(request, handler);
assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE);
assertThat(response.getContentAsString()).isEqualTo("""
event:next
data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}}
event:complete
data:
""");
}
@Test
void shouldWriteEventsAndTerminalError() throws Exception {