2 * Copyright (c) 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.openo.baseservice.roa.util.ServiceUtil;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
44 * @version SDNO 0.5 Aug 9, 2016
46 public abstract class HttpBaseRest implements Restful {
48 private static final Logger LOG = LoggerFactory.getLogger(HttpRest.class);
50 final AtomicInteger requestId = new AtomicInteger(0);
52 protected HttpClient client = null;
54 private static final String LOCAL_HOST = "127.0.0.1";
56 static final String HTTP_PATCH = "PATCH";
58 String defaultIP = LOCAL_HOST;
60 int defaultPort = -10000;
62 int defaultTimeout = 30000;
64 final String procenameRouteID = "RouteID-" + System.currentTimeMillis() + "-";
73 public HttpBaseRest() {
77 protected void createHttpClient() {
78 client = new HttpClient();
81 protected RestHttpContentExchange createRestHttpContentExchange(final RestfulAsyncCallback callback) {
82 final RestHttpContentExchange exchange = new RestHttpContentExchange(true, callback);
83 exchange.setScheme("http");
87 private String encodeParams(final RestfulParametes restParametes) throws ServiceException {
88 final Map<String, String> parm = restParametes.getParamMap();
90 boolean bHasParma = false;
91 final StringBuilder builder = new StringBuilder();
93 for(final String key : parm.keySet()) {
94 value = parm.get(key);
100 str = String.format("&%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
101 URLEncoder.encode(value, RestfulClientConst.ENCODING));
104 str = String.format("%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
105 URLEncoder.encode(value, RestfulClientConst.ENCODING));
109 } catch(final UnsupportedEncodingException ex) {
110 LOG.error("unsupported encoding: ", ex);
111 throw new ServiceException("Broken VM does not support UTF-8");
113 return builder.toString();
116 private void processHeader(final RestHttpContentExchange contentExchange, final Map<String, String> headerMap) {
117 for(final String key : headerMap.keySet()) {
118 final String value = headerMap.get(key);
119 contentExchange.addRequestHeader(key, value);
124 private void setContentExchangeParams(final RestHttpContentExchange contentExchange) {
125 final String contentType = contentExchange.getRequestFields().getStringField("Content-Type");
126 if(null == contentType || contentType.isEmpty()) {
127 // application/json;charset=utf-8
128 contentExchange.setRequestContentType(RestfulClientConst.APPLICATION_FORM_URLENCODED);
130 final String encoding = contentExchange.getRequestFields().getStringField("Accept-Encoding");
131 if(null == encoding || encoding.isEmpty()) {
133 contentExchange.setRequestHeader("Accept-Encoding", "*/*");
135 contentExchange.setVersion(11);
143 * @param restParametes
147 * @throws ServiceException
150 protected RestfulResponse sendHttpRequest(final String method, final String servicePath,
151 final RestfulParametes restParametes, final RestfulOptions options, final RestfulAsyncCallback callback)
152 throws ServiceException {
153 final RestHttpContentExchange contentExchange = createRestHttpContentExchange(callback);
154 if(null == restParametes) {
155 return new RestfulResponse();
157 final String requestTrace = this.getReuqestIdString();
158 restParametes.putHttpContextHeader(RestfulClientConst.REQUEST_ID, requestTrace);
160 RestfulResponse rsp = null;
162 contentExchange.setMethod(method);
163 final String str = encodeParams(restParametes);
164 final StringBuilder builder = new StringBuilder();
165 builder.append(servicePath);
166 if(str.length() > 0 && (method.equals(HttpMethods.GET) || method.equals(HttpMethods.DELETE)
167 || method.equals(HttpMethods.HEAD))) {
171 setDefaultUrl(contentExchange, options, builder);
172 processHeader(contentExchange, restParametes.getHeaderMap());
173 setContentExchangeParams(contentExchange);
175 setPostPutParam(method, restParametes, contentExchange, str);
176 setTimeout(options, contentExchange);
178 client.send(contentExchange);
179 rsp = callbackExecute(callback, contentExchange);
180 } catch(final Exception e) {
181 LOG.error("request reply message have exception:status is "
182 + RestHttpContentExchange.toState(contentExchange.getStatus()));
183 throw new ServiceException(e);
188 private void setDefaultUrl(final RestHttpContentExchange contentExchange, final RestfulOptions options,
189 final StringBuilder url) {
191 if(url.toString().startsWith("http")) {
192 contentExchange.setURL(url.toString());
194 String host = defaultIP;
195 int iPort = defaultPort;
196 String calledServiceName = null;
197 if(options != null) {
198 calledServiceName = options.getCalledServicName();
200 final ServiceUtil serviceUtil = new ServiceUtil(calledServiceName, url.toString());
201 final String configHost = serviceUtil.getServiceHost();
202 final int configPort = serviceUtil.getServicePort();
203 if(!configHost.isEmpty() && configPort > 0) {
204 if(options != null) {
205 options.setHost(configHost);
206 options.setPort(configPort);
213 if(options != null) {
214 host = options.getHost();
218 iPort = options.getPort();
223 // Integer.getInteger(".http.client.maxThread",30)
224 contentExchange.setAddress(new Address(host, iPort));
225 contentExchange.setRequestURI(url.toString());
229 private String getReuqestIdString() {
230 if(this.requestId.get() == 0x7FFFFFFF) {
231 this.requestId.set(1);
233 final int reqId = this.requestId.getAndIncrement();
234 final StringBuilder builder = new StringBuilder(this.procenameRouteID);
236 final SimpleDateFormat dateFormate = new SimpleDateFormat("yyMMdd");
237 final SimpleDateFormat timeFormate = new SimpleDateFormat("HHmmss");
238 final Date date = Calendar.getInstance().getTime();
239 builder.append(dateFormate.format(date) + timeFormate.format(date));
241 builder.append(reqId);
242 return builder.toString();
245 private void setPostPutParam(final String method, final RestfulParametes restParametes,
246 final RestHttpContentExchange contentExchange, final String str) throws UnsupportedEncodingException {
247 if(HttpMethods.POST.equals(method) || HttpMethods.PUT.equals(method) || HTTP_PATCH.equals(method)) {
248 ByteArrayInputStream buff;
249 final String tmpRaw = restParametes.getRawData();
251 buff = new ByteArrayInputStream(str.getBytes(RestfulClientConst.ENCODING));
253 buff = new ByteArrayInputStream(tmpRaw.getBytes(RestfulClientConst.ENCODING));
255 final int len = buff.available();
256 contentExchange.setRequestContentSource(buff);
257 contentExchange.setRequestHeader("content-length", String.valueOf(len));
261 private void setTimeout(final RestfulOptions options, final RestHttpContentExchange contentExchange) {
262 if(options != null) {
263 final long timeout = options.getRestTimeout();
265 contentExchange.setTimeout(timeout);
267 contentExchange.setTimeout(defaultTimeout);
270 contentExchange.setTimeout(defaultTimeout);
274 private RestfulResponse callbackExecute(final RestfulAsyncCallback callback,
275 final RestHttpContentExchange contentExchange) throws InterruptedException, IOException, ServiceException {
276 if(callback == null) {
277 final int exchangeState = contentExchange.waitForDone();
278 if(exchangeState == HttpExchange.STATUS_COMPLETED) {
279 return contentExchange.getResponse();
280 } else if(exchangeState == HttpExchange.STATUS_EXCEPTED) {
281 throw new ServiceException(
282 "request is exception: " + RestHttpContentExchange.toState(HttpExchange.STATUS_EXCEPTED));
283 } else if(exchangeState == HttpExchange.STATUS_EXPIRED) {
284 throw new ServiceException(
285 "request is expierd: " + RestHttpContentExchange.toState(HttpExchange.STATUS_EXPIRED));