d8b5215738e05d2a012ffa4975005c7402245651
[holmes/common.git] / holmes-actions / src / main / java / org / onap / holmes / common / utils / JerseyClient.java
1 /**
2  * Copyright 2020 ZTE Corporation.
3  * <p>
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  * <p>
8  * http://www.apache.org/licenses/LICENSE-2.0
9  * <p>
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.holmes.common.utils;
18
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import javax.net.ssl.SSLContext;
23 import javax.net.ssl.TrustManager;
24 import javax.net.ssl.X509TrustManager;
25 import javax.ws.rs.client.*;
26 import javax.ws.rs.core.Response;
27 import java.security.KeyManagementException;
28 import java.security.NoSuchAlgorithmException;
29 import java.security.cert.X509Certificate;
30 import java.util.*;
31 import java.util.concurrent.TimeUnit;
32
33 public class JerseyClient {
34     static final public String PROTOCOL_HTTP = "http";
35     static final public String PROTOCOL_HTTPS = "https";
36     static private Logger logger = LoggerFactory.getLogger(JerseyClient.class);
37     static private long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
38     static private SSLContext SSLCONTEXT;
39
40     static {
41         try {
42             SSLCONTEXT = SSLContext.getInstance("TLS");
43             SSLCONTEXT.init(null, new TrustManager[]{new X509TrustManager() {
44                 public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
45                 }
46
47                 public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
48                 }
49
50                 public X509Certificate[] getAcceptedIssuers() {
51                     return new X509Certificate[0];
52                 }
53             }}, new java.security.SecureRandom());
54         } catch (NoSuchAlgorithmException | KeyManagementException e) {
55             logger.error("Failed to initialize the SSLContext instance!", e);
56         }
57     }
58
59     private Client client;
60     private Map<String, Object> headers = new HashMap();
61     private Map<String, Object> parameters = new HashMap();
62     private List<String> paths = new ArrayList();
63
64     public static JerseyClient newInstance() {
65         return new JerseyClient();
66     }
67
68     public static JerseyClient newInstance(long timeout) {
69         return new JerseyClient(timeout);
70     }
71
72     private JerseyClient() {
73         this(DEFAULT_TIMEOUT);
74     }
75
76     private JerseyClient(long timeout) {
77         this.client = ClientBuilder.newBuilder()
78                 .connectTimeout(timeout, TimeUnit.MILLISECONDS)
79                 .readTimeout(timeout, TimeUnit.MILLISECONDS)
80                 .sslContext(SSLCONTEXT)
81                 .hostnameVerifier((s1, s2) -> true)
82                 .build();
83     }
84
85     public JerseyClient header(String name, Object value) {
86         headers.put(name, value);
87         return this;
88     }
89
90     public JerseyClient headers(Map<String, Object> hds) {
91         headers.putAll(hds);
92         return this;
93     }
94
95     public JerseyClient queryParam(String name, Object value) {
96         parameters.put(name, value);
97         return this;
98     }
99
100     public JerseyClient queryParams(Map<String, Object> params) {
101         parameters.putAll(params);
102         return this;
103     }
104
105     public JerseyClient path(String path) {
106         paths.add(path);
107         return this;
108     }
109
110     public String get(String url) {
111         return get(url, String.class);
112     }
113
114     public <T> T get(String url, Class<T> clazz) {
115
116         WebTarget target = appendPaths(client.target(url));
117
118         target = setParameters(target);
119
120         Invocation.Builder builder = setHeaders(target.request());
121
122         Response response = builder.get();
123
124         if (isSuccessful(response, url)) {
125             return response2Target(response, clazz);
126         }
127
128         return null;
129     }
130
131     public String post(String url) {
132         return post(url, null);
133     }
134
135     public String post(String url, Entity entity) {
136         return post(url, entity, String.class);
137     }
138
139     public <T> T post(String url, Entity entity, Class<T> clazz) {
140
141         WebTarget target = appendPaths(client.target(url));
142
143         setParameters(target);
144
145         Invocation.Builder builder = setHeaders(target.request());
146
147         Response response = builder.post(entity);
148
149         if (isSuccessful(response, url)) {
150             return response2Target(response, clazz);
151         }
152
153         return null;
154     }
155
156     public String put(String url, Entity entity) {
157         return put(url, entity, String.class);
158     }
159
160     public <T> T put(String url, Entity entity, Class<T> clazz) {
161         WebTarget target = appendPaths(client.target(url));
162
163         setParameters(target);
164
165         Invocation.Builder builder = setHeaders(target.request());
166
167         Response response = builder.put(entity);
168
169         if (isSuccessful(response, url)) {
170             return response2Target(response, clazz);
171         }
172
173         return null;
174     }
175
176     public String delete(String url) {
177         return delete(url, String.class);
178     }
179
180     public <T> T delete(String url, Class<T> clazz) {
181         WebTarget target = appendPaths(client.target(url));
182
183         setParameters(target);
184
185         Invocation.Builder builder = setHeaders(target.request());
186
187         Response response = builder.delete();
188
189         if (isSuccessful(response, url)) {
190             return response2Target(response, clazz);
191         }
192
193         return null;
194     }
195
196     private boolean isSuccessful(Response response, String url) {
197         Response.StatusType statusInfo = response.getStatusInfo();
198         if (statusInfo.getFamily() != Response.Status.Family.SUCCESSFUL) {
199             logger.error(
200                     String.format("Failed to get response from the server <%d>. " +
201                                     "\nURL: %s\nCause: %s\nResponse body: %s",
202                             statusInfo.getStatusCode(),
203                             url,
204                             statusInfo.getReasonPhrase(),
205                             response.readEntity(String.class)));
206             return false;
207         }
208         return true;
209     }
210
211     private WebTarget appendPaths(WebTarget target) {
212         for (String path : paths) {
213             target = target.path(path);
214         }
215         return target;
216     }
217
218     private Invocation.Builder setHeaders(Invocation.Builder builder) {
219         Set<Map.Entry<String, Object>> entries = headers.entrySet();
220         for (Map.Entry<String, Object> entry : entries) {
221             builder = builder.header(entry.getKey(), entry.getValue());
222         }
223         return builder;
224     }
225
226     private WebTarget setParameters(WebTarget target) {
227         Set<Map.Entry<String, Object>> entries = parameters.entrySet();
228         for (Map.Entry<String, Object> entry : entries) {
229             target = target.queryParam(entry.getKey(), entry.getValue());
230         }
231         return target;
232     }
233
234     private <T> T response2Target(Response response, Class<T> clazz) {
235         String responseText = response.readEntity(String.class);
236         if (clazz == null || clazz == String.class) {
237             return (T) responseText;
238         } else {
239             return GsonUtil.jsonToBean(responseText, clazz);
240         }
241     }
242 }