use of org.glassfish.jersey.internal.util.collection.ByteBufferInputStream in project jersey by jersey.
the class JettyConnector method apply.
@Override
public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCallback callback) {
final Request jettyRequest = translateRequest(jerseyRequest);
final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(jerseyRequest.getHeaders(), jettyRequest);
final ContentProvider entity = getStreamProvider(jerseyRequest);
if (entity != null) {
jettyRequest.content(entity);
}
final AtomicBoolean callbackInvoked = new AtomicBoolean(false);
final Throwable failure;
try {
final CompletableFuture<ClientResponse> responseFuture = new CompletableFuture<ClientResponse>().whenComplete((clientResponse, throwable) -> {
if (throwable != null && throwable instanceof CancellationException) {
// take care of future cancellation
jettyRequest.abort(throwable);
}
});
final AtomicReference<ClientResponse> jerseyResponse = new AtomicReference<>();
final ByteBufferInputStream entityStream = new ByteBufferInputStream();
jettyRequest.send(new Response.Listener.Adapter() {
@Override
public void onHeaders(final Response jettyResponse) {
HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(), JettyConnector.this.getClass().getName());
if (responseFuture.isDone()) {
if (!callbackInvoked.compareAndSet(false, true)) {
return;
}
}
final ClientResponse response = translateResponse(jerseyRequest, jettyResponse, entityStream);
jerseyResponse.set(response);
callback.response(response);
}
@Override
public void onContent(final Response jettyResponse, final ByteBuffer content) {
try {
entityStream.put(content);
} catch (final InterruptedException ex) {
final ProcessingException pe = new ProcessingException(ex);
entityStream.closeQueue(pe);
// try to complete the future with an exception
responseFuture.completeExceptionally(pe);
Thread.currentThread().interrupt();
}
}
@Override
public void onComplete(final Result result) {
entityStream.closeQueue();
// try to complete the future with the response only once truly done
responseFuture.complete(jerseyResponse.get());
}
@Override
public void onFailure(final Response response, final Throwable t) {
entityStream.closeQueue(t);
// try to complete the future with an exception
responseFuture.completeExceptionally(t);
if (callbackInvoked.compareAndSet(false, true)) {
callback.failure(t);
}
}
});
processContent(jerseyRequest, entity);
return responseFuture;
} catch (final Throwable t) {
failure = t;
}
if (callbackInvoked.compareAndSet(false, true)) {
callback.failure(failure);
}
CompletableFuture<Object> future = new CompletableFuture<>();
future.completeExceptionally(failure);
return future;
}
use of org.glassfish.jersey.internal.util.collection.ByteBufferInputStream in project jersey by jersey.
the class GrizzlyConnector method apply.
@Override
public Future<?> apply(final ClientRequest request, final AsyncConnectorCallback callback) {
final Request connectorRequest = translate(request);
final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(request.getHeaders(), connectorRequest);
final ByteBufferInputStream entityStream = new ByteBufferInputStream();
final AtomicBoolean callbackInvoked = new AtomicBoolean(false);
Throwable failure;
try {
return grizzlyClient.executeRequest(connectorRequest, new AsyncHandler<Void>() {
private volatile HttpResponseStatus status = null;
@Override
public STATE onStatusReceived(final HttpResponseStatus responseStatus) throws Exception {
status = responseStatus;
return STATE.CONTINUE;
}
@Override
public STATE onHeadersReceived(HttpResponseHeaders headers) throws Exception {
if (!callbackInvoked.compareAndSet(false, true)) {
return STATE.ABORT;
}
HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, request.getHeaders(), GrizzlyConnector.this.getClass().getName());
// hand-off to grizzly's application thread pool for response processing
processResponse(new Runnable() {
@Override
public void run() {
callback.response(translate(request, status, headers, entityStream));
}
});
return STATE.CONTINUE;
}
@Override
public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
entityStream.put(bodyPart.getBodyByteBuffer());
return STATE.CONTINUE;
}
@Override
public Void onCompleted() throws Exception {
entityStream.closeQueue();
return null;
}
@Override
public void onThrowable(Throwable t) {
entityStream.closeQueue(t);
if (callbackInvoked.compareAndSet(false, true)) {
t = t instanceof IOException ? new ProcessingException(t.getMessage(), t) : t;
callback.failure(t);
}
}
});
} catch (Throwable t) {
failure = t;
}
if (callbackInvoked.compareAndSet(false, true)) {
callback.failure(failure);
}
CompletableFuture<Object> future = new CompletableFuture<>();
future.completeExceptionally(failure);
return future;
}
use of org.glassfish.jersey.internal.util.collection.ByteBufferInputStream in project jersey by jersey.
the class GrizzlyConnector method apply.
/**
* Sends the {@link javax.ws.rs.core.Request} via Grizzly transport and returns the {@link javax.ws.rs.core.Response}.
*
* @param request Jersey client request to be sent.
* @return received response.
*/
@Override
public ClientResponse apply(final ClientRequest request) {
final Request connectorRequest = translate(request);
final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(request.getHeaders(), connectorRequest);
final CompletableFuture<ClientResponse> responseFuture = new CompletableFuture<>();
final ByteBufferInputStream entityStream = new ByteBufferInputStream();
final AtomicBoolean futureSet = new AtomicBoolean(false);
try {
grizzlyClient.executeRequest(connectorRequest, new AsyncHandler<Void>() {
private volatile HttpResponseStatus status = null;
@Override
public STATE onStatusReceived(final HttpResponseStatus responseStatus) throws Exception {
status = responseStatus;
return STATE.CONTINUE;
}
@Override
public STATE onHeadersReceived(HttpResponseHeaders headers) throws Exception {
if (!futureSet.compareAndSet(false, true)) {
return STATE.ABORT;
}
HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, request.getHeaders(), GrizzlyConnector.this.getClass().getName());
responseFuture.complete(translate(request, this.status, headers, entityStream));
return STATE.CONTINUE;
}
@Override
public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
entityStream.put(bodyPart.getBodyByteBuffer());
return STATE.CONTINUE;
}
@Override
public Void onCompleted() throws Exception {
entityStream.closeQueue();
return null;
}
@Override
public void onThrowable(Throwable t) {
entityStream.closeQueue(t);
if (futureSet.compareAndSet(false, true)) {
t = t instanceof IOException ? new ProcessingException(t.getMessage(), t) : t;
responseFuture.completeExceptionally(t);
}
}
});
return responseFuture.get();
} catch (ExecutionException ex) {
Throwable e = ex.getCause() == null ? ex : ex.getCause();
throw new ProcessingException(e.getMessage(), e);
} catch (InterruptedException ex) {
throw new ProcessingException(ex.getMessage(), ex);
}
}
use of org.glassfish.jersey.internal.util.collection.ByteBufferInputStream in project jersey by jersey.
the class AsynchronousBodyInputStream method commitToMode.
private synchronized void commitToMode() {
// return if the mode has already been committed
if (mode != Mode.UNDECIDED) {
return;
}
// go asynchronous, if the user has made any move suggesting asynchronous mode
if (readListener != null || listenerExecutor != null) {
mode = Mode.ASYNCHRONOUS;
return;
}
// go synchronous, if the user has not made any move suggesting asynchronous mode
mode = Mode.SYNCHRONOUS;
synchronousStream = new ByteBufferInputStream();
// move all buffered data to synchronous stream
for (ByteBuffer b : data) {
if (b == EOF) {
synchronousStream.closeQueue();
} else if (b == ERROR) {
synchronousStream.closeQueue(t);
} else {
try {
synchronousStream.put(b);
} catch (InterruptedException e) {
synchronousStream.closeQueue(e);
}
}
}
}
Aggregations