• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.awscore.eventstream;
17 
18 import java.util.function.Consumer;
19 import java.util.function.Function;
20 import java.util.function.Supplier;
21 import org.reactivestreams.Publisher;
22 import org.reactivestreams.Subscriber;
23 import org.reactivestreams.Subscription;
24 import software.amazon.awssdk.annotations.SdkProtectedApi;
25 import software.amazon.awssdk.core.async.SdkPublisher;
26 
27 /**
28  * Response handler for event streaming operations.
29  *
30  * @param <ResponseT> the POJO response type
31  * @param <EventT> the event type
32  */
33 @SdkProtectedApi
34 public interface EventStreamResponseHandler<ResponseT, EventT> {
35 
36     /**
37      * Called when the initial response has been received and the POJO response has
38      * been unmarshalled. This is guaranteed to be called before {@link #onEventStream(SdkPublisher)}.
39      *
40      * <p>In the event of a retryable error, this callback may be called multiple times. It
41      * also may never be invoked if the request never succeeds.</p>
42      *
43      * @param response Unmarshalled POJO containing metadata about the streamed data.
44      */
responseReceived(ResponseT response)45     void responseReceived(ResponseT response);
46 
47     /**
48      * Called when events are ready to be streamed. Implementations  must subscribe to the {@link Publisher} and request data via
49      * a {@link org.reactivestreams.Subscription} as they can handle it.
50      *
51      * <p>
52      * If at any time the subscriber wishes to stop receiving data, it may call {@link Subscription#cancel()}. This
53      * will <b>NOT</b> be treated as a failure of the response and the response will be completed normally.
54      * </p>
55      *
56      * <p>This callback may never be called if the response has no content or if an error occurs.</p>
57      *
58      * <p>
59      * In the event of a retryable error, this callback may be called multiple times with different Publishers.
60      * If this method is called more than once, implementation must either reset any state to prepare for another
61      * stream of data or must throw an exception indicating they cannot reset. If any exception is thrown then no
62      * automatic retry is performed.
63      * </p>
64      */
onEventStream(SdkPublisher<EventT> publisher)65     void onEventStream(SdkPublisher<EventT> publisher);
66 
67     /**
68      * Called when an exception occurs while establishing the connection or streaming the response. Implementations
69      * should free up any resources in this method. This method may be called multiple times during the lifecycle
70      * of a request if automatic retries are enabled.
71      *
72      * @param throwable Exception that occurred.
73      */
exceptionOccurred(Throwable throwable)74     void exceptionOccurred(Throwable throwable);
75 
76     /**
77      * Called when all data has been successfully published to the {@link org.reactivestreams.Subscriber}. This will
78      * only be called once during the lifecycle of the request. Implementors should free up any resources they have
79      * opened.
80      */
complete()81     void complete();
82 
83     /**
84      * Base builder for sub-interfaces of {@link EventStreamResponseHandler}.
85      */
86     interface Builder<ResponseT, EventT, SubBuilderT> {
87 
88         /**
89          * Callback to invoke when the initial response is received.
90          *
91          * @param responseConsumer Callback that will process the initial response.
92          * @return This builder for method chaining.
93          */
onResponse(Consumer<ResponseT> responseConsumer)94         SubBuilderT onResponse(Consumer<ResponseT> responseConsumer);
95 
96         /**
97          * Callback to invoke in the event on an error.
98          *
99          * @param consumer Callback that will process any error that occurs.
100          * @return This builder for method chaining.
101          */
onError(Consumer<Throwable> consumer)102         SubBuilderT onError(Consumer<Throwable> consumer);
103 
104         /**
105          * Action to invoke when the event stream completes. This will only be invoked
106          * when all events are being received.
107          *
108          * @param runnable Action to run on the completion of the event stream.
109          * @return This builder for method chaining.
110          */
onComplete(Runnable runnable)111         SubBuilderT onComplete(Runnable runnable);
112 
113         /**
114          * Subscriber that will subscribe to the {@link SdkPublisher} of events. Subscriber
115          * must be provided.
116          *
117          * @param eventSubscriberSupplier Supplier for a subscriber that will be subscribed to the publisher of events.
118          * @return This builder for method chaining.
119          */
subscriber(Supplier<Subscriber<EventT>> eventSubscriberSupplier)120         SubBuilderT subscriber(Supplier<Subscriber<EventT>> eventSubscriberSupplier);
121 
122         /**
123          * Sets the subscriber to the {@link SdkPublisher} of events. The given consumer will be called for each event received
124          * by the publisher. Events are requested sequentially after each event is processed. If you need more control over
125          * the backpressure strategy consider using {@link #subscriber(Supplier)} instead.
126          *
127          * @param eventConsumer Consumer that will process incoming events.
128          * @return This builder for method chaining.
129          */
subscriber(Consumer<EventT> eventConsumer)130         SubBuilderT subscriber(Consumer<EventT> eventConsumer);
131 
132         /**
133          * Callback to invoke when the {@link SdkPublisher} is available. This callback must subscribe to the given publisher.
134          * This method should not be used with {@link #subscriber(Supplier)} or any of it's overloads.
135          *
136          * @param onSubscribe Callback that will subscribe to the {@link SdkPublisher}.
137          * @return This builder for method chaining.
138          */
onEventStream(Consumer<SdkPublisher<EventT>> onSubscribe)139         SubBuilderT onEventStream(Consumer<SdkPublisher<EventT>> onSubscribe);
140 
141         /**
142          * Allows for optional transformation of the publisher of events before subscribing. This transformation must return
143          * a {@link SdkPublisher} of the same type so methods like {@link SdkPublisher#map(Function)} and
144          * {@link SdkPublisher#buffer(int)} that change the type cannot be used with this method.
145          *
146          * @param publisherTransformer Function that returns a new {@link SdkPublisher} with augmented behavior.
147          * @return This builder for method chaining.
148          */
publisherTransformer(Function<SdkPublisher<EventT>, SdkPublisher<EventT>> publisherTransformer)149         SubBuilderT publisherTransformer(Function<SdkPublisher<EventT>, SdkPublisher<EventT>> publisherTransformer);
150 
151     }
152 }
153