2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.vid.mso;
23 import com.att.eelf.configuration.EELFLogger;
24 import com.fasterxml.jackson.databind.ObjectMapper;
25 import org.apache.commons.codec.binary.Base64;
26 import org.apache.http.HttpException;
27 import org.eclipse.jetty.util.security.Password;
28 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
29 import org.onap.portalsdk.core.util.SystemProperties;
30 import org.onap.vid.aai.ExceptionWithRequestInfo;
31 import org.onap.vid.aai.util.HttpClientMode;
32 import org.onap.vid.aai.util.HttpsAuthClient;
33 import org.onap.vid.client.HttpBasicClient;
34 import org.onap.vid.exceptions.GenericUncheckedException;
35 import org.onap.vid.mso.rest.RestInterface;
36 import org.onap.vid.utils.Logging;
37 import org.springframework.beans.factory.annotation.Autowired;
38 import org.springframework.http.HttpMethod;
40 import javax.ws.rs.client.Client;
41 import javax.ws.rs.client.Entity;
42 import javax.ws.rs.client.Invocation;
43 import javax.ws.rs.core.MediaType;
44 import javax.ws.rs.core.MultivaluedHashMap;
45 import javax.ws.rs.core.Response;
46 import java.util.Collections;
47 import java.util.Optional;
49 import static org.onap.vid.utils.Logging.*;
52 * Created by pickjonathan on 26/06/2017.
54 public class RestMsoImplementation implements RestInterface {
59 protected EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMsoImplementation.class);
60 private final EELFLogger outgoingRequestsLogger = Logging.getRequestsLogger("mso");
63 private Client client = null;
66 protected HttpsAuthClient httpsAuthClient;
68 private static final String START_LOG = " start";
69 private static final String APPLICATION_JSON = "application/json";
70 private static final String WITH_STATUS = " with status=";
71 private static final String URL_LOG = ", url=";
72 private static final String NO_RESPONSE_ENTITY_LOG = " No response entity, this is probably ok, e=";
73 private static final String WITH_URL_LOG = " with url=";
74 private static final String EXCEPTION_LOG = ", Exception: ";
75 private static final String REST_API_SUCCESSFULL_LOG = " REST api was successfull!";
76 private static final String REST_MSG_TEMPLATE = "start {}->{}({}, {}, {})";
77 /** The common headers. */
79 * Instantiates a new mso rest interface.
83 protected RestMsoImplementation(HttpsAuthClient httpsAuthClient){
84 this.httpsAuthClient=httpsAuthClient;
87 @SuppressWarnings("Duplicates")
88 protected MultivaluedHashMap<String, Object> initMsoClient()
90 final String methodname = "initRestClient()";
92 final String username = SystemProperties.getProperty(MsoProperties.MSO_USER_NAME);
93 final String password = SystemProperties.getProperty(MsoProperties.MSO_PASSWORD);
94 final String mso_url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL);
95 final String decrypted_password = Password.deobfuscate(password);
97 String authString = username + ":" + decrypted_password;
99 byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
100 String authStringEnc = new String(authEncBytes);
102 MultivaluedHashMap<String, Object> commonHeaders = new MultivaluedHashMap();
103 commonHeaders.put("Authorization", Collections.singletonList(("Basic " + authStringEnc)));
104 commonHeaders.put("X-ONAP-PartnerName", Collections.singletonList("VID"));
106 String requestIdValue = Logging.extractOrGenerateRequestId();
107 commonHeaders.put(REQUEST_ID_HEADER_KEY, Collections.singletonList(requestIdValue));
108 commonHeaders.put(ONAP_REQUEST_ID_HEADER_KEY, Collections.singletonList(requestIdValue));
111 boolean useSsl = true;
112 if ( (mso_url != null) && ( !(mso_url.isEmpty()) ) ) {
113 useSsl = mso_url.startsWith("https");
115 if (client == null) {
119 client = httpsAuthClient.getClient(HttpClientMode.WITHOUT_KEYSTORE);
122 client = HttpBasicClient.getClient();
124 } catch (Exception e) {
125 logger.info(EELFLoggerDelegate.errorLogger,methodname + " Unable to get the SSL client");
129 return commonHeaders;
132 public <T> RestObjectWithRequestInfo<T> Get(T t, String path, RestObject<T> restObject, boolean warpException) {
133 String methodName = "Get";
135 logger.debug(EELFLoggerDelegate.debugLogger, methodName + START_LOG);
138 String rawData = null;
139 Integer status = null;
143 url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
145 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
146 Logging.logRequest(outgoingRequestsLogger, HttpMethod.GET, url);
147 final Response cres = client.target(url)
149 .accept(APPLICATION_JSON)
150 .headers(commonHeaders)
152 Logging.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres);
155 status = cres.getStatus();
156 rawData = cres.readEntity(String.class);
158 restObject.setStatusCode(status);
160 if (status == 200 || status == 202) {
161 t = (T) cres.readEntity(t.getClass());
163 logger.debug(EELFLoggerDelegate.debugLogger, methodName + REST_API_SUCCESSFULL_LOG);
166 throw new GenericUncheckedException(new HttpException(methodName + WITH_STATUS + status + " (200 or 202 expected), url= " + url));
169 logger.debug(EELFLoggerDelegate.debugLogger, methodName + " received status=" + status);
171 return new RestObjectWithRequestInfo<>(HttpMethod.GET, url, restObject, status, rawData);
172 } catch (RuntimeException e) {
173 throw warpException ? new ExceptionWithRequestInfo(HttpMethod.GET, url, rawData, status, e) : e;
178 public <T> RestObject<T> GetForObject(String path, Class<T> clazz) {
179 final String methodName = getMethodName();
180 logger.debug(EELFLoggerDelegate.debugLogger, "start {}->{}({}, {})", getMethodCallerName(), methodName, path, clazz);
182 String url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
183 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + methodName + " sending request to url= " + url);
185 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
186 Logging.logRequest(outgoingRequestsLogger, HttpMethod.GET, url);
187 final Response cres = client.target(url)
189 .accept(APPLICATION_JSON)
190 .headers(commonHeaders)
192 Logging.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres);
193 final RestObject<T> restObject = cresToRestObject(cres, clazz);
194 int status = cres.getStatus();
196 if (status == 200 || status == 202) {
197 logger.debug(EELFLoggerDelegate.debugLogger, methodName + REST_API_SUCCESSFULL_LOG);
199 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_STATUS +status+ URL_LOG +url);
202 logger.debug(EELFLoggerDelegate.debugLogger,methodName + " received status=" + status );
208 public <T> void Delete(T t, Object r, String path, RestObject<T> restObject) {
210 String methodName = "Delete";
214 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + START_LOG);
217 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
219 url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
220 Logging.logRequest(outgoingRequestsLogger, HttpMethod.DELETE, url, r);
221 cres = client.target(url)
224 .accept(APPLICATION_JSON)
225 .headers(commonHeaders)
227 .build("DELETE", Entity.entity(r, MediaType.APPLICATION_JSON))
229 Logging.logResponse(outgoingRequestsLogger, HttpMethod.DELETE, url, cres);
230 int status = cres.getStatus();
231 restObject.setStatusCode (status);
233 if (status == 404) { // resource not found
234 String msg = "Resource does not exist...: " + cres.getStatus();
235 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + msg);
236 } else if (status == 200 || status == 204){
237 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + "Resource " + url + " deleted");
238 } else if (status == 202) {
239 String msg = "Delete in progress: " + status;
240 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + msg);
243 String msg = "Deleting Resource failed: " + status;
244 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + msg);
248 t = (T) cres.readEntity(t.getClass());
251 catch ( Exception e ) {
252 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + NO_RESPONSE_ENTITY_LOG
260 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_URL_LOG +url+ EXCEPTION_LOG + e.toString());
265 public <T> RestObject<T> PostForObject(Object requestDetails, String path, Class<T> clazz) {
266 logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), requestDetails, path, clazz);
267 return restCall(HttpMethod.POST, clazz, requestDetails, path);
270 public <T> RestObject<T> DeleteForObject(Object requestDetails, String path, Class<T> clazz) {
271 logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), requestDetails, path, clazz);
272 return restCall(HttpMethod.DELETE, clazz, requestDetails, path);
276 public void Post(String t, Object r, String path, RestObject<String> restObject) {
277 logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), t.getClass(), r, path);
278 restObject.copyFrom(restCall(HttpMethod.POST, String.class, r, path));
281 public Invocation.Builder prepareClient(String path, String methodName) {
282 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
284 String url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
285 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + " sending request to url= " + url);
286 // Change the content length
287 return client.target(url)
289 .accept(APPLICATION_JSON)
290 .headers(commonHeaders);
293 public <T> RestObject<T> restCall(HttpMethod httpMethod, Class<T> tClass, Object payload, String path) {
294 return restCall(httpMethod, tClass, payload, path, Optional.empty());
299 user id is needed to be pass as X-RequestorID in new MSO flows like Delete instanceGroup
301 public <T> RestObject<T> restCall(HttpMethod httpMethod, Class<T> tClass, Object payload, String path, Optional<String> userId) {
302 String methodName = httpMethod.name();
307 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
308 userId.ifPresent(id->commonHeaders.put("X-RequestorID", Collections.singletonList(id)));
310 url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
311 Logging.logRequest(outgoingRequestsLogger, httpMethod, url, payload);
312 // Change the content length
313 final Invocation.Builder restBuilder = client.target(url)
315 .accept(APPLICATION_JSON)
316 .headers(commonHeaders);
318 Invocation restInvocation = payload==null ?
319 restBuilder.build(httpMethod.name()) :
320 restBuilder.build(httpMethod.name(), Entity.entity(payload, MediaType.APPLICATION_JSON));
321 final Response cres = restInvocation.invoke();
323 Logging.logResponse(outgoingRequestsLogger, httpMethod, url, cres);
324 return cresToRestObject(cres, tClass);
326 catch (Exception e) {
327 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_URL_LOG +url+ EXCEPTION_LOG + e.toString());
333 private <T> RestObject<T> cresToRestObject(Response cres, Class<?> tClass) {
334 RestObject<T> restObject = new RestObject<>();
336 String rawEntity = null;
339 rawEntity = cres.readEntity(String.class);
340 restObject.setRaw(rawEntity);
341 T t = (T) new ObjectMapper().readValue(rawEntity, tClass);
344 catch ( Exception e ) {
346 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + getMethodCallerName() + " Error reading response entity as " + tClass + ": , e="
347 + e.getMessage() + ", Entity=" + rawEntity);
348 } catch (Exception e2) {
349 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + getMethodCallerName() + NO_RESPONSE_ENTITY_LOG
354 int status = cres.getStatus();
355 restObject.setStatusCode (status);
361 public <T> void Put(T t, org.onap.vid.changeManagement.RequestDetailsWrapper r, String path, RestObject<T> restObject) {
363 String methodName = "Put";
366 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + START_LOG);
370 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
372 url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
373 Logging.logRequest(outgoingRequestsLogger, HttpMethod.PUT, url, r);
374 // Change the content length
375 final Response cres = client.target(url)
377 .accept(APPLICATION_JSON)
378 .headers(commonHeaders)
379 //.header("content-length", 201)
380 .put(Entity.entity(r, MediaType.APPLICATION_JSON));
382 Logging.logResponse(outgoingRequestsLogger, HttpMethod.PUT, url, cres);
385 t = (T) cres.readEntity(t.getClass());
388 catch ( Exception e ) {
389 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + NO_RESPONSE_ENTITY_LOG
394 int status = cres.getStatus();
395 restObject.setStatusCode (status);
397 if ( status >= 200 && status <= 299 ) {
398 logger.info(EELFLoggerDelegate.errorLogger, "<== " + methodName + REST_API_SUCCESSFULL_LOG);
399 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + REST_API_SUCCESSFULL_LOG);
402 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_STATUS +status+ URL_LOG +url);
405 } catch (Exception e)
407 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_URL_LOG +url+ EXCEPTION_LOG + e.toString());