MsoRestClientNew not extends RestMsoImplementation
[vid.git] / vid-app-common / src / main / java / org / onap / vid / mso / RestMsoImplementation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.vid.mso;
22
23 import static org.onap.vid.logging.Headers.PARTNER_NAME;
24 import static org.onap.vid.utils.Logging.ONAP_REQUEST_ID_HEADER_KEY;
25 import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY;
26 import static org.onap.vid.utils.Logging.getMethodCallerName;
27 import static org.onap.vid.utils.Logging.getMethodName;
28
29 import com.att.eelf.configuration.EELFLogger;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31 import java.util.Collections;
32 import java.util.Optional;
33 import javax.ws.rs.client.Client;
34 import javax.ws.rs.client.Entity;
35 import javax.ws.rs.client.Invocation;
36 import javax.ws.rs.core.MediaType;
37 import javax.ws.rs.core.MultivaluedHashMap;
38 import javax.ws.rs.core.Response;
39 import org.apache.commons.codec.binary.Base64;
40 import org.apache.http.HttpException;
41 import org.eclipse.jetty.util.security.Password;
42 import org.glassfish.jersey.client.ClientProperties;
43 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
44 import org.onap.vid.aai.ExceptionWithRequestInfo;
45 import org.onap.vid.aai.util.HttpClientMode;
46 import org.onap.vid.aai.util.HttpsAuthClient;
47 import org.onap.vid.client.HttpBasicClient;
48 import org.onap.vid.exceptions.GenericUncheckedException;
49 import org.onap.vid.mso.rest.RestInterface;
50 import org.onap.vid.utils.Logging;
51 import org.onap.vid.utils.SystemPropertiesWrapper;
52 import org.springframework.beans.factory.annotation.Autowired;
53 import org.springframework.http.HttpMethod;
54
55 /**
56  * Created by pickjonathan on 26/06/2017.
57  */
58 public class RestMsoImplementation implements RestInterface {
59
60     
61     /**
62      * The logger.
63      */
64     protected EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMsoImplementation.class);
65     private final EELFLogger outgoingRequestsLogger = Logging.getRequestsLogger("mso");
66
67     /** The client. */
68     private Client client = null;
69
70
71     protected HttpsAuthClient httpsAuthClient;
72     protected SystemPropertiesWrapper systemProperties;
73     protected final Logging loggingService;
74
75     private static final String START_LOG = " start";
76     private static final String APPLICATION_JSON = "application/json";
77     private static final String WITH_STATUS = " with status=";
78     private static final String URL_LOG = ", url=";
79     private static final String NO_RESPONSE_ENTITY_LOG = " No response entity, this is probably ok, e=";
80     private static final String WITH_URL_LOG = " with url=";
81     private static final String EXCEPTION_LOG = ", Exception: ";
82     private static final String REST_API_SUCCESSFULL_LOG = " REST api was successfull!";
83     private static final String REST_MSG_TEMPLATE = "start {}->{}({}, {}, {})";
84     /** The common headers. */
85     /**
86      * Instantiates a new mso rest interface.
87      */
88
89     @Autowired
90     public RestMsoImplementation(HttpsAuthClient httpsAuthClient, SystemPropertiesWrapper systemProperties, Logging loggingService){
91         this.httpsAuthClient=httpsAuthClient;
92         this.systemProperties = systemProperties;
93         this.loggingService = loggingService;
94     }
95
96     @SuppressWarnings("Duplicates")
97     protected MultivaluedHashMap<String, Object> initMsoClient()
98     {
99         final String methodname = "initRestClient()";
100
101         final String username = systemProperties.getProperty(MsoProperties.MSO_USER_NAME);
102         final String password = systemProperties.getProperty(MsoProperties.MSO_PASSWORD);
103         final String mso_url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL);
104         final String decrypted_password = Password.deobfuscate(password);
105
106         String authString = username + ":" + decrypted_password;
107
108         byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
109         String authStringEnc = new String(authEncBytes);
110
111         MultivaluedHashMap<String, Object> commonHeaders = new MultivaluedHashMap();
112         commonHeaders.put("Authorization",  Collections.singletonList(("Basic " + authStringEnc)));
113         commonHeaders.put(PARTNER_NAME.getHeaderName(), Collections.singletonList(PARTNER_NAME.getHeaderValue()));
114
115         String requestIdValue = Logging.extractOrGenerateRequestId();
116         commonHeaders.put(REQUEST_ID_HEADER_KEY, Collections.singletonList(requestIdValue));
117         commonHeaders.put(ONAP_REQUEST_ID_HEADER_KEY, Collections.singletonList(requestIdValue));
118
119
120         boolean useSsl = true;
121         if ( (mso_url != null) && ( !(mso_url.isEmpty()) ) ) {
122             useSsl = mso_url.startsWith("https");
123         }
124         if (client == null) {
125
126             try {
127                 if ( useSsl ) {
128                     client = httpsAuthClient.getClient(HttpClientMode.WITHOUT_KEYSTORE);
129                 }
130                 else {
131                     client = HttpBasicClient.getClient();
132                 }
133             } catch (Exception e) {
134                 logger.info(EELFLoggerDelegate.errorLogger,methodname + " Unable to get the SSL client");
135             }
136         }
137
138         return commonHeaders;
139     }
140
141     public <T> RestObjectWithRequestInfo<T> Get(T t, String path, RestObject<T> restObject, boolean warpException) {
142         String methodName = "Get";
143
144         logger.debug(EELFLoggerDelegate.debugLogger, methodName + START_LOG);
145
146         String url = null;
147         String rawData = null;
148         Integer status = null;
149
150         try {
151             restObject.set(t);
152             url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
153
154             MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
155             loggingService.logRequest(outgoingRequestsLogger, HttpMethod.GET, url);
156                 final Response cres = client.target(url)
157                     .request()
158                     .accept(APPLICATION_JSON)
159                     .headers(commonHeaders)
160                     .get();
161             loggingService.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres);
162
163             cres.bufferEntity();
164             status = cres.getStatus();
165             rawData = cres.readEntity(String.class);
166
167             restObject.setStatusCode(status);
168
169             if (status == 200 || status == 202) {
170                 t = (T) cres.readEntity(t.getClass());
171                 restObject.set(t);
172                 logger.debug(EELFLoggerDelegate.debugLogger, methodName + REST_API_SUCCESSFULL_LOG);
173
174             } else {
175                 throw new GenericUncheckedException(new HttpException(methodName + WITH_STATUS + status + " (200 or 202 expected), url= " + url));
176             }
177
178             logger.debug(EELFLoggerDelegate.debugLogger, methodName + " received status=" + status);
179
180             return new RestObjectWithRequestInfo<>(HttpMethod.GET, url, restObject, status, rawData);
181         } catch (RuntimeException e) {
182             throw warpException ? new ExceptionWithRequestInfo(HttpMethod.GET, url, rawData, status, e) : e;
183         }
184     }
185
186     @Override
187     public <T> RestObject<T> GetForObject(String path, Class<T> clazz) {
188         final String methodName = getMethodName();
189         logger.debug(EELFLoggerDelegate.debugLogger, "start {}->{}({}, {})", getMethodCallerName(), methodName, path, clazz);
190
191         String url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
192         logger.debug(EELFLoggerDelegate.debugLogger, "<== " +  methodName + " sending request to url= " + url);
193
194         MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
195         loggingService.logRequest(outgoingRequestsLogger, HttpMethod.GET, url);
196         final Response cres = client.target(url)
197                 .request()
198                 .accept(APPLICATION_JSON)
199                 .headers(commonHeaders)
200                 .get();
201         loggingService.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres);
202         final RestObject<T> restObject = cresToRestObject(cres, clazz);
203         int status = cres.getStatus();
204
205         if (status == 200 || status == 202) {
206             logger.debug(EELFLoggerDelegate.debugLogger, methodName + REST_API_SUCCESSFULL_LOG);
207         } else {
208             logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_STATUS +status+ URL_LOG +url);
209         }
210
211         logger.debug(EELFLoggerDelegate.debugLogger,methodName + " received status=" + status );
212
213         return restObject;
214     }
215
216     public <T> RestObject<T> PostForObject(Object requestDetails, String path, Class<T> clazz) {
217         logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), requestDetails, path, clazz);
218         return restCall(HttpMethod.POST, clazz, requestDetails, path);
219     }
220
221     public <T> RestObject<T> DeleteForObject(Object requestDetails, String path, Class<T> clazz) {
222         logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), requestDetails, path, clazz);
223         return restCall(HttpMethod.DELETE, clazz, requestDetails, path);
224     }
225
226     @Override
227     public void Post(String t, Object r, String path, RestObject<String> restObject) {
228         logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), t.getClass(), r, path);
229         restObject.copyFrom(restCall(HttpMethod.POST, String.class, r, path));
230     }
231
232     public Invocation.Builder prepareClient(String path, String methodName) {
233         MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
234
235         String url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
236         logger.debug(EELFLoggerDelegate.debugLogger,"<== " +  methodName + " sending request to url= " + url);
237         // Change the content length
238         return client.target(url)
239                 .request()
240                 .accept(APPLICATION_JSON)
241                 .headers(commonHeaders);
242     }
243
244     public <T> RestObject<T> restCall(HttpMethod httpMethod, Class<T> tClass, Object payload, String path) {
245         return restCall(httpMethod, tClass, payload, path, Optional.empty());
246     }
247
248
249     /*
250     user id is needed to be pass as X-RequestorID in new MSO flows like Delete instanceGroup
251      */
252     public <T> RestObject<T> restCall(HttpMethod httpMethod, Class<T> tClass, Object payload, String path, Optional<String> userId)  {
253         String methodName = httpMethod.name();
254         String url="";
255
256         try {
257
258             MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
259             userId.ifPresent(id->commonHeaders.put("X-RequestorID", Collections.singletonList(id)));
260
261             url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
262             loggingService.logRequest(outgoingRequestsLogger, httpMethod, url, payload);
263             // Change the content length
264             final Invocation.Builder restBuilder = client.target(url)
265                     .request()
266                     .accept(APPLICATION_JSON)
267                     .headers(commonHeaders)
268                     .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true)
269                 ;
270
271             Invocation restInvocation = payload==null ?
272                     restBuilder.build(httpMethod.name()) :
273                     restBuilder.build(httpMethod.name(), Entity.entity(payload, MediaType.APPLICATION_JSON));
274             final Response cres = restInvocation.invoke();
275
276             loggingService.logResponse(outgoingRequestsLogger, httpMethod, url, cres);
277             return cresToRestObject(cres, tClass);
278         }
279         catch (Exception e) {
280             logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_URL_LOG +url+ EXCEPTION_LOG + e.toString());
281             throw e;
282         }
283
284     }
285
286     private <T> RestObject<T> cresToRestObject(Response cres, Class<?> tClass) {
287         RestObject<T> restObject = new RestObject<>();
288
289         String rawEntity = null;
290         try {
291             cres.bufferEntity();
292             rawEntity = cres.readEntity(String.class);
293             restObject.setRaw(rawEntity);
294             T t = (T) new ObjectMapper().readValue(rawEntity, tClass);
295             restObject.set(t);
296         }
297         catch ( Exception e ) {
298             try {
299                 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + getMethodCallerName() + " Error reading response entity as " + tClass + ": , e="
300                         + e.getMessage() + ", Entity=" + rawEntity);
301             } catch (Exception e2) {
302                 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + getMethodCallerName() + NO_RESPONSE_ENTITY_LOG
303                         + e.getMessage());
304             }
305         }
306
307         int status = cres.getStatus();
308         restObject.setStatusCode (status);
309
310         return restObject;
311     }
312
313     @Override
314     public <T> void Put(T t, org.onap.vid.changeManagement.RequestDetailsWrapper r, String path, RestObject<T> restObject) {
315
316         String methodName = "Put";
317         String url="";
318
319         logger.debug(EELFLoggerDelegate.debugLogger,"<== " +  methodName + START_LOG);
320
321         try {
322
323             MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
324
325             url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
326             loggingService.logRequest(outgoingRequestsLogger, HttpMethod.PUT, url, r);
327             // Change the content length
328             final Response cres = client.target(url)
329                     .request()
330                     .accept(APPLICATION_JSON)
331                     .headers(commonHeaders)
332                     //.header("content-length", 201)
333                     .put(Entity.entity(r, MediaType.APPLICATION_JSON));
334
335             loggingService.logResponse(outgoingRequestsLogger, HttpMethod.PUT, url, cres);
336
337             try {
338                 t = (T) cres.readEntity(t.getClass());
339                 restObject.set(t);
340             }
341             catch ( Exception e ) {
342                 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + NO_RESPONSE_ENTITY_LOG
343                         + e.getMessage());
344                 throw e;
345             }
346
347             int status = cres.getStatus();
348             restObject.setStatusCode (status);
349
350             if ( status >= 200 && status <= 299 ) {
351                 logger.info(EELFLoggerDelegate.errorLogger, "<== " + methodName + REST_API_SUCCESSFULL_LOG);
352                 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + REST_API_SUCCESSFULL_LOG);
353
354             } else {
355                 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_STATUS +status+ URL_LOG +url);
356             }
357
358         } catch (Exception e)
359         {
360             logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_URL_LOG +url+ EXCEPTION_LOG + e.toString());
361             throw e;
362
363         }
364     }
365 }