2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
23 package org.openecomp.sparky.inventory.servlet;
25 import org.openecomp.cl.mdc.MdcContext;
26 import com.fasterxml.jackson.core.JsonProcessingException;
27 import com.fasterxml.jackson.databind.JsonNode;
28 import com.fasterxml.jackson.databind.ObjectMapper;
29 import com.fasterxml.jackson.databind.SerializationFeature;
31 import java.io.IOException;
32 import java.io.PrintWriter;
33 import java.nio.ByteBuffer;
34 import java.security.SecureRandom;
35 import java.util.Arrays;
36 import java.util.HashMap;
37 import java.util.List;
39 import java.util.Map.Entry;
40 import java.util.TreeMap;
42 import javax.servlet.ServletException;
43 import javax.servlet.http.HttpServlet;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
47 import org.openecomp.cl.api.Logger;
48 import org.openecomp.cl.eelf.LoggerFactory;
49 import org.openecomp.sparky.logging.AaiUiMsgs;
50 import org.json.JSONArray;
51 import org.json.JSONObject;
52 import org.openecomp.sparky.dal.elasticsearch.SearchAdapter;
53 import org.openecomp.sparky.dal.elasticsearch.config.ElasticSearchConfig;
54 import org.openecomp.sparky.dal.rest.OperationResult;
55 import org.openecomp.sparky.dal.rest.RestClientBuilder;
56 import org.openecomp.sparky.inventory.EntityHistoryQueryBuilder;
57 import org.openecomp.sparky.util.NodeUtils;
58 import org.openecomp.sparky.util.ServletUtils;
59 import org.openecomp.sparky.viewandinspect.config.VisualizationConfig;
62 * The Class EntityCountHistoryServlet.
64 public class EntityCountHistoryServlet extends HttpServlet {
66 private static final Logger LOG = LoggerFactory.getInstance().getLogger(EntityCountHistoryServlet.class);
68 private static final long serialVersionUID = 1L;
70 private SearchAdapter search = null;
71 private ElasticSearchConfig elasticConfig = null;
72 private VisualizationConfig visualConfig = null;
73 private ObjectMapper mapper;
75 private static final String SEARCH_STRING = "_search";
76 private static final String TABLE = "table";
77 private static final String GRAPH = "graph";
79 private List<String> vnfEntityTypesToSummarize;
80 private boolean summarizevnf = false;
83 * Instantiates a new entity count history servlet.
85 * @throws ServletException the servlet exception
87 public EntityCountHistoryServlet() throws ServletException {
92 * @see javax.servlet.GenericServlet#init()
95 public void init() throws ServletException {
98 if (elasticConfig == null) {
99 elasticConfig = ElasticSearchConfig.getConfig();
101 if (visualConfig == null) {
102 visualConfig = VisualizationConfig.getConfig();
103 vnfEntityTypesToSummarize =
104 Arrays.asList(visualConfig.getVnfEntityTypes().toLowerCase().split("[\\s,]+"));
105 summarizevnf = visualConfig.getEntityTypesToSummarize().toLowerCase().contains("vnf");
107 if (search == null) {
108 search = new SearchAdapter();
110 this.mapper = new ObjectMapper();
111 this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
112 } catch (Exception exc) {
113 new ServletException(
114 "Caught an exception while getting an instance of servlet configuration.", exc);
118 public void setSearch(SearchAdapter search) {
119 this.search = search;
122 public void setElasticConfig(ElasticSearchConfig elasticConfig) {
123 this.elasticConfig = elasticConfig;
127 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
130 protected void doGet(HttpServletRequest request, HttpServletResponse response)
131 throws ServletException, IOException {
132 String txnID = request.getHeader("X-TransactionId");
134 txnID = NodeUtils.getRandomTxnId();
137 String partnerName = request.getHeader("X-FromAppId");
138 if ( partnerName == null)
139 partnerName = "Browser";
141 MdcContext.initialize(txnID, "AAI-UI", "", partnerName,
142 request.getRemoteAddr());
144 @SuppressWarnings("unused")
145 OperationResult operationResult = null;
146 if (request.getParameter("type") != null
147 && (request.getParameter("type").equalsIgnoreCase(TABLE)
148 || request.getParameter("type").equalsIgnoreCase(GRAPH))) {
150 operationResult = getResults(response, request.getParameter("type"));
151 } catch (Exception exc) {
152 LOG.error(AaiUiMsgs.ERROR_SERVLET_PROCESSSING, exc);
155 ServletUtils.setServletResponse(LOG, true, 501, response,
156 ServletUtils.generateJsonErrorResponse("Unsupported request"));
161 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
164 protected void doPost(HttpServletRequest request, HttpServletResponse response)
165 throws ServletException {
172 * @param response the response
173 * @param type the type
174 * @return the results
175 * @throws Exception the exception
177 private OperationResult getResults(HttpServletResponse response, String type) throws Exception {
178 OperationResult operationResult = new OperationResult();
180 String requestString =
181 String.format("/%s/%s?pretty", elasticConfig.getEntityCountHistoryIndex(), SEARCH_STRING);
183 String reqPayload = EntityHistoryQueryBuilder.getQuery(type).toString();
186 final String fullUrlStr = ServletUtils.getFullUrl(elasticConfig, requestString);
187 OperationResult opResult =
188 ServletUtils.executePostQuery(LOG, search, response, fullUrlStr, reqPayload);
190 JSONObject finalOutput = null;
191 if (type.equalsIgnoreCase(TABLE)) {
192 finalOutput = formatTableOutput(opResult.getResult());
193 } else if (type.equalsIgnoreCase(GRAPH)) {
194 finalOutput = formatLineGraphOutput(opResult.getResult());
197 if (finalOutput != null) {
198 response.setContentType("application/json");
199 PrintWriter out = response.getWriter();
200 out.println(finalOutput);
204 } catch (JsonProcessingException exc) {
205 ServletUtils.handleSearchServletErrors(LOG, "Unable to map JSONpayload", exc, response);
208 return operationResult;
212 * Format table output.
214 * @param results the results
215 * @return the JSON object
216 * @throws JsonProcessingException the json processing exception
218 private JSONObject formatTableOutput(String results) throws JsonProcessingException {
219 JsonNode resultNode = null;
221 JSONObject finalResult = new JSONObject();
222 JSONArray entitiesArr = new JSONArray();
224 Map<String, Long> entityCountInTable = initializeEntityMap();
229 resultNode = mapper.readTree(results);
231 final JsonNode bucketsNode = getBucketsNode(resultNode);
232 if (bucketsNode.isArray()) {
234 for (final JsonNode entityNode : bucketsNode) {
235 String entityType = entityNode.get("key").asText();
236 boolean isAVnf = vnfEntityTypesToSummarize.contains(entityType);
239 if (isAVnf || entityCountInTable.get(entityType) != null) {
240 final JsonNode hitsBucketNode = entityNode.get("sort_by_date").get("hits").get("hits");
241 if (hitsBucketNode.isArray()) {
242 // the first bucket will be the latest
243 final JsonNode hitNode = hitsBucketNode.get(0);
245 countValue = hitNode.get("_source").get("count").asLong();
248 * Special case: Add all the VNF types together to get aggregate count
250 if (summarizevnf && isAVnf) {
251 vnfCount += countValue;
252 countValue = vnfCount;
256 entityCountInTable.replace(entityType, countValue);
262 for (Entry<String, Long> entry : entityCountInTable.entrySet()) {
263 JSONObject entityType = new JSONObject();
264 entityType.put("key", entry.getKey());
265 entityType.put("doc_count", entry.getValue());
266 entitiesArr.put(entityType);
269 finalResult.put("result", entitiesArr);
271 } catch (Exception exc) {
272 LOG.warn(AaiUiMsgs.ERROR_BUILDING_RESPONSE_FOR_TABLE_QUERY, exc.getLocalizedMessage());
280 * Format line graph output.
282 * @param results the results
283 * @return the JSON object
284 * @throws JsonProcessingException the json processing exception
286 private JSONObject formatLineGraphOutput(String results) throws JsonProcessingException {
287 Map<Long, Long> countByDateMap = new HashMap<Long, Long>();
289 JsonNode resultNode = null;
291 JSONObject finalResult = new JSONObject();
292 JSONArray finalResultArr = new JSONArray();
295 resultNode = mapper.readTree(results);
297 final JsonNode bucketsNode = getBucketsNode(resultNode);
299 if (bucketsNode.isArray()) {
301 for (final JsonNode entityNode : bucketsNode) {
302 final JsonNode dateBucketNode = entityNode.get("group_by_date").get("buckets");
303 if (dateBucketNode.isArray()) {
304 for (final JsonNode dateBucket : dateBucketNode) {
305 Long date = dateBucket.get("key").asLong();
306 final JsonNode countBucketNode =
307 dateBucket.get("sort_by_date").get("hits").get("hits");
309 if (countBucketNode.isArray()) {
310 final JsonNode latestEntityNode = countBucketNode.get(0);
312 long currentCount = latestEntityNode.get("_source").get("count").asLong();
313 if (countByDateMap.containsKey(date)) {
314 // add to the value if map already contains this date
315 currentCount += countByDateMap.get(date);
318 countByDateMap.put(date, currentCount);
326 * Sort the map by epoch timestamp
328 Map<Long, Long> sortedMap = new TreeMap<Long, Long>(countByDateMap);
329 for (Entry<Long, Long> entry : sortedMap.entrySet()) {
330 JSONObject dateEntry = new JSONObject();
331 dateEntry.put("date", entry.getKey());
332 dateEntry.put("count", entry.getValue());
333 finalResultArr.put(dateEntry);
336 } catch (Exception exc) {
337 LOG.warn(AaiUiMsgs.ERROR_BUILDING_SEARCH_RESPONSE, exc.getLocalizedMessage());
340 return finalResult.put("result", finalResultArr);
344 * Gets the buckets node.
346 * @param node the node
347 * @return the buckets node
348 * @throws Exception the exception
350 private JsonNode getBucketsNode(JsonNode node) throws Exception {
351 if (node.get("aggregations").get("group_by_entityType").get("buckets") != null) {
352 return node.get("aggregations").get("group_by_entityType").get("buckets");
354 throw new Exception("Failed to map JSON response");
359 * Initialize entity map.
363 private Map<String, Long> initializeEntityMap() {
364 Map<String, Long> entityMap = new HashMap<String, Long>();
365 String[] entityTypes = visualConfig.getEntityTypesToSummarize().split(",");
366 for (String entity : entityTypes) {
367 entityMap.put(entity, (long) 0);