Fix SVNFM jetty-all vulnerability fix
[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.*;
20 import java.net.URLEncoder;
21 import java.text.SimpleDateFormat;
22 import java.util.*;
23 import java.util.concurrent.ExecutionException;
24 import java.util.concurrent.TimeUnit;
25 import java.util.concurrent.TimeoutException;
26 import java.util.concurrent.atomic.AtomicInteger;
27
28 import org.eclipse.jetty.client.*;
29 import org.eclipse.jetty.client.api.*;
30 import org.eclipse.jetty.http.HttpHeader;
31 import org.eclipse.jetty.http.HttpMethod;
32 import org.eclipse.jetty.http.HttpVersion;
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 /**
39  * <br/>
40  * <p>
41  * </p>
42  *
43  * @author
44  * @version Aug 9, 2016
45  */
46 public abstract class HttpBaseRest implements Restful {
47     private Response responseGlobal;
48     private ContentResponse contentResponse;
49     private Request request;
50     private static final Logger LOG = LoggerFactory.getLogger(HttpRest.class);
51
52     final AtomicInteger requestId = new AtomicInteger(0);
53
54     protected HttpClient client = null;
55
56     static final String HTTP_PATCH = "PATCH";
57
58     String defaultIP = Constant.LOCAL_HOST;
59     int defaultPort = -10000;
60     int defaultTimeout = 30000;
61     final String procenameRouteID = "RouteID-" + System.currentTimeMillis() + "-";
62
63
64     /**
65      * Constructor<br/>
66      * <p>
67      * </p>
68      *
69      * @since
70      */
71     public HttpBaseRest() {
72         super();
73     }
74
75     public HttpBaseRest(final Response response) {
76         this.responseGlobal = response;
77     }
78
79     protected void createHttpClient() {
80         client = new HttpClient();
81     }
82
83     private String encodeParams(final RestfulParametes restParametes) throws ServiceException {
84         final Map<String, String> parm = restParametes.getParamMap();
85         String value = null;
86         boolean bHasParma = false;
87         final StringBuilder builder = new StringBuilder();
88         try {
89             for (final String key : parm.keySet()) {
90                 value = parm.get(key);
91                 if (value == null) {
92                     value = "";
93                 }
94                 String str;
95                 if (bHasParma) {
96                     str = String.format("&%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
97                             URLEncoder.encode(value, RestfulClientConst.ENCODING));
98                 } else {
99                     bHasParma = true;
100                     str = String.format("%s=%s", URLEncoder.encode(key, RestfulClientConst.ENCODING),
101                             URLEncoder.encode(value, RestfulClientConst.ENCODING));
102                 }
103                 builder.append(str);
104             }
105         } catch (final UnsupportedEncodingException ex) {
106             LOG.error("unsupported encoding: ", ex);
107             throw new ServiceException("Broken VM does not support UTF-8");
108         }
109         return builder.toString();
110     }
111
112     private void processHeader(final Request request, final Map<String, String> headerMap) {
113         for (final String key : headerMap.keySet()) {
114             final String value = headerMap.get(key);
115             HttpHeader headers[] = HttpHeader.values();
116             if (Arrays.asList(headers).contains('"' + key + '"')) ;
117             {
118                 request.header(key, value);
119
120             }
121
122         }
123
124     }
125
126     private void setRequestParams(final Request request, String httpMethod) {
127         final String contentType = request.getHeaders().get("Content-Type");
128         if (null == contentType || contentType.isEmpty()) {
129             // application/json;charset=utf-8
130             request.header(HttpHeader.CONTENT_TYPE, RestfulClientConst.APPLICATION_FORM_URLENCODED);
131         }
132         //final String encoding = contentExchange.getRequestFields().getStringField("Accept-Encoding");
133         final String encoding = request.getHeaders().get("Accept-Encoding");
134         if (null == encoding || encoding.isEmpty()) {
135             // compress,gzip
136             request.header(HttpHeader.ACCEPT_ENCODING, "*/*");
137         }
138         request.version(HttpVersion.HTTP_1_1);
139         request.scheme("http");
140         request.method(httpMethod);
141     }
142
143
144     /**
145      * <br/>
146      *
147      * @param httpMethod
148      * @param servicePath
149      * @param restParametes
150      * @param options
151      * @param callback
152      * @return
153      * @throws ServiceException
154      * @since
155      */
156
157     protected RestfulResponse sendHttpRequest(final String httpMethod, final String servicePath,
158                                               final RestfulParametes restParametes, final RestfulOptions options, RestfulAsyncCallback callback)
159             throws ServiceException {
160
161
162         if (null == restParametes) {
163             return new RestfulResponse();
164         }
165         final String requestTrace = this.getRequestIdString();
166         restParametes.putHttpContextHeader(RestfulClientConst.REQUEST_ID, requestTrace);
167
168         RestfulResponse rsp = null;
169         try {
170             final String str = encodeParams(restParametes);
171             final StringBuilder builder = new StringBuilder();
172             builder.append(servicePath);
173             if (str.length() > 0 && (httpMethod.equals(HttpMethod.GET.asString()) || httpMethod.equals(HttpMethod.DELETE.asString())
174                     || httpMethod.equals(HttpMethod.HEAD.asString()))) {
175                 builder.append('?');
176                 builder.append(str);
177             }
178             String url = setDefaultUrl(options, builder);
179             System.out.println(url);
180             request = client.newRequest(url);
181             setRequestParams(request, httpMethod);
182             processHeader(request, restParametes.getHeaderMap());
183             setPostPutParam(httpMethod, restParametes, request, str);
184             setTimeout(options, request);
185             ContentResponse contentResponse = getResponse();
186 //            HttpRequestListeners httpRequestListeners = new HttpRequestListeners();
187 //            RestHttpContentExchange contentExchange = new RestHttpContentExchange();
188 //            Response.CompleteListener responseListener = contentExchange;
189 //            // Response.CompleteListener responseListener =f;
190 //            request.method(httpMethod)
191 //                    .onRequestSuccess(httpRequestListeners)
192 //                    .onRequestBegin(httpRequestListeners)
193 //                    .scheme("http")
194 //                    .send(responseListener);
195 //            Thread.sleep(2000);
196 //            System.out.println("content:- " + contentExchange._responseContentString);
197 //            System.out.println("code :-" + contentExchange._responseStatus);
198
199
200 //            Origin origin=new Origin("http","localhost",8980);
201 //            HttpDestination httpDestination=new HttpDestination(client,origin) {
202 //                @Override
203 //                protected SendFailure send(Connection connection, HttpExchange exchange) {
204 //                    return null;
205 //                }
206 //            };
207 //            List<Response.ResponseListener> listenersList=new ArrayList<>();
208 //            listenersList.add(responseListener);
209 //
210 //            HttpExchange httpExchange=new HttpExchange(httpDestination,(HttpRequest)request,listenersList);
211 //            System.out.println("httpExchange : "+httpExchange.getResponse().getStatus());
212             //System.out.println("request :- " + httpRequestListeners.method);
213             RestHttpContentExchange contentExchange = new RestHttpContentExchange();
214             contentExchange.setResponseStatus(contentResponse.getStatus());
215             contentExchange.setResponseContentBytes(contentResponse.getContent());
216             contentExchange.setResponseFields(contentResponse.getHeaders());
217             contentExchange.setResponseContentString(contentResponse.getContentAsString());
218             rsp = callbackExecute(callback, contentExchange);
219 //            List<Response.Listener> list = contentResponse.getListeners(Response.Listener.class);
220 //            for (Response.Listener listener : list) {
221 //                System.out.println(listener.getClass());
222 //            }
223             System.out.println("Testing :: " + contentResponse.getContentAsString());
224             System.out.println("rsp::::::: " + rsp);
225         } catch (final Exception e) {
226             System.out.println("ex : " + e.getMessage());
227             if(request!=null){
228                 LOG.error("request reply message have exception:status is "
229                         + request.getAbortCause());
230             }
231
232             throw new ServiceException(e);
233         }
234         return rsp;
235     }
236
237     private ContentResponse getResponse() throws InterruptedException, ExecutionException, TimeoutException {
238         return request.send();
239     }
240
241
242     private String setDefaultUrl(final RestfulOptions options, final StringBuilder url) {
243         // server
244
245         if (url.toString().startsWith("http")) {
246             return url.toString();
247         } else {
248             String host = Constant.LOCAL_HOST;
249             int iPort = defaultPort;
250             if (options != null) {
251                 host = options.getHost();
252                 if (host.isEmpty()) {
253                     host = defaultIP;
254                 }
255                 iPort = options.getPort();
256                 if (iPort == 0) {
257                     iPort = defaultPort;
258                 }
259             }
260             // Integer.getInteger(".http.client.maxThread",30)
261             return "http://" + host + ":" + iPort + "/" + url;
262             //return "http://reqres.in/api/users/4";
263             //return "https://jsonplaceholder.typicode.com/users"; //for 404 bad request
264
265         }
266     }
267
268     private String getRequestIdString() {
269         if (this.requestId.get() == 0x7FFFFFFF) {
270             this.requestId.set(1);
271         }
272         final int reqId = this.requestId.getAndIncrement();
273         final StringBuilder builder = new StringBuilder(this.procenameRouteID);
274         // time
275         final SimpleDateFormat dateFormate = new SimpleDateFormat("yyMMdd");
276         final SimpleDateFormat timeFormate = new SimpleDateFormat("HHmmss");
277         final Date date = Calendar.getInstance().getTime();
278         builder.append(dateFormate.format(date) + timeFormate.format(date));
279         builder.append('-');
280         builder.append(reqId);
281         return builder.toString();
282     }
283
284     private void setPostPutParam(final String method, final RestfulParametes restParametes,
285                                  final Request request, final String str) throws UnsupportedEncodingException {
286         if (HttpMethod.POST.equals(method) || HttpMethod.PUT.equals(method) || HTTP_PATCH.equals(method)) {
287             ByteArrayInputStream buff;
288             final String tmpRaw = restParametes.getRawData();
289             if (tmpRaw == null) {
290                 buff = new ByteArrayInputStream(str.getBytes(RestfulClientConst.ENCODING));
291             } else {
292                 buff = new ByteArrayInputStream(tmpRaw.getBytes(RestfulClientConst.ENCODING));
293             }
294             final int len = buff.available();
295             //contentExchange.setRequestContentSource(buff);
296             request.header("content-length", String.valueOf(len));
297         }
298     }
299
300     private void setTimeout(final RestfulOptions options, final Request request) {
301         if (options != null) {
302             final long timeout = options.getRestTimeout();
303             if (timeout != 0) {
304                 request.idleTimeout(timeout, TimeUnit.MILLISECONDS);
305             } else {
306                 request.idleTimeout(defaultTimeout, TimeUnit.MILLISECONDS);
307             }
308         } else {
309             request.idleTimeout(defaultTimeout, TimeUnit.MILLISECONDS);
310         }
311     }
312
313     private RestfulResponse callbackExecute(final RestfulAsyncCallback callback,
314                                             final RestHttpContentExchange contentExchange) throws ServiceException, IOException {
315         if (callback == null) {
316             int exchangeState = contentExchange.getResponse().getStatus();
317             if (exchangeState == 200) {
318                 System.out.println("Restful Response " + contentExchange.getResponse().getResponseContent());
319                 return contentExchange.getResponse();
320             } else {
321                 throw new ServiceException("status code : "+exchangeState);
322             }
323         }
324         return null;
325     }
326 }