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