CommonLibrary(util/rest-client) code upload.
[vfc/nfvo/wfengine.git] / CommonLibrary / rest-client / src / main / java / org / openo / baseservice / roa / util / restclient / RestHttpContentExchange.java
1 /*
2  * Copyright (c) 2016, 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 package org.openo.baseservice.roa.util.restclient;
17
18 import org.openo.baseservice.remoteservice.exception.ServiceException;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.eclipse.jetty.client.ContentExchange;
22 import org.eclipse.jetty.client.HttpDestination;
23 import org.eclipse.jetty.http.HttpFields;
24 import org.eclipse.jetty.http.HttpHeaders;
25 import org.eclipse.jetty.io.Buffer;
26 import org.eclipse.jetty.util.StringUtil;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.IOException;
32 import java.io.InputStreamReader;
33 import java.nio.charset.Charset;
34 import java.util.Enumeration;
35 import java.util.HashMap;
36 import java.util.Map;
37 import java.util.zip.GZIPInputStream;
38
39 /**
40  * ContentExchange implementation classe to provide access to response.
41  * <br/>
42  * <p>
43  * </p>
44  * 
45  * @author
46  * @version SDNO 0.5 28-May-2016
47  */
48 public class RestHttpContentExchange extends ContentExchange {
49
50     private static final Logger LOGGER = LoggerFactory.getLogger(RestHttpContentExchange.class);
51
52     private boolean gzip = false;
53
54     private RestfulAsyncCallback callback = null;
55
56     /**
57      * Constructor<br/>
58      * <p>
59      * </p>
60      * 
61      * @since SDNO 0.5
62      * @param cacheFields whether to cache response header.
63      * @param asyncCallback callback method.
64      */
65     RestHttpContentExchange(final boolean cacheFields, final RestfulAsyncCallback asyncCallback) {
66         super(cacheFields);
67         this.callback = asyncCallback;
68     }
69
70     /**
71      * Extract message.
72      * <br/>
73      * 
74      * @param data GZipped data.
75      * @return Uncompressed data.
76      * @throws IOException
77      * @since SDNO 0.5
78      */
79     public String decompressGzipToStr(final byte[] data) throws IOException {
80         if(data == null) {
81             return "";
82         }
83         ByteArrayInputStream input = null;
84         GZIPInputStream gzis = null;
85         InputStreamReader reader = null;
86         final StringBuilder out = new StringBuilder();
87         try {
88             input = new ByteArrayInputStream(data);
89             gzis = new GZIPInputStream(input);
90             reader = new InputStreamReader(gzis, Charset.forName(RestfulClientConst.ENCODING));
91             final char[] buff = new char[1024];
92             for(int n; (n = reader.read(buff)) != -1;) {
93                 out.append(new String(buff, 0, n));
94             }
95         } finally {
96             if(reader != null) {
97                 try {
98                     reader.close();
99                 } catch(final IOException e) {
100                     LOGGER.error("decompress Gzip reader exception:", e);
101                 }
102             }
103             if(gzis != null) {
104                 try {
105                     gzis.close();
106                 } catch(final IOException e) {
107                     LOGGER.error("decompress Gzip exception:", e);
108                 }
109             }
110             if(input != null) {
111                 try {
112                     input.close();
113                 } catch(final IOException e) {
114                     LOGGER.error("decompress Gzip input exception:", e);
115                 }
116             }
117         }
118         return out.toString();
119
120     }
121
122     /**
123      * View response headers Content-Encoding values if you need to extract data.<br/>
124      * 
125      * @param name buffer
126      * @param value value
127      * @throws IOException
128      * @since SDNO 0.5
129      */
130     @Override
131     protected synchronized void onResponseHeader(final Buffer name, final Buffer value) throws IOException {
132         super.onResponseHeader(name, value);
133         final int header = HttpHeaders.CACHE.getOrdinal(name);
134         if(header == HttpHeaders.CONTENT_ENCODING_ORDINAL) {
135             final String encoding = StringUtil.asciiToLowerCase(value.toString());
136             gzip = encoding != null && StringUtils.contains(encoding, "gzip");
137         }
138
139     }
140
141     @Override
142     protected void onResponseComplete() throws IOException {
143         if(LOGGER.isInfoEnabled()) {
144             LOGGER.info("Response has Complete:" + "path:" + this.getRequestURI().replace("\n", "0x0A"));
145         }
146         super.onResponseComplete();
147         if(callback != null) {
148             final RestfulResponse rsp = getResponse();
149             callback.callback(rsp);
150         }
151     }
152
153     @Override
154     protected void onRequestCommitted() throws IOException {
155         if(LOGGER.isInfoEnabled()) {
156             LOGGER.info("Request Header has been send:" + "path:" + this.getRequestURI().replace("\n", "0x0A"));
157         }
158         super.onRequestCommitted();
159     }
160
161     @Override
162     protected void onRequestComplete() throws IOException {
163         if(LOGGER.isInfoEnabled()) {
164             LOGGER.info("Request has bend send complete:" + "path:" + this.getRequestURI().replace("\n", "0x0A"));
165         }
166         super.onRequestComplete();
167     }
168
169     @Override
170     protected void onException(final Throwable x) {
171         LOGGER.warn("onException:", x);
172         super.onException(x);
173         if(callback != null) {
174             callback.handleExcepion(x);
175         }
176     }
177
178     @Override
179     protected void onConnectionFailed(final Throwable x) {
180         LOGGER.warn("onConnectionFailed:", x);
181         super.onConnectionFailed(x);
182         if(callback != null) {
183             callback.handleExcepion(x);
184         }
185
186     }
187
188     @Override
189     protected void expire(final HttpDestination destination) {
190         super.expire(destination);
191         if(callback != null) {
192             callback.handleExcepion(new ServiceException("request is expired, status:" + toState(getStatus())));
193         }
194     }
195
196     public boolean isGzip() {
197         return gzip;
198     }
199
200     /**
201      * Get the response as RestfulResponse.
202      * <br/>
203      * 
204      * @return response object.
205      * @throws IOException
206      * @since SDNO 0.5
207      */
208     public RestfulResponse getResponse() throws IOException {
209         final RestfulResponse rsp = new RestfulResponse();
210         rsp.setStatus(this.getResponseStatus());
211         if(isGzip()) {
212             final String responseString = decompressGzipToStr(getResponseContentBytes());
213             rsp.setResponseJson(responseString);
214         } else {
215             rsp.setResponseJson(this.getResponseContent());
216         }
217
218         final HttpFields field = this.getResponseFields();
219         if(field != null) {
220             final Map<String, String> header = new HashMap<>();
221
222             final Enumeration<String> names = field.getFieldNames();
223             for(final Enumeration<String> e = names; e.hasMoreElements();) {
224                 final String fieldName = e.nextElement();
225                 final String fieldValue = field.getStringField(fieldName);
226                 header.put(fieldName, fieldValue);
227             }
228
229             rsp.setRespHeaderMap(header);
230         }
231         return rsp;
232     }
233
234 }