Java tutorial
/* * Copyright (c) 2015-2016. Ventu.io, Oleg Sklyar and contributors, distributed under the MIT license. */ package io.ventu.rpc.rest; import java.util.Collections; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.CompletableFuture; import java.util.function.Function; import io.ventu.rpc.exception.ApiException; import io.ventu.rpc.exception.EncodingException; import io.ventu.rpc.rest.exception.HttpException; import io.ventu.rpc.rest.util.HttpRequestRouter; import io.ventu.rpc.util.Serializer; import io.ventu.rpc.util.Validator; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientOptions; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class HttpRestInvokerImpl implements HttpRestInvoker { private static Logger log = LoggerFactory.getLogger(HttpRestInvoker.class); private final HttpClient client; private final HttpRequestRouter requestRouter; private final Validator responseValidator; private final Serializer serializer; private final Map<String, String> headers; HttpRestInvokerImpl(Function<HttpClientOptions, HttpClient> initializer, HttpClientOptions opts, HttpRequestRouter requestRouter, Validator responseValidator, Serializer serializer, Map<String, String> headers) { this.requestRouter = requestRouter; this.responseValidator = responseValidator; this.serializer = serializer; this.headers = Collections.unmodifiableMap(headers); client = initializer.apply(opts); } @Override public <RQ, RS> CompletableFuture<RS> invoke(final RQ request, final Class<RS> responseClass) { final CompletableFuture<RS> answer = new CompletableFuture<>(); try { String url = requestRouter.route(request); HttpMethod method = HttpMethod.POST; switch (requestRouter.type(request)) { case GET: method = HttpMethod.GET; break; case PUT: method = HttpMethod.PUT; break; case DELETE: method = HttpMethod.DELETE; break; default: // POST, keep as is } HttpClientRequest httpRequest = client.request(method, url, httpResponse -> { int statusCode = httpResponse.statusCode(); if (statusCode < 400) { httpResponse.bodyHandler(buffer -> { try { RS resp = serializer.decode(buffer.getBytes(), responseClass); responseValidator.validate(resp); answer.complete(resp); } catch (ApiException | EncodingException | IllegalArgumentException | NullPointerException ex) { answer.completeExceptionally(ex); } }); } else { answer.completeExceptionally(new HttpException(statusCode, httpResponse.statusMessage())); } }); for (Entry<String, String> entry : headers.entrySet()) { httpRequest.putHeader(entry.getKey(), entry.getValue()); } httpRequest.putHeader("Content-type", CONTENT_TYPE).putHeader("Accept", CONTENT_TYPE); if ((method == HttpMethod.POST) || (method == HttpMethod.PUT)) { byte[] payload = serializer.encode(request); httpRequest.setChunked(true).end(Buffer.buffer(payload)); } else { httpRequest.end(); } } catch (IllegalArgumentException | EncodingException ex) { answer.completeExceptionally(ex); } return answer; } @Override public CompletableFuture<Void> close() { CompletableFuture<Void> future = new CompletableFuture<>(); client.close(); future.complete(null); return future; } }