getQueryParameters(String key) {
return Collections.emptyList();
}
- @SuppressWarnings({"unchecked"})
+ @SuppressWarnings({"rawtypes", "unchecked"})
public AsyncHttpRequest setQueryParameter(String key, Object value) {
if (key != null) {
switch (value) {
@@ -434,7 +433,7 @@ public AsyncHttpRequest removeQueryParameter(String key) {
/**
* The set methods and toMap method are used for manually construct an HTTP request object
* that are typically used for Unit Test or for a service to emulate a REST browser.
- *
+ *
* In normal case, the AsyncHttpRequest map is generated by the rest-automation application.
*
* @return async http request object as a map
@@ -459,18 +458,12 @@ public Map toMap() {
if (url != null) {
result.put(URL_LABEL, url);
}
- if (timeoutSeconds != -1) {
- result.put(TIMEOUT, timeoutSeconds);
- }
if (fileName != null) {
result.put(FILE_NAME, fileName);
}
if (contentLength != -1) {
result.put(CONTENT_LENGTH, contentLength);
}
- if (streamRoute != null) {
- result.put(STREAM, streamRoute);
- }
if (body != null) {
result.put(HTTP_BODY, body);
}
@@ -513,10 +506,8 @@ private void fromMap(Object input) {
this.method = source.method;
this.ip = source.ip;
this.url = source.url;
- this.timeoutSeconds = source.timeoutSeconds;
this.fileName = source.fileName;
this.contentLength = source.contentLength;
- this.streamRoute = source.streamRoute;
this.body = source.body;
this.queryString = source.queryString;
this.https = source.https;
@@ -546,18 +537,12 @@ private void fromMap(Object input) {
if (map.containsKey(URL_LABEL)) {
url = (String) map.get(URL_LABEL);
}
- if (map.containsKey(TIMEOUT)) {
- timeoutSeconds = (int) map.get(TIMEOUT);
- }
if (map.containsKey(FILE_NAME)) {
fileName = (String) map.get(FILE_NAME);
}
if (map.containsKey(CONTENT_LENGTH)) {
contentLength = (int) map.get(CONTENT_LENGTH);
}
- if (map.containsKey(STREAM)) {
- streamRoute = (String) map.get(STREAM);
- }
if (map.containsKey(HTTP_BODY)) {
body = map.get(HTTP_BODY);
}
diff --git a/system/platform-core/src/main/java/org/platformlambda/core/services/EventApiService.java b/system/platform-core/src/main/java/org/platformlambda/core/services/EventApiService.java
index 3c6f15ad..89f6cecb 100644
--- a/system/platform-core/src/main/java/org/platformlambda/core/services/EventApiService.java
+++ b/system/platform-core/src/main/java/org/platformlambda/core/services/EventApiService.java
@@ -43,16 +43,13 @@ public class EventApiService implements TypedLambdaFunction
private static final Logger log = LoggerFactory.getLogger(EventApiService.class);
private static final String EVENT_API_SERVICE = "event.api.service";
- private static final String STREAM_TO_BYTES = "stream.to.bytes";
private static final String TYPE = "type";
private static final String ASYNC = "async";
private static final String DELIVERED = "delivered";
private static final String TIME = "time";
- private static final String STREAM = "stream";
- private static final String TIMEOUT = "timeout";
private static final String CONTENT_TYPE = "content-type";
private static final String OCTET_STREAM = "application/octet-stream";
- private static final String X_TIMEOUT = "X-Timeout";
+ private static final String X_TTL = "x-ttl";
private static final String X_ASYNC = "X-Async";
private static final String MISSING_ROUTING_PATH = "Missing routing path";
private static final String PRIVATE_FUNCTION = " is private";
@@ -63,36 +60,18 @@ public class EventApiService implements TypedLambdaFunction
public Void handleEvent(Map headers, EventEnvelope input, int instance) throws IOException {
if (input.getRawBody() instanceof Map && input.getReplyTo() != null) {
Utility util = Utility.getInstance();
- AsyncHttpRequest httpRequest = new AsyncHttpRequest(input.getRawBody());
- Map sessionInfo = httpRequest.getSessionInfo();
- long timeout = Math.max(100, util.str2long(httpRequest.getHeader(X_TIMEOUT)));
- boolean async = "true".equals(httpRequest.getHeader(X_ASYNC));
- String streamId = httpRequest.getStreamRoute();
- if (streamId != null) {
- // read the input stream into a byte array using the "stream.to.bytes" function
- EventEmitter po = EventEmitter.getInstance();
- EventEnvelope req = new EventEnvelope().setTo(STREAM_TO_BYTES)
- .setHeader(STREAM, streamId).setHeader(TIMEOUT, timeout);
- po.asyncRequest(req, timeout)
- .onSuccess(result -> {
- if (result.getRawBody() instanceof byte[] b) {
- try {
- handleRequest(sessionInfo, headers, instance, b, input, timeout, async);
- } catch (Exception e) {
- sendError(input, 400, e.getMessage());
- }
- } else {
- sendError(input, 500, "Corrupted input stream");
- }
- })
- .onFailure(e -> sendError(input, 408, e.getMessage()));
-
- } else if (httpRequest.getBody() instanceof byte[] b) {
+ AsyncHttpRequest request = new AsyncHttpRequest(input.getRawBody());
+ Map sessionInfo = request.getSessionInfo();
+ long timeout = Math.max(1000, util.str2long(request.getHeader(X_TTL)));
+ boolean async = "true".equals(request.getHeader(X_ASYNC));
+ if (request.getBody() instanceof byte[] b) {
try {
handleRequest(sessionInfo, headers, instance, b, input, timeout, async);
} catch (Exception e) {
sendError(input, 400, e.getMessage());
}
+ } else {
+ sendError(input, 500, "Invalid event-over-http data format");
}
}
return null;
diff --git a/system/platform-core/src/main/java/org/platformlambda/core/system/EventEmitter.java b/system/platform-core/src/main/java/org/platformlambda/core/system/EventEmitter.java
index cfed3715..159eeca3 100644
--- a/system/platform-core/src/main/java/org/platformlambda/core/system/EventEmitter.java
+++ b/system/platform-core/src/main/java/org/platformlambda/core/system/EventEmitter.java
@@ -53,14 +53,17 @@ public class EventEmitter {
private static final String TYPE = "type";
private static final String ERROR = "error";
private static final String MESSAGE = "message";
+ private static final String X_EVENT_API = "x-event-api";
private static final String HTTP_REQUEST = "async.http.request";
+ private static final String X_NO_STREAM = "x-small-payload-as-bytes";
private static final String HTTP = "http";
private static final String HTTPS = "https";
private static final String HTTP_OR_HTTPS = "Protocol must be http or https";
private static final String POST = "POST";
private static final String CONTENT_TYPE = "content-type";
+ private static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
private static final String ACCEPT = "accept";
- private static final String X_TIMEOUT = "x-timeout";
+ private static final String X_TTL = "x-ttl";
private static final String X_ASYNC = "x-async";
private static final String X_TRACE_ID = "x-trace-id";
private static final String ROUTE_SUBSTITUTION = "route.substitution";
@@ -674,11 +677,11 @@ public void send(final EventEnvelope event) throws IOException {
}
String to = substituteRouteIfAny(destination);
event.setTo(to);
- var targetHttp = event.getHeader("_") == null? getEventHttpTarget(to) : null;
+ var targetHttp = event.getHeader(X_EVENT_API) == null? getEventHttpTarget(to) : null;
if (targetHttp != null) {
String callback = event.getReplyTo();
event.setReplyTo(null);
- EventEnvelope forwardEvent = new EventEnvelope(event.toMap()).setHeader("_", "async");
+ EventEnvelope forwardEvent = new EventEnvelope(event.toMap()).setHeader(X_EVENT_API, "async");
Future response = asyncRequest(forwardEvent, ASYNC_EVENT_HTTP_TIMEOUT,
getEventHttpHeaders(to), targetHttp, callback != null);
response.onSuccess(evt -> {
@@ -808,9 +811,10 @@ public Future asyncRequest(final EventEnvelope event, long timeou
}
AsyncHttpRequest req = new AsyncHttpRequest();
req.setMethod(POST);
- req.setHeader(CONTENT_TYPE, "application/octet-stream");
+ req.setHeader(CONTENT_TYPE, APPLICATION_OCTET_STREAM);
+ req.setHeader(X_NO_STREAM, "true");
req.setHeader(ACCEPT, "*/*");
- req.setHeader(X_TIMEOUT, String.valueOf(Math.max(100L, timeout)));
+ req.setHeader(X_TTL, String.valueOf(Math.max(100L, timeout)));
if (!rpc) {
req.setHeader(X_ASYNC, "true");
}
@@ -918,9 +922,10 @@ public java.util.concurrent.Future request(final EventEnvelope ev
}
AsyncHttpRequest req = new AsyncHttpRequest();
req.setMethod(POST);
- req.setHeader(CONTENT_TYPE, "application/octet-stream");
+ req.setHeader(CONTENT_TYPE, APPLICATION_OCTET_STREAM);
+ req.setHeader(X_NO_STREAM, "true");
req.setHeader(ACCEPT, "*/*");
- req.setHeader(X_TIMEOUT, String.valueOf(Math.max(100L, timeout)));
+ req.setHeader(X_TTL, String.valueOf(Math.max(100L, timeout)));
if (!rpc) {
req.setHeader(X_ASYNC, "true");
}
@@ -1057,9 +1062,9 @@ public Future asyncRequest(final EventEnvelope event, long timeou
}
String to = substituteRouteIfAny(destination);
event.setTo(to);
- var targetHttp = event.getHeader("_") == null? getEventHttpTarget(to) : null;
+ var targetHttp = event.getHeader(X_EVENT_API) == null? getEventHttpTarget(to) : null;
if (targetHttp != null) {
- EventEnvelope forwardEvent = new EventEnvelope(event.toMap()).setHeader("_", "async_request");
+ EventEnvelope forwardEvent = new EventEnvelope(event.toMap()).setHeader(X_EVENT_API, "asyncRequest");
return asyncRequest(forwardEvent, timeout, getEventHttpHeaders(to), targetHttp, true);
}
Platform platform = Platform.getInstance();
@@ -1115,9 +1120,9 @@ public java.util.concurrent.Future request(final EventEnvelope ev
}
String to = substituteRouteIfAny(destination);
event.setTo(to);
- var targetHttp = event.getHeader("_") == null? getEventHttpTarget(to) : null;
+ var targetHttp = event.getHeader(X_EVENT_API) == null? getEventHttpTarget(to) : null;
if (targetHttp != null) {
- EventEnvelope forwardEvent = new EventEnvelope(event.toMap()).setHeader("_", "request");
+ EventEnvelope forwardEvent = new EventEnvelope(event.toMap()).setHeader(X_EVENT_API, "request");
return request(forwardEvent, timeout, getEventHttpHeaders(to), targetHttp, true);
}
Platform platform = Platform.getInstance();
diff --git a/system/platform-core/src/main/java/org/platformlambda/core/system/EventPublisher.java b/system/platform-core/src/main/java/org/platformlambda/core/system/EventPublisher.java
index 59df9527..8654db01 100644
--- a/system/platform-core/src/main/java/org/platformlambda/core/system/EventPublisher.java
+++ b/system/platform-core/src/main/java/org/platformlambda/core/system/EventPublisher.java
@@ -44,10 +44,12 @@ public class EventPublisher {
private final ObjectStreamIO stream;
private final String outStream;
private final long timer;
+ private final long ttl;
private final AtomicBoolean eof = new AtomicBoolean(false);
private final AtomicBoolean expired = new AtomicBoolean(false);
public EventPublisher(long ttl) {
+ this.ttl = ttl;
this.stream = new ObjectStreamIO((int) ttl / 1000);
this.outStream = this.stream.getOutputStreamId();
long expiry = this.stream.getExpirySeconds() * 1000L;
@@ -68,6 +70,10 @@ public String getStreamId() {
return stream.getInputStreamId();
}
+ public long getTimeToLive() {
+ return ttl;
+ }
+
public void publish(Object data) {
try {
EventEmitter.getInstance().send(outStream, data, new Kv(TYPE, DATA));
diff --git a/system/platform-core/src/main/kotlin/org/platformlambda/core/services/StreamToBytes.kt b/system/platform-core/src/main/kotlin/org/platformlambda/core/services/StreamToBytes.kt
deleted file mode 100644
index b22c916a..00000000
--- a/system/platform-core/src/main/kotlin/org/platformlambda/core/services/StreamToBytes.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-
- Copyright 2018-2024 Accenture Technology
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-package org.platformlambda.core.services
-
-import org.platformlambda.core.annotations.PreLoad
-import org.platformlambda.core.annotations.ZeroTracing
-import org.platformlambda.core.exception.AppException
-import org.platformlambda.core.models.EventEnvelope
-import org.platformlambda.core.models.KotlinLambdaFunction
-import org.platformlambda.core.models.Kv
-import org.platformlambda.core.system.EventEmitter
-import org.platformlambda.core.system.FastRPC
-import org.platformlambda.core.util.Utility
-import java.io.ByteArrayOutputStream
-
-@ZeroTracing
-@PreLoad(route = "stream.to.bytes", instances = 50)
-class StreamToBytes : KotlinLambdaFunction {
- override suspend fun handleEvent(headers: Map, input: EventEnvelope, instance: Int): ByteArray {
- val fastRPC = FastRPC(headers)
- val util = Utility.getInstance()
- val streamId = headers[STREAM]
- val timeout = headers[TIMEOUT]
- val out = ByteArrayOutputStream()
-
- var n = 0
- if (streamId != null && timeout != null) {
- val req = EventEnvelope().setTo(streamId).setHeader(TYPE, READ)
- while (true) {
- val event = fastRPC.awaitRequest(req, 100L.coerceAtLeast(util.str2long(timeout)))
- if (event.status == 408) {
- throw AppException(408, "timeout for $timeout ms")
- }
- if (EOF == event.headers[TYPE]) {
- EventEmitter.getInstance().send(streamId, Kv(TYPE, CLOSE))
- break
- }
- if (DATA == event.headers[TYPE]) {
- val block = event.body
- if (block is ByteArray) {
- n++
- out.write(block)
- }
- }
- }
- }
- return out.toByteArray()
- }
-
- companion object {
- private const val TYPE = "type"
- private const val READ = "read"
- private const val DATA = "data"
- private const val EOF = "eof"
- private const val CLOSE = "close"
- private const val STREAM = "stream"
- private const val TIMEOUT = "timeout"
- }
-}
\ No newline at end of file
diff --git a/system/platform-core/src/main/kotlin/org/platformlambda/core/system/FastRPC.kt b/system/platform-core/src/main/kotlin/org/platformlambda/core/system/FastRPC.kt
index cc448429..2bc03835 100644
--- a/system/platform-core/src/main/kotlin/org/platformlambda/core/system/FastRPC.kt
+++ b/system/platform-core/src/main/kotlin/org/platformlambda/core/system/FastRPC.kt
@@ -56,9 +56,9 @@ class FastRPC(headers: Map) {
val dest = request.to ?: throw IllegalArgumentException(EventEmitter.MISSING_ROUTING_PATH)
val to = po.substituteRouteIfAny(dest)
request.to = to
- val targetHttp: String? = if (request.getHeader("_") == null) po.getEventHttpTarget(to) else null
+ val targetHttp: String? = if (request.getHeader(X_EVENT_API) == null) po.getEventHttpTarget(to) else null
if (targetHttp != null) {
- val forwardEvent = EventEnvelope(request.toMap()).setHeader("_", "await_request")
+ val forwardEvent = EventEnvelope(request.toMap()).setHeader(X_EVENT_API, "awaitRequest")
return awaitRequest(forwardEvent, timeout, po.getEventHttpHeaders(to), targetHttp, true)
}
propagateTrace(request)
@@ -131,7 +131,7 @@ class FastRPC(headers: Map) {
req.setMethod(POST)
req.setHeader(CONTENT_TYPE, "application/octet-stream")
req.setHeader(ACCEPT, "*/*")
- req.setHeader(X_TIMEOUT, 100L.coerceAtLeast(timeout).toString())
+ req.setHeader(X_TTL, 100L.coerceAtLeast(timeout).toString())
if (!rpc) {
req.setHeader(X_ASYNC, "true")
}
@@ -149,6 +149,7 @@ class FastRPC(headers: Map) {
val b: ByteArray = request.toBytes()
req.setBody(b)
req.setContentLength(b.size)
+ req.setHeader(X_NO_STREAM, "true")
val remoteRequest = EventEnvelope().setTo(HTTP_REQUEST).setBody(req)
// add 100 ms to make sure it does not time out earlier than the target service
val response = awaitRequest(remoteRequest, 100L.coerceAtLeast(timeout) + 100L)
@@ -358,7 +359,7 @@ class FastRPC(headers: Map) {
private const val POST = "POST"
private const val CONTENT_TYPE = "content-type"
private const val ACCEPT = "accept"
- private const val X_TIMEOUT = "x-timeout"
+ private const val X_TTL = "x-ttl"
private const val X_ASYNC = "x-async"
private const val X_TRACE_ID = "x-trace-id"
private const val HTTP = "http"
@@ -368,5 +369,7 @@ class FastRPC(headers: Map) {
private const val TYPE = "type"
private const val ERROR = "error"
private const val MESSAGE = "message"
+ private const val X_NO_STREAM = "x-small-payload-as-bytes"
+ private const val X_EVENT_API = "x-event-api"
}
}
\ No newline at end of file
diff --git a/system/platform-core/src/test/java/org/platformlambda/automation/RestEndpointTest.java b/system/platform-core/src/test/java/org/platformlambda/automation/RestEndpointTest.java
index 22331ea2..a8a25bdc 100644
--- a/system/platform-core/src/test/java/org/platformlambda/automation/RestEndpointTest.java
+++ b/system/platform-core/src/test/java/org/platformlambda/automation/RestEndpointTest.java
@@ -19,7 +19,6 @@
package org.platformlambda.automation;
import io.vertx.core.Future;
-import io.vertx.core.Promise;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.platformlambda.common.TestBase;
@@ -100,6 +99,7 @@ public void optionsMethodTest() throws IOException, InterruptedException {
@SuppressWarnings(value = "unchecked")
@Test
public void serviceTest() throws IOException, InterruptedException {
+ final int TTL_SECONDS = 7;
final BlockingQueue bench = new ArrayBlockingQueue<>(1);
EventEmitter po = EventEmitter.getInstance();
AsyncHttpRequest req = new AsyncHttpRequest();
@@ -112,6 +112,7 @@ public void serviceTest() throws IOException, InterruptedException {
list.add("b");
req.setQueryParameter("x2", list);
req.setTargetHost("http://127.0.0.1:"+port);
+ req.setTimeoutSeconds(TTL_SECONDS);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -124,7 +125,7 @@ public void serviceTest() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("GET", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals(10, map.getElement("timeout"));
+ assertEquals(String.valueOf(TTL_SECONDS * 1000), map.getElement("headers.x-ttl"));
assertEquals("y", map.getElement("parameters.query.x1"));
assertEquals(list, map.getElement("parameters.query.x2"));
// the HTTP request filter will not execute because the request is not a static content request
@@ -215,12 +216,41 @@ public void authRoutingTest2() throws IOException, InterruptedException {
assertEquals("Unauthorized", map.get("message"));
}
+ @Test
+ public void uploadBytesWithPut() throws IOException, InterruptedException {
+ final BlockingQueue bench = new ArrayBlockingQueue<>(1);
+ Utility util = Utility.getInstance();
+ EventEmitter po = EventEmitter.getInstance();
+ int len = 0;
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ for (int i=0; i < 100; i++) {
+ byte[] line = util.getUTF("hello world "+i+"\n");
+ bytes.write(line);
+ len += line.length;
+ }
+ byte[] b = bytes.toByteArray();
+ AsyncHttpRequest req = new AsyncHttpRequest();
+ req.setMethod("PUT");
+ req.setUrl("/api/hello/world");
+ req.setTargetHost("http://127.0.0.1:"+port);
+ req.setBody(b);
+ req.setContentLength(len);
+ EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
+ Future res = po.asyncRequest(request, RPC_TIMEOUT);
+ res.onSuccess(bench::offer);
+ EventEnvelope response = bench.poll(10, TimeUnit.SECONDS);
+ assert response != null;
+ assertInstanceOf(byte[].class, response.getBody());
+ assertArrayEquals(b, (byte[]) response.getBody());
+ }
+
@Test
public void uploadSmallBlockWithPut() throws IOException, InterruptedException {
final BlockingQueue bench1 = new ArrayBlockingQueue<>(1);
final BlockingQueue bench2 = new ArrayBlockingQueue<>(1);
final Utility util = Utility.getInstance();
final EventEmitter po = EventEmitter.getInstance();
+ int TTL = 9;
int len = 0;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
EventPublisher publisher = new EventPublisher(10000);
@@ -241,6 +271,7 @@ public void uploadSmallBlockWithPut() throws IOException, InterruptedException {
req.setUrl("/api/v1/hello/world");
req.setTargetHost("http://127.0.0.1:"+port);
req.setStreamRoute(publisher.getStreamId());
+ req.setTimeoutSeconds(TTL);
req.setContentLength(len);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
@@ -249,7 +280,8 @@ public void uploadSmallBlockWithPut() throws IOException, InterruptedException {
assert response != null;
assertNull(response.getBody());
// async.http.request returns a stream
- String streamId = response.getHeader("stream");
+ String streamId = response.getHeader("X-Stream-Id");
+ assertEquals(String.valueOf(TTL * 1000), response.getHeader("x-ttl"));
assertNotNull(streamId);
ByteArrayOutputStream result = new ByteArrayOutputStream();
FluxConsumer flux = new FluxConsumer<>(streamId, RPC_TIMEOUT);
@@ -265,34 +297,6 @@ public void uploadSmallBlockWithPut() throws IOException, InterruptedException {
assertArrayEquals(b, result.toByteArray());
}
- @Test
- public void uploadBytesWithPut() throws IOException, InterruptedException {
- final BlockingQueue bench = new ArrayBlockingQueue<>(1);
- Utility util = Utility.getInstance();
- EventEmitter po = EventEmitter.getInstance();
- int len = 0;
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- for (int i=0; i < 100; i++) {
- byte[] line = util.getUTF("hello world "+i+"\n");
- bytes.write(line);
- len += line.length;
- }
- byte[] b = bytes.toByteArray();
- AsyncHttpRequest req = new AsyncHttpRequest();
- req.setMethod("PUT");
- req.setUrl("/api/hello/world");
- req.setTargetHost("http://127.0.0.1:"+port);
- req.setBody(b);
- req.setContentLength(len);
- EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
- Future res = po.asyncRequest(request, RPC_TIMEOUT);
- res.onSuccess(bench::offer);
- EventEnvelope response = bench.poll(10, TimeUnit.SECONDS);
- assert response != null;
- assertInstanceOf(byte[].class, response.getBody());
- assertArrayEquals(b, (byte[]) response.getBody());
- }
-
@Test
public void uploadLargePayloadWithPut() throws IOException, InterruptedException {
final BlockingQueue bench1 = new ArrayBlockingQueue<>(1);
@@ -324,7 +328,7 @@ public void uploadLargePayloadWithPut() throws IOException, InterruptedException
assert response != null;
assertNull(response.getBody());
// async.http.request returns a stream
- String streamId = response.getHeader("stream");
+ String streamId = response.getHeader("x-stream-id");
assertNotNull(streamId);
ByteArrayOutputStream result = new ByteArrayOutputStream();
FluxConsumer flux = new FluxConsumer<>(streamId, RPC_TIMEOUT);
@@ -365,15 +369,18 @@ public void uploadStreamWithPut() throws IOException, InterruptedException {
req.setHeader("content-type", "application/octet-stream");
req.setContentLength(len);
req.setStreamRoute(publisher.getStreamId());
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench1::offer);
EventEnvelope response = bench1.poll(10, TimeUnit.SECONDS);
assert response != null;
- assertNotNull(response.getHeader("stream"));
- String streamId = response.getHeader("stream");
+ assertNotNull(response.getHeader("x-stream-id"));
+ String streamId = response.getHeader("x-stream-id");
+ long ttl = util.str2long(response.getHeader("x-ttl"));
+ assertEquals(RPC_TIMEOUT, ttl);
ByteArrayOutputStream result = new ByteArrayOutputStream();
- FluxConsumer flux = new FluxConsumer<>(streamId, RPC_TIMEOUT);
+ FluxConsumer flux = new FluxConsumer<>(streamId, ttl);
flux.consume(data -> {
try {
result.write(data);
@@ -417,8 +424,8 @@ public void uploadMultipartWithPost() throws IOException, InterruptedException {
res.onSuccess(bench1::offer);
EventEnvelope response = bench1.poll(10, TimeUnit.SECONDS);
assert response != null;
- assertNotNull(response.getHeader("stream"));
- String streamId = response.getHeader("stream");
+ assertNotNull(response.getHeader("x-stream-id"));
+ String streamId = response.getHeader("x-stream-id");
ByteArrayOutputStream result = new ByteArrayOutputStream();
FluxConsumer flux = new FluxConsumer<>(streamId, RPC_TIMEOUT);
flux.consume(data -> {
@@ -449,6 +456,7 @@ public void postJson() throws IOException, InterruptedException {
req.setBody(json);
req.setHeader("accept", "application/json");
req.setHeader("content-type", "application/json");
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -462,7 +470,7 @@ public void postJson() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("POST", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals(10, map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertInstanceOf(Map.class, map.getElement("body"));
Map received = (Map) map.getElement("body");
assertEquals(data, received);
@@ -483,6 +491,7 @@ public void postXmlAsMap() throws IOException, InterruptedException {
data.put("test", "message");
String xml = xmlWriter.write(data);
req.setBody(xml);
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
req.setHeader("accept", "application/xml");
req.setHeader("content-type", "application/xml");
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
@@ -498,7 +507,7 @@ public void postXmlAsMap() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("POST", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals("10", map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertInstanceOf(Map.class, map.getElement("body"));
Map received = (Map) map.getElement("body");
assertEquals(data, received);
@@ -516,6 +525,7 @@ public void postXmlAsText() throws IOException, InterruptedException {
req.setHeader("accept", "application/xml");
req.setHeader("content-type", "application/xml");
req.setHeader("x-raw-xml", "true");
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -532,7 +542,7 @@ public void postXmlAsText() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("POST", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals("10", map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertInstanceOf(String.class, map.getElement("body"));
assertEquals("hello world", map.getElement("body"));
}
@@ -552,6 +562,7 @@ public void postJsonMap() throws IOException, InterruptedException {
req.setBody(data);
req.setHeader("accept", "application/json");
req.setHeader("content-type", "application/json");
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -565,7 +576,7 @@ public void postJsonMap() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("POST", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals(10, map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertInstanceOf(Map.class, map.getElement("body"));
Map received = (Map) map.getElement("body");
assertEquals(data, received);
@@ -586,6 +597,7 @@ public void testJsonResultList() throws IOException, InterruptedException {
req.setBody(data);
req.setHeader("accept", "application/json");
req.setHeader("content-type", "application/json");
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -602,7 +614,7 @@ public void testJsonResultList() throws IOException, InterruptedException {
assertEquals("/api/hello/list", map.getElement("url"));
assertEquals("POST", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals(15, map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertInstanceOf(Map.class, map.getElement("body"));
Map received = (Map) map.getElement("body");
assertEquals(data, received);
@@ -622,7 +634,7 @@ public void testXmlResultList() throws IOException, InterruptedException {
data.put("hello", "world");
data.put("test", "message");
String xml = xmlWriter.write(data);
- req.setBody(xml);
+ req.setTimeoutSeconds((int) (RPC_TIMEOUT / 1000)).setBody(xml);
req.setHeader("accept", "application/xml");
req.setHeader("content-type", "application/xml");
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
@@ -639,7 +651,7 @@ public void testXmlResultList() throws IOException, InterruptedException {
assertEquals("/api/hello/list", map.getElement("result.url"));
assertEquals("POST", map.getElement("result.method"));
assertEquals("127.0.0.1", map.getElement("result.ip"));
- assertEquals("15", map.getElement("result.timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("result.headers.x-ttl"));
assertInstanceOf(Map.class, map.getElement("result.body"));
Map received = (Map) map.getElement("result.body");
assertEquals(data, received);
@@ -655,6 +667,7 @@ public void sendHttpDelete() throws IOException, InterruptedException {
req.setUrl("/api/hello/world");
req.setTargetHost("http://127.0.0.1:"+port);
req.setHeader("accept", "application/json");
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -667,7 +680,7 @@ public void sendHttpDelete() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("DELETE", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals(10, map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertNull(map.getElement("body"));
}
@@ -735,6 +748,7 @@ public void postXmlMap() throws IOException, InterruptedException {
req.setBody(data);
req.setHeader("accept", "application/json");
req.setHeader("content-type", "application/xml");
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -748,13 +762,12 @@ public void postXmlMap() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("POST", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals(10, map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertInstanceOf(Map.class, map.getElement("body"));
Map received = (Map) map.getElement("body");
assertEquals(data, received);
}
-
@SuppressWarnings("unchecked")
@Test
public void postList() throws IOException, InterruptedException {
@@ -770,6 +783,7 @@ public void postList() throws IOException, InterruptedException {
req.setBody(Collections.singletonList(data));
req.setHeader("accept", "application/json");
req.setHeader("content-type", "application/json");
+ req.setTimeoutSeconds((int) RPC_TIMEOUT / 1000);
EventEnvelope request = new EventEnvelope().setTo(HTTP_REQUEST).setBody(req);
Future res = po.asyncRequest(request, RPC_TIMEOUT);
res.onSuccess(bench::offer);
@@ -783,7 +797,7 @@ public void postList() throws IOException, InterruptedException {
assertEquals("/api/hello/world", map.getElement("url"));
assertEquals("POST", map.getElement("method"));
assertEquals("127.0.0.1", map.getElement("ip"));
- assertEquals(10, map.getElement("timeout"));
+ assertEquals(String.valueOf(RPC_TIMEOUT), map.getElement("headers.x-ttl"));
assertInstanceOf(List.class, map.getElement("body"));
List