Custom Query Code
[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     /** The rest manager. */
49     // The REST manager used for processing REST calls for this AAI manager
50     private final RestManager restManager;
51
52     /** custom query URLs. */
53     private static String cqUrl =  "/aai/v16/query?format=resource";
54     private static String tenantUrl = "/aai/v16/search/nodes-query?search-node-type=vserver&filter=vserver-name:";
55     private static String prefix = "/aai/v16";
56
57
58     /**
59      * Constructor, create the AAI manager with the specified REST manager.
60      *
61      * @param restManager the rest manager to use for REST calls
62      */
63     public AaiManager(final RestManager restManager) {
64         this.restManager = restManager;
65     }
66
67     /**
68      * Creates the custom query payload from a tenant query response.
69      *
70      * @param getResponse response from the tenant query
71      * @return String Payload
72      */
73     private String createCustomQueryPayload(String getResponse) {
74
75         if (getResponse == null) {
76             return null;
77         } else {
78             JSONObject responseObj = new JSONObject(getResponse);
79             JSONArray resultsArray = new JSONArray();
80             if (responseObj.has("result-data")) {
81                 resultsArray = (JSONArray) responseObj.get("result-data");
82             } else {
83                 return null;
84             }
85             String resourceLink = resultsArray.getJSONObject(0).getString("resource-link");
86             String start = resourceLink.replace(prefix, "");
87             String query = "query/closed-loop";
88             JSONObject payload = new JSONObject();
89             payload.put("start", start);
90             payload.put("query", query);
91             return payload.toString();
92
93         }
94     }
95
96
97     /**
98      * This method is used to get the information for custom query.
99      *
100      * @param url url of the get method
101      * @param username Aai username
102      * @param password Aai password
103      * @param requestId request ID
104      * @param vserver Id of the vserver
105      * @return String
106      */
107     private String getCustomQueryRequestPayload(String url, String username, String password, UUID requestId,
108             String vserver) {
109
110         String urlGet = url + tenantUrl;
111         String getResponse = getStringQuery(urlGet, username, password, requestId, vserver);
112         return createCustomQueryPayload(getResponse);
113     }
114
115
116
117     /**
118      * Calls Aai and returns a custom query response for a vserver.
119      *
120      * @param url Aai url
121      * @param username Aai Username
122      * @param password Aai Password
123      * @param requestId request ID
124      * @param vserver Vserver
125      * @return AaiCqResponse response from Aai for custom query
126      */
127     public AaiCqResponse getCustomQueryResponse(String url, String username, String password, UUID requestId,
128             String vserver) {
129
130         final Map<String, String> headers = createHeaders(requestId);
131
132         url = url + cqUrl;
133
134         logger.debug("RestManager.put before");
135         String requestJson = getCustomQueryRequestPayload(url, username, password, requestId, vserver);
136         NetLoggerUtil.log(EventType.OUT, CommInfrastructure.REST, url, requestJson);
137         Pair<Integer, String> httpDetails =
138                 this.restManager.put(url, username, password, headers, "application/json", requestJson);
139         logger.debug("RestManager.put after");
140
141         if (httpDetails == null) {
142             logger.info("AAI POST Null Response to {}", url);
143             return null;
144         }
145
146         int httpResponseCode = httpDetails.first;
147
148         logger.info(url);
149         logger.info("{}", httpResponseCode);
150         logger.info(httpDetails.second);
151
152         if (httpDetails.second != null) {
153             String resp = httpDetails.second;
154             return new AaiCqResponse(resp);
155         }
156         return null;
157     }
158
159
160
161     /**
162      * Returns the string response of a get query.
163      *
164      * @param url Aai URL
165      * @param username Aai Username
166      * @param password Aai Password
167      * @param requestId AaiRequestId
168      * @param key Aai Key
169      * @return String returns the string from the get query
170      */
171     private String getStringQuery(final String url, final String username, final String password, final UUID requestId,
172             final String key) {
173
174         Map<String, String> headers = createHeaders(requestId);
175
176         String urlGet = url + key;
177
178         int attemptsLeft = 3;
179
180         while (attemptsLeft-- > 0) {
181             NetLoggerUtil.getNetworkLogger().info("[OUT|{}|{}|]", CommInfrastructure.REST, urlGet);
182             Pair<Integer, String> httpDetailsGet = restManager.get(urlGet, username, password, headers);
183             if (httpDetailsGet == null) {
184                 logger.info("AAI GET Null Response to {}", urlGet);
185                 return null;
186             }
187
188             int httpResponseCode = httpDetailsGet.first;
189
190             logger.info(urlGet);
191             logger.info("{}", httpResponseCode);
192             logger.info(httpDetailsGet.second);
193
194             if (httpResponseCode == 200) {
195                 String responseGet = httpDetailsGet.second;
196                 if (responseGet != null) {
197                     return responseGet;
198                 }
199             }
200             try {
201                 Thread.sleep(1000);
202             } catch (InterruptedException e) {
203                 Thread.currentThread().interrupt();
204             }
205
206         }
207
208         return null;
209     }
210
211
212     /**
213      * Post a query to A&AI.
214      *
215      * @param url the A&AI URL
216      * @param username the user name for authentication
217      * @param password the password for authentication
218      * @param request the request to issue towards A&AI
219      * @param requestId the UUID of the request
220      * @return the response from A&AI
221      */
222     public AaiNqResponse postQuery(String url, String username, String password, AaiNqRequest request, UUID requestId) {
223
224         final Map<String, String> headers = createHeaders(requestId);
225
226         url = url + "/aai/search/named-query";
227
228         logger.debug("RestManager.post before");
229         String requestJson = Serialization.gsonPretty.toJson(request);
230         NetLoggerUtil.log(EventType.OUT, CommInfrastructure.REST, url, requestJson);
231         Pair<Integer, String> httpDetails =
232                 restManager.post(url, username, password, headers, "application/json", requestJson);
233         logger.debug("RestManager.post after");
234
235         if (httpDetails == null) {
236             logger.info("AAI POST Null Response to {}", url);
237             return null;
238         }
239
240         int httpResponseCode = httpDetails.first;
241
242         logger.info(url);
243         logger.info("{}", httpResponseCode);
244         logger.info(httpDetails.second);
245
246         if (httpDetails.second != null) {
247             return composeResponse(httpDetails, url, AaiNqResponse.class);
248         }
249         return null;
250     }
251
252     /**
253      * Perform a GET request for a particular virtual server towards A&AI.
254      *
255      * @param urlGet the A&AI URL
256      * @param username the user name for authentication
257      * @param password the password for authentication
258      * @param requestId the UUID of the request
259      * @param key the key of the virtual server
260      * @return the response for the virtual server from A&AI
261      */
262     public AaiGetVserverResponse getQueryByVserverName(String urlGet, String username, String password, UUID requestId,
263             String key) {
264         return getQuery(urlGet, username, password, requestId, key, AaiGetVserverResponse.class);
265     }
266
267     /**
268      * Perform a GET request for a particular VNF by VNF ID towards A&AI.
269      *
270      * @param urlGet the A&AI URL
271      * @param username the user name for authentication
272      * @param password the password for authentication
273      * @param requestId the UUID of the request
274      * @param key the ID of the VNF
275      * @return the response for the virtual server from A&AI
276      */
277     public AaiGetVnfResponse getQueryByVnfId(String urlGet, String username, String password, UUID requestId,
278             String key) {
279         return getQuery(urlGet, username, password, requestId, key, AaiGetVnfResponse.class);
280     }
281
282     /**
283      * Perform a GET request for a particular VNF by VNF name towards A&AI.
284      *
285      * @param urlGet the A&AI URL
286      * @param username the user name for authentication
287      * @param password the password for authentication
288      * @param requestId the UUID of the request
289      * @param key the name of the VNF
290      * @return the response for the virtual server from A&AI
291      */
292     public AaiGetVnfResponse getQueryByVnfName(String urlGet, String username, String password, UUID requestId,
293             String key) {
294         return getQuery(urlGet, username, password, requestId, key, AaiGetVnfResponse.class);
295     }
296
297     /**
298      * Perform a GET query for a particular entity towards A&AI.
299      *
300      * @param <T> the generic type for the response
301      * @param urlGet the A&AI URL
302      * @param username the user name for authentication
303      * @param password the password for authentication
304      * @param requestId the UUID of the request
305      * @param key the name of the VNF
306      * @param classOfT the class of the response to return
307      * @return the response for the virtual server from A&AI
308      */
309     private <T> T getQuery(final String url, final String username, final String password, final UUID requestId,
310             final String key, final Class<T> classOfResponse) {
311
312         Map<String, String> headers = createHeaders(requestId);
313
314         String urlGet = url + key;
315
316         int attemptsLeft = 3;
317
318         while (attemptsLeft-- > 0) {
319             NetLoggerUtil.getNetworkLogger().info("[OUT|{}|{}|]", CommInfrastructure.REST, urlGet);
320             Pair<Integer, String> httpDetailsGet = restManager.get(urlGet, username, password, headers);
321             if (httpDetailsGet == null) {
322                 logger.info("AAI GET Null Response to {}", urlGet);
323                 return null;
324             }
325
326             int httpResponseCode = httpDetailsGet.first;
327
328             logger.info(urlGet);
329             logger.info("{}", httpResponseCode);
330             logger.info(httpDetailsGet.second);
331
332             if (httpResponseCode == 200) {
333                 T responseGet = composeResponse(httpDetailsGet, urlGet, classOfResponse);
334                 if (responseGet != null) {
335                     return responseGet;
336                 }
337             }
338             try {
339                 Thread.sleep(1000);
340             } catch (InterruptedException e) {
341                 Thread.currentThread().interrupt();
342             }
343
344         }
345
346         return null;
347     }
348
349     /**
350      * Create the headers for the HTTP request.
351      *
352      * @param requestId the request ID to insert in the headers
353      * @return the HTTP headers
354      */
355     private Map<String, String> createHeaders(final UUID requestId) {
356         Map<String, String> headers = new HashMap<>();
357
358         headers.put("X-FromAppId", "POLICY");
359         headers.put("X-TransactionId", requestId.toString());
360         headers.put("Accept", "application/json");
361
362         return headers;
363     }
364
365     /**
366      * This method uses Google's GSON to create a response object from a JSON string.
367      *
368      * @param <T> the generic type
369      * @param httpDetails the HTTP response
370      * @param url the URL from which the response came
371      * @param classOfResponse The response class
372      * @return an instance of the response class
373      * @throws JsonSyntaxException on GSON errors instantiating the response
374      */
375     private <T> T composeResponse(final Pair<Integer, String> httpDetails, final String url,
376             final Class<T> classOfResponse) {
377         try {
378             T response = Serialization.gsonPretty.fromJson(httpDetails.second, classOfResponse);
379             NetLoggerUtil.log(EventType.IN, CommInfrastructure.REST, url, httpDetails.second);
380             return response;
381         } catch (JsonSyntaxException e) {
382             logger.error("postQuery threw: ", e);
383             return null;
384         }
385     }
386 }