2 * ============LICENSE_START===================================================
3 * SPARKY (AAI UI service)
4 * ============================================================================
5 * Copyright © 2017 AT&T Intellectual Property.
6 * Copyright © 2017 Amdocs
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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=====================================================
22 * ECOMP and OpenECOMP are trademarks
23 * and service marks of AT&T Intellectual Property.
26 package org.openecomp.sparky.inventory.servlet;
28 import org.openecomp.cl.mdc.MdcContext;
29 import com.fasterxml.jackson.core.JsonProcessingException;
30 import com.fasterxml.jackson.databind.JsonNode;
31 import com.fasterxml.jackson.databind.ObjectMapper;
32 import com.fasterxml.jackson.databind.SerializationFeature;
34 import java.io.IOException;
35 import java.io.PrintWriter;
36 import java.nio.ByteBuffer;
37 import java.security.SecureRandom;
38 import java.util.Arrays;
39 import java.util.HashMap;
40 import java.util.List;
42 import java.util.Map.Entry;
43 import java.util.TreeMap;
45 import javax.servlet.ServletException;
46 import javax.servlet.http.HttpServlet;
47 import javax.servlet.http.HttpServletRequest;
48 import javax.servlet.http.HttpServletResponse;
50 import org.openecomp.cl.api.Logger;
51 import org.openecomp.cl.eelf.LoggerFactory;
52 import org.openecomp.sparky.logging.AaiUiMsgs;
53 import org.json.JSONArray;
54 import org.json.JSONObject;
55 import org.openecomp.sparky.dal.elasticsearch.SearchAdapter;
56 import org.openecomp.sparky.dal.elasticsearch.config.ElasticSearchConfig;
57 import org.openecomp.sparky.dal.rest.OperationResult;
58 import org.openecomp.sparky.dal.rest.RestClientBuilder;
59 import org.openecomp.sparky.inventory.EntityHistoryQueryBuilder;
60 import org.openecomp.sparky.util.NodeUtils;
61 import org.openecomp.sparky.util.ServletUtils;
62 import org.openecomp.sparky.viewandinspect.config.VisualizationConfig;
65 * The Class EntityCountHistoryServlet.
67 public class EntityCountHistoryServlet extends HttpServlet {
69 private static final Logger LOG = LoggerFactory.getInstance().getLogger(EntityCountHistoryServlet.class);
71 private static final long serialVersionUID = 1L;
73 private SearchAdapter search = null;
74 private ElasticSearchConfig elasticConfig = null;
75 private VisualizationConfig visualConfig = null;
76 private ObjectMapper mapper;
78 private static final String SEARCH_STRING = "_search";
79 private static final String TABLE = "table";
80 private static final String GRAPH = "graph";
82 private List<String> vnfEntityTypesToSummarize;
83 private boolean summarizevnf = false;
86 * Instantiates a new entity count history servlet.
88 * @throws ServletException the servlet exception
90 public EntityCountHistoryServlet() throws ServletException {
95 * @see javax.servlet.GenericServlet#init()
98 public void init() throws ServletException {
101 if (elasticConfig == null) {
102 elasticConfig = ElasticSearchConfig.getConfig();
104 if (visualConfig == null) {
105 visualConfig = VisualizationConfig.getConfig();
106 vnfEntityTypesToSummarize =
107 Arrays.asList(visualConfig.getVnfEntityTypes().toLowerCase().split("[\\s,]+"));
108 summarizevnf = visualConfig.getEntityTypesToSummarize().toLowerCase().contains("vnf");
110 if (search == null) {
111 search = new SearchAdapter();
113 this.mapper = new ObjectMapper();
114 this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
115 } catch (Exception exc) {
116 new ServletException(
117 "Caught an exception while getting an instance of servlet configuration.", exc);
121 public void setSearch(SearchAdapter search) {
122 this.search = search;
125 public void setElasticConfig(ElasticSearchConfig elasticConfig) {
126 this.elasticConfig = elasticConfig;
130 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
133 protected void doGet(HttpServletRequest request, HttpServletResponse response)
134 throws ServletException, IOException {
135 String txnID = request.getHeader("X-TransactionId");
137 txnID = NodeUtils.getRandomTxnId();
140 String partnerName = request.getHeader("X-FromAppId");
141 if ( partnerName == null)
142 partnerName = "Browser";
144 MdcContext.initialize(txnID, "AAI-UI", "", partnerName,
145 request.getRemoteAddr());
147 @SuppressWarnings("unused")
148 OperationResult operationResult = null;
149 if (request.getParameter("type") != null
150 && (request.getParameter("type").equalsIgnoreCase(TABLE)
151 || request.getParameter("type").equalsIgnoreCase(GRAPH))) {
153 operationResult = getResults(response, request.getParameter("type"));
154 } catch (Exception exc) {
155 LOG.error(AaiUiMsgs.ERROR_SERVLET_PROCESSSING, exc);
158 ServletUtils.setServletResponse(LOG, true, 501, response,
159 ServletUtils.generateJsonErrorResponse("Unsupported request"));
164 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
167 protected void doPost(HttpServletRequest request, HttpServletResponse response)
168 throws ServletException {
175 * @param response the response
176 * @param type the type
177 * @return the results
178 * @throws Exception the exception
180 private OperationResult getResults(HttpServletResponse response, String type) throws Exception {
181 OperationResult operationResult = new OperationResult();
183 String requestString =
184 String.format("/%s/%s?pretty", elasticConfig.getEntityCountHistoryIndex(), SEARCH_STRING);
186 String reqPayload = EntityHistoryQueryBuilder.getQuery(type).toString();
189 final String fullUrlStr = ServletUtils.getFullUrl(elasticConfig, requestString);
190 OperationResult opResult =
191 ServletUtils.executePostQuery(LOG, search, response, fullUrlStr, reqPayload);
193 JSONObject finalOutput = null;
194 if (type.equalsIgnoreCase(TABLE)) {
195 finalOutput = formatTableOutput(opResult.getResult());
196 } else if (type.equalsIgnoreCase(GRAPH)) {
197 finalOutput = formatLineGraphOutput(opResult.getResult());
200 if (finalOutput != null) {
201 response.setContentType("application/json");
202 PrintWriter out = response.getWriter();
203 out.println(finalOutput);
207 } catch (JsonProcessingException exc) {
208 ServletUtils.handleSearchServletErrors(LOG, "Unable to map JSONpayload", exc, response);
211 return operationResult;
215 * Format table output.
217 * @param results the results
218 * @return the JSON object
219 * @throws JsonProcessingException the json processing exception
221 private JSONObject formatTableOutput(String results) throws JsonProcessingException {
222 JsonNode resultNode = null;
224 JSONObject finalResult = new JSONObject();
225 JSONArray entitiesArr = new JSONArray();
227 Map<String, Long> entityCountInTable = initializeEntityMap();
232 resultNode = mapper.readTree(results);
234 final JsonNode bucketsNode = getBucketsNode(resultNode);
235 if (bucketsNode.isArray()) {
237 for (final JsonNode entityNode : bucketsNode) {
238 String entityType = entityNode.get("key").asText();
239 boolean isAVnf = vnfEntityTypesToSummarize.contains(entityType);
242 if (isAVnf || entityCountInTable.get(entityType) != null) {
243 final JsonNode hitsBucketNode = entityNode.get("sort_by_date").get("hits").get("hits");
244 if (hitsBucketNode.isArray()) {
245 // the first bucket will be the latest
246 final JsonNode hitNode = hitsBucketNode.get(0);
248 countValue = hitNode.get("_source").get("count").asLong();
251 * Special case: Add all the VNF types together to get aggregate count
253 if (summarizevnf && isAVnf) {
254 vnfCount += countValue;
255 countValue = vnfCount;
259 entityCountInTable.replace(entityType, countValue);
265 for (Entry<String, Long> entry : entityCountInTable.entrySet()) {
266 JSONObject entityType = new JSONObject();
267 entityType.put("key", entry.getKey());
268 entityType.put("doc_count", entry.getValue());
269 entitiesArr.put(entityType);
272 finalResult.put("result", entitiesArr);
274 } catch (Exception exc) {
275 LOG.warn(AaiUiMsgs.ERROR_BUILDING_RESPONSE_FOR_TABLE_QUERY, exc.getLocalizedMessage());
283 * Format line graph output.
285 * @param results the results
286 * @return the JSON object
287 * @throws JsonProcessingException the json processing exception
289 private JSONObject formatLineGraphOutput(String results) throws JsonProcessingException {
290 Map<Long, Long> countByDateMap = new HashMap<Long, Long>();
292 JsonNode resultNode = null;
294 JSONObject finalResult = new JSONObject();
295 JSONArray finalResultArr = new JSONArray();
298 resultNode = mapper.readTree(results);
300 final JsonNode bucketsNode = getBucketsNode(resultNode);
302 if (bucketsNode.isArray()) {
304 for (final JsonNode entityNode : bucketsNode) {
305 final JsonNode dateBucketNode = entityNode.get("group_by_date").get("buckets");
306 if (dateBucketNode.isArray()) {
307 for (final JsonNode dateBucket : dateBucketNode) {
308 Long date = dateBucket.get("key").asLong();
309 final JsonNode countBucketNode =
310 dateBucket.get("sort_by_date").get("hits").get("hits");
312 if (countBucketNode.isArray()) {
313 final JsonNode latestEntityNode = countBucketNode.get(0);
315 long currentCount = latestEntityNode.get("_source").get("count").asLong();
316 if (countByDateMap.containsKey(date)) {
317 // add to the value if map already contains this date
318 currentCount += countByDateMap.get(date);
321 countByDateMap.put(date, currentCount);
329 * Sort the map by epoch timestamp
331 Map<Long, Long> sortedMap = new TreeMap<Long, Long>(countByDateMap);
332 for (Entry<Long, Long> entry : sortedMap.entrySet()) {
333 JSONObject dateEntry = new JSONObject();
334 dateEntry.put("date", entry.getKey());
335 dateEntry.put("count", entry.getValue());
336 finalResultArr.put(dateEntry);
339 } catch (Exception exc) {
340 LOG.warn(AaiUiMsgs.ERROR_BUILDING_SEARCH_RESPONSE, exc.getLocalizedMessage());
343 return finalResult.put("result", finalResultArr);
347 * Gets the buckets node.
349 * @param node the node
350 * @return the buckets node
351 * @throws Exception the exception
353 private JsonNode getBucketsNode(JsonNode node) throws Exception {
354 if (node.get("aggregations").get("group_by_entityType").get("buckets") != null) {
355 return node.get("aggregations").get("group_by_entityType").get("buckets");
357 throw new Exception("Failed to map JSON response");
362 * Initialize entity map.
366 private Map<String, Long> initializeEntityMap() {
367 Map<String, Long> entityMap = new HashMap<String, Long>();
368 String[] entityTypes = visualConfig.getEntityTypesToSummarize().split(",");
369 for (String entity : entityTypes) {
370 entityMap.put(entity, (long) 0);