Skip to content

Commit b4e635d

Browse files
stub: Utility method StreamObservers.nextAndComplete() that does both onNext and onComplete (#11778) (#12021)
1 parent a6e1c1f commit b4e635d

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

stub/src/main/java/io/grpc/stub/StreamObservers.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,21 @@
2323
/**
2424
* Utility functions for working with {@link StreamObserver} and it's common subclasses like
2525
* {@link CallStreamObserver}.
26-
*
27-
* @deprecated Of questionable utility and generally not used.
2826
*/
29-
@Deprecated
30-
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4694")
3127
public final class StreamObservers {
28+
// Prevent instantiation
29+
private StreamObservers() { }
30+
31+
/**
32+
* Utility method to call {@link StreamObserver#onNext(Object)} and
33+
* {@link StreamObserver#onCompleted()} on the specified responseObserver.
34+
*/
35+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/10957")
36+
public static <T> void nextAndComplete(StreamObserver<T> responseObserver, T response) {
37+
responseObserver.onNext(response);
38+
responseObserver.onCompleted();
39+
}
40+
3241
/**
3342
* Copy the values of an {@link Iterator} to the target {@link CallStreamObserver} while properly
3443
* accounting for outbound flow-control. After calling this method, {@code target} should no
@@ -40,7 +49,10 @@ public final class StreamObservers {
4049
*
4150
* @param source of values expressed as an {@link Iterator}.
4251
* @param target {@link CallStreamObserver} which accepts values from the source.
52+
* @deprecated Of questionable utility and generally not used.
4353
*/
54+
@Deprecated
55+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4694")
4456
public static <V> void copyWithFlowControl(final Iterator<V> source,
4557
final CallStreamObserver<V> target) {
4658
Preconditions.checkNotNull(source, "source");
@@ -80,7 +92,10 @@ public void run() {
8092
*
8193
* @param source of values expressed as an {@link Iterable}.
8294
* @param target {@link CallStreamObserver} which accepts values from the source.
95+
* @deprecated Of questionable utility and generally not used.
8396
*/
97+
@Deprecated
98+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4694")
8499
public static <V> void copyWithFlowControl(final Iterable<V> source,
85100
CallStreamObserver<V> target) {
86101
Preconditions.checkNotNull(source, "source");
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2025 The gRPC 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+
* http://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 io.grpc.stub;
18+
19+
import org.junit.Test;
20+
import org.mockito.InOrder;
21+
import org.mockito.Mockito;
22+
23+
public class StreamObserversTest {
24+
25+
@Test
26+
public void nextAndComplete() {
27+
@SuppressWarnings("unchecked")
28+
StreamObserver<String> observer = Mockito.mock(StreamObserver.class);
29+
InOrder inOrder = Mockito.inOrder(observer);
30+
StreamObservers.nextAndComplete(observer, "TEST");
31+
inOrder.verify(observer).onNext("TEST");
32+
inOrder.verify(observer).onCompleted();
33+
inOrder.verifyNoMoreInteractions();
34+
}
35+
}

0 commit comments

Comments
 (0)