Define constant instead of localhost
[vfc/nfvo/driver/vnfm/svnfm.git] / huawei / vnfmadapter / VnfmadapterService / service / src / main / java / org / onap / vfc / nfvo / vnfm / svnfm / vnfmadapter / common / restclient / HttpBaseRest.java
1 /*
2  * Copyright 2016-2017 Huawei Technologies Co., Ltd.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.vfc.nfvo.vnfm.svnfm.vnfmadapter.common.restclient;
18
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;
26 import java.util.Map;
27 import java.util.concurrent.atomic.AtomicInteger;
28
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;
36
37 /**
38  * <br/>
39  * <p>
40  * </p>
41  * 
42  * @author
43  * @version Aug 9, 2016
44  */
45 public abstract class HttpBaseRest implements Restful {
46
47     private static final Logger LOG = LoggerFactory.getLogger(HttpRest.class);
48
49     final AtomicInteger requestId = new AtomicInteger(0);
50
51     protected HttpClient client = null;
52
53     static final String HTTP_PATCH = "PATCH";
54
55     String defaultIP = Constant.LOCAL_HOST;
56
57     int defaultPort = -10000;
58
59     int defaultTimeout = 30000;
60
61     final String procenameRouteID = "RouteID-" + System.currentTimeMillis() + "-";
62
63     /**
64      * Constructor<br/>
65      * <p>
66      * </p>
67      * 
68      * @since
69      */
70     public HttpBaseRest() {
71         super();
72     }
73
74     protected void createHttpClient() {
75         client = new HttpClient();
76     }
77
78     protected RestHttpContentExchange createRestHttpContentExchange(final RestfulAsyncCallback callback) {
79         final RestHttpContentExchange exchange = new RestHttpContentExchange(true, callback);
80         exchange.setScheme("http");
81         return exchange;
82     }
83
84     private String encodeParams(final RestfulParametes restParametes) throws ServiceException {
85         final Map<String, String> parm = restParametes.getParamMap();
86         String value = null;
87         boolean bHasParma = false;
88         final StringBuilder builder = new StringBuilder();
89         try {
90             for(final String key : parm.keySet()) {
91                 value = parm.get(key);
92                 if(value == null) {
93                     value = "";
94                 }
95                 String str;
96                 if(bHasParma) {
97                     str = String.format("&%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
98                             URLEncoder.encode(value, RestfulClientConst.ENCODING));
99                 } else {
100                     bHasParma = true;
101                     str = String.format("%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
102                             URLEncoder.encode(value, RestfulClientConst.ENCODING));
103                 }
104                 builder.append(str);
105             }
106         } catch(final UnsupportedEncodingException ex) {
107             LOG.error("unsupported encoding: ", ex);
108             throw new ServiceException("Broken VM does not support UTF-8");
109         }
110         return builder.toString();
111     }
112
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);
117         }
118
119     }
120
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);
126         }
127         final String encoding = contentExchange.getRequestFields().getStringField("Accept-Encoding");
128         if(null == encoding || encoding.isEmpty()) {
129             // compress,gzip
130             contentExchange.setRequestHeader("Accept-Encoding", "*/*");
131         }
132         contentExchange.setVersion(11);
133     }
134
135     /**
136      * <br/>
137      * 
138      * @param method
139      * @param servicePath
140      * @param restParametes
141      * @param options
142      * @param callback
143      * @return
144      * @throws ServiceException
145      * @since
146      */
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();
153         }
154         final String requestTrace = this.getReuqestIdString();
155         restParametes.putHttpContextHeader(RestfulClientConst.REQUEST_ID, requestTrace);
156
157         RestfulResponse rsp = null;
158         try {
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))) {
165                 builder.append('?');
166                 builder.append(str);
167             }
168             setDefaultUrl(contentExchange, options, builder);
169             processHeader(contentExchange, restParametes.getHeaderMap());
170             setContentExchangeParams(contentExchange);
171
172             setPostPutParam(method, restParametes, contentExchange, str);
173             setTimeout(options, contentExchange);
174
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);
181         }
182         return rsp;
183     }
184
185     private void setDefaultUrl(final RestHttpContentExchange contentExchange, final RestfulOptions options,
186             final StringBuilder url) {
187         // server
188         if(url.toString().startsWith("http")) {
189             contentExchange.setURL(url.toString());
190         } else {
191             String host = defaultIP;
192             int iPort = defaultPort;
193             if(options != null) {
194                 host = options.getHost();
195                 if(host.isEmpty()) {
196                     host = defaultIP;
197                 }
198                 iPort = options.getPort();
199                 if(iPort == 0) {
200                     iPort = defaultPort;
201                 }
202             }
203             // Integer.getInteger(".http.client.maxThread",30)
204             contentExchange.setAddress(new Address(host, iPort));
205             contentExchange.setRequestURI(url.toString());
206         }
207     }
208
209     private String getReuqestIdString() {
210         if(this.requestId.get() == 0x7FFFFFFF) {
211             this.requestId.set(1);
212         }
213         final int reqId = this.requestId.getAndIncrement();
214         final StringBuilder builder = new StringBuilder(this.procenameRouteID);
215         // time
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));
220         builder.append('-');
221         builder.append(reqId);
222         return builder.toString();
223     }
224
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();
230             if(tmpRaw == null) {
231                 buff = new ByteArrayInputStream(str.getBytes(RestfulClientConst.ENCODING));
232             } else {
233                 buff = new ByteArrayInputStream(tmpRaw.getBytes(RestfulClientConst.ENCODING));
234             }
235             final int len = buff.available();
236             contentExchange.setRequestContentSource(buff);
237             contentExchange.setRequestHeader("content-length", String.valueOf(len));
238         }
239     }
240
241     private void setTimeout(final RestfulOptions options, final RestHttpContentExchange contentExchange) {
242         if(options != null) {
243             final long timeout = options.getRestTimeout();
244             if(timeout != 0) {
245                 contentExchange.setTimeout(timeout);
246             } else {
247                 contentExchange.setTimeout(defaultTimeout);
248             }
249         } else {
250             contentExchange.setTimeout(defaultTimeout);
251         }
252     }
253
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));
266             }
267         }
268         return null;
269     }
270
271 }