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