Use new version of A&AI APIs
[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-2021 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019-2020 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 java.io.UnsupportedEncodingException;
26 import java.net.URLEncoder;
27 import java.nio.charset.StandardCharsets;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.UUID;
31 import java.util.stream.Collectors;
32 import org.apache.commons.lang3.tuple.Pair;
33 import org.json.JSONArray;
34 import org.json.JSONObject;
35 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
36 import org.onap.policy.common.endpoints.utils.NetLoggerUtil;
37 import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType;
38 import org.onap.policy.common.utils.coder.CoderException;
39 import org.onap.policy.common.utils.coder.StandardCoder;
40 import org.onap.policy.rest.RestManager;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 /**
45  * This class handles communication towards and responses from A&AI for this module.
46  */
47 public final class AaiManager {
48
49     // TODO remove this class
50
51     /** The Constant logger. */
52     private static final Logger logger = LoggerFactory.getLogger(AaiManager.class);
53
54     private static final String APPLICATION_JSON = "application/json";
55
56     private static final StandardCoder CODER = new StandardCoder();
57
58     // The REST manager used for processing REST calls for this AAI manager
59     private final RestManager restManager;
60
61     /** custom query and other AAI resource URLs. */
62     private static final String CQ_URL = "/aai/v21/query?format=resource";
63     private static final String TENANT_URL = "/aai/v21/search/nodes-query?"
64                     + "search-node-type=vserver&filter=vserver-name:EQUALS:";
65     private static final String PREFIX = "/aai/v21";
66     private static final String PNF_URL = PREFIX + "/network/pnfs/pnf/";
67     private static final String AAI_DEPTH_SUFFIX = "?depth=0";
68
69     /**
70      * Constructor, create the AAI manager with the specified REST manager.
71      *
72      * @param restManager the rest manager to use for REST calls
73      */
74     public AaiManager(final RestManager restManager) {
75         this.restManager = restManager;
76     }
77
78     /**
79      * Creates the custom query payload from a tenant query response.
80      *
81      * @param getResponse response from the tenant query
82      * @return String Payload
83      */
84     private String createCustomQueryPayload(String getResponse) {
85
86         if (getResponse == null) {
87             return null;
88         } else {
89             JSONObject responseObj = new JSONObject(getResponse);
90             JSONArray resultsArray;
91             if (responseObj.has("result-data")) {
92                 resultsArray = (JSONArray) responseObj.get("result-data");
93             } else {
94                 return null;
95             }
96             String resourceLink = resultsArray.getJSONObject(0).getString("resource-link");
97             String start = resourceLink.replace(PREFIX, "");
98             String query = "query/closed-loop";
99             JSONObject payload = new JSONObject();
100             payload.put("start", start);
101             payload.put("query", query);
102             return payload.toString();
103
104         }
105     }
106
107     /**
108      * This method is used to get the information for custom query.
109      *
110      * @param url url of the get method
111      * @param username Aai username
112      * @param password Aai password
113      * @param requestId request ID
114      * @param vserver Id of the vserver
115      * @return String
116      */
117     private String getCustomQueryRequestPayload(String url, String username, String password, UUID requestId,
118                     String vserver) {
119
120         String urlGet = url + TENANT_URL;
121
122         String getResponse = getStringQuery(urlGet, username, password, requestId, vserver);
123         return createCustomQueryPayload(getResponse);
124     }
125
126     /**
127      * Calls Aai and returns a custom query response for a vserver.
128      *
129      * @param url Aai url
130      * @param username Aai Username
131      * @param password Aai Password
132      * @param requestId request ID
133      * @param vserver Vserver
134      * @return AaiCqResponse response from Aai for custom query
135      */
136     public AaiCqResponse getCustomQueryResponse(String url, String username, String password, UUID requestId,
137                     String vserver) {
138
139         final Map<String, String> headers = createHeaders(requestId);
140
141         logger.debug("RestManager.put before");
142         String requestJson = getCustomQueryRequestPayload(url, username, password, requestId, vserver);
143         NetLoggerUtil.log(EventType.OUT, CommInfrastructure.REST, url, requestJson);
144
145         url = url + CQ_URL;
146
147         Pair<Integer, String> httpDetails = this.restManager.put(url, username, password, headers, APPLICATION_JSON,
148                         requestJson);
149         logger.debug("RestManager.put after");
150
151         if (httpDetails == null) {
152             NetLoggerUtil.log(EventType.IN, CommInfrastructure.REST, url, "AAI POST Null Response");
153             logger.debug("AAI POST Null Response to {}", url);
154             return null;
155         }
156
157         int httpResponseCode = httpDetails.getLeft();
158
159         NetLoggerUtil.log(EventType.IN, CommInfrastructure.REST, url, "Response code: " + httpResponseCode);
160         NetLoggerUtil.getNetworkLogger().debug(httpDetails.getRight());
161
162         logger.debug(url);
163         logger.debug("{}", httpResponseCode);
164         logger.debug(httpDetails.getRight());
165
166         if (httpDetails.getRight() != null) {
167             return new AaiCqResponse(httpDetails.getRight());
168         }
169         return null;
170     }
171
172     /**
173      * Returns the string response of a get query.
174      *
175      * @param url Aai URL
176      * @param username Aai Username
177      * @param password Aai Password
178      * @param requestId AaiRequestId
179      * @param key Aai Key
180      * @return String returns the string from the get query
181      */
182     private String getStringQuery(final String url, final String username, final String password, final UUID requestId,
183                     final String key) {
184
185         Map<String, String> headers = createHeaders(requestId);
186
187         String urlGet = url + key;
188
189         int attemptsLeft = 3;
190
191         while (attemptsLeft-- > 0) {
192             NetLoggerUtil.getNetworkLogger().info("[OUT|{}|{}|]", CommInfrastructure.REST, urlGet);
193             Pair<Integer, String> httpDetailsGet = restManager.get(urlGet, username, password, headers);
194             if (httpDetailsGet == null) {
195                 NetLoggerUtil.log(EventType.IN, CommInfrastructure.REST, url, "AAI POST Null Response");
196                 logger.debug("AAI GET Null Response to {}", urlGet);
197                 return null;
198             }
199
200             int httpResponseCode = httpDetailsGet.getLeft();
201
202             NetLoggerUtil.log(EventType.IN, CommInfrastructure.REST, url, "Response code: " + httpResponseCode);
203             NetLoggerUtil.getNetworkLogger().debug(httpDetailsGet.getRight());
204
205             logger.debug(urlGet);
206             logger.debug("{}", httpResponseCode);
207             logger.debug(httpDetailsGet.getRight());
208
209             if (httpResponseCode == 200 && httpDetailsGet.getRight() != null) {
210                 return httpDetailsGet.getRight();
211             }
212             try {
213                 Thread.sleep(1000);
214             } catch (InterruptedException e) {
215                 Thread.currentThread().interrupt();
216             }
217
218         }
219
220         return null;
221     }
222
223     /**
224      * Create the headers for the HTTP request.
225      *
226      * @param requestId the request ID to insert in the headers
227      * @return the HTTP headers
228      */
229     private Map<String, String> createHeaders(final UUID requestId) {
230         Map<String, String> headers = new HashMap<>();
231
232         headers.put("X-FromAppId", "POLICY");
233         headers.put("X-TransactionId", requestId.toString());
234         headers.put("Accept", APPLICATION_JSON);
235
236         return headers;
237     }
238
239     /**
240      * Perform a GET request for a particular PNF by PNF ID towards A&AI.
241      *
242      * @param url the A&AI URL
243      * @param username the user name for authentication
244      * @param password the password for authentication
245      * @param requestId the UUID of the request
246      * @param pnfName the AAI unique identifier for PNF object
247      * @return HashMap of PNF properties
248      */
249     public Map<String, String> getPnf(String url, String username, String password, UUID requestId, String pnfName) {
250         String urlGet;
251         try {
252             urlGet = url + PNF_URL;
253             pnfName = URLEncoder.encode(pnfName, StandardCharsets.UTF_8.toString()) + AAI_DEPTH_SUFFIX;
254         } catch (UnsupportedEncodingException e) {
255             logger.error("Failed to encode the pnfName: {} using UTF-8", pnfName, e);
256             return null;
257         }
258         String responseGet = getStringQuery(urlGet, username, password, requestId, pnfName);
259         if (responseGet == null) {
260             logger.error("Null response from AAI for the url: {}.", urlGet);
261             return null;
262         }
263         try {
264             @SuppressWarnings("unchecked")
265             Map<String, String> pnfParams = CODER.decode(responseGet, HashMap.class);
266             // Map to AAI node.attribute notation
267             return pnfParams.entrySet().stream()
268                             .collect(Collectors.toMap(e -> "pnf." + e.getKey(), Map.Entry::getValue));
269         } catch (CoderException e) {
270             logger.error("Failed to fetch PNF from AAI", e);
271             return null;
272         }
273     }
274 }