2 * Copyright 2016-2017 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.onap.vfc.nfvo.vnfm.svnfm.vnfmadapter.common.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.onap.vfc.nfvo.vnfm.svnfm.vnfmadapter.service.constant.Constant;
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 static final String HTTP_PATCH = "PATCH";
55 String defaultIP = Constant.LOCAL_HOST;
57 int defaultPort = -10000;
59 int defaultTimeout = 30000;
61 final String procenameRouteID = "RouteID-" + System.currentTimeMillis() + "-";
70 public HttpBaseRest() {
74 protected void createHttpClient() {
75 client = new HttpClient();
78 protected RestHttpContentExchange createRestHttpContentExchange(final RestfulAsyncCallback callback) {
79 final RestHttpContentExchange exchange = new RestHttpContentExchange(true, callback);
80 exchange.setScheme("http");
84 private String encodeParams(final RestfulParametes restParametes) throws ServiceException {
85 final Map<String, String> parm = restParametes.getParamMap();
87 boolean bHasParma = false;
88 final StringBuilder builder = new StringBuilder();
90 for(final String key : parm.keySet()) {
91 value = parm.get(key);
97 str = String.format("&%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
98 URLEncoder.encode(value, RestfulClientConst.ENCODING));
101 str = String.format("%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
102 URLEncoder.encode(value, RestfulClientConst.ENCODING));
106 } catch(final UnsupportedEncodingException ex) {
107 LOG.error("unsupported encoding: ", ex);
108 throw new ServiceException("Broken VM does not support UTF-8");
110 return builder.toString();
113 private void processHeader(final RestHttpContentExchange contentExchange, final Map<String, String> headerMap) {
114 for(final String key : headerMap.keySet()) {
115 final String value = headerMap.get(key);
116 contentExchange.addRequestHeader(key, value);
121 private void setContentExchangeParams(final RestHttpContentExchange contentExchange) {
122 final String contentType = contentExchange.getRequestFields().getStringField("Content-Type");
123 if(null == contentType || contentType.isEmpty()) {
124 // application/json;charset=utf-8
125 contentExchange.setRequestContentType(RestfulClientConst.APPLICATION_FORM_URLENCODED);
127 final String encoding = contentExchange.getRequestFields().getStringField("Accept-Encoding");
128 if(null == encoding || encoding.isEmpty()) {
130 contentExchange.setRequestHeader("Accept-Encoding", "*/*");
132 contentExchange.setVersion(11);
140 * @param restParametes
144 * @throws ServiceException
147 protected RestfulResponse sendHttpRequest(final String method, final String servicePath,
148 final RestfulParametes restParametes, final RestfulOptions options, final RestfulAsyncCallback callback)
149 throws ServiceException {
150 final RestHttpContentExchange contentExchange = createRestHttpContentExchange(callback);
151 if(null == restParametes) {
152 return new RestfulResponse();
154 final String requestTrace = this.getReuqestIdString();
155 restParametes.putHttpContextHeader(RestfulClientConst.REQUEST_ID, requestTrace);
157 RestfulResponse rsp = null;
159 contentExchange.setMethod(method);
160 final String str = encodeParams(restParametes);
161 final StringBuilder builder = new StringBuilder();
162 builder.append(servicePath);
163 if(str.length() > 0 && (method.equals(HttpMethods.GET) || method.equals(HttpMethods.DELETE)
164 || method.equals(HttpMethods.HEAD))) {
168 setDefaultUrl(contentExchange, options, builder);
169 processHeader(contentExchange, restParametes.getHeaderMap());
170 setContentExchangeParams(contentExchange);
172 setPostPutParam(method, restParametes, contentExchange, str);
173 setTimeout(options, contentExchange);
175 client.send(contentExchange);
176 rsp = callbackExecute(callback, contentExchange);
177 } catch(final Exception e) {
178 LOG.error("request reply message have exception:status is "
179 + RestHttpContentExchange.toState(contentExchange.getStatus()));
180 throw new ServiceException(e);
185 private void setDefaultUrl(final RestHttpContentExchange contentExchange, final RestfulOptions options,
186 final StringBuilder url) {
188 if(url.toString().startsWith("http")) {
189 contentExchange.setURL(url.toString());
191 String host = defaultIP;
192 int iPort = defaultPort;
193 if(options != null) {
194 host = options.getHost();
198 iPort = options.getPort();
203 // Integer.getInteger(".http.client.maxThread",30)
204 contentExchange.setAddress(new Address(host, iPort));
205 contentExchange.setRequestURI(url.toString());
209 private String getReuqestIdString() {
210 if(this.requestId.get() == 0x7FFFFFFF) {
211 this.requestId.set(1);
213 final int reqId = this.requestId.getAndIncrement();
214 final StringBuilder builder = new StringBuilder(this.procenameRouteID);
216 final SimpleDateFormat dateFormate = new SimpleDateFormat("yyMMdd");
217 final SimpleDateFormat timeFormate = new SimpleDateFormat("HHmmss");
218 final Date date = Calendar.getInstance().getTime();
219 builder.append(dateFormate.format(date) + timeFormate.format(date));
221 builder.append(reqId);
222 return builder.toString();
225 private void setPostPutParam(final String method, final RestfulParametes restParametes,
226 final RestHttpContentExchange contentExchange, final String str) throws UnsupportedEncodingException {
227 if(HttpMethods.POST.equals(method) || HttpMethods.PUT.equals(method) || HTTP_PATCH.equals(method)) {
228 ByteArrayInputStream buff;
229 final String tmpRaw = restParametes.getRawData();
231 buff = new ByteArrayInputStream(str.getBytes(RestfulClientConst.ENCODING));
233 buff = new ByteArrayInputStream(tmpRaw.getBytes(RestfulClientConst.ENCODING));
235 final int len = buff.available();
236 contentExchange.setRequestContentSource(buff);
237 contentExchange.setRequestHeader("content-length", String.valueOf(len));
241 private void setTimeout(final RestfulOptions options, final RestHttpContentExchange contentExchange) {
242 if(options != null) {
243 final long timeout = options.getRestTimeout();
245 contentExchange.setTimeout(timeout);
247 contentExchange.setTimeout(defaultTimeout);
250 contentExchange.setTimeout(defaultTimeout);
254 private RestfulResponse callbackExecute(final RestfulAsyncCallback callback,
255 final RestHttpContentExchange contentExchange) throws InterruptedException, IOException, ServiceException {
256 if(callback == null) {
257 final int exchangeState = contentExchange.waitForDone();
258 if(exchangeState == HttpExchange.STATUS_COMPLETED) {
259 return contentExchange.getResponse();
260 } else if(exchangeState == HttpExchange.STATUS_EXCEPTED) {
261 throw new ServiceException(
262 "request is exception: " + RestHttpContentExchange.toState(HttpExchange.STATUS_EXCEPTED));
263 } else if(exchangeState == HttpExchange.STATUS_EXPIRED) {
264 throw new ServiceException(
265 "request is expierd: " + RestHttpContentExchange.toState(HttpExchange.STATUS_EXPIRED));