use of software.amazon.eventstream.Message in project aws-sdk-java-v2 by aws.
the class EventStreamAsyncResponseTransformerTest method verifyExceptionThrown.
private void verifyExceptionThrown(Map<String, HeaderValue> headers) {
SdkServiceException exception = SdkServiceException.builder().build();
Message exceptionMessage = new Message(headers, new byte[0]);
Flowable<ByteBuffer> bytePublisher = Flowable.just(exceptionMessage.toByteBuffer());
SubscribingResponseHandler handler = new SubscribingResponseHandler();
AsyncResponseTransformer<SdkResponse, Void> transformer = EventStreamAsyncResponseTransformer.builder().eventStreamResponseHandler(handler).exceptionResponseHandler((response, executionAttributes) -> exception).executor(Executors.newSingleThreadExecutor()).future(new CompletableFuture<>()).build();
CompletableFuture<Void> cf = transformer.prepare();
transformer.onResponse(null);
transformer.onStream(SdkPublisher.adapt(bytePublisher));
assertThatThrownBy(() -> {
try {
cf.join();
} catch (CompletionException e) {
if (e.getCause() instanceof SdkServiceException) {
throw e.getCause();
}
}
}).isSameAs(exception);
assertThat(handler.exceptionOccurredCalled).isTrue();
}
use of software.amazon.eventstream.Message in project aws-sdk-java-v2 by aws.
the class EventStreamInitialRequestInterceptor method modifyAsyncHttpContent.
@Override
public Optional<AsyncRequestBody> modifyAsyncHttpContent(ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
if (!Boolean.TRUE.equals(executionAttributes.getAttribute(HAS_INITIAL_REQUEST_EVENT))) {
return context.asyncRequestBody();
}
/*
* At this point in the request execution, the requestBody contains the serialized initial request,
* and the asyncRequestBody contains the event stream proper. We will prepend the former to the
* latter.
*/
byte[] payload = getInitialRequestPayload(context);
String contentType = context.httpRequest().headers().get(CONTENT_TYPE).get(0);
Map<String, HeaderValue> initialRequestEventHeaders = new HashMap<>();
initialRequestEventHeaders.put(":message-type", HeaderValue.fromString("event"));
initialRequestEventHeaders.put(":event-type", HeaderValue.fromString("initial-request"));
initialRequestEventHeaders.put(":content-type", HeaderValue.fromString(contentType));
ByteBuffer initialRequest = new Message(initialRequestEventHeaders, payload).toByteBuffer();
Publisher<ByteBuffer> asyncRequestBody = context.asyncRequestBody().orElseThrow(() -> new IllegalStateException("This request is an event streaming request and thus " + "should have an asyncRequestBody"));
Publisher<ByteBuffer> withInitialRequest = new AsyncStreamPrepender<>(asyncRequestBody, initialRequest);
return Optional.of(AsyncRequestBody.fromPublisher(withInitialRequest));
}
use of software.amazon.eventstream.Message in project aws-sdk-java-v2 by aws.
the class EventStreamAws4SignerTest method openStreamEventSignaturesCanRollOverBetweenDays.
/**
* Verify that when an event stream is open from one day to the next, the signature is properly signed for the day of the
* event.
*/
@Test
public void openStreamEventSignaturesCanRollOverBetweenDays() {
EventStreamAws4Signer signer = EventStreamAws4Signer.create();
Region region = Region.US_WEST_2;
AwsCredentials credentials = AwsBasicCredentials.create("a", "s");
String signingName = "name";
AdjustableClock clock = new AdjustableClock();
clock.time = Instant.parse("2020-01-01T23:59:59Z");
SdkHttpFullRequest initialRequest = SdkHttpFullRequest.builder().uri(URI.create("http://localhost:8080")).method(SdkHttpMethod.GET).build();
SdkHttpFullRequest signedRequest = SignerTestUtils.signRequest(signer, initialRequest, credentials, signingName, clock, region.id());
ByteBuffer event = new Message(Collections.emptyMap(), "foo".getBytes(UTF_8)).toByteBuffer();
Callable<ByteBuffer> lastEvent = () -> {
clock.time = Instant.parse("2020-01-02T00:00:00Z");
return event;
};
AsyncRequestBody requestBody = AsyncRequestBody.fromPublisher(Flowable.concatArray(Flowable.just(event), Flowable.fromCallable(lastEvent)));
AsyncRequestBody signedBody = SignerTestUtils.signAsyncRequest(signer, signedRequest, requestBody, credentials, signingName, clock, region.id());
List<Message> signedMessages = readMessages(signedBody);
assertThat(signedMessages.size()).isEqualTo(3);
Map<String, HeaderValue> firstMessageHeaders = signedMessages.get(0).getHeaders();
assertThat(firstMessageHeaders.get(":date").getTimestamp()).isEqualTo("2020-01-01T23:59:59Z");
assertThat(Base64.getEncoder().encodeToString(firstMessageHeaders.get(":chunk-signature").getByteArray())).isEqualTo("EFt7ZU043r/TJE8U+1GxJXscmNxoqmIdGtUIl8wE9u0=");
Map<String, HeaderValue> lastMessageHeaders = signedMessages.get(2).getHeaders();
assertThat(lastMessageHeaders.get(":date").getTimestamp()).isEqualTo("2020-01-02T00:00:00Z");
assertThat(Base64.getEncoder().encodeToString(lastMessageHeaders.get(":chunk-signature").getByteArray())).isEqualTo("UTRGo0D7BQytiVkH1VofR/8f3uFsM4V5QR1A8grr1+M=");
}
use of software.amazon.eventstream.Message in project aws-sdk-java-v2 by aws.
the class BaseEventStreamAsyncAws4SignerTest method toDebugString_largePayload_truncate_generatesCorrectString.
@Test
public void toDebugString_largePayload_truncate_generatesCorrectString() {
byte[] payload = new byte[128];
new Random().nextBytes(payload);
Message m = new Message(headers, payload);
byte[] first32 = Arrays.copyOf(payload, 32);
String expectedPayloadString = BinaryUtils.toHex(first32);
assertThat(BaseEventStreamAsyncAws4Signer.toDebugString(m, true)).isEqualTo("Message = {headers={header1={42}, header2={false}, header3={\"Hello world\"}}, payload=" + expectedPayloadString + "...}");
}
use of software.amazon.eventstream.Message in project aws-sdk-java-v2 by aws.
the class Aws4EventStreamSignerTest method testBackPressure.
/**
* Test that without demand from subscriber, trailing empty frame is not delivered
*/
@Test
public void testBackPressure() {
TestVector testVector = generateTestVector();
SdkHttpFullRequest.Builder request = testVector.httpFullRequest();
AwsBasicCredentials credentials = AwsBasicCredentials.create("access", "secret");
SdkHttpFullRequest signedRequest = SignerTestUtils.signRequest(signer, request.build(), credentials, "demo", signingClock(), "us-east-1");
AsyncRequestBody transformedPublisher = SignerTestUtils.signAsyncRequest(signer, signedRequest, testVector.requestBodyPublisher(), credentials, "demo", signingClock(), "us-east-1");
Subscriber<Object> subscriber = Mockito.spy(new Subscriber<Object>() {
@Override
public void onSubscribe(Subscription s) {
// Only request the number of request body (excluding trailing empty frame)
s.request(testVector.requestBody().size());
}
@Override
public void onNext(Object o) {
}
@Override
public void onError(Throwable t) {
fail("onError should never been called");
}
@Override
public void onComplete() {
fail("onComplete should never been called");
}
});
Flowable.fromPublisher(transformedPublisher).flatMap(new Function<ByteBuffer, Publisher<?>>() {
Queue<Message> messages = new LinkedList<>();
MessageDecoder decoder = new MessageDecoder(message -> messages.offer(message));
@Override
public Publisher<?> apply(ByteBuffer byteBuffer) throws Exception {
decoder.feed(byteBuffer.array());
List<Message> messageList = new ArrayList<>();
while (!messages.isEmpty()) {
messageList.add(messages.poll());
}
return Flowable.fromIterable(messageList);
}
}).subscribe(subscriber);
// The number of events equal to the size of request body (excluding trailing empty frame)
verify(subscriber, times(testVector.requestBody().size())).onNext(any());
// subscriber is not terminated (no onError/onComplete) since trailing empty frame is not delivered yet
verify(subscriber, never()).onError(any());
verify(subscriber, never()).onComplete();
}
Aggregations