Java tutorial
/** * Copyright (C) 2015 The Gravitee team (http://gravitee.io) * * 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 io.gravitee.fetcher.http; import io.gravitee.common.http.HttpStatusCode; import io.gravitee.fetcher.api.Fetcher; import io.gravitee.fetcher.api.FetcherException; import io.gravitee.fetcher.api.Resource; import io.gravitee.fetcher.http.vertx.VertxCompletableFuture; import io.vertx.core.Vertx; 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 io.vertx.core.net.ProxyOptions; import io.vertx.core.net.ProxyType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import java.io.ByteArrayInputStream; import java.net.URI; import java.util.concurrent.CompletableFuture; /** * @author David BRASSELY (david.brassely at graviteesource.com) * @author Nicolas GERAUD (nicolas.geraud at graviteesource.com) * @author GraviteeSource Team */ public class HttpFetcher implements Fetcher { private static final Logger logger = LoggerFactory.getLogger(HttpFetcher.class); private static final String HTTPS_SCHEME = "https"; private HttpFetcherConfiguration httpFetcherConfiguration; @Value("${httpClient.timeout:10000}") private int httpClientTimeout; @Value("${httpClient.proxy.type:HTTP}") private String httpClientProxyType; @Value("${httpClient.proxy.http.host:#{systemProperties['http.proxyHost'] ?: 'localhost'}}") private String httpClientProxyHttpHost; @Value("${httpClient.proxy.http.port:#{systemProperties['http.proxyPort'] ?: 3128}}") private int httpClientProxyHttpPort; @Value("${httpClient.proxy.http.username:#{null}}") private String httpClientProxyHttpUsername; @Value("${httpClient.proxy.http.password:#{null}}") private String httpClientProxyHttpPassword; @Value("${httpClient.proxy.https.host:#{systemProperties['https.proxyHost'] ?: 'localhost'}}") private String httpClientProxyHttpsHost; @Value("${httpClient.proxy.https.port:#{systemProperties['https.proxyPort'] ?: 3128}}") private int httpClientProxyHttpsPort; @Value("${httpClient.proxy.https.username:#{null}}") private String httpClientProxyHttpsUsername; @Value("${httpClient.proxy.https.password:#{null}}") private String httpClientProxyHttpsPassword; @Autowired private Vertx vertx; public HttpFetcher(HttpFetcherConfiguration httpFetcherConfiguration) { this.httpFetcherConfiguration = httpFetcherConfiguration; } @Override public Resource fetch() throws FetcherException { try { Buffer buffer = fetchContent().join(); if (buffer == null) { throw new FetcherException( "Unable to fetch Http content '" + httpFetcherConfiguration.getUrl() + "': no content", null); } final Resource resource = new Resource(); resource.setContent(new ByteArrayInputStream(buffer.getBytes())); return resource; } catch (Exception ex) { throw new FetcherException("Unable to fetch Http content (" + ex.getMessage() + ")", ex); } } private CompletableFuture<Buffer> fetchContent() { CompletableFuture<Buffer> future = new VertxCompletableFuture<>(vertx); URI requestUri = URI.create(httpFetcherConfiguration.getUrl()); boolean ssl = HTTPS_SCHEME.equalsIgnoreCase(requestUri.getScheme()); final HttpClientOptions options = new HttpClientOptions().setSsl(ssl).setTrustAll(true).setMaxPoolSize(1) .setKeepAlive(false).setTcpKeepAlive(false).setConnectTimeout(httpClientTimeout); if (httpFetcherConfiguration.isUseSystemProxy()) { ProxyOptions proxyOptions = new ProxyOptions(); proxyOptions.setType(ProxyType.valueOf(httpClientProxyType)); if (HTTPS_SCHEME.equals(requestUri.getScheme())) { proxyOptions.setHost(httpClientProxyHttpsHost); proxyOptions.setPort(httpClientProxyHttpsPort); proxyOptions.setUsername(httpClientProxyHttpsUsername); proxyOptions.setPassword(httpClientProxyHttpsPassword); } else { proxyOptions.setHost(httpClientProxyHttpHost); proxyOptions.setPort(httpClientProxyHttpPort); proxyOptions.setUsername(httpClientProxyHttpUsername); proxyOptions.setPassword(httpClientProxyHttpPassword); } options.setProxyOptions(proxyOptions); } final HttpClient httpClient = vertx.createHttpClient(options); final int port = requestUri.getPort() != -1 ? requestUri.getPort() : (HTTPS_SCHEME.equals(requestUri.getScheme()) ? 443 : 80); try { HttpClientRequest request = httpClient.request(HttpMethod.GET, port, requestUri.getHost(), requestUri.toString()); request.setTimeout(httpClientTimeout); request.handler(response -> { if (response.statusCode() == HttpStatusCode.OK_200) { response.bodyHandler(buffer -> { future.complete(buffer); // Close client httpClient.close(); }); } else { future.complete(null); } }); request.exceptionHandler(event -> { try { future.completeExceptionally(event); // Close client httpClient.close(); } catch (IllegalStateException ise) { // Do not take care about exception when closing client } }); request.end(); } catch (Exception ex) { logger.error("Unable to fetch content using HTTP", ex); future.completeExceptionally(ex); } return future; } public void setVertx(Vertx vertx) { this.vertx = vertx; } }