From 86115147f09f2f2a0702a82c1895e13ff7f37131 Mon Sep 17 00:00:00 2001 From: "Kajur, Harish (vk250x)" Date: Sun, 7 Apr 2019 20:18:24 -0400 Subject: Optimize the areas where its creating extra memory After doing some analysis using profiler found that the most cases where memory is being spent when doing an GET is during the conversion from one case to another case and instead cached that during the start of the application Issue-ID: AAI-2331 Change-Id: I291d5f953d4158daca293198cf6fc7f5cf86d25d Signed-off-by: Kajur, Harish (vk250x) --- .../java/org/onap/aai/nodes/CaseFormatStore.java | 105 +++++++++++++++++++++ .../main/java/org/onap/aai/nodes/NodeIngestor.java | 39 +++++--- .../java/org/onap/aai/setup/SchemaVersion.java | 24 +++-- 3 files changed, 140 insertions(+), 28 deletions(-) create mode 100644 aai-schema-ingest/src/main/java/org/onap/aai/nodes/CaseFormatStore.java (limited to 'aai-schema-ingest') diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/nodes/CaseFormatStore.java b/aai-schema-ingest/src/main/java/org/onap/aai/nodes/CaseFormatStore.java new file mode 100644 index 00000000..69a153da --- /dev/null +++ b/aai-schema-ingest/src/main/java/org/onap/aai/nodes/CaseFormatStore.java @@ -0,0 +1,105 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.nodes; + +import com.google.common.base.CaseFormat; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * CaseFormatStore stores the converted strings from + * lower hyphen (example-object) to lower camel case (exampleObject) + * so it avoids the creation of the object for every single request + * and cause an issue with taking too much memory just for the conversion + */ +public class CaseFormatStore { + + private final Map lowerHyphenToLowerCamel = new HashMap<>(); + private final Map lowerHyphenToUpperCamel = new HashMap<>(); + private final Map lowerCamelToLowerHyphen = new HashMap<>(); + private final Map upperCamelToLowerHyphen = new HashMap<>(); + + CaseFormatStore(){} + + /** + * Parses the document and creates a lower camel case string + * upper camel string, lower hyphen and lower camel case + * + * @param doc Takes an xml document and adds it to the hash maps as appropriate + */ + void parse(Document doc){ + + // Get the xml-root-element and add those nodes + // with the attribute name and it to the hashmaps + // For the attribute with name, it is going to be lower-hyphen + // If the attribute is javaAttribute then it will be lower camel case + NodeList list = doc.getElementsByTagName("xml-root-element"); + addCaseFormatForNodesAndProperties(list, "name"); + + list = doc.getElementsByTagName("xml-element"); + addCaseFormatForNodesAndProperties(list, "java-attribute"); + + list = doc.getElementsByTagName("xml-any-element"); + addCaseFormatForNodesAndProperties(list, "java-attribute"); + } + + private void addCaseFormatForNodesAndProperties(NodeList list, String attributeName) { + for (int i = 0; i < list.getLength(); i++) { + + String lowerCamel = null; + String lowerHyphen = null; + + if ("java-attribute".equals(attributeName)) { + lowerCamel = list.item(i).getAttributes().getNamedItem(attributeName).getNodeValue(); + lowerHyphen = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, lowerCamel); + } else { + lowerHyphen = list.item(i).getAttributes().getNamedItem(attributeName).getNodeValue(); + lowerCamel = CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_CAMEL, lowerHyphen); + } + + String upperCamel = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, lowerHyphen); + lowerHyphenToLowerCamel.put(lowerHyphen, lowerCamel); + lowerHyphenToUpperCamel.put(lowerHyphen, upperCamel); + upperCamelToLowerHyphen.put(upperCamel, lowerHyphen); + lowerCamelToLowerHyphen.put(lowerCamel, lowerHyphen); + } + } + + public Optional fromLowerHyphenToLowerCamel(String value){ + return Optional.ofNullable(lowerHyphenToLowerCamel.get(value)); + } + + public Optional fromLowerHyphenToUpperCamel(String value){ + return Optional.ofNullable(lowerHyphenToUpperCamel.get(value)); + } + + public Optional fromUpperCamelToLowerHyphen(String value){ + return Optional.ofNullable(upperCamelToLowerHyphen.get(value)); + } + + public Optional fromLowerCamelToLowerHyphen(String value){ + return Optional.ofNullable(lowerCamelToLowerHyphen.get(value)); + } + +} diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/nodes/NodeIngestor.java b/aai-schema-ingest/src/main/java/org/onap/aai/nodes/NodeIngestor.java index 69cd51ab..82991f06 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/nodes/NodeIngestor.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/nodes/NodeIngestor.java @@ -62,14 +62,14 @@ public class NodeIngestor { private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(NodeIngestor.class); private static final Pattern classNamePattern = Pattern.compile("\\.(v\\d+)\\."); - Map> filesToIngest; - private Map versionContextMap = new TreeMap<>(); - private Map> typesPerVersion = new TreeMap<>(); - private Map schemaPerVersion = new TreeMap<>(); + private Map versionContextMap = new HashMap<>(); + private Map> typesPerVersion = new HashMap<>(); + private Map schemaPerVersion = new HashMap<>(); private String localSchema; private SchemaVersions schemaVersions; private Set translators; - + + private CaseFormatStore caseFormatStore; //TODO : See if you can get rid of InputStream resets /** * Instantiates the NodeIngestor bean. @@ -82,6 +82,7 @@ public class NodeIngestor { public NodeIngestor(Set translatorSet) { LOGGER.debug("Local Schema files will be fetched"); this.translators = translatorSet; + this.caseFormatStore = new CaseFormatStore(); } @PostConstruct @@ -128,7 +129,7 @@ public class NodeIngestor { final DynamicJAXBContext ctx = ingest(inputStreams); versionContextMap.put(version, ctx); - typesPerVersion.put(version, getAllNodeTypes(inputStreams)); + setAllTypesAndProperties(version, inputStreams); schemaPerVersion.put(version, createCombinedSchema(inputStreams, version, retrieveLocalSchema)); } } catch (JAXBException | ParserConfigurationException | SAXException | IOException e) { @@ -152,8 +153,7 @@ public class NodeIngestor { return DynamicJAXBContextFactory.createContextFromOXM(this.getClass().getClassLoader(), properties); } - private Set getAllNodeTypes(List inputStreams) throws ParserConfigurationException, SAXException, IOException { - //Reset the InputStream to reset the offset to inital position + private void setAllTypesAndProperties(SchemaVersion version, List inputStreams) throws ParserConfigurationException, IOException, SAXException { Set types = new HashSet<>(); final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); docFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); @@ -164,15 +164,20 @@ public class NodeIngestor { inputStream.reset(); final Document doc = docBuilder.parse(inputStream); final NodeList list = doc.getElementsByTagName("java-type"); - - for (int i = 0; i < list.getLength(); i++) { - String type = list.item(i).getAttributes().getNamedItem("name").getNodeValue(); - types.add(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, type)); - } + getAllNodeTypes(list, types); + caseFormatStore.parse(doc); } - LOGGER.debug("Types size" + types.size()); - return types; + LOGGER.debug("Types size {}", types.size()); + typesPerVersion.put(version, types); + } + + private void getAllNodeTypes(NodeList list, Set types){ + + for (int i = 0; i < list.getLength(); i++) { + String type = list.item(i).getAttributes().getNamedItem("name").getNodeValue(); + types.add(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, type)); + } } private Document createCombinedSchema(List inputStreams, SchemaVersion version, boolean localSchema) throws ParserConfigurationException, SAXException, IOException { @@ -274,4 +279,8 @@ public class NodeIngestor { ""; return new ByteArrayInputStream(source.getBytes(StandardCharsets.UTF_8)); } + + public CaseFormatStore getCaseFormatStore(){ + return caseFormatStore; + } } diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/setup/SchemaVersion.java b/aai-schema-ingest/src/main/java/org/onap/aai/setup/SchemaVersion.java index a1a40e69..8143b5e1 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/setup/SchemaVersion.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/setup/SchemaVersion.java @@ -21,20 +21,23 @@ package org.onap.aai.setup; import org.onap.aai.validation.AAISchemaValidationException; +import java.util.regex.Matcher; import java.util.regex.Pattern; public class SchemaVersion implements Comparable { - public static final Pattern VERSION_PATTERN = Pattern.compile("v[1-9][0-9]*"); + public static final Pattern VERSION_PATTERN = Pattern.compile("v([1-9][0-9]*)"); - private final String value; + private final Integer value; public SchemaVersion(String value){ - if(!VERSION_PATTERN.matcher(value).matches()){ + Matcher matcher = VERSION_PATTERN.matcher(value); + + if(!matcher.find()){ throw new AAISchemaValidationException("Invalid Schema Version " + value + ", value doesn't match the expected regex: " + VERSION_PATTERN); + } else { + this.value = Integer.parseInt(matcher.group(1)); } - - this.value = value; } @Override @@ -44,6 +47,7 @@ public class SchemaVersion implements Comparable { @Override public boolean equals(Object other){ + if(this == other){ return true; } @@ -62,7 +66,7 @@ public class SchemaVersion implements Comparable { @Override public String toString(){ - return value; + return String.valueOf("v" + value); } @Override @@ -72,12 +76,6 @@ public class SchemaVersion implements Comparable { return -1; } - // Requires to convert to integer to match the past behavior - // Otherwise the string comparison of versions aren't working as expected - - Integer tVal = Integer.parseInt(this.value.replaceAll("v", "")); - Integer oVal = Integer.parseInt(o.value.replaceAll("v", "")); - - return tVal.compareTo(oVal); + return this.value.compareTo(o.value); } } -- cgit 1.2.3-korg