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.onap.aai.sparky.util;
25 import java.io.BufferedReader;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.lang.Thread.UncaughtExceptionHandler;
30 import java.nio.ByteBuffer;
31 import java.security.SecureRandom;
32 import java.text.ParseException;
33 import java.text.SimpleDateFormat;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.Date;
39 import java.util.Iterator;
40 import java.util.List;
42 import java.util.TimeZone;
43 import java.util.concurrent.ExecutorService;
44 import java.util.concurrent.Executors;
45 import java.util.concurrent.ThreadFactory;
46 import java.util.concurrent.TimeUnit;
47 import java.util.regex.Matcher;
48 import java.util.regex.Pattern;
50 import javax.servlet.http.HttpServletRequest;
51 import javax.xml.stream.XMLStreamConstants;
53 import org.onap.aai.sparky.logging.AaiUiMsgs;
54 import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants;
55 import org.onap.aai.cl.api.Logger;
57 import com.fasterxml.jackson.core.JsonProcessingException;
58 import com.fasterxml.jackson.databind.JsonNode;
59 import com.fasterxml.jackson.databind.ObjectMapper;
60 import com.fasterxml.jackson.databind.ObjectWriter;
61 import com.fasterxml.jackson.databind.SerializationFeature;
62 import com.google.common.util.concurrent.ThreadFactoryBuilder;
66 * The Class NodeUtils.
68 public class NodeUtils {
69 private static SecureRandom sRandom = new SecureRandom();
74 public static SecureRandom getsRandom() {
79 * @param sRandom the sRandom to set
81 public static void setsRandom(SecureRandom sRandom) {
82 NodeUtils.sRandom = sRandom;
86 * @return the entityResourceKeyFormat
88 public static String getEntityResourceKeyFormat() {
89 return ENTITY_RESOURCE_KEY_FORMAT;
93 * @return the timeBreakDownFormat
95 public static String getTimeBreakDownFormat() {
96 return TIME_BREAK_DOWN_FORMAT;
99 public static synchronized String getRandomTxnId(){
100 byte bytes[] = new byte[6];
101 sRandom.nextBytes(bytes);
102 return Integer.toUnsignedString(ByteBuffer.wrap(bytes).getInt());
106 * Builds the depth padding.
108 * @param depth the depth
111 public static String buildDepthPadding(int depth) {
112 StringBuilder sb = new StringBuilder(32);
114 for (int x = 0; x < depth; x++) {
118 return sb.toString();
122 * Checks if is numeric.
124 * @param numberStr the number str
125 * @return true, if is numeric
127 public static boolean isNumeric(String numberStr) {
130 Double.parseDouble(numberStr);
131 } catch (Exception exc) {
140 * Creates the named executor.
142 * @param name the name
143 * @param numWorkers the num workers
144 * @param logger the logger
145 * @return the executor service
147 public static ExecutorService createNamedExecutor(String name, int numWorkers, final Logger logger) {
148 UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
151 public void uncaughtException(Thread thread, Throwable exc) {
153 logger.error(AaiUiMsgs.ERROR_GENERIC, thread.getName() + ": " + exc);
158 ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat(name + "-%d")
159 .setUncaughtExceptionHandler(uncaughtExceptionHandler).build();
161 return Executors.newScheduledThreadPool(numWorkers + 1, namedThreadFactory);
165 * Calculate edit attribute uri.
167 * @param link the link
170 public static String calculateEditAttributeUri(String link) {
175 Pattern pattern = Pattern.compile(TierSupportUiConstants.URI_VERSION_REGEX_PATTERN);
176 Matcher matcher = pattern.matcher(link);
177 if (matcher.find()) {
178 uri = link.substring(matcher.end());
185 * Generate unique sha digest.
187 * @param keys the keys
190 public static String generateUniqueShaDigest(String... keys) {
192 if ((keys == null) || keys.length == 0) {
196 final String keysStr = Arrays.asList(keys).toString();
197 final String hashedId = org.apache.commons.codec.digest.DigestUtils.sha256Hex(keysStr);
203 * Gets the node field as text.
205 * @param node the node
206 * @param fieldName the field name
207 * @return the node field as text
209 public static String getNodeFieldAsText(JsonNode node, String fieldName) {
211 String fieldValue = null;
213 JsonNode valueNode = node.get(fieldName);
215 if (valueNode != null) {
216 fieldValue = valueNode.asText();
222 private static final String ENTITY_RESOURCE_KEY_FORMAT = "%s.%s";
225 * Convert a millisecond duration to a string format
227 * @param millis A duration to convert to a string form
228 * @return A string of the form "X Days Y Hours Z Minutes A Seconds".
231 private static final String TIME_BREAK_DOWN_FORMAT =
232 "[ %d days, %d hours, %d minutes, %d seconds ]";
235 * Gets the duration breakdown.
237 * @param millis the millis
238 * @return the duration breakdown
240 public static String getDurationBreakdown(long millis) {
243 return String.format(TIME_BREAK_DOWN_FORMAT, 0, 0, 0, 0);
246 long days = TimeUnit.MILLISECONDS.toDays(millis);
247 millis -= TimeUnit.DAYS.toMillis(days);
248 long hours = TimeUnit.MILLISECONDS.toHours(millis);
249 millis -= TimeUnit.HOURS.toMillis(hours);
250 long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
251 millis -= TimeUnit.MINUTES.toMillis(minutes);
252 long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
254 return String.format(TIME_BREAK_DOWN_FORMAT, days, hours, minutes, seconds);
259 * Checks if is equal.
263 * @return true, if is equal
265 public static boolean isEqual(JsonNode n1, JsonNode n2) {
268 * due to the inherent nature of json being unordered, comparing object representations of the
269 * same keys and values but different order makes comparison challenging. Let's try an
270 * experiment where we compare the structure of the json, and then simply compare the sorted
271 * order of that structure which should be good enough for what we are trying to accomplish.
274 TreeWalker walker = new TreeWalker();
275 List<String> n1Paths = new ArrayList<String>();
276 List<String> n2Paths = new ArrayList<String>();
278 walker.walkTree(n1Paths, n1);
279 walker.walkTree(n2Paths, n2);
281 Collections.sort(n1Paths);
282 Collections.sort(n2Paths);
284 return n1Paths.equals(n2Paths);
291 * @param list the list
294 public static String concatArray(List<String> list) {
295 return concatArray(list, " ");
301 * @param list the list
302 * @param delimiter the delimiter
305 public static String concatArray(List<String> list, String delimiter) {
307 if (list == null || list.size() == 0) {
311 StringBuilder result = new StringBuilder(64);
313 boolean firstValue = true;
315 for (String item : list) {
321 result.append(delimiter).append(item);
326 return result.toString();
333 * @param values the values
336 public static String concatArray(String[] values) {
338 if (values == null || values.length == 0) {
342 StringBuilder result = new StringBuilder(64);
344 boolean firstValue = true;
346 for (String item : values) {
352 result.append(".").append(item);
357 return result.toString();
362 * Builds the entity resource key.
364 * @param entityType the entity type
365 * @param resourceId the resource id
368 public static String buildEntityResourceKey(String entityType, String resourceId) {
369 return String.format(ENTITY_RESOURCE_KEY_FORMAT, entityType, resourceId);
373 * Extract resource id from link.
375 * @param link the link
378 public static String extractResourceIdFromLink(String link) {
384 int linkLength = link.length();
385 if (linkLength == 0) {
390 * if the last character != / then we need to change the lastIndex position
394 String resourceId = null;
395 if ("/".equals(link.substring(linkLength - 1))) {
397 // https://<AAI-hostname>:9292/aai/v7/business/customers/customer/1607_20160524Func_Ak1_01/service-subscriptions/service-subscription/uCPE-VMS/
398 startIndex = link.lastIndexOf("/", linkLength - 2);
399 resourceId = link.substring(startIndex + 1, linkLength - 1);
402 // https://<AAI-Hostname>:9292/aai/v7/business/customers/customer/1607_20160524Func_Ak1_01/service-subscriptions/service-subscription/uCPE-VMS
403 startIndex = link.lastIndexOf("/");
404 resourceId = link.substring(startIndex + 1, linkLength);
407 String result = null;
409 if (resourceId != null) {
411 result = java.net.URLDecoder.decode(resourceId, "UTF-8");
412 } catch (Exception exc) {
414 * if there is a failure decoding the parameter we will just return the original value.
425 * Gets the xml stream constant as str.
427 * @param value the value
428 * @return the xml stream constant as str
430 public static String getXmlStreamConstantAsStr(int value) {
432 case XMLStreamConstants.ATTRIBUTE:
434 case XMLStreamConstants.CDATA:
436 case XMLStreamConstants.CHARACTERS:
438 case XMLStreamConstants.COMMENT:
440 case XMLStreamConstants.DTD:
442 case XMLStreamConstants.END_DOCUMENT:
443 return "END_DOCUMENT";
444 case XMLStreamConstants.END_ELEMENT:
445 return "END_ELEMENT";
446 case XMLStreamConstants.ENTITY_DECLARATION:
447 return "ENTITY_DECLARATION";
448 case XMLStreamConstants.ENTITY_REFERENCE:
449 return "ENTITY_REFERENCE";
450 case XMLStreamConstants.NAMESPACE:
452 case XMLStreamConstants.NOTATION_DECLARATION:
453 return "NOTATION_DECLARATION";
454 case XMLStreamConstants.PROCESSING_INSTRUCTION:
455 return "PROCESSING_INSTRUCTION";
456 case XMLStreamConstants.SPACE:
458 case XMLStreamConstants.START_DOCUMENT:
459 return "START_DOCUMENT";
460 case XMLStreamConstants.START_ELEMENT:
461 return "START_ELEMENT";
464 return "Unknown(" + value + ")";
469 * Convert object to json.
471 * @param object the object
472 * @param pretty the pretty
474 * @throws JsonProcessingException the json processing exception
476 public static String convertObjectToJson(Object object, boolean pretty)
477 throws JsonProcessingException {
478 ObjectWriter ow = null;
480 ObjectMapper mapper = new ObjectMapper();
481 mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
484 ow = mapper.writer().withDefaultPrettyPrinter();
487 ow = mapper.writer();
490 return ow.writeValueAsString(object);
494 * Convert json str to json node.
496 * @param jsonStr the json str
497 * @return the json node
498 * @throws IOException Signals that an I/O exception has occurred.
500 public static JsonNode convertJsonStrToJsonNode(String jsonStr) throws IOException {
501 ObjectMapper mapper = new ObjectMapper();
502 if (jsonStr == null || jsonStr.length() == 0) {
506 return mapper.readTree(jsonStr);
510 * Convert object to xml.
512 * @param object the object
514 * @throws JsonProcessingException the json processing exception
516 public static String convertObjectToXml(Object object) throws JsonProcessingException {
517 ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
518 String jsonOutput = ow.writeValueAsString(object);
520 if (jsonOutput == null) {
524 return JsonXmlConverter.convertJsontoXml(jsonOutput);
529 * Extract objects by key.
531 * @param node the node
532 * @param searchKey the search key
533 * @param foundObjects the found objects
535 public static void extractObjectsByKey(JsonNode node, String searchKey,
536 Collection<JsonNode> foundObjects) {
538 if ( node == null ) {
542 if (node.isObject()) {
543 Iterator<Map.Entry<String, JsonNode>> nodeIterator = node.fields();
545 while (nodeIterator.hasNext()) {
546 Map.Entry<String, JsonNode> entry = nodeIterator.next();
547 if (!entry.getValue().isValueNode()) {
548 extractObjectsByKey(entry.getValue(), searchKey, foundObjects);
551 String name = entry.getKey();
552 if (name.equalsIgnoreCase(searchKey)) {
554 JsonNode entryNode = entry.getValue();
556 if (entryNode.isArray()) {
558 Iterator<JsonNode> arrayItemsIterator = entryNode.elements();
559 while (arrayItemsIterator.hasNext()) {
560 foundObjects.add(arrayItemsIterator.next());
564 foundObjects.add(entry.getValue());
570 } else if (node.isArray()) {
571 Iterator<JsonNode> arrayItemsIterator = node.elements();
572 while (arrayItemsIterator.hasNext()) {
573 extractObjectsByKey(arrayItemsIterator.next(), searchKey, foundObjects);
581 * Convert array into list.
583 * @param node the node
584 * @param instances the instances
586 public static void convertArrayIntoList(JsonNode node, Collection<JsonNode> instances) {
588 if (node.isArray()) {
589 Iterator<JsonNode> arrayItemsIterator = node.elements();
590 while (arrayItemsIterator.hasNext()) {
591 instances.add(arrayItemsIterator.next());
601 * Extract field values from object.
603 * @param node the node
604 * @param attributesToExtract the attributes to extract
605 * @param fieldValues the field values
607 public static void extractFieldValuesFromObject(JsonNode node,
608 Collection<String> attributesToExtract, Collection<String> fieldValues) {
614 if (node.isObject()) {
616 JsonNode valueNode = null;
618 for (String attrToExtract : attributesToExtract) {
620 valueNode = node.get(attrToExtract);
622 if (valueNode != null) {
624 if (valueNode.isValueNode()) {
625 fieldValues.add(valueNode.asText());
633 * Extract field value from object.
635 * @param node the node
636 * @param fieldName the field name
639 public static String extractFieldValueFromObject(JsonNode node, String fieldName) {
645 if (node.isObject()) {
647 JsonNode valueNode = node.get(fieldName);
649 if (valueNode != null) {
651 if (valueNode.isValueNode()) {
652 return valueNode.asText();
664 * @param timestamp the timestamp
667 public static String formatTimestamp(String timestamp) {
669 SimpleDateFormat originalFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
670 originalFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
671 Date toDate = originalFormat.parse(timestamp);
672 SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
673 newFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
674 return newFormat.format(toDate);
676 } catch (ParseException pe) {
682 * Gets the HttpRequest payload.
684 * @param request the request
686 * @throws IOException Signals that an I/O exception has occurred.
688 public static String getBody(HttpServletRequest request) throws IOException {
691 StringBuilder stringBuilder = new StringBuilder();
692 BufferedReader bufferedReader = null;
695 InputStream inputStream = request.getInputStream();
696 if (inputStream != null) {
697 bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
698 char[] charBuffer = new char[128];
700 while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
701 stringBuilder.append(charBuffer, 0, bytesRead);
704 stringBuilder.append("");
706 } catch (IOException ex) {
709 if (bufferedReader != null) {
711 bufferedReader.close();
712 } catch (IOException ex) {
718 body = stringBuilder.toString();