1 package org.onap.msb.apiroute.wrapper.consulextend.util;
3 import java.io.IOException;
4 import java.lang.reflect.ParameterizedType;
5 import java.lang.reflect.Type;
6 import java.math.BigInteger;
10 import org.apache.commons.io.IOUtils;
11 import org.apache.http.HttpEntity;
12 import org.apache.http.HttpResponse;
13 import org.apache.http.client.methods.HttpGet;
14 import org.apache.http.concurrent.FutureCallback;
15 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
16 import org.apache.http.impl.nio.client.HttpAsyncClients;
17 import org.eclipse.jetty.http.HttpStatus;
18 import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseCallback;
19 import org.onap.msb.apiroute.wrapper.consulextend.async.ConsulResponseHeader;
20 import org.onap.msb.apiroute.wrapper.consulextend.async.OriginalConsulResponse;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
24 import com.fasterxml.jackson.core.type.TypeReference;
25 import com.google.common.collect.ImmutableList;
26 import com.google.common.collect.ImmutableMap;
27 import com.google.common.collect.Sets;
28 import com.orbitz.consul.ConsulException;
29 import com.orbitz.consul.model.ConsulResponse;
30 import com.orbitz.consul.option.CatalogOptions;
31 import com.orbitz.consul.option.QueryOptions;
32 import com.orbitz.consul.util.Jackson;
35 private static final Logger LOGGER = LoggerFactory.getLogger(Http.class);
37 private final static CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients
38 .custom().setMaxConnTotal(Integer.MAX_VALUE)
39 .setMaxConnPerRoute(Integer.MAX_VALUE).build();
41 private static Http instance = null;
46 public static Http getInstance() {
47 if (instance == null) {
48 instance = new Http();
49 httpAsyncClient.start();
55 // async get data from consul,and handle response immediately
56 public <T> void asyncGet(String requestURI,
57 final TypeReference<T> responseType,
58 final ConsulResponseCallback<T> callback, final Integer... okCodes) {
59 // LOGGER.info("Async request:"+requestURI);
61 httpAsyncClient.execute(new HttpGet(requestURI),
62 new FutureCallback<HttpResponse>() {
64 public void completed(final HttpResponse response) {
65 callback.onComplete(consulResponse(responseType,
69 public void failed(final Exception ex) {
70 callback.onFailure(ex);
73 public void cancelled() {
74 LOGGER.warn("cancelled async request");
79 // async get data from consul,and handle response delay
80 public <T> void asyncGetDelayHandle(String requestURI,
81 final TypeReference<T> responseType,
82 final ConsulResponseCallback<T> callback, final Integer... okCodes) {
84 httpAsyncClient.execute(new HttpGet(requestURI),
85 new FutureCallback<HttpResponse>() {
87 public void completed(final HttpResponse response) {
88 OriginalConsulResponse<T> originalConsulResponse = new OriginalConsulResponse<T>(
89 response, responseType);
92 if (!isSuccessful(response)) {
94 LOGGER.warn("response statuscode:"
95 + response.getStatusLine().getStatusCode());
97 callback.onFailure(new ConsulException(
98 "response statuscode:"
99 + response.getStatusLine()
102 callback.onDelayComplete(originalConsulResponse);
107 public void failed(final Exception ex) {
108 callback.onFailure(ex);
111 public void cancelled() {
112 LOGGER.warn("cancelled async request");
117 public static ConsulResponseHeader consulResponseHeader(
118 HttpResponse response) {
119 String indexHeaderValue = response.getFirstHeader("X-Consul-Index")
121 String lastContactHeaderValue = response.getFirstHeader(
122 "X-Consul-Lastcontact").getValue();
123 String knownLeaderHeaderValue = response.getFirstHeader(
124 "X-Consul-Knownleader").getValue();
126 BigInteger index = indexHeaderValue == null ? new BigInteger("0")
127 : new BigInteger(indexHeaderValue);
128 long lastContact = lastContactHeaderValue == null ? 0 : Long
129 .parseLong(lastContactHeaderValue);
130 boolean knownLeader = knownLeaderHeaderValue == null ? false : Boolean
131 .parseBoolean(knownLeaderHeaderValue);
133 return new ConsulResponseHeader(lastContact, knownLeader, index);
136 public static <T> ConsulResponse<T> consulResponse(
137 TypeReference<T> responseType, HttpResponse response) {
139 String indexHeaderValue = response.getFirstHeader("X-Consul-Index")
141 String lastContactHeaderValue = response.getFirstHeader(
142 "X-Consul-Lastcontact").getValue();
143 String knownLeaderHeaderValue = response.getFirstHeader(
144 "X-Consul-Knownleader").getValue();
146 BigInteger index = indexHeaderValue == null ? new BigInteger("0")
147 : new BigInteger(indexHeaderValue);
148 long lastContact = lastContactHeaderValue == null ? 0 : Long
149 .parseLong(lastContactHeaderValue);
150 boolean knownLeader = knownLeaderHeaderValue == null ? false : Boolean
151 .parseBoolean(knownLeaderHeaderValue);
153 ConsulResponse<T> consulResponse = new ConsulResponse<T>(readResponse(
154 response, responseType), lastContact, knownLeader, index);
155 return consulResponse;
158 @SuppressWarnings({ "unchecked", "rawtypes" })
159 public static <T> T readResponse(HttpResponse response,
160 TypeReference<T> responseType) {
162 // read streamed entity
165 // HttpEntity,read original data.
166 Type _type = responseType.getType();
167 if (_type instanceof Class
168 && (((Class) _type).isAssignableFrom(HttpEntity.class))) {
169 object = (T) response.getEntity();
173 // String,read original data.
174 if (_type instanceof Class
175 && (((Class) _type).isAssignableFrom(String.class))) {
180 .toString(response.getEntity().getContent());
181 response.getEntity().getContent().close();
183 } catch (UnsupportedOperationException e) {
185 LOGGER.warn("covert streamed entity to String exception:", e);
186 } catch (IOException e) {
188 LOGGER.warn("covert streamed entity to String exception:", e);
196 object = Jackson.MAPPER.readValue(
197 response.getEntity().getContent(), responseType);
198 } catch (IOException e) {
199 LOGGER.warn("covert streamed entity to object exception:", e);
200 object = readDefaultResponse(responseType);
206 @SuppressWarnings("unchecked")
207 public static <T> T readDefaultResponse(TypeReference<T> responseType) {
208 Type _type = responseType.getType();
209 if (_type instanceof ParameterizedType
210 && ((ParameterizedType) _type).getRawType() == List.class) {
211 return (T) ImmutableList.of();
212 } else if (_type instanceof ParameterizedType
213 && ((ParameterizedType) _type).getRawType() == Map.class) {
214 return (T) ImmutableMap.of();
216 // Not sure if this case will be reached, but if it is it'll be nice
218 throw new IllegalStateException(
219 "Cannot determine empty representation for " + _type);
223 public static boolean isSuccessful(HttpResponse response,
224 Integer... okCodes) {
225 return HttpStatus.isSuccess(response.getStatusLine().getStatusCode())
226 || Sets.newHashSet(okCodes).contains(
227 response.getStatusLine().getStatusCode());
230 public static String optionsFrom(CatalogOptions catalogOptions,
231 QueryOptions queryOptions) {
234 if (catalogOptions != null) {
235 Map<String, Object> options = catalogOptions.toQuery();
237 if (options.containsKey("dc")) {
238 params += "dc=" + options.get("dc");
240 if (options.containsKey("tag")) {
241 params += params.isEmpty() ? "" : "&";
242 params += "tag=" + options.get("tag");
246 if (queryOptions != null) {
247 Map<String, Object> options = queryOptions.toQuery();
249 if (options.containsKey("consistent")) {
250 params += params.isEmpty() ? "" : "&";
251 params += "consistent=" + options.get("consistent");
253 if (options.containsKey("stale")) {
254 params += params.isEmpty() ? "" : "&";
255 params += "stale=" + options.get("stale");
257 if (options.containsKey("wait")) {
258 params += params.isEmpty() ? "" : "&";
259 params += "wait=" + options.get("wait");
262 if (options.containsKey("index")) {
263 params += params.isEmpty() ? "" : "&";
264 params += "index=" + options.get("index");
266 if (options.containsKey("token")) {
267 params += params.isEmpty() ? "" : "&";
268 params += "token=" + options.get("token");
270 if (options.containsKey("near")) {
271 params += params.isEmpty() ? "" : "&";
272 params += "near=" + options.get("near");
274 if (options.containsKey("dc")) {
275 params += params.isEmpty() ? "" : "&";
276 params += "dc=" + options.get("dc");