use of org.webpieces.util.futures.XFuture in project webpieces by deanhiller.
the class ResponseCacher method run.
public XFuture<FullResponse> run(FullRequest request) {
SingleResponseListener responseListener = new SingleResponseListener();
RequestStreamHandle streamHandle = openStreamFunc.get();
Http2Request req = request.getHeaders();
if (request.getPayload() == null) {
request.getHeaders().setEndOfStream(true);
streamHandle.process(req, responseListener);
return responseListener.fetchResponseFuture();
} else if (request.getTrailingHeaders() == null) {
request.getHeaders().setEndOfStream(false);
DataFrame data = createData(request, true);
StreamRef streamRef = streamHandle.process(request.getHeaders(), responseListener);
return streamRef.getWriter().thenCompose(writer -> {
data.setStreamId(req.getStreamId());
return writer.processPiece(data);
}).thenCompose(writer -> responseListener.fetchResponseFuture());
}
request.getHeaders().setEndOfStream(false);
DataFrame data = createData(request, false);
Http2Trailers trailers = request.getTrailingHeaders();
trailers.setEndOfStream(true);
StreamRef streamRef = streamHandle.process(request.getHeaders(), responseListener);
return streamRef.getWriter().thenCompose(writer -> writeStuff(writer, req, data, trailers, responseListener));
}
use of org.webpieces.util.futures.XFuture in project webpieces by deanhiller.
the class TestStreamingRaw method testAsyncJsonGet.
@Test
public void testAsyncJsonGet() throws InterruptedException, ExecutionException {
MockChannel channel = new MockChannel();
XFuture<DataListener> future = mgr.simulateHttpConnect(channel);
DataListener dataListener = future.get();
HttpFullRequest fullRequest = Requests.createJsonRequest(KnownHttpMethod.GET, "/json/streaming");
ByteBuffer buffer = parser.marshalToByteBuffer(fullRequest.getRequest());
DataWrapper data = fullRequest.getData();
byte[] headers = new byte[buffer.remaining()];
buffer.get(headers);
data.getReadableSize();
byte[] part1 = data.readBytesAt(0, 10);
String str = new String(part1);
byte[] part2 = data.readBytesAt(10, data.getReadableSize() - 10);
String str2 = new String(part2);
ByteBuffer firstPacket = ByteBuffer.allocate(headers.length + part1.length);
firstPacket.put(headers);
firstPacket.put(part1);
firstPacket.flip();
XFuture<Boolean> authFuture = new XFuture<Boolean>();
mockAuth.addValueToReturn(authFuture);
Assert.assertEquals(0, Context.getContext().size());
// Feed in request with content-length AND part of the body as well...
XFuture<Void> fut1 = dataListener.incomingData(channel, firstPacket);
Assert.assertEquals(0, Context.getContext().size());
// Feed in more BEFORE authFuture is complete(this was the bug, ie. race condition)
ByteBuffer buf2 = ByteBuffer.allocate(part2.length);
buf2.put(part2);
buf2.flip();
XFuture<Void> fut2 = dataListener.incomingData(channel, buf2);
Assert.assertEquals(0, Context.getContext().size());
XFuture<StreamWriter> streamWriterFuture = new XFuture<StreamWriter>();
mockStreamClient.addStreamWriter(streamWriterFuture);
// complete it
authFuture.complete(true);
Assert.assertFalse(fut1.isDone());
Assert.assertFalse(fut2.isDone());
MockStreamWriter2 mockStreamWriter = new MockStreamWriter2();
streamWriterFuture.complete(mockStreamWriter);
Assert.assertEquals(0, Context.getContext().size());
Assert.assertTrue(fut1.isDone());
Assert.assertTrue(fut2.isDone());
List<StreamMsg> frames = mockStreamWriter.getFrames();
Assert.assertEquals(2, frames.size());
DataFrame f1 = (DataFrame) frames.get(0);
DataFrame f2 = (DataFrame) frames.get(1);
String s1 = f1.getData().createStringFromUtf8(0, f1.getData().getReadableSize());
Assert.assertEquals(str, s1);
String s2 = f2.getData().createStringFromUtf8(0, f2.getData().getReadableSize());
Assert.assertEquals(str2, s2);
Assert.assertEquals(0, Context.getContext().size());
}
use of org.webpieces.util.futures.XFuture in project webpieces by deanhiller.
the class HttpsJsonClientInvokeHandler method invoke.
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
TestCaseRecorder recorder = (TestCaseRecorder) Context.get(RECORDER_KEY);
EndpointInfo recordingInfo = null;
if (recorder != null) {
Map<String, Object> ctxSnapshot = Context.copyContext();
recordingInfo = new EndpointInfo(method, args, ctxSnapshot);
recorder.addEndpointInfo(recordingInfo);
}
clientAssertions.throwIfCannotGoRemote();
Path annotation = method.getAnnotation(Path.class);
if (annotation == null) {
throw new IllegalArgumentException("The @Path annotation is missing from method=" + method + " clazz=" + method.getDeclaringClass());
}
String path = getPath(method);
HttpMethod httpMethod = getHttpMethod(method);
Class<?> clazz = method.getReturnType();
if (!(CompletableFuture.class.isAssignableFrom(clazz))) {
throw new IllegalStateException("All api methods must return a XFuture");
}
ParameterizedType t = (ParameterizedType) method.getGenericReturnType();
Class retType = (Class) t.getActualTypeArguments()[0];
Map<String, Object> context = Context.getContext();
if (context == null) {
throw new IllegalStateException("Please call Current.setContext with the request context or create your own context");
}
Object header = context.get(Context.HEADERS);
if (header == null) {
throw new IllegalStateException("Context.HEADERS is missing from the Context. please set that up first");
} else if (!(header instanceof Map)) {
throw new IllegalStateException("Context.HEADERS is not a Map<String, String> and is setup incorrectly");
}
log.info("Sending http request to: " + addr.getHostName() + ":" + addr.getPort() + path);
Object body = args[0];
if (hasUrlParams) {
path = transformPath(path, method, args);
body = findBody(method, args);
}
Endpoint endpoint = new Endpoint(addr, httpMethod.getCode(), path);
XFuture<Object> xFuture = clientHelper.sendHttpRequest(method, body, endpoint, retType).thenApply(retVal -> {
// Only needed by APIs/methods that return CompletableFuture :( not XFuture
Context.restoreContext(context);
return retVal;
});
if (recorder == null) {
return xFuture;
}
EndpointInfo finalInfo = recordingInfo;
return xFuture.handle((resp, exc1) -> addTestRecordingInfo(finalInfo, resp, exc1)).thenCompose(Function.identity());
}
use of org.webpieces.util.futures.XFuture in project webpieces by deanhiller.
the class TestHttp11Backpressure method testInitializeThenPostWithChunkingBackpressure.
@Test
public void testInitializeThenPostWithChunkingBackpressure() throws InterruptedException, ExecutionException, TimeoutException {
// send first request to get past protocoal detection(ie. initialize) and send response
initialize();
List<ByteBuffer> buffers = create4SplitPayloads();
XFuture<Void> ackBytePayload1 = mockChannel.sendToSvr(buffers.get(0));
// not enough data. parser consumes and acks future for more data(no client ack needed right now)
Assert.assertTrue(ackBytePayload1.isDone());
XFuture<StreamWriter> ackRequest = new XFuture<StreamWriter>();
mockListener.addMockStreamToReturn(new MockStreamRef(ackRequest));
XFuture<Void> ackBytePayload2 = mockChannel.sendToSvr(buffers.get(1));
Assert.assertFalse(ackBytePayload2.isDone());
// This releases the response msg acking 10 bytes
ackRequest.complete(mockStreamWriter);
Assert.assertTrue(ackBytePayload2.isDone());
// feed the rest of first chunk in and feed part of last chunk
XFuture<Void> firstChunkAck = new XFuture<Void>();
mockStreamWriter.addProcessResponse(firstChunkAck);
XFuture<Void> ackBytePayload3 = mockChannel.sendToSvr(buffers.get(2));
Assert.assertFalse(ackBytePayload3.isDone());
// ack the http chunk packet
firstChunkAck.complete(null);
Assert.assertTrue(ackBytePayload3.isDone());
XFuture<Void> lastChunkAck = new XFuture<Void>();
mockStreamWriter.addProcessResponse(lastChunkAck);
XFuture<Void> ackBytePayload4 = mockChannel.sendToSvr(buffers.get(3));
Assert.assertFalse(ackBytePayload4.isDone());
lastChunkAck.complete(null);
Assert.assertTrue(ackBytePayload4.isDone());
}
use of org.webpieces.util.futures.XFuture in project webpieces by deanhiller.
the class TestHttp11Backpressure method testPostWithChunkingBackpressure.
@Test
public void testPostWithChunkingBackpressure() throws InterruptedException, ExecutionException, TimeoutException {
List<ByteBuffer> buffers = create4SplitPayloads();
XFuture<Void> ackBytePayload1 = mockChannel.sendToSvr(buffers.get(0));
ackBytePayload1.get(2, TimeUnit.SECONDS);
XFuture<StreamWriter> ackRequest = new XFuture<StreamWriter>();
mockListener.addMockStreamToReturn(new MockStreamRef(ackRequest));
XFuture<Void> ackBytePayload2 = mockChannel.sendToSvr(buffers.get(1));
// have to ack TWO...the stream writer AND the first HttpData fed in
Assert.assertFalse(ackBytePayload2.isDone());
XFuture<Void> firstChunkAck1 = new XFuture<Void>();
mockStreamWriter.addProcessResponse(firstChunkAck1);
ackRequest.complete(mockStreamWriter);
Assert.assertFalse(ackBytePayload2.isDone());
firstChunkAck1.complete(null);
Assert.assertTrue(ackBytePayload2.isDone());
// feed the rest of first chunk in and feed part of last chunk
XFuture<Void> firstChunkAck = new XFuture<Void>();
mockStreamWriter.addProcessResponse(firstChunkAck);
XFuture<Void> ackBytePayload3 = mockChannel.sendToSvr(buffers.get(2));
Assert.assertFalse(ackBytePayload3.isDone());
// ack the http chunk packet
firstChunkAck.complete(null);
Assert.assertTrue(ackBytePayload3.isDone());
XFuture<Void> lastChunkAck = new XFuture<Void>();
mockStreamWriter.addProcessResponse(lastChunkAck);
XFuture<Void> ackBytePayload4 = mockChannel.sendToSvr(buffers.get(3));
Assert.assertFalse(ackBytePayload4.isDone());
lastChunkAck.complete(null);
ackBytePayload4.get(2, TimeUnit.SECONDS);
}
Aggregations