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 static org.onap.vid.logging.Headers.INVOCATION_ID;
24 import static org.onap.vid.logging.Headers.PARTNER_NAME;
25 import static org.onap.vid.utils.Logging.ONAP_REQUEST_ID_HEADER_KEY;
26 import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY;
27 import static org.onap.vid.utils.Logging.getMethodCallerName;
28 import static org.onap.vid.utils.Logging.getMethodName;
30 import com.att.eelf.configuration.EELFLogger;
31 import com.fasterxml.jackson.databind.ObjectMapper;
32 import java.util.Collections;
33 import java.util.Optional;
34 import javax.ws.rs.client.Client;
35 import javax.ws.rs.client.Entity;
36 import javax.ws.rs.client.Invocation;
37 import javax.ws.rs.core.MediaType;
38 import javax.ws.rs.core.MultivaluedHashMap;
39 import javax.ws.rs.core.Response;
40 import org.apache.commons.codec.binary.Base64;
41 import org.apache.http.HttpException;
42 import org.eclipse.jetty.util.security.Password;
43 import org.glassfish.jersey.client.ClientProperties;
44 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
45 import org.onap.vid.aai.ExceptionWithRequestInfo;
46 import org.onap.vid.aai.util.HttpClientMode;
47 import org.onap.vid.aai.util.HttpsAuthClient;
48 import org.onap.vid.client.HttpBasicClient;
49 import org.onap.vid.exceptions.GenericUncheckedException;
50 import org.onap.vid.mso.rest.RestInterface;
51 import org.onap.vid.utils.Logging;
52 import org.onap.vid.utils.SystemPropertiesWrapper;
53 import org.springframework.beans.factory.annotation.Autowired;
54 import org.springframework.http.HttpMethod;
57 * Created by pickjonathan on 26/06/2017.
59 public class RestMsoImplementation implements RestInterface {
65 protected EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMsoImplementation.class);
66 private final EELFLogger outgoingRequestsLogger = Logging.getRequestsLogger("mso");
69 private Client client = null;
72 protected HttpsAuthClient httpsAuthClient;
73 protected SystemPropertiesWrapper systemProperties;
74 protected final Logging loggingService;
76 private static final String START_LOG = " start";
77 private static final String APPLICATION_JSON = "application/json";
78 private static final String WITH_STATUS = " with status=";
79 private static final String URL_LOG = ", url=";
80 private static final String NO_RESPONSE_ENTITY_LOG = " No response entity, this is probably ok, e=";
81 private static final String WITH_URL_LOG = " with url=";
82 private static final String EXCEPTION_LOG = ", Exception: ";
83 private static final String REST_API_SUCCESSFULL_LOG = " REST api was successfull!";
84 private static final String REST_MSG_TEMPLATE = "start {}->{}({}, {}, {})";
85 /** The common headers. */
87 * Instantiates a new mso rest interface.
91 public RestMsoImplementation(HttpsAuthClient httpsAuthClient, SystemPropertiesWrapper systemProperties, Logging loggingService){
92 this.httpsAuthClient=httpsAuthClient;
93 this.systemProperties = systemProperties;
94 this.loggingService = loggingService;
97 @SuppressWarnings("Duplicates")
98 protected MultivaluedHashMap<String, Object> initMsoClient()
100 final String methodname = "initRestClient()";
102 final String username = systemProperties.getProperty(MsoProperties.MSO_USER_NAME);
103 final String password = systemProperties.getProperty(MsoProperties.MSO_PASSWORD);
104 final String mso_url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL);
105 final String decrypted_password = Password.deobfuscate(password);
107 String authString = username + ":" + decrypted_password;
109 byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
110 String authStringEnc = new String(authEncBytes);
112 MultivaluedHashMap<String, Object> commonHeaders = new MultivaluedHashMap();
113 commonHeaders.put("Authorization", Collections.singletonList(("Basic " + authStringEnc)));
114 commonHeaders.put(PARTNER_NAME.getHeaderName(), Collections.singletonList(PARTNER_NAME.getHeaderValue()));
116 String requestIdValue = Logging.extractOrGenerateRequestId();
117 commonHeaders.put(REQUEST_ID_HEADER_KEY, Collections.singletonList(requestIdValue));
118 commonHeaders.put(ONAP_REQUEST_ID_HEADER_KEY, Collections.singletonList(requestIdValue));
119 commonHeaders.put(INVOCATION_ID.getHeaderName(), Collections.singletonList(INVOCATION_ID.getHeaderValue()));
121 boolean useSsl = true;
122 if ( (mso_url != null) && ( !(mso_url.isEmpty()) ) ) {
123 useSsl = mso_url.startsWith("https");
125 if (client == null) {
129 client = httpsAuthClient.getClient(HttpClientMode.WITHOUT_KEYSTORE);
132 client = HttpBasicClient.getClient();
134 } catch (Exception e) {
135 logger.info(EELFLoggerDelegate.errorLogger,methodname + " Unable to get the SSL client");
139 return commonHeaders;
142 public <T> RestObjectWithRequestInfo<T> Get(T t, String path, RestObject<T> restObject, boolean warpException) {
143 String methodName = "Get";
145 logger.debug(EELFLoggerDelegate.debugLogger, methodName + START_LOG);
148 String rawData = null;
149 Integer status = null;
153 url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
155 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
156 loggingService.logRequest(outgoingRequestsLogger, HttpMethod.GET, url);
157 final Response cres = client.target(url)
159 .accept(APPLICATION_JSON)
160 .headers(commonHeaders)
162 loggingService.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres);
165 status = cres.getStatus();
166 rawData = cres.readEntity(String.class);
168 restObject.setStatusCode(status);
170 if (status == 200 || status == 202) {
171 t = (T) cres.readEntity(t.getClass());
173 logger.debug(EELFLoggerDelegate.debugLogger, methodName + REST_API_SUCCESSFULL_LOG);
176 throw new GenericUncheckedException(new HttpException(methodName + WITH_STATUS + status + " (200 or 202 expected), url= " + url));
179 logger.debug(EELFLoggerDelegate.debugLogger, methodName + " received status=" + status);
181 return new RestObjectWithRequestInfo<>(HttpMethod.GET, url, restObject, status, rawData);
182 } catch (RuntimeException e) {
183 throw warpException ? new ExceptionWithRequestInfo(HttpMethod.GET, url, rawData, status, e) : e;
188 public <T> RestObject<T> GetForObject(String path, Class<T> clazz) {
189 final String methodName = getMethodName();
190 logger.debug(EELFLoggerDelegate.debugLogger, "start {}->{}({}, {})", getMethodCallerName(), methodName, path, clazz);
192 String url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
193 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + methodName + " sending request to url= " + url);
195 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
196 loggingService.logRequest(outgoingRequestsLogger, HttpMethod.GET, url);
197 final Response cres = client.target(url)
199 .accept(APPLICATION_JSON)
200 .headers(commonHeaders)
202 loggingService.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres);
203 final RestObject<T> restObject = cresToRestObject(cres, clazz);
204 int status = cres.getStatus();
206 if (status == 200 || status == 202) {
207 logger.debug(EELFLoggerDelegate.debugLogger, methodName + REST_API_SUCCESSFULL_LOG);
209 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_STATUS +status+ URL_LOG +url);
212 logger.debug(EELFLoggerDelegate.debugLogger,methodName + " received status=" + status );
217 public <T> RestObject<T> PostForObject(Object requestDetails, String path, Class<T> clazz) {
218 logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), requestDetails, path, clazz);
219 return restCall(HttpMethod.POST, clazz, requestDetails, path);
222 public <T> RestObject<T> DeleteForObject(Object requestDetails, String path, Class<T> clazz) {
223 logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), requestDetails, path, clazz);
224 return restCall(HttpMethod.DELETE, clazz, requestDetails, path);
228 public void Post(String t, Object r, String path, RestObject<String> restObject) {
229 logger.debug(EELFLoggerDelegate.debugLogger, REST_MSG_TEMPLATE, getMethodCallerName(), getMethodName(), t.getClass(), r, path);
230 restObject.copyFrom(restCall(HttpMethod.POST, String.class, r, path));
233 public Invocation.Builder prepareClient(String path, String methodName) {
234 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
236 String url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
237 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + " sending request to url= " + url);
238 // Change the content length
239 return client.target(url)
241 .accept(APPLICATION_JSON)
242 .headers(commonHeaders);
245 public <T> RestObject<T> restCall(HttpMethod httpMethod, Class<T> tClass, Object payload, String path) {
246 return restCall(httpMethod, tClass, payload, path, Optional.empty());
251 user id is needed to be pass as X-RequestorID in new MSO flows like Delete instanceGroup
253 public <T> RestObject<T> restCall(HttpMethod httpMethod, Class<T> tClass, Object payload, String path, Optional<String> userId) {
254 String methodName = httpMethod.name();
259 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
260 userId.ifPresent(id->commonHeaders.put("X-RequestorID", Collections.singletonList(id)));
262 url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
263 loggingService.logRequest(outgoingRequestsLogger, httpMethod, url, payload);
264 // Change the content length
265 final Invocation.Builder restBuilder = client.target(url)
267 .accept(APPLICATION_JSON)
268 .headers(commonHeaders)
269 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true)
272 Invocation restInvocation = payload==null ?
273 restBuilder.build(httpMethod.name()) :
274 restBuilder.build(httpMethod.name(), Entity.entity(payload, MediaType.APPLICATION_JSON));
275 final Response cres = restInvocation.invoke();
277 loggingService.logResponse(outgoingRequestsLogger, httpMethod, url, cres);
278 return cresToRestObject(cres, tClass);
280 catch (Exception e) {
281 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_URL_LOG +url+ EXCEPTION_LOG + e.toString());
287 private <T> RestObject<T> cresToRestObject(Response cres, Class<?> tClass) {
288 RestObject<T> restObject = new RestObject<>();
290 String rawEntity = null;
293 rawEntity = cres.readEntity(String.class);
294 restObject.setRaw(rawEntity);
295 T t = (T) new ObjectMapper().readValue(rawEntity, tClass);
298 catch ( Exception e ) {
300 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + getMethodCallerName() + " Error reading response entity as " + tClass + ": , e="
301 + e.getMessage() + ", Entity=" + rawEntity);
302 } catch (Exception e2) {
303 logger.debug(EELFLoggerDelegate.debugLogger, "<== " + getMethodCallerName() + NO_RESPONSE_ENTITY_LOG
308 int status = cres.getStatus();
309 restObject.setStatusCode (status);
315 public <T> void Put(T t, org.onap.vid.changeManagement.RequestDetailsWrapper r, String path, RestObject<T> restObject) {
317 String methodName = "Put";
320 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + START_LOG);
324 MultivaluedHashMap<String, Object> commonHeaders = initMsoClient();
326 url = systemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
327 loggingService.logRequest(outgoingRequestsLogger, HttpMethod.PUT, url, r);
328 // Change the content length
329 final Response cres = client.target(url)
331 .accept(APPLICATION_JSON)
332 .headers(commonHeaders)
333 //.header("content-length", 201)
334 .put(Entity.entity(r, MediaType.APPLICATION_JSON));
336 loggingService.logResponse(outgoingRequestsLogger, HttpMethod.PUT, url, cres);
339 t = (T) cres.readEntity(t.getClass());
342 catch ( Exception e ) {
343 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + NO_RESPONSE_ENTITY_LOG
348 int status = cres.getStatus();
349 restObject.setStatusCode (status);
351 if ( status >= 200 && status <= 299 ) {
352 logger.info(EELFLoggerDelegate.errorLogger, "<== " + methodName + REST_API_SUCCESSFULL_LOG);
353 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + REST_API_SUCCESSFULL_LOG);
356 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_STATUS +status+ URL_LOG +url);
359 } catch (Exception e)
361 logger.debug(EELFLoggerDelegate.debugLogger,"<== " + methodName + WITH_URL_LOG +url+ EXCEPTION_LOG + e.toString());