Java tutorial
/* * Copyright 2015 Cisco Systems, Inc. * * 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 com.cisco.oss.foundation.http.jetty; import com.cisco.oss.foundation.flowcontext.FlowContext; import com.cisco.oss.foundation.flowcontext.FlowContextFactory; import com.cisco.oss.foundation.http.*; import com.cisco.oss.foundation.loadbalancer.LoadBalancerStrategy; import com.cisco.oss.foundation.loadbalancer.InternalServerProxy; import com.cisco.oss.foundation.loadbalancer.RequestTimeoutException; import com.google.common.base.Joiner; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang3.StringUtils; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.util.BytesContentProvider; import org.eclipse.jetty.util.HttpCookieStore; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collection; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * Created by Yair Ogen on 1/16/14. */ public class JettyHttpClient<S extends HttpRequest, R extends HttpResponse> extends AbstractHttpClient<S, R> { private static final Logger LOGGER = LoggerFactory.getLogger(JettyHttpClient.class); public JettyHttpClient(String apiName, Configuration configuration, boolean enableLoadBalancing) { super(apiName, configuration, enableLoadBalancing); configureClient(); } public JettyHttpClient(String apiName, LoadBalancerStrategy.STRATEGY_TYPE strategyType, Configuration configuration, boolean enableLoadBalancing) { super(apiName, strategyType, configuration, enableLoadBalancing); configureClient(); } private org.eclipse.jetty.client.HttpClient httpClient = new HttpClient(); @Override protected void configureClient() { boolean addSslSupport = StringUtils.isNotEmpty(metadata.getKeyStorePath()) && StringUtils.isNotEmpty(metadata.getKeyStorePassword()); if (addSslSupport) { SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setKeyStorePath(metadata.getKeyStorePath()); sslContextFactory.setKeyStorePassword(metadata.getKeyStorePassword()); boolean addTrustSupport = StringUtils.isNotEmpty(metadata.getTrustStorePath()) && StringUtils.isNotEmpty(metadata.getTrustStorePassword()); if (addTrustSupport) { sslContextFactory.setTrustStorePath(metadata.getTrustStorePath()); sslContextFactory.setTrustStorePassword(metadata.getTrustStorePassword()); } else { sslContextFactory.setTrustAll(true); } httpClient = new HttpClient(sslContextFactory); } httpClient.setConnectTimeout(metadata.getConnectTimeout()); httpClient.setIdleTimeout(metadata.getIdleTimeout()); httpClient.setMaxConnectionsPerDestination(metadata.getMaxConnectionsPerAddress()); httpClient.setMaxRequestsQueuedPerDestination(metadata.getMaxQueueSizePerAddress()); httpClient.setFollowRedirects(followRedirects); if (metadata.isDisableCookies()) { httpClient.setCookieStore(new HttpCookieStore.Empty()); } try { httpClient.start(); } catch (Exception e) { throw new ClientException("failed to start jetty http client: " + e, e); } } @Override public HttpResponse executeDirect(HttpRequest request) { Request httpRequest = prepareRequest(request); try { ContentResponse contentResponse = httpRequest.send(); return new JettyHttpResponse(contentResponse, httpRequest.getURI()); } catch (InterruptedException e) { throw new ClientException(e.toString(), e); } catch (TimeoutException e) { throw new RequestTimeoutException(e.toString(), e); } catch (ExecutionException e) { throw new ClientException(e.toString(), e); } } @Override public void execute(HttpRequest request, ResponseCallback responseCallback, LoadBalancerStrategy loadBalancerStrategy, String apiName) { InternalServerProxy serverProxy = loadBalancerStrategy.getServerProxy(request); Throwable lastCaugtException = null; if (serverProxy == null) { // server proxy will be null if the configuration was not // configured properly // or if all the servers are passivated. loadBalancerStrategy.handleNullserverProxy(apiName, lastCaugtException); } request = updateRequestUri((S) request, serverProxy); final HttpRequest tempRequest = request; LOGGER.info("sending request: {}", request.getUri()); final FlowContext fc = FlowContextFactory.getFlowContext(); Request httpRequest = prepareRequest(request).onRequestQueued(new Request.QueuedListener() { @Override public void onQueued(Request jettyRequest) { FlowContextFactory.addFlowContext(((S) tempRequest).getFlowContext()); } }).onRequestBegin(new Request.BeginListener() { @Override public void onBegin(Request jettyRequest) { FlowContextFactory.addFlowContext(((S) tempRequest).getFlowContext()); } }).onRequestFailure(new Request.FailureListener() { @Override public void onFailure(Request jettyRequest, Throwable failure) { FlowContextFactory.addFlowContext(((S) tempRequest).getFlowContext()); } }); httpRequest.send(new JettyCompleteListener(this, request, responseCallback, serverProxy, loadBalancerStrategy, apiName)); } private Request prepareRequest(HttpRequest request) { Request httpRequest = httpClient.newRequest(request.getUri()) .timeout(metadata.getReadTimeout(), TimeUnit.MILLISECONDS).method(request.getHttpMethod().method()); byte[] entity = request.getEntity(); if (entity != null) { httpRequest = httpRequest.content(new BytesContentProvider(entity), request.getContentType()); } Joiner joiner = Joiner.on(",").skipNulls(); Map<String, Collection<String>> headers = request.getHeaders(); for (Map.Entry<String, Collection<String>> stringCollectionEntry : headers.entrySet()) { String key = stringCollectionEntry.getKey(); Collection<String> stringCollection = stringCollectionEntry.getValue(); String value = joiner.join(stringCollection); httpRequest = httpRequest.header(key, value); } for (Map.Entry<String, Collection<String>> stringCollectionEntry : request.getQueryParams().entrySet()) { String key = stringCollectionEntry.getKey(); Collection<String> stringCollection = stringCollectionEntry.getValue(); String value = joiner.join(stringCollection); httpRequest = httpRequest.param(key, value); } return httpRequest; } }