use of com.linkedin.r2.message.rest.RestRequestBuilder in project rest.li by linkedin.
the class HttpNettyClient method doWriteRequest.
@Override
protected void doWriteRequest(RestRequest request, RequestContext requestContext, SocketAddress address, Map<String, String> wireAttrs, final TimeoutTransportCallback<RestResponse> callback, long requestTimeout) {
final RestRequest newRequest = new RestRequestBuilder(request).overwriteHeaders(WireAttributeHelper.toWireAttributes(wireAttrs)).build();
requestContext.putLocalAttr(R2Constants.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_1_1);
final AsyncPool<Channel> pool;
try {
pool = getChannelPoolManagerPerRequest(request).getPoolForAddress(address);
} catch (IllegalStateException e) {
errorResponse(callback, e);
return;
}
final Cancellable pendingGet = pool.get(new Callback<Channel>() {
@Override
public void onSuccess(final Channel channel) {
// This handler ensures the channel is returned to the pool at the end of the
// Netty pipeline.
channel.attr(ChannelPoolHandler.CHANNEL_POOL_ATTR_KEY).set(pool);
callback.addTimeoutTask(() -> {
AsyncPool<Channel> pool1 = channel.attr(ChannelPoolHandler.CHANNEL_POOL_ATTR_KEY).getAndSet(null);
if (pool1 != null) {
pool1.dispose(channel);
}
});
TransportCallback<RestResponse> sslTimingCallback = SslHandshakeTimingHandler.getSslTimingCallback(channel, requestContext, callback);
// This handler invokes the callback with the response once it arrives.
channel.attr(RAPResponseHandler.CALLBACK_ATTR_KEY).set(sslTimingCallback);
// Set the session validator requested by the user
SslSessionValidator sslSessionValidator = (SslSessionValidator) requestContext.getLocalAttr(R2Constants.REQUESTED_SSL_SESSION_VALIDATOR);
channel.attr(NettyChannelAttributes.SSL_SESSION_VALIDATOR).set(sslSessionValidator);
final NettyClientState state = _state.get();
if (state == NettyClientState.REQUESTS_STOPPING || state == NettyClientState.SHUTDOWN) {
// In this case, we acquired a channel from the pool as request processing is halting.
// The shutdown task might not timeout this callback, since it may already have scanned
// all the channels for pending requests before we set the callback as the channel
// attachment. The TimeoutTransportCallback ensures the user callback in never
// invoked more than once, so it is safe to invoke it unconditionally.
errorResponse(sslTimingCallback, new TimeoutException("Operation did not complete before shutdown"));
// The channel is usually release in two places: timeout or in the netty pipeline.
// Since we call the callback above, the timeout associated will be never invoked. On top of that
// we never send the request to the pipeline (due to the return statement), and nobody is releasing the channel
// until the channel is forcefully closed by the shutdownTimeout. Therefore we have to release it here
AsyncPool<Channel> pool = channel.attr(ChannelPoolHandler.CHANNEL_POOL_ATTR_KEY).getAndSet(null);
if (pool != null) {
pool.put(channel);
}
return;
}
// here we want the exception in outbound operations to be passed back through pipeline so that
// the user callback would be invoked with the exception and the channel can be put back into the pool
channel.writeAndFlush(newRequest).addListener(new ErrorChannelFutureListener());
}
@Override
public void onError(Throwable e) {
errorResponse(callback, e);
}
});
if (pendingGet != null) {
callback.addTimeoutTask(pendingGet::cancel);
}
}
use of com.linkedin.r2.message.rest.RestRequestBuilder in project rest.li by linkedin.
the class RestClient method buildRestRequest.
// This throws Exception to remind the caller to deal with arbitrary exceptions including RuntimeException
// in a way appropriate for the public method that was originally invoked.
private RestRequest buildRestRequest(URI uri, ResourceMethod method, DataMap dataMap, Map<String, String> headers, List<String> cookies, ProtocolVersion protocolVersion, ContentType contentType, List<ContentType> acceptTypes, boolean acceptResponseAttachments) throws Exception {
RestRequestBuilder requestBuilder = new RestRequestBuilder(uri).setMethod(method.getHttpMethod().toString());
requestBuilder.setHeaders(headers);
requestBuilder.setCookies(cookies);
addAcceptHeaders(requestBuilder, acceptTypes, acceptResponseAttachments);
final ContentType type = resolveContentType(requestBuilder, dataMap, contentType, uri);
if (type != null) {
requestBuilder.setHeader(RestConstants.HEADER_CONTENT_TYPE, type.getHeaderKey());
requestBuilder.setEntity(type.getCodec().mapToByteString(dataMap));
}
addProtocolVersionHeader(requestBuilder, protocolVersion);
if (method.getHttpMethod() == HttpMethod.POST) {
requestBuilder.setHeader(RestConstants.HEADER_RESTLI_REQUEST_METHOD, method.toString());
}
return requestBuilder.build();
}
use of com.linkedin.r2.message.rest.RestRequestBuilder in project rest.li by linkedin.
the class PatchBuilder method buildPatchFromString.
@SuppressWarnings("unchecked")
public static <T extends RecordTemplate> PatchRequest<T> buildPatchFromString(String patch) {
PatchRequest<T> patchRequest = null;
try {
RestRequest restRequest = new RestRequestBuilder(new URI("/test")).setEntity(patch.getBytes()).build();
patchRequest = (PatchRequest<T>) ArgumentBuilder.extractEntity(restRequest, PatchRequest.class);
} catch (URISyntaxException e) {
}
return patchRequest;
}
use of com.linkedin.r2.message.rest.RestRequestBuilder in project rest.li by linkedin.
the class TestDocumentationHandler method testHTML.
@Test
public void testHTML() throws ExecutionException, InterruptedException {
Map<String, String> transportProperties = Collections.singletonMap(HttpClientFactory.HTTP_REQUEST_TIMEOUT, "10000");
Client client = newTransportClient(transportProperties);
URI uri = URI.create("http://localhost:" + RestLiIntTestServer.DEFAULT_PORT + "/restli/docs");
RestRequest r = new RestRequestBuilder(uri).setMethod(RestMethod.GET).build();
RestResponse response = client.restRequest(r).get();
Assert.assertFalse(response.getEntity().isEmpty());
String html = response.getEntity().asString(StandardCharsets.UTF_8);
Assert.assertTrue(html.contains("<a href=\"http://localhost:1338/restli/docs?format=json\">View in JSON format</a>"));
}
use of com.linkedin.r2.message.rest.RestRequestBuilder in project rest.li by linkedin.
the class TestResourceContextImpl method testReturnEntityParameter.
@Test(dataProvider = "returnEntityParameterData")
public void testReturnEntityParameter(String uri, boolean expectReturnEntity, boolean expectException) throws RestLiSyntaxException {
final ResourceContextImpl context = new ResourceContextImpl(new PathKeysImpl(), new RestRequestBuilder(URI.create(uri)).setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.LATEST_PROTOCOL_VERSION.toString()).build(), new RequestContext());
try {
final boolean returnEntity = context.isReturnEntityRequested();
if (expectException) {
Assert.fail("Exception should be thrown for URI: " + uri);
}
Assert.assertEquals(returnEntity, expectReturnEntity, "Resource context was wrong about whether the URI \"" + uri + "\" indicates that the entity should be returned.");
} catch (RestLiServiceException e) {
if (!expectException) {
Assert.fail("Exception should not be thrown for URI: " + uri);
}
}
}
Aggregations