2 * Copyright 2016 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openo.baseservice.roa.util.restclient;
19 import java.io.ByteArrayInputStream;
20 import java.io.IOException;
21 import java.io.UnsupportedEncodingException;
22 import java.net.URLEncoder;
23 import java.text.SimpleDateFormat;
24 import java.util.Calendar;
25 import java.util.Date;
27 import java.util.concurrent.atomic.AtomicInteger;
29 import org.eclipse.jetty.client.Address;
30 import org.eclipse.jetty.client.HttpClient;
31 import org.eclipse.jetty.client.HttpExchange;
32 import org.eclipse.jetty.http.HttpMethods;
33 import org.openo.baseservice.remoteservice.exception.ServiceException;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
43 * @version Aug 9, 2016
45 public abstract class HttpBaseRest implements Restful {
47 private static final Logger LOG = LoggerFactory.getLogger(HttpRest.class);
49 final AtomicInteger requestId = new AtomicInteger(0);
51 protected HttpClient client = null;
53 private static final String LOCAL_HOST = "127.0.0.1";
55 static final String HTTP_PATCH = "PATCH";
57 String defaultIP = LOCAL_HOST;
59 int defaultPort = -10000;
61 int defaultTimeout = 30000;
63 final String procenameRouteID = "RouteID-" + System.currentTimeMillis() + "-";
72 public HttpBaseRest() {
76 protected void createHttpClient() {
77 client = new HttpClient();
80 protected RestHttpContentExchange createRestHttpContentExchange(final RestfulAsyncCallback callback) {
81 final RestHttpContentExchange exchange = new RestHttpContentExchange(true, callback);
82 exchange.setScheme("http");
86 private String encodeParams(final RestfulParametes restParametes) throws ServiceException {
87 final Map<String, String> parm = restParametes.getParamMap();
89 boolean bHasParma = false;
90 final StringBuilder builder = new StringBuilder();
92 for(final String key : parm.keySet()) {
93 value = parm.get(key);
99 str = String.format("&%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
100 URLEncoder.encode(value, RestfulClientConst.ENCODING));
103 str = String.format("%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
104 URLEncoder.encode(value, RestfulClientConst.ENCODING));
108 } catch(final UnsupportedEncodingException ex) {
109 LOG.error("unsupported encoding: ", ex);
110 throw new ServiceException("Broken VM does not support UTF-8");
112 return builder.toString();
115 private void processHeader(final RestHttpContentExchange contentExchange, final Map<String, String> headerMap) {
116 for(final String key : headerMap.keySet()) {
117 final String value = headerMap.get(key);
118 contentExchange.addRequestHeader(key, value);
123 private void setContentExchangeParams(final RestHttpContentExchange contentExchange) {
124 final String contentType = contentExchange.getRequestFields().getStringField("Content-Type");
125 if(null == contentType || contentType.isEmpty()) {
126 // application/json;charset=utf-8
127 contentExchange.setRequestContentType(RestfulClientConst.APPLICATION_FORM_URLENCODED);
129 final String encoding = contentExchange.getRequestFields().getStringField("Accept-Encoding");
130 if(null == encoding || encoding.isEmpty()) {
132 contentExchange.setRequestHeader("Accept-Encoding", "*/*");
134 contentExchange.setVersion(11);
142 * @param restParametes
146 * @throws ServiceException
149 protected RestfulResponse sendHttpRequest(final String method, final String servicePath,
150 final RestfulParametes restParametes, final RestfulOptions options, final RestfulAsyncCallback callback)
151 throws ServiceException {
152 final RestHttpContentExchange contentExchange = createRestHttpContentExchange(callback);
153 if(null == restParametes) {
154 return new RestfulResponse();
156 final String requestTrace = this.getReuqestIdString();
157 restParametes.putHttpContextHeader(RestfulClientConst.REQUEST_ID, requestTrace);
159 RestfulResponse rsp = null;
161 contentExchange.setMethod(method);
162 final String str = encodeParams(restParametes);
163 final StringBuilder builder = new StringBuilder();
164 builder.append(servicePath);
165 if(str.length() > 0 && (method.equals(HttpMethods.GET) || method.equals(HttpMethods.DELETE)
166 || method.equals(HttpMethods.HEAD))) {
170 setDefaultUrl(contentExchange, options, builder);
171 processHeader(contentExchange, restParametes.getHeaderMap());
172 setContentExchangeParams(contentExchange);
174 setPostPutParam(method, restParametes, contentExchange, str);
175 setTimeout(options, contentExchange);
177 client.send(contentExchange);
178 rsp = callbackExecute(callback, contentExchange);
179 } catch(final Exception e) {
180 LOG.error("request reply message have exception:status is "
181 + RestHttpContentExchange.toState(contentExchange.getStatus()));
182 throw new ServiceException(e);
187 private void setDefaultUrl(final RestHttpContentExchange contentExchange, final RestfulOptions options,
188 final StringBuilder url) {
190 if(url.toString().startsWith("http")) {
191 contentExchange.setURL(url.toString());
193 String host = defaultIP;
194 int iPort = defaultPort;
195 if(options != null) {
196 host = options.getHost();
200 iPort = options.getPort();
205 // Integer.getInteger(".http.client.maxThread",30)
206 contentExchange.setAddress(new Address(host, iPort));
207 contentExchange.setRequestURI(url.toString());
211 private String getReuqestIdString() {
212 if(this.requestId.get() == 0x7FFFFFFF) {
213 this.requestId.set(1);
215 final int reqId = this.requestId.getAndIncrement();
216 final StringBuilder builder = new StringBuilder(this.procenameRouteID);
218 final SimpleDateFormat dateFormate = new SimpleDateFormat("yyMMdd");
219 final SimpleDateFormat timeFormate = new SimpleDateFormat("HHmmss");
220 final Date date = Calendar.getInstance().getTime();
221 builder.append(dateFormate.format(date) + timeFormate.format(date));
223 builder.append(reqId);
224 return builder.toString();
227 private void setPostPutParam(final String method, final RestfulParametes restParametes,
228 final RestHttpContentExchange contentExchange, final String str) throws UnsupportedEncodingException {
229 if(HttpMethods.POST.equals(method) || HttpMethods.PUT.equals(method) || HTTP_PATCH.equals(method)) {
230 ByteArrayInputStream buff;
231 final String tmpRaw = restParametes.getRawData();
233 buff = new ByteArrayInputStream(str.getBytes(RestfulClientConst.ENCODING));
235 buff = new ByteArrayInputStream(tmpRaw.getBytes(RestfulClientConst.ENCODING));
237 final int len = buff.available();
238 contentExchange.setRequestContentSource(buff);
239 contentExchange.setRequestHeader("content-length", String.valueOf(len));
243 private void setTimeout(final RestfulOptions options, final RestHttpContentExchange contentExchange) {
244 if(options != null) {
245 final long timeout = options.getRestTimeout();
247 contentExchange.setTimeout(timeout);
249 contentExchange.setTimeout(defaultTimeout);
252 contentExchange.setTimeout(defaultTimeout);
256 private RestfulResponse callbackExecute(final RestfulAsyncCallback callback,
257 final RestHttpContentExchange contentExchange) throws InterruptedException, IOException, ServiceException {
258 if(callback == null) {
259 final int exchangeState = contentExchange.waitForDone();
260 if(exchangeState == HttpExchange.STATUS_COMPLETED) {
261 return contentExchange.getResponse();
262 } else if(exchangeState == HttpExchange.STATUS_EXCEPTED) {
263 throw new ServiceException(
264 "request is exception: " + RestHttpContentExchange.toState(HttpExchange.STATUS_EXCEPTED));
265 } else if(exchangeState == HttpExchange.STATUS_EXPIRED) {
266 throw new ServiceException(
267 "request is expierd: " + RestHttpContentExchange.toState(HttpExchange.STATUS_EXPIRED));