Merge "Fix simple sonar issues in models-tosca"
[policy/models.git] / models-interactions / model-impl / aai / src / main / java / org / onap / policy / aai / AaiManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * aai
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
7  * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.aai;
24
25 import com.google.gson.JsonSyntaxException;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.UUID;
29 import org.json.JSONArray;
30 import org.json.JSONObject;
31 import org.onap.policy.aai.util.Serialization;
32 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
33 import org.onap.policy.common.endpoints.utils.NetLoggerUtil;
34 import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType;
35 import org.onap.policy.rest.RestManager;
36 import org.onap.policy.rest.RestManager.Pair;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * This class handles communication towards and responses from A&AI for this module.
42  */
43 public final class AaiManager {
44
45     /** The Constant logger. */
46     private static final Logger logger = LoggerFactory.getLogger(AaiManager.class);
47
48     private static final String APPLICATION_JSON = "application/json";
49
50     /** The rest manager. */
51     // The REST manager used for processing REST calls for this AAI manager
52     private final RestManager restManager;
53
54     /** custom query URLs. */
55     private static final String CQ_URL = "/aai/v16/query?format=resource";
56     private static final String TENANT_URL =
57             "/aai/v16/search/nodes-query?search-node-type=vserver&filter=vserver-name:EQUALS:";
58     private static final String PREFIX = "/aai/v16";
59
60
61     /**
62      * Constructor, create the AAI manager with the specified REST manager.
63      *
64      * @param restManager the rest manager to use for REST calls
65      */
66     public AaiManager(final RestManager restManager) {
67         this.restManager = restManager;
68     }
69
70     /**
71      * Creates the custom query payload from a tenant query response.
72      *
73      * @param getResponse response from the tenant query
74      * @return String Payload
75      */
76     private String createCustomQueryPayload(String getResponse) {
77
78         if (getResponse == null) {
79             return null;
80         } else {
81             JSONObject responseObj = new JSONObject(getResponse);
82             JSONArray resultsArray;
83             if (responseObj.has("result-data")) {
84                 resultsArray = (JSONArray) responseObj.get("result-data");
85             } else {
86                 return null;
87             }
88             String resourceLink = resultsArray.getJSONObject(0).getString("resource-link");
89             String start = resourceLink.replace(PREFIX, "");
90             String query = "query/closed-loop";
91             JSONObject payload = new JSONObject();
92             payload.put("start", start);
93             payload.put("query", query);
94             return payload.toString();
95
96         }
97     }
98
99
100     /**
101      * This method is used to get the information for custom query.
102      *
103      * @param url url of the get method
104      * @param username Aai username
105      * @param password Aai password
106      * @param requestId request ID
107      * @param vserver Id of the vserver
108      * @return String
109      */
110     private String getCustomQueryRequestPayload(String url, String username, String password, UUID requestId,
111             String vserver) {
112
113         String urlGet = url + TENANT_URL;
114
115         String getResponse = getStringQuery(urlGet, username, password, requestId, vserver);
116         return createCustomQueryPayload(getResponse);
117     }
118
119
120
121     /**
122      * Calls Aai and returns a custom query response for a vserver.
123      *
124      * @param url Aai url
125      * @param username Aai Username
126      * @param password Aai Password
127      * @param requestId request ID
128      * @param vserver Vserver
129      * @return AaiCqResponse response from Aai for custom query
130      */
131     public AaiCqResponse getCustomQueryResponse(String url, String username, String password, UUID requestId,
132             String vserver) {
133
134         final Map<String, String> headers = createHeaders(requestId);
135
136         logger.debug("RestManager.put before");
137         String requestJson = getCustomQueryRequestPayload(url, username, password, requestId, vserver);
138         NetLoggerUtil.log(EventType.OUT, CommInfrastructure.REST, url, requestJson);
139
140         url = url + CQ_URL;
141
142         Pair<Integer, String> httpDetails =
143                 this.restManager.put(url, username, password, headers, APPLICATION_JSON, requestJson);
144         logger.debug("RestManager.put after");
145
146         if (httpDetails == null) {
147             logger.info("AAI POST Null Response to {}", url);
148             return null;
149         }
150
151         int httpResponseCode = httpDetails.first;
152
153         logger.info(url);
154         logger.info("{}", httpResponseCode);
155         logger.info(httpDetails.second);
156
157         if (httpDetails.second != null) {
158             String resp = httpDetails.second;
159             return new AaiCqResponse(resp);
160         }
161         return null;
162     }
163
164
165
166     /**
167      * Returns the string response of a get query.
168      *
169      * @param url Aai URL
170      * @param username Aai Username
171      * @param password Aai Password
172      * @param requestId AaiRequestId
173      * @param key Aai Key
174      * @return String returns the string from the get query
175      */
176     private String getStringQuery(final String url, final String username, final String password, final UUID requestId,
177             final String key) {
178
179         Map<String, String> headers = createHeaders(requestId);
180
181         String urlGet = url + key;
182
183         int attemptsLeft = 3;
184
185         while (attemptsLeft-- > 0) {
186             NetLoggerUtil.getNetworkLogger().info("[OUT|{}|{}|]", CommInfrastructure.REST, urlGet);
187             Pair<Integer, String> httpDetailsGet = restManager.get(urlGet, username, password, headers);
188             if (httpDetailsGet == null) {
189                 logger.info("AAI GET Null Response to {}", urlGet);
190                 return null;
191             }
192
193             int httpResponseCode = httpDetailsGet.first;
194
195             logger.info(urlGet);
196             logger.info("{}", httpResponseCode);
197             logger.info(httpDetailsGet.second);
198
199             if (httpResponseCode == 200) {
200                 String responseGet = httpDetailsGet.second;
201                 if (responseGet != null) {
202                     return responseGet;
203                 }
204             }
205             try {
206                 Thread.sleep(1000);
207             } catch (InterruptedException e) {
208                 Thread.currentThread().interrupt();
209             }
210
211         }
212
213         return null;
214     }
215
216
217     /**
218      * Post a query to A&AI.
219      *
220      * @param url the A&AI URL
221      * @param username the user name for authentication
222      * @param password the password for authentication
223      * @param request the request to issue towards A&AI
224      * @param requestId the UUID of the request
225      * @return the response from A&AI
226      */
227     public AaiNqResponse postQuery(String url, String username, String password, AaiNqRequest request, UUID requestId) {
228
229         final Map<String, String> headers = createHeaders(requestId);
230
231         url = url + "/aai/search/named-query";
232
233         logger.debug("RestManager.post before");
234         String requestJson = Serialization.gsonPretty.toJson(request);
235         NetLoggerUtil.log(EventType.OUT, CommInfrastructure.REST, url, requestJson);
236         Pair<Integer, String> httpDetails =
237                 restManager.post(url, username, password, headers, APPLICATION_JSON, requestJson);
238         logger.debug("RestManager.post after");
239
240         if (httpDetails == null) {
241             logger.info("AAI POST Null Response to {}", url);
242             return null;
243         }
244
245         int httpResponseCode = httpDetails.first;
246
247         logger.info(url);
248         logger.info("{}", httpResponseCode);
249         logger.info(httpDetails.second);
250
251         if (httpDetails.second != null) {
252             return composeResponse(httpDetails, url, AaiNqResponse.class);
253         }
254         return null;
255     }
256
257     /**
258      * Perform a GET request for a particular virtual server towards A&AI.
259      *
260      * @param urlGet the A&AI URL
261      * @param username the user name for authentication
262      * @param password the password for authentication
263      * @param requestId the UUID of the request
264      * @param key the key of the virtual server
265      * @return the response for the virtual server from A&AI
266      */
267     public AaiGetVserverResponse getQueryByVserverName(String urlGet, String username, String password, UUID requestId,
268             String key) {
269         return getQuery(urlGet, username, password, requestId, key, AaiGetVserverResponse.class);
270     }
271
272     /**
273      * Perform a GET request for a particular VNF by VNF ID towards A&AI.
274      *
275      * @param urlGet the A&AI URL
276      * @param username the user name for authentication
277      * @param password the password for authentication
278      * @param requestId the UUID of the request
279      * @param key the ID of the VNF
280      * @return the response for the virtual server from A&AI
281      */
282     public AaiGetVnfResponse getQueryByVnfId(String urlGet, String username, String password, UUID requestId,
283             String key) {
284         return getQuery(urlGet, username, password, requestId, key, AaiGetVnfResponse.class);
285     }
286
287     /**
288      * Perform a GET request for a particular VNF by VNF name towards A&AI.
289      *
290      * @param urlGet the A&AI URL
291      * @param username the user name for authentication
292      * @param password the password for authentication
293      * @param requestId the UUID of the request
294      * @param key the name of the VNF
295      * @return the response for the virtual server from A&AI
296      */
297     public AaiGetVnfResponse getQueryByVnfName(String urlGet, String username, String password, UUID requestId,
298             String key) {
299         return getQuery(urlGet, username, password, requestId, key, AaiGetVnfResponse.class);
300     }
301
302     /**
303      * Perform a GET query for a particular entity towards A&AI.
304      *
305      * @param <T> the generic type for the response
306      * @param urlGet the A&AI URL
307      * @param username the user name for authentication
308      * @param password the password for authentication
309      * @param requestId the UUID of the request
310      * @param key the name of the VNF
311      * @param classOfT the class of the response to return
312      * @return the response for the virtual server from A&AI
313      */
314     private <T> T getQuery(final String url, final String username, final String password, final UUID requestId,
315             final String key, final Class<T> classOfResponse) {
316
317         Map<String, String> headers = createHeaders(requestId);
318
319         String urlGet = url + key;
320
321         int attemptsLeft = 3;
322
323         while (attemptsLeft-- > 0) {
324             NetLoggerUtil.getNetworkLogger().info("[OUT|{}|{}|]", CommInfrastructure.REST, urlGet);
325             Pair<Integer, String> httpDetailsGet = restManager.get(urlGet, username, password, headers);
326             if (httpDetailsGet == null) {
327                 logger.info("AAI GET Null Response to {}", urlGet);
328                 return null;
329             }
330
331             int httpResponseCode = httpDetailsGet.first;
332
333             logger.info(urlGet);
334             logger.info("{}", httpResponseCode);
335             logger.info(httpDetailsGet.second);
336
337             if (httpResponseCode == 200) {
338                 T responseGet = composeResponse(httpDetailsGet, urlGet, classOfResponse);
339                 if (responseGet != null) {
340                     return responseGet;
341                 }
342             }
343             try {
344                 Thread.sleep(1000);
345             } catch (InterruptedException e) {
346                 Thread.currentThread().interrupt();
347             }
348
349         }
350
351         return null;
352     }
353
354     /**
355      * Create the headers for the HTTP request.
356      *
357      * @param requestId the request ID to insert in the headers
358      * @return the HTTP headers
359      */
360     private Map<String, String> createHeaders(final UUID requestId) {
361         Map<String, String> headers = new HashMap<>();
362
363         headers.put("X-FromAppId", "POLICY");
364         headers.put("X-TransactionId", requestId.toString());
365         headers.put("Accept", APPLICATION_JSON);
366
367         return headers;
368     }
369
370
371     /**
372      * This method uses Google's GSON to create a response object from a JSON string.
373      *
374      * @param <T> the generic type
375      * @param httpDetails the HTTP response
376      * @param url the URL from which the response came
377      * @param classOfResponse The response class
378      * @return an instance of the response class
379      * @throws JsonSyntaxException on GSON errors instantiating the response
380      */
381     private <T> T composeResponse(final Pair<Integer, String> httpDetails, final String url,
382             final Class<T> classOfResponse) {
383         try {
384             T response = Serialization.gsonPretty.fromJson(httpDetails.second, classOfResponse);
385             NetLoggerUtil.log(EventType.IN, CommInfrastructure.REST, url, httpDetails.second);
386             return response;
387         } catch (JsonSyntaxException e) {
388             logger.error("postQuery threw: ", e);
389             return null;
390         }
391     }
392 }