diff options
25 files changed, 466 insertions, 376 deletions
@@ -4,11 +4,11 @@ project_creation_date: '2017-05-03' project_category: '' lifecycle_state: 'Incubation' project_lead: &onap_aai_ptl - name: 'James Forsyth' - email: 'jf2512@att.com' - id: 'jimmydot' + name: 'William Reehil' + email: 'william.reehil@att.com' company: 'ATT' - timezone: 'America/Detroit' + id: 'wreehil' + timezone: 'America/New_York' primary_contact: *onap_aai_ptl issue_tracking: type: 'jira' @@ -46,6 +46,11 @@ committers: company: 'ATT' id: 'vk250x' timezone: 'America/New_York' + - name: 'James Forsyth' + email: 'jf2512@att.com' + id: 'jimmydot' + company: 'ATT' + timezone: 'America/Detroit' tsc: approval: 'https://lists.onap.org/g/onap-tsc' changes: @@ -55,3 +60,6 @@ tsc: - type: 'removal' name: 'Tian Lee' link: 'https://lists.onap.org/g/onap-tsc/message/6227' + - type: 'Addition' + name: 'William Reehil' + link: 'https://lists.onap.org/g/onap-tsc/message/6506' diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java index e6b6fbaf..af81c2d2 100644 --- a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java +++ b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -23,7 +23,6 @@ package org.onap.aai.dbgen; import com.google.common.collect.Multimap; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.janusgraph.core.Cardinality; -import org.janusgraph.core.JanusGraph; import org.janusgraph.core.Multiplicity; import org.janusgraph.core.PropertyKey; import org.janusgraph.core.schema.JanusGraphManagement; @@ -32,7 +31,6 @@ import org.onap.aai.edges.EdgeIngestor; import org.onap.aai.edges.EdgeRule; import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException; import org.onap.aai.introspection.Introspector; -import org.onap.aai.introspection.Loader; import org.onap.aai.introspection.LoaderUtil; import org.onap.aai.logging.LogFormatTools; import org.onap.aai.schema.enums.PropertyMetadata; @@ -40,14 +38,19 @@ import org.onap.aai.util.AAIConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; public class SchemaGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(SchemaGenerator.class); private SchemaGenerator() { - } /** @@ -56,13 +59,12 @@ public class SchemaGenerator { * @param graphMgmt * the graph mgmt */ - public static void loadSchemaIntoJanusGraph(final JanusGraphManagement graphMgmt, - String backend) { + public static void loadSchemaIntoJanusGraph(final JanusGraphManagement graphMgmt, String backend) { try { AAIConfig.init(); } catch (Exception ex) { - LOGGER.error(" ERROR - Could not run AAIConfig.init(). " + LogFormatTools.getStackTop(ex)); + LOGGER.error(" ERROR - Could not run AAIConfig.init(). {}", LogFormatTools.getStackTop(ex)); System.exit(1); } @@ -79,35 +81,10 @@ public class SchemaGenerator { // multiplicty definitions depends on which two types of nodes are being // connected. - Multimap<String, EdgeRule> edges = null; - Set<String> labels = new HashSet<>(); - - EdgeIngestor edgeIngestor = SpringContextAware.getBean(EdgeIngestor.class); - - try { - edges = edgeIngestor.getAllCurrentRules(); - } catch (EdgeRuleNotFoundException e) { - LOGGER.error("Unable to find all rules {}", LogFormatTools.getStackTop(e)); - } - - for (EdgeRule rule : edges.values()) { - labels.add(rule.getLabel()); - } + makeEdgeLabels(graphMgmt); - for (String label : labels) { - if (graphMgmt.containsRelationType(label)) { - String dmsg = " EdgeLabel [" + label + "] already existed. "; - LOGGER.debug(dmsg); - } else { - String dmsg = "Making EdgeLabel: [" + label + "]"; - LOGGER.debug(dmsg); - graphMgmt.makeEdgeLabel(label).multiplicity(Multiplicity.valueOf("MULTI")).make(); - } - } - Loader loader = LoaderUtil.getLatestVersion(); - - Map<String, Introspector> objs = loader.getAllObjects(); + Map<String, Introspector> objs = LoaderUtil.getLatestVersion().getAllObjects(); Map<String, PropertyKey> seenProps = new HashMap<>(); for (Introspector obj : objs.values()) { @@ -118,8 +95,7 @@ public class SchemaGenerator { dbPropName = alias.get(); } if (graphMgmt.containsRelationType(dbPropName)) { - String dmsg = " PropertyKey [" + dbPropName + "] already existed in the DB. "; - LOGGER.debug(dmsg); + LOGGER.debug(" PropertyKey [{}] already existed in the DB. ", dbPropName); } else { Class<?> type = obj.getClass(propName); Cardinality cardinality = Cardinality.SINGLE; @@ -134,9 +110,8 @@ public class SchemaGenerator { if (process) { - String imsg = "Creating PropertyKey: [" + dbPropName + "], [" + type.getSimpleName() + "], [" - + cardinality + "]"; - LOGGER.info(imsg); + LOGGER.info("Creating PropertyKey: [{}], [{}], [{}]", + dbPropName, type.getSimpleName(), cardinality); PropertyKey propK; if (!seenProps.containsKey(dbPropName)) { propK = graphMgmt.makePropertyKey(dbPropName).dataType(type).cardinality(cardinality) @@ -146,23 +121,19 @@ public class SchemaGenerator { propK = seenProps.get(dbPropName); } if (graphMgmt.containsGraphIndex(dbPropName)) { - String dmsg = " Index [" + dbPropName + "] already existed in the DB. "; - LOGGER.debug(dmsg); + LOGGER.debug(" Index [{}] already existed in the DB. ", dbPropName); } else { if (obj.getIndexedProperties().contains(propName)) { if (obj.getUniqueProperties().contains(propName)) { - imsg = "Add Unique index for PropertyKey: [" + dbPropName + "]"; - LOGGER.info(imsg); + LOGGER.info("Add Unique index for PropertyKey: [{}]", dbPropName); graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).unique() .buildCompositeIndex(); } else { - imsg = "Add index for PropertyKey: [" + dbPropName + "]"; - LOGGER.info(imsg); + LOGGER.info("Add index for PropertyKey: [{}]", dbPropName); graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).buildCompositeIndex(); } } else { - imsg = "No index added for PropertyKey: [" + dbPropName + "]"; - LOGGER.info(imsg); + LOGGER.info("No index added for PropertyKey: [{}]", dbPropName); } } } @@ -170,13 +141,46 @@ public class SchemaGenerator { } } - String imsg = "-- About to call graphMgmt commit"; - LOGGER.info(imsg); + LOGGER.info("-- About to call graphMgmt commit"); if (backend != null) { - LOGGER.info(String.format("Successfully loaded the schema to %s", backend)); + LOGGER.info("Successfully loaded the schema to {}", backend); } graphMgmt.commit(); } + private static void makeEdgeLabels(JanusGraphManagement graphMgmt) { + try { + EdgeIngestor edgeIngestor = SpringContextAware.getBean(EdgeIngestor.class); + + Set<String> labels = Optional.ofNullable(edgeIngestor.getAllCurrentRules()) + .map(collectValues(EdgeRule::getLabel)) + .orElseGet(HashSet::new); + + labels.forEach(label -> { + if (graphMgmt.containsRelationType(label)) { + LOGGER.debug(" EdgeLabel [{}] already existed. ", label); + } else { + LOGGER.debug("Making EdgeLabel: [{}]", label); + graphMgmt.makeEdgeLabel(label).multiplicity(Multiplicity.valueOf("MULTI")).make(); + } + }); + } catch (EdgeRuleNotFoundException e) { + LOGGER.error("Unable to find all rules {}", LogFormatTools.getStackTop(e)); + } + } + + /** + * Returns a function collecting all the values in a {@link com.google.common.collect.Multimap} + * given a mapping function + * + * @param f The mapper function + * @param <K> The type of key used by the provided {@link com.google.common.collect.Multimap} + * @param <V> The type of value used by the provided {@link com.google.common.collect.Multimap} + * @param <V0> The type which <V> is mapped to + */ + private static <K, V, V0> Function<Multimap<K, V>, Set<V0>> collectValues(Function<V, V0> f) { + return as -> as.values().stream().map(f).collect(Collectors.toSet()); + } + } diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java index 0f88de24..a35625f6 100644 --- a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java +++ b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java @@ -20,12 +20,9 @@ package org.onap.aai.dbgen; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.collect.Multimap; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.janusgraph.core.Cardinality; -import org.janusgraph.core.JanusGraph; import org.janusgraph.core.Multiplicity; import org.janusgraph.core.PropertyKey; import org.janusgraph.core.schema.JanusGraphManagement; @@ -39,8 +36,14 @@ import org.onap.aai.introspection.LoaderUtil; import org.onap.aai.logging.LogFormatTools; import org.onap.aai.schema.enums.PropertyMetadata; import org.onap.aai.util.AAIConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import static org.onap.aai.db.props.AAIProperties.*; @@ -48,22 +51,21 @@ public class SchemaGenerator4Hist { private static final Logger LOGGER = LoggerFactory.getLogger(SchemaGenerator4Hist.class); + private SchemaGenerator4Hist(){ + + } /** * Load schema into JanusGraph. * - * @param graph - * the graph * @param graphMgmt * the graph mgmt */ - public static void loadSchemaIntoJanusGraph(final JanusGraph graph, final JanusGraphManagement graphMgmt, - String backend) { + public static void loadSchemaIntoJanusGraph(final JanusGraphManagement graphMgmt, String backend) { try { AAIConfig.init(); } catch (Exception ex) { - LOGGER.error(" ERROR - Could not run AAIConfig.init(). " + LogFormatTools.getStackTop(ex)); - // System.out.println(" ERROR - Could not run AAIConfig.init(). "); + LOGGER.error(" ERROR - Could not run AAIConfig.init(). {}", LogFormatTools.getStackTop(ex)); System.exit(1); } @@ -97,11 +99,9 @@ public class SchemaGenerator4Hist { for (String label : labels) { if (graphMgmt.containsRelationType(label)) { - String dmsg = " EdgeLabel [" + label + "] already existed. "; - LOGGER.debug(dmsg); + LOGGER.debug(" EdgeLabel [{}] already existed. ", label); } else { - String dmsg = "Making EdgeLabel: [" + label + "]"; - LOGGER.debug(dmsg); + LOGGER.debug("Making EdgeLabel: [{}]", label); graphMgmt.makeEdgeLabel(label).multiplicity(Multiplicity.valueOf("MULTI")).make(); } } @@ -119,8 +119,7 @@ public class SchemaGenerator4Hist { dbPropName = alias.get(); } if (graphMgmt.containsRelationType(dbPropName)) { - String dmsg = " PropertyKey [" + dbPropName + "] already existed in the DB. "; - LOGGER.debug(dmsg); + LOGGER.debug(" PropertyKey [{}] already existed in the DB. ", dbPropName); } else { Class<?> type = obj.getClass(propName); Cardinality cardinality = Cardinality.LIST; @@ -132,7 +131,6 @@ public class SchemaGenerator4Hist { // above) will be stored in our db as a single String. And that // single string will have Cardinality = LIST so we can track its // history. - //cardinality = Cardinality.SET; type = obj.getGenericTypeClass(propName); process = true; } else if (obj.isSimpleType(propName)) { @@ -141,9 +139,8 @@ public class SchemaGenerator4Hist { if (process) { - String imsg = " Creating PropertyKey: [" + dbPropName + "], [" + type.getSimpleName() + "], [" - + cardinality + "]"; - LOGGER.info(imsg); + LOGGER.info(" Creating PropertyKey: [{}], [{}], [{}]", + dbPropName, type.getSimpleName(), cardinality); PropertyKey propK; if (!seenProps.containsKey(dbPropName)) { propK = graphMgmt.makePropertyKey(dbPropName).dataType(type).cardinality(cardinality) @@ -153,17 +150,14 @@ public class SchemaGenerator4Hist { propK = seenProps.get(dbPropName); } if (graphMgmt.containsGraphIndex(dbPropName)) { - String dmsg = " Index [" + dbPropName + "] already existed in the DB. "; - LOGGER.debug(dmsg); + LOGGER.debug(" Index [{}] already existed in the DB. ", dbPropName); } else { if (obj.getIndexedProperties().contains(propName)) { // NOTE - for History we never add a unique index - just a regular index - imsg = "Add index for PropertyKey: [" + dbPropName + "]"; - LOGGER.info(imsg); + LOGGER.info("Add index for PropertyKey: [{}]", dbPropName); graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).buildCompositeIndex(); } else { - imsg = "No index needed/added for PropertyKey: [" + dbPropName + "]"; - LOGGER.info(imsg); + LOGGER.info("No index needed/added for PropertyKey: [{}]", dbPropName); } } } @@ -176,63 +170,33 @@ public class SchemaGenerator4Hist { // only have one of them. That is, a Property can show up many times in a // node, but each instance of that property will only have a single start-ts, // end-ts, end-source-of-truth. Same goes for a node or edge itself. - if (graphMgmt.containsRelationType(END_SOT)) { - String dmsg = "PropertyKey [" + END_SOT + "] already existed in the DB. "; - LOGGER.debug(dmsg); - } else if (!seenProps.containsKey(END_SOT) ) { - String imsg = " Creating PropertyKey: [" + END_SOT + "], [String], [SINGLE]"; - LOGGER.info(imsg); - graphMgmt.makePropertyKey(END_SOT).dataType(String.class) - .cardinality(Cardinality.SINGLE).make(); - } - - if (graphMgmt.containsRelationType(START_TS)) { - String dmsg = " PropertyKey [" + START_TS + "] already existed in the DB. "; - LOGGER.debug(dmsg); - } else if (!seenProps.containsKey(START_TS) ) { - String imsg = " Creating PropertyKey: [" + START_TS + "], [Long], [SINGLE]"; - LOGGER.info(imsg); - graphMgmt.makePropertyKey(START_TS).dataType(Long.class) - .cardinality(Cardinality.SINGLE).make(); - } - - if (graphMgmt.containsRelationType(END_TS)) { - String dmsg = "PropertyKey [" + END_TS + "] already existed in the DB. "; - LOGGER.debug(dmsg); - } else if (!seenProps.containsKey(END_TS) ) { - String imsg = " Creating PropertyKey: [" + END_TS + "], [Long], [SINGLE]"; - LOGGER.info(imsg); - graphMgmt.makePropertyKey(END_TS).dataType(Long.class) - .cardinality(Cardinality.SINGLE).make(); - } - - if (graphMgmt.containsRelationType(START_TX_ID)) { - String dmsg = "PropertyKey [" + START_TX_ID + "] already existed in the DB. "; - LOGGER.debug(dmsg); - } else if (!seenProps.containsKey(START_TX_ID) ) { - String imsg = " Creating PropertyKey: [" + START_TX_ID + "], [String], [SINGLE]"; - LOGGER.info(imsg); - graphMgmt.makePropertyKey(START_TX_ID).dataType(String.class) - .cardinality(Cardinality.SINGLE).make(); - } + makeNewProperty(graphMgmt, seenProps, String.class, END_SOT); + makeNewProperty(graphMgmt, seenProps, Long.class, START_TS); + makeNewProperty(graphMgmt, seenProps, Long.class, END_TS); + makeNewProperty(graphMgmt, seenProps, String.class, START_TX_ID); + makeNewProperty(graphMgmt, seenProps, String.class, END_TX_ID); - if (graphMgmt.containsRelationType(END_TX_ID)) { - String dmsg = "PropertyKey [" + END_TX_ID + "] already existed in the DB. "; - LOGGER.debug(dmsg); - } else if (!seenProps.containsKey(END_TX_ID) ) { - String imsg = " Creating PropertyKey: [" + END_TX_ID + "], [String], [SINGLE]"; - LOGGER.info(imsg); - graphMgmt.makePropertyKey(END_TX_ID).dataType(String.class) - .cardinality(Cardinality.SINGLE).make(); - } String imsg = "-- About to call graphMgmt commit"; LOGGER.info(imsg); graphMgmt.commit(); if (backend != null) { - LOGGER.info("Successfully loaded the schema to " + backend); + LOGGER.info("Successfully loaded the schema to {}", backend); } } + private static <T> void makeNewProperty(JanusGraphManagement graphMgmt, + Map<String, PropertyKey> seenProps, + Class<T> type, + String propertyName) { + if (graphMgmt.containsRelationType(propertyName)) { + LOGGER.debug("PropertyKey [{}] already existed in the DB.", propertyName); + } else if (!seenProps.containsKey(propertyName)) { + LOGGER.info("Creating PropertyKey: [{}], [{}], [{}]", + propertyName, type.getSimpleName(), Cardinality.SINGLE); + graphMgmt.makePropertyKey(propertyName).dataType(type).cardinality(Cardinality.SINGLE) + .make(); + } + } } diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java index 13040d30..f2f24334 100644 --- a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java +++ b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java @@ -152,7 +152,7 @@ public class AAIGraph { logger.info("-- loading schema into JanusGraph"); if ("true".equals(SpringContextAware.getApplicationContext().getEnvironment().getProperty("history.enabled", "false"))) { - SchemaGenerator4Hist.loadSchemaIntoJanusGraph(graph, graphMgt, IN_MEMORY); + SchemaGenerator4Hist.loadSchemaIntoJanusGraph(graphMgt, IN_MEMORY); } else { SchemaGenerator.loadSchemaIntoJanusGraph(graphMgt, IN_MEMORY); } diff --git a/aai-core/src/main/java/org/onap/aai/introspection/exceptions/AAIUnmarshallingException.java b/aai-core/src/main/java/org/onap/aai/introspection/exceptions/AAIUnmarshallingException.java index 5dfc5d3e..6ce42e4e 100644 --- a/aai-core/src/main/java/org/onap/aai/introspection/exceptions/AAIUnmarshallingException.java +++ b/aai-core/src/main/java/org/onap/aai/introspection/exceptions/AAIUnmarshallingException.java @@ -26,18 +26,19 @@ public class AAIUnmarshallingException extends AAIException { private static final long serialVersionUID = -5615651557821878103L; + private static final String AAI_MSG="AAI_3000"; public AAIUnmarshallingException() { } public AAIUnmarshallingException(String message) { - super("AAI_3000", message); + super(AAI_MSG, message); } public AAIUnmarshallingException(Throwable cause) { - super("AAI_3000", cause); + super(AAI_MSG, cause); } public AAIUnmarshallingException(String message, Throwable cause) { - super("AAI_3000", cause, message); + super(AAI_MSG, cause, message); } } diff --git a/aai-core/src/main/java/org/onap/aai/rest/RestHandlerService.java b/aai-core/src/main/java/org/onap/aai/rest/RestHandlerService.java index aeb58c4b..e3ac2b26 100644 --- a/aai-core/src/main/java/org/onap/aai/rest/RestHandlerService.java +++ b/aai-core/src/main/java/org/onap/aai/rest/RestHandlerService.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -24,10 +24,9 @@ import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; public class RestHandlerService { - private static RestHandlerService single_instance = null; + private static RestHandlerService singleInstance = null; public ThreadPoolExecutor executor; - // private constructor restricted to this class itself private RestHandlerService() { executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(50); } @@ -38,9 +37,9 @@ public class RestHandlerService { * @return single instance of RestHandlerService */ public static RestHandlerService getInstance() { - if (single_instance == null) { - single_instance = new RestHandlerService(); + if (singleInstance == null) { + singleInstance = new RestHandlerService(); } - return single_instance; + return singleInstance; } } diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java index b250d8f3..41d97077 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -34,7 +34,7 @@ import org.onap.aai.introspection.Loader; public abstract class QueryEngine { - final protected GraphTraversalSource g; + protected final GraphTraversalSource g; protected double dbTimeMsecs = 0; /** @@ -177,5 +177,4 @@ public abstract class QueryEngine { public abstract List<Path> findCousinsAsPath(Vertex start); public abstract double getDBTimeMsecs(); - } diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java index b7627267..9ce343f6 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java @@ -129,7 +129,7 @@ public class Aggregate extends MultiFormatMapper { json.addProperty(prop.key(), gson.toJson(prop.value())); } else { // throw exception? - return null; + return Optional.empty(); } } } else { @@ -214,7 +214,7 @@ public class Aggregate extends MultiFormatMapper { json.add(inner); } else { Optional<JsonObject> obj = this.getJsonFromVertex((Vertex)l, properties); - json.add(obj.get()); + if(obj.isPresent()) json.add(obj.get()); } } return Optional.of(json); diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java index 847c832a..4977cb86 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java @@ -23,6 +23,9 @@ package org.onap.aai.serialization.queryformats; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import java.util.stream.Collectors; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.Pair; import org.apache.tinkerpop.gremlin.process.traversal.Path; import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.structure.Vertex; @@ -38,6 +41,11 @@ public abstract class MultiFormatMapper implements FormatMapper { Logger logger = LoggerFactory.getLogger(MultiFormatMapper.class); protected boolean isTree = false; + protected static final String PROPERTIES_KEY = "properties"; + protected static final String NODE_TYPE_KEY = "node-type"; + + protected static final String RETURNED_EMPTY_JSONARRAY_MSG = + "Returned empty JsonArray - Could not populate nested json objects for wrapper: {}"; @Override public Optional<JsonObject> formatObject(Object input) @@ -118,7 +126,7 @@ public abstract class MultiFormatMapper implements FormatMapper { if (ja.size() > 0) { t.add("nodes", ja); } else { - logger.debug("Returned empty JsonArray - Could not populate nested json objects for wrapper: {}", nodeIdentifier); + logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier); } return Optional.of(t); @@ -147,7 +155,7 @@ public abstract class MultiFormatMapper implements FormatMapper { t.add("results", ja); return Optional.of(t); } else { - logger.debug("Returned empty JsonArray - Could not populate nested json objects for wrapper: {}", nodeIdentifier); + logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier); } return Optional.empty(); @@ -177,7 +185,7 @@ public abstract class MultiFormatMapper implements FormatMapper { if (ja.size() > 0) { me.add(nodeIdentifier, ja); } else { - logger.debug("Returned empty JsonArray - Could not populate nested json objects for wrapper: {}", nodeIdentifier); + logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier); } nodes.add(me); } @@ -193,18 +201,15 @@ public abstract class MultiFormatMapper implements FormatMapper { if (properties == null) return new HashMap<>(); - Map<String, Set<String>> filterPropertiesMap = new HashMap<>(); - for (String key : properties.keySet()) { - if (!filterPropertiesMap.containsKey(key)) { - Set<String> newSet = new HashSet<>(); - for (String currProperty : properties.get(key)) { - currProperty = truncateApostrophes(currProperty); - newSet.add(currProperty); + return properties.entrySet().stream() + .map(entry -> { + Set<String> newSet = entry.getValue().stream() + .map(this::truncateApostrophes) + .collect(Collectors.toSet()); + + return Pair.of(entry.getKey(), newSet); } - filterPropertiesMap.put(key, newSet); - } - } - return filterPropertiesMap; + ).collect(Collectors.toMap(Pair::getKey, Pair::getValue)); } /** @@ -229,37 +234,55 @@ public abstract class MultiFormatMapper implements FormatMapper { * @param filterPropertiesMap * @return */ - protected JsonObject getPropertyFilteredObject(Optional<JsonObject> obj, Map<String, Set<String>> filterPropertiesMap) { - if (filterPropertiesMap == null || filterPropertiesMap.isEmpty()) { - return obj.get(); - } - JsonObject jsonObj = obj.get(); - JsonObject result = new JsonObject(); - if (jsonObj != null) { - String nodeType = ""; - JsonObject properties = null; - // clone object - for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) { - String key = mapEntry.getKey(); JsonElement value = mapEntry.getValue(); - - // also, check if payload has node-type and properties fields - if (key.equals("node-type") && value != null) { - nodeType = value.getAsString(); - } else if (key.equals("properties") && value != null && value.isJsonObject()) { - properties = value.getAsJsonObject(); + protected JsonObject getPropertyFilteredObject(Optional<JsonObject> obj, + Map<String, Set<String>> filterPropertiesMap) { + return obj.map( + jsonObj -> { + if (filterPropertiesMap == null || filterPropertiesMap.isEmpty()) { + return jsonObj; + } else { + ImmutableTriple<JsonObject, Optional<String>, Optional<JsonObject>> triple = + cloneObjectAndExtractNodeTypeAndProperties(jsonObj); + + JsonObject result = triple.left; + Optional<String> nodeType = triple.middle; + Optional<JsonObject> properties = triple.right; + + // Filter current object based on it containing fields: "node-type" and "properties" + if (nodeType.isPresent() && properties.isPresent()) { + filterByNodeTypeAndProperties(result, nodeType.get(), properties.get(), filterPropertiesMap); + } else { + // filter current object based on the: key - nodeType & value - JsonObject of nodes properties + filterByJsonObj(result, jsonObj, filterPropertiesMap); + } + + return result; } - result.add(key, value); } + ).orElseGet(JsonObject::new); + } - // Filter current object based on it containing fields: "node-type" and "properties" - if (!nodeType.isEmpty() && properties != null) { - filterByNodeTypeAndProperties(result, nodeType, properties, filterPropertiesMap); - } else { - // filter current object based on the: key - nodeType & value - JsonObject of nodes properties - filterByJsonObj(result, jsonObj, filterPropertiesMap); + private ImmutableTriple<JsonObject, Optional<String>, Optional<JsonObject>> cloneObjectAndExtractNodeTypeAndProperties( + JsonObject jsonObj) { + JsonObject result = new JsonObject(); + Optional<String> nodeType = Optional.empty(); + Optional<JsonObject> properties = Optional.empty(); + + // clone object + for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) { + String key = mapEntry.getKey(); + JsonElement value = mapEntry.getValue(); + + // also, check if payload has node-type and properties fields + if (key.equals(NODE_TYPE_KEY) && value != null) { + nodeType = Optional.of(value.getAsString()); + } else if (key.equals(PROPERTIES_KEY) && value != null && value.isJsonObject()) { + properties = Optional.of(value.getAsJsonObject()); } + result.add(key, value); } - return result; + + return ImmutableTriple.of(result, nodeType, properties); } /** @@ -283,8 +306,8 @@ public abstract class MultiFormatMapper implements FormatMapper { filteredProperties.add(property, properties.get(property)); } } - result.remove("properties"); - result.add("properties", filteredProperties); + result.remove(PROPERTIES_KEY); + result.add(PROPERTIES_KEY, filteredProperties); } return result; } @@ -302,7 +325,8 @@ public abstract class MultiFormatMapper implements FormatMapper { } for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) { - String key = mapEntry.getKey(); JsonElement value = mapEntry.getValue(); + String key = mapEntry.getKey(); + JsonElement value = mapEntry.getValue(); JsonObject filteredProperties = new JsonObject(); if (value != null && value.isJsonObject() && filterPropertiesMap.containsKey(key)) { JsonObject joProperties = value.getAsJsonObject(); @@ -325,14 +349,14 @@ public abstract class MultiFormatMapper implements FormatMapper { * @param filterPropertiesMap * @return */ - protected JsonObject filterProperties(Optional<JsonObject> properties, String nodeType, Map<String, Set<String>> filterPropertiesMap) { - if (filterPropertiesMap == null || filterPropertiesMap.isEmpty()) { - return properties.get(); - } + protected JsonObject filterProperties(Optional<JsonObject> properties, String nodeType, + Map<String, Set<String>> filterPropertiesMap) { + return properties.map(jo -> { + if (filterPropertiesMap == null || filterPropertiesMap.isEmpty()) { + return properties.get(); + } - JsonObject jo = properties.get(); - JsonObject result = new JsonObject(); - if (jo != null) { + JsonObject result = new JsonObject(); // clone the object for (Map.Entry<String, JsonElement> mapEntry : jo.entrySet()) { String key = mapEntry.getKey(); @@ -350,8 +374,8 @@ public abstract class MultiFormatMapper implements FormatMapper { } } } - } - return result; + return result; + }).orElseGet(JsonObject::new); } @Override diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/TreeFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/TreeFormat.java index 632a800a..d94c4b92 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/TreeFormat.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/TreeFormat.java @@ -26,6 +26,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import java.util.Map.Entry; import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet; import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.structure.Vertex; @@ -41,14 +42,12 @@ import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexExcepti import org.onap.aai.serialization.queryformats.params.Depth; import org.onap.aai.serialization.queryformats.params.NodesOnly; import org.onap.aai.serialization.queryformats.utils.UrlBuilder; -import org.onap.aai.util.AAIConfig; import java.io.UnsupportedEncodingException; import java.util.*; -import java.util.stream.Stream; public class TreeFormat extends MultiFormatMapper { - private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(TreeFormat.class); + private static final EELFLogger TREE_FORMAT_LOGGER = EELFManager.getInstance().getLogger(TreeFormat.class); protected JsonParser parser = new JsonParser(); protected final DBSerializer serializer; protected final Loader loader; @@ -137,16 +136,19 @@ public class TreeFormat extends MultiFormatMapper { return new TreeFormat(this); } } - + public JsonArray process(List<Object> queryResults, Map<String, List<String>> properties) { JsonArray body = new JsonArray(); for (Object o : queryResults) { try { - return this.formatObjectToJsonArray(o, properties).get(); + return this.formatObjectToJsonArray(o, properties).orElseGet( () -> { + TREE_FORMAT_LOGGER.warn("Empty Optional returned by 'formatObjectToJsonArray'"); + return body; + }); } catch (AAIFormatVertexException e) { - LOGGER.warn("Failed to format vertex, returning a partial list " + LogFormatTools.getStackTop(e)); + TREE_FORMAT_LOGGER.warn("Failed to format vertex, returning a partial list " + LogFormatTools.getStackTop(e)); } catch (AAIFormatQueryResultFormatNotSupported e) { - LOGGER.warn("Failed to format result type of the query " + LogFormatTools.getStackTop(e)); + TREE_FORMAT_LOGGER.warn("Failed to format result type of the query " + LogFormatTools.getStackTop(e)); } } return body; @@ -158,13 +160,13 @@ public class TreeFormat extends MultiFormatMapper { if (input == null) return Optional.of(json); if (input instanceof Tree) { - return this.getJsonArrayFromTree((Tree<?>) input); + return this.getJsonArrayFromTree((Tree<Object>) input); } else { throw new AAIFormatQueryResultFormatNotSupported(); } } - protected Optional<JsonArray> getJsonArrayFromTree(Tree<?> tree) throws AAIFormatVertexException { + protected Optional<JsonArray> getJsonArrayFromTree(Tree<Object> tree) throws AAIFormatVertexException { if (tree.isEmpty()) { return Optional.of(new JsonArray()); } @@ -172,23 +174,24 @@ public class TreeFormat extends MultiFormatMapper { // DSL Query JsonArray jsonArray = new JsonArray(); JsonObject jsonObject = new JsonObject(); - for (Object o : tree.keySet()) { + for (Map.Entry<Object, Tree<Object>> entry : tree.entrySet()) { + Object o = entry.getKey(); + // DSL Query - if (o instanceof AbstractSet) { + if (o instanceof BulkSet) { BulkSet bs = (BulkSet) o; for (Object o1 : bs) { Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) o1); if (obj.isPresent()) { jsonObject = obj.get(); for (Map.Entry<String, JsonElement> mapEntry : jsonObject.entrySet()) { - String s = mapEntry.getKey(); - JsonElement jsonRootElementContents = jsonObject.get(s); // getting everyObject inside + JsonElement jsonRootElementContents = mapEntry.getValue(); // getting everyObject inside if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) { JsonObject relatedJsonNode = (JsonObject) jsonRootElementContents; - JsonArray relatedNodes = this.getRelatedNodes(relatedJsonNode).get(); - if (relatedNodes != null && relatedNodes.size() > 0) { - jsonRootElementContents.getAsJsonObject().add("related-nodes", relatedNodes); - } + addRelatedNodesToJsonObject( + jsonRootElementContents.getAsJsonObject(), + getRelatedNodes(relatedJsonNode) + ); } } jsonArray.add(jsonObject); @@ -201,13 +204,11 @@ public class TreeFormat extends MultiFormatMapper { if (obj.isPresent()) { jsonObject = obj.get(); for (Map.Entry<String, JsonElement> mapEntry : jsonObject.entrySet()) { - String s = mapEntry.getKey(); - JsonElement jsonRootElementContents = jsonObject.get(s); + JsonElement jsonRootElementContents = mapEntry.getValue(); if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) { - JsonArray relatedNodes = this.getRelatedNodes(tree.get(o)).get(); - if (relatedNodes != null && relatedNodes.size() > 0) { - jsonRootElementContents.getAsJsonObject().add("related-nodes", relatedNodes); - } + addRelatedNodesToJsonObject( + jsonRootElementContents.getAsJsonObject(), + getRelatedNodes(entry.getValue())); } } jsonArray.add(jsonObject); @@ -224,41 +225,56 @@ public class TreeFormat extends MultiFormatMapper { JsonElement jsonRootElementContents = jsonObj.get(s); if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) { JsonObject relatedJsonNode = jsonRootElementContents.getAsJsonObject(); - JsonArray currRelatedNodes = this.getRelatedNodes(relatedJsonNode).get(); - if (currRelatedNodes != null && currRelatedNodes.size() > 0) { - relatedJsonNode.add("related-nodes", currRelatedNodes); - } + addRelatedNodesToJsonObject( + relatedJsonNode, + this.getRelatedNodes(relatedJsonNode) + ); relatedNodes.add(relatedJsonNode); } } return Optional.of(relatedNodes); } - protected Optional<JsonArray> getRelatedNodes(Tree<?> tree) throws AAIFormatVertexException { + protected Optional<JsonArray> getRelatedNodes(Tree<Object> tree) throws AAIFormatVertexException { JsonArray relatedNodes = new JsonArray(); - for (Object o : tree.keySet()) { + for (Map.Entry<Object, Tree<Object>> entry : tree.entrySet()) { + Object o = entry.getKey(); + if (o instanceof Vertex) { - Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) o); - if (obj.isPresent()) { - JsonObject jsonObj = obj.get(); - for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) { - String s = mapEntry.getKey(); - JsonElement jsonRootElementContents = jsonObj.get(s); - if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) { - JsonArray currRelatedNodes = this.getRelatedNodes(tree.get(o)).get(); - JsonObject jsonObject = jsonRootElementContents.getAsJsonObject(); - if (currRelatedNodes != null && currRelatedNodes.size() > 0) { - jsonObject.add("related-nodes", currRelatedNodes); - } - relatedNodes.add(jsonObject); - } - } - } + processVertex(relatedNodes, entry, (Vertex) o); } } return Optional.of(relatedNodes); } + private void processVertex(JsonArray relatedNodes, Entry<Object, Tree<Object>> entry, Vertex o) + throws AAIFormatVertexException { + Optional<JsonObject> obj = this.getJsonFromVertex(o); + if (obj.isPresent()) { + JsonObject jsonObj = obj.get(); + for (Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) { + JsonElement jsonRootElementContents = mapEntry.getValue(); + if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) { + JsonObject jsonObject = addRelatedNodesToJsonObject( + jsonRootElementContents.getAsJsonObject(), + getRelatedNodes(entry.getValue())); + relatedNodes.add(jsonObject); + } + } + } + } + + + private static JsonObject addRelatedNodesToJsonObject(JsonObject jsonObject, Optional<JsonArray> relatedNodesOpt) { + relatedNodesOpt.ifPresent( relatedNodes -> { + if (relatedNodes.size() > 0) { + jsonObject.add("related-nodes", relatedNodes); + } + }); + + return jsonObject; + } + /** * * Returns an Optional<JsonObject> to convert the contents from the given Vertex object into a JsonObject. diff --git a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java index c2bfabf4..84935cdb 100644 --- a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java +++ b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java @@ -93,9 +93,9 @@ public class HttpsAuthClient { ctx = SSLContext.getInstance("TLSv1.2"); KeyManagerFactory kmf = null; - try { + + try(FileInputStream fin = new FileInputStream(keystorePath)) { kmf = KeyManagerFactory.getInstance("SunX509"); - FileInputStream fin = new FileInputStream(keystorePath); KeyStore ks = KeyStore.getInstance("PKCS12"); char[] pwd = keystorePassword.toCharArray(); ks.load(fin, pwd); diff --git a/aai-core/src/test/java/org/onap/aai/audit/ListEndpointsTest.java b/aai-core/src/test/java/org/onap/aai/audit/ListEndpointsTest.java index 5c825242..5d606733 100644 --- a/aai-core/src/test/java/org/onap/aai/audit/ListEndpointsTest.java +++ b/aai-core/src/test/java/org/onap/aai/audit/ListEndpointsTest.java @@ -25,11 +25,13 @@ import org.junit.Before; import org.junit.Test; import org.onap.aai.AAISetup; import org.onap.aai.setup.SchemaVersion; +import org.springframework.test.annotation.DirtiesContext; import java.util.List; import java.util.Map; import java.util.Properties; +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) public class ListEndpointsTest extends AAISetup { private Properties properties; diff --git a/aai-core/src/test/java/org/onap/aai/dbmap/AAIGraphTest.java b/aai-core/src/test/java/org/onap/aai/dbmap/AAIGraphTest.java index f2c7b27c..cc420018 100644 --- a/aai-core/src/test/java/org/onap/aai/dbmap/AAIGraphTest.java +++ b/aai-core/src/test/java/org/onap/aai/dbmap/AAIGraphTest.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -55,7 +55,7 @@ public class AAIGraphTest extends AAISetup { } @Test - public void getRealtimeInstanceConnectionName() throws Exception { + public void getRealtimeInstanceConnectionName() { JanusGraphManagement graphMgt = AAIGraph.getInstance().getGraph().openManagement(); String connectionInstanceName = @@ -96,7 +96,7 @@ public class AAIGraphTest extends AAISetup { @Ignore("Need to create schema specific to the test") @Test - public void checkIndexOfAliasedIndexedProps() throws Exception { + public void checkIndexOfAliasedIndexedProps() { Set<String> aliasedIndexedProps = getAliasedIndexedProps(); JanusGraphManagement graphMgt = AAIGraph.getInstance().getGraph().openManagement(); for (String aliasedIndexedProp : aliasedIndexedProps) { diff --git a/aai-els-onap-logging/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java b/aai-els-onap-logging/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java index fef10a77..95f9c1b7 100644 --- a/aai-els-onap-logging/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java +++ b/aai-els-onap-logging/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -27,33 +27,20 @@ package org.onap.aai.util; * as these keys are generated in a couple places, I made a class to contain that logic */ public class HbaseSaltPrefixer { - private int NUM_REGION_BUCKETS = 3; // the number of hbase region servers per cluster + // the number of hbase region servers per cluster + private static int NUM_REGION_BUCKETS = 3; private static class SingletonHolder { private static final HbaseSaltPrefixer INSTANCE = new HbaseSaltPrefixer(); } - /** - * Instantiates a new hbase salt prefixer. - */ private HbaseSaltPrefixer() { } - /** - * Gets the single instance of HbaseSaltPrefixer. - * - * @return single instance of HbaseSaltPrefixer - */ public static HbaseSaltPrefixer getInstance() { return SingletonHolder.INSTANCE; } - /** - * Prepend salt. - * - * @param key the key - * @return the string - */ public String prependSalt(String key) { int salt = Math.abs(key.hashCode()) % NUM_REGION_BUCKETS; return salt + "-" + key; diff --git a/aai-els-onap-logging/src/test/java/org/onap/aai/logging/LoggingContextTest.java b/aai-els-onap-logging/src/test/java/org/onap/aai/logging/LoggingContextTest.java index 245840bc..4fe60315 100644 --- a/aai-els-onap-logging/src/test/java/org/onap/aai/logging/LoggingContextTest.java +++ b/aai-els-onap-logging/src/test/java/org/onap/aai/logging/LoggingContextTest.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -39,7 +39,7 @@ public class LoggingContextTest { LoggingContext.elapsedTime(300, TimeUnit.MILLISECONDS); assertEquals(MDC.get(LoggingContext.LoggingField.ELAPSED_TIME.toString()), "300"); LoggingContext.init(); - assertTrue(MDC.get(LoggingContext.LoggingField.ELAPSED_TIME.toString()) == null); + assertNull(MDC.get(LoggingContext.LoggingField.ELAPSED_TIME.toString())); } @Test public void stopWatchTest() { @@ -60,7 +60,7 @@ public class LoggingContextTest { assertEquals(testServiceName, MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString())); LoggingContext.clear(); - assertTrue(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()) == null); + assertNull(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString())); } @@ -71,7 +71,7 @@ public class LoggingContextTest { assertEquals(testServiceName, MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString())); LoggingContext.remove(LoggingContext.LoggingField.SERVICE_NAME.toString()); - assertTrue(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()) == null); + assertNull(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString())); } diff --git a/aai-rest/src/main/java/org/onap/aai/restclient/ClientType.java b/aai-rest/src/main/java/org/onap/aai/restclient/ClientType.java index 4633b425..9ca9a7c2 100644 --- a/aai-rest/src/main/java/org/onap/aai/restclient/ClientType.java +++ b/aai-rest/src/main/java/org/onap/aai/restclient/ClientType.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -7,9 +7,9 @@ * 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 - * + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> * 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. @@ -22,4 +22,7 @@ package org.onap.aai.restclient; public class ClientType { public static final String AAI = "aai-rest-client"; + + private ClientType() { + } } diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java index 1e798196..5aa8d688 100644 --- a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java @@ -21,77 +21,75 @@ package org.onap.aai.schemaif; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.onap.aai.schemaif.definitions.EdgeSchema; import org.onap.aai.schemaif.definitions.VertexSchema; +import java.util.Map; +import java.util.Set; + public interface SchemaProvider { - + /** * Load the schema into memory */ - public void loadSchema() throws SchemaProviderException; - + void loadSchema() throws SchemaProviderException; + /** * Get the identifier for the more recent version of the schema * * @return The schema version identifier */ - public String getLatestSchemaVersion() throws SchemaProviderException; - + String getLatestSchemaVersion() throws SchemaProviderException; + /** * Get the schema definition for a vertex * * @param vertexName - Name of the vertex * @param schemaVersion - Version of the schema to use - * + * * @return The vertex schema definition */ - public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException; - + VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException; + /** * Get the schema definition for an edge * * @param edgeType - Type of the edge * @param sourceVertex - The source vertex for the edge * @param targetVertex - The target vertex for the edge - * @param schemaVersion - Version of the schema to use - * + * @param version - Version of the schema to use + * * @return The edge schema definition */ - public EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version) throws SchemaProviderException; + EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version) throws SchemaProviderException; /** * Get the list of edge definitions which are adjacent to the given vertex * * @param vertexType - Type of the vertex - * @param schemaVersion - Version of the schema to use - * + * @param version - Version of the schema to use + * * @return The list of edge schema definitions */ - public Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException; - + Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException; + /** * Get the list of edge definitions which are valid for the given source and target * * @param sourceType - Type of the source vertex * @param targetType - Type of the target vertex - * @param schemaVersion - Version of the schema to use - * + * @param version - Version of the schema to use + * * @return The list of edge schema definitions */ - public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException; + Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException; /** * Get vertex map for a schema version * * @param schemaVersion - Version of the schema to use - * + * * @return The list of vertex types */ - public Map<String, VertexSchema> getVertexMap(String schemaVersion) throws SchemaProviderException; - + Map<String, VertexSchema> getVertexMap(String schemaVersion) throws SchemaProviderException; } diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java index a0586037..2e2884b4 100644 --- a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -21,11 +21,9 @@ package org.onap.aai.schemaif.definitions.types; -import org.onap.aai.schemaif.SchemaProviderException; - public abstract class DataType { public enum Type { - STRING, + STRING, BOOL, INT, LONG, @@ -34,9 +32,9 @@ public abstract class DataType { MAP, COMPLEX } - - private Type type; - + + private final Type type; + public DataType(Type type) { this.type = type; } @@ -44,9 +42,9 @@ public abstract class DataType { public Type getType() { return type; } - + public abstract Object validateValue(String value); - + public String toString() { return getType().toString(); } diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java index 7fa123a5..0bc1760b 100644 --- a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -20,26 +20,24 @@ */ package org.onap.aai.schemaif.json; -import org.onap.aai.schemaif.SchemaProviderException; -import org.onap.aai.schemaif.json.definitions.JsonSchema; - import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; import com.google.gson.annotations.SerializedName; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.json.definitions.JsonSchema; public class SchemaServiceResponse { public static final String SCHEMA_TYPE_OXM = "oxm"; public static final String SCHEMA_TYPE_JSON = "json"; - + private static final Gson gson = new GsonBuilder().create(); @SerializedName("schema-version") private String version; - + @SerializedName("schema-content") private JsonSchema data; - + public String getVersion() { return version; } @@ -57,11 +55,10 @@ public class SchemaServiceResponse { if (json == null || json.isEmpty()) { throw new SchemaProviderException("Empty schema-service response"); } - + return gson.fromJson(json, SchemaServiceResponse.class); } catch (Exception ex) { throw new SchemaProviderException("Invalid response from schema service: " + ex.getMessage()); } } - } diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java index 0ad8bf45..bced602c 100644 --- a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -40,7 +40,7 @@ public class OxmSchemaProvider implements SchemaProvider { OxmEdgeRulesLoader.loadModels(); OxmSchemaLoader.loadModels(); } - + @Override public String getLatestSchemaVersion() throws SchemaProviderException { return OxmSchemaLoader.getLatestVersion(); @@ -72,41 +72,41 @@ public class OxmSchemaProvider implements SchemaProvider { if (edgeRule == null) { return null; } - + FromOxmEdgeSchema es = new FromOxmEdgeSchema(); es.fromEdgeRule(edgeRule); - + return es; } @Override public Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException { RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version); - Set<EdgeSchema> edges = new HashSet<EdgeSchema>(); + Set<EdgeSchema> edges = new HashSet<>(); List<EdgeRule> rules = relSchema.lookupAdjacentEdges(vertexType); - + for (EdgeRule rule : rules) { FromOxmEdgeSchema es = new FromOxmEdgeSchema(); es.fromEdgeRule(rule); edges.add(es); } - + return edges; } - + @Override public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException { RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version); - Set<EdgeSchema> edges = new HashSet<EdgeSchema>(); + Set<EdgeSchema> edges = new HashSet<>(); Set<String> relTypes = relSchema.getValidRelationTypes(sourceType, targetType); - + for (String type : relTypes) { EdgeSchema edgeSchema = getEdgeSchema(type, sourceType, targetType, version); if (edgeSchema != null) { edges.add(edgeSchema); } } - + return edges; } diff --git a/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorLocalTest.java b/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorLocalTest.java index dca21f2d..83d7dc44 100644 --- a/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorLocalTest.java +++ b/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorLocalTest.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -20,18 +20,6 @@ package org.onap.aai.nodes; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; - -import javax.xml.bind.SchemaOutputResolver; -import javax.xml.transform.*; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - import org.eclipse.persistence.dynamic.DynamicEntity; import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; import org.junit.Rule; @@ -39,7 +27,6 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.onap.aai.config.NodesConfiguration; -import org.onap.aai.restclient.MockProvider; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.testutils.TestUtilConfigTranslator; import org.springframework.beans.factory.annotation.Autowired; @@ -47,10 +34,29 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringRunner; import org.w3c.dom.Document; +import javax.xml.bind.SchemaOutputResolver; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + @RunWith(SpringRunner.class) @TestPropertySource( properties = { @@ -69,7 +75,7 @@ public class NodeIngestorLocalTest { @Autowired NodeIngestor nodeIngestor; - public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException { + public static void printDocument(Document doc, OutputStream out) throws TransformerException { TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); @@ -78,7 +84,7 @@ public class NodeIngestorLocalTest { transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); - transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, "UTF-8"))); + transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, UTF_8))); } @Test @@ -89,12 +95,12 @@ public class NodeIngestorLocalTest { DynamicEntity foo10 = ctx10.newDynamicEntity("Foo"); foo10.set("fooId", "bar"); - assertTrue("bar".equals(foo10.get("fooId"))); + assertEquals("bar", foo10.get("fooId")); // should work bc Bar is valid in test_business_v10 schema DynamicEntity bar10 = ctx10.newDynamicEntity("Bar"); bar10.set("barId", "bar2"); - assertTrue("bar2".equals(bar10.get("barId"))); + assertEquals("bar2", bar10.get("barId")); XSDOutputResolver outputResolver10 = new XSDOutputResolver(); ctx10.generateSchema(outputResolver10); @@ -103,11 +109,11 @@ public class NodeIngestorLocalTest { // should work bc Foo.quantity is valid in test_network_v11 schema DynamicEntity foo11 = ctx11.newDynamicEntity("Foo"); foo11.set("quantity", "12"); - assertTrue("12".equals(foo11.get("quantity"))); + assertEquals("12", foo11.get("quantity")); DynamicEntity quux11 = ctx11.newDynamicEntity("Quux"); quux11.set("qManagerName", "some guy"); - assertTrue("some guy".equals(quux11.get("qManagerName"))); + assertEquals("some guy", quux11.get("qManagerName")); XSDOutputResolver outputResolver11 = new XSDOutputResolver(); ctx11.generateSchema(outputResolver11); @@ -126,19 +132,16 @@ public class NodeIngestorLocalTest { @Test public void testGetVersionFromClassName() { assertEquals(nodeIngestor.getVersionFromClassName("inventory.aai.onap.org.v13.Evc"), new SchemaVersion("v13")); - } @Test public void testGetVersionFromClassNameNull() { assertEquals(nodeIngestor.getVersionFromClassName("blah"), new SchemaVersion("v15")); - } @Test public void testGetObjectsInVersion() { assertEquals(nodeIngestor.getObjectsInVersion(new SchemaVersion("v13")).size(), 148); - } @Test @@ -155,7 +158,7 @@ public class NodeIngestorLocalTest { assertThat("OXM:\n" + expected, expected, is(content)); } - private class XSDOutputResolver extends SchemaOutputResolver { + private static class XSDOutputResolver extends SchemaOutputResolver { @Override public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { diff --git a/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorTest.java b/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorTest.java index dc4e1e46..b70b1bfc 100644 --- a/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorTest.java +++ b/aai-schema-ingest/src/test/java/org/onap/aai/nodes/NodeIngestorTest.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -20,18 +20,6 @@ package org.onap.aai.nodes; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; - -import javax.xml.bind.SchemaOutputResolver; -import javax.xml.transform.*; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - import org.eclipse.persistence.dynamic.DynamicEntity; import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; import org.junit.Rule; @@ -49,6 +37,26 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.w3c.dom.Document; +import javax.xml.bind.SchemaOutputResolver; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + @RunWith(SpringJUnit4ClassRunner.class) @TestPropertySource( properties = { @@ -76,12 +84,12 @@ public class NodeIngestorTest { DynamicEntity foo10 = ctx10.newDynamicEntity("Foo"); foo10.set("fooId", "bar"); - assertTrue("bar".equals(foo10.get("fooId"))); + assertEquals("bar", foo10.get("fooId")); // should work bc Bar is valid in test_business_v10 schema DynamicEntity bar10 = ctx10.newDynamicEntity("Bar"); bar10.set("barId", "bar2"); - assertTrue("bar2".equals(bar10.get("barId"))); + assertEquals("bar2", bar10.get("barId")); XSDOutputResolver outputResolver10 = new XSDOutputResolver(); ctx10.generateSchema(outputResolver10); @@ -90,11 +98,11 @@ public class NodeIngestorTest { // should work bc Foo.quantity is valid in test_network_v11 schema DynamicEntity foo11 = ctx11.newDynamicEntity("Foo"); foo11.set("quantity", "12"); - assertTrue("12".equals(foo11.get("quantity"))); + assertEquals("12", foo11.get("quantity")); DynamicEntity quux11 = ctx11.newDynamicEntity("Quux"); quux11.set("qManagerName", "some guy"); - assertTrue("some guy".equals(quux11.get("qManagerName"))); + assertEquals("some guy", quux11.get("qManagerName")); XSDOutputResolver outputResolver11 = new XSDOutputResolver(); ctx11.generateSchema(outputResolver11); @@ -154,24 +162,19 @@ public class NodeIngestorTest { transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); - transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, "UTF-8"))); + transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, UTF_8))); } - private class XSDOutputResolver extends SchemaOutputResolver { + private static class XSDOutputResolver extends SchemaOutputResolver { @Override public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { - - // create new file - // create stream result File temp = File.createTempFile("schema", ".xsd"); StreamResult result = new StreamResult(temp); System.out.println("Schema file: " + temp.getAbsolutePath()); - // set system id result.setSystemId(temp.toURI().toURL().toString()); - // return result return result; } } diff --git a/docs/conf.py b/docs/conf.py index 8f40e8b8..5371015c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,4 +12,4 @@ intersphinx_mapping = {} html_last_updated_fmt = '%d-%b-%y %H:%M' def setup(app): - app.add_stylesheet("css/ribbon_onap.css") + app.add_stylesheet("css/ribbon.css") diff --git a/docs/platform/architecture.rst b/docs/platform/architecture.rst index f370daac..9ca5ed3a 100644 --- a/docs/platform/architecture.rst +++ b/docs/platform/architecture.rst @@ -21,3 +21,87 @@ AAI is where the data converges, where the pictures come together, and where the With the high volume and variety of data, AAI must be prepared to answer many types of queries; real-time search to quickly retrieve specific items from an ocean of data, relationships to determine impacts and consequences, aggregations and counts to explore availability and consumption, validation and integrity to establish whether systems are acting on good information, history and provenance to reconstruct the current view and its context, and enrichment out to legacy systems to examine the low-level details of the network and virtual assets. .. image:: images/aai_in_onap.png + +AAI Components +^^^^^^^^^^^^^^ + +.. image:: images/aai_components.png + +ESR +""" +Applications for management of external systems. + +================== === +**aai/esr-gui** External system management ui. UI for esr-server. +**aai/esr-server** ESR backend, mainly include the function of external system reachable check and data pretreatment. +================== === + +Input abstraction +""""""""""""""""" +Applications that serve as entry points to A&AI. + +==================== === +**aai/model-loader** Obtains SDC artifacts and loads them into the A&AI Resources service for storage. +**aai/sparky-be** AAI user interface back end. +**aai/sparky-fe** AAI user interface front end. +==================== === + +Query abstraction +""""""""""""""""" +Query abstraction point for clients that routes AAI queries and event data. + +=================== === +**aai/data-router** AAI Microservice used to route AAI queries and event data to correct storage engine. Serves as a query abstraction point for clients, as well as a gateway. +=================== === + +Data management +""""""""""""""" +Microservices that facilitate data management of AAI objects. + +============================ === +**aai/babel** AAI Microservice to generate AAI model XML from SDC TOSCA CSAR artifacts. +**aai/cacher** Cacher is a generic service that can be used to snapshot json responses, force sync them, sync them periodically, or update them by consuming dmaap events. +**aai/chameleon** (deprecated) Abstraction service for historical database. +**aai/champ** Abstraction from underlying graph storage systems that A&AI would interface with. +**aai/gizmo** (deprecated) CRUD Rest API endpoint for resources and relationships, delivering atomic interactions with the graph for improved scalability. +**aai/resources** AAI Resources Micro Service providing CRUD REST APIs for inventory resources. This microservice provides the main path for updating and searching the graph - java-types defined in the OXM file for each version of the API define the REST endpoints - for example, the java-type "CloudRegion" in aai-common/aai-schema/src/main/resources/oxm/aai_oxm_v11.xml maps to /aai/v11/cloud-infrastructure/cloud-regions/cloud-region. +**aai/search-data-service** Abstraction layer for searchengine, supporting queries and updates. Currently supports Elasticsearch, but has also been design with Solr support in mind. +**aai/spike** (deprecated) Microservice used to generate events describing changes to the graph data. +**aai/tabular-data-service** (deprecated) Microservice which serves as an abstraction layer to a tabular data store. +**aai/validation** Microservice used to invoke validation mechanism . +============================ === + +Graph services +"""""""""""""" +Set of components, which store, provide or display schemas. + +====================== === +**aai/graphadmin** Microservice with various functions for graph management. +**aai/graphgraph** Microservice used to provide view of AAI model, schema and edge rules. +**aai/schema-service** Application holds and provides specified schema versions. +**aai/traversal** AAI Traversal Micro Service providing REST APIs for traversal/search of inventory resources. Custom queries (gremin-style traversals) model based queries (which use a model either manually created or loaded from SDC models) and named-queries (traversals which ignore edge labels and direction and just link together objects of given node types from a starting node). +====================== === + +Libraries +""""""""" +Libraries don't run as standalone applications. They contain general functionality, which may be imported and used in other modules. + +======================= === +**aai/aai-common** This holds the model, annotations and common modules used across the Resources and Traversal micro services. aai/aai-common creates artifacts like aai-core, aai-schema and aai-annotations, which are used by the rest of the microservices and libraries. +**aai/event-client** Event bus client library. +**aai/logging-service** AAI common logging library. +**aai/rest-client** Library for making REST calls. +**aai/router-core** Library containing the core camel components for the data router. +======================= === + +Configuration repositories +"""""""""""""""""""""""""" +Contain several repositories that include various configuration. + +=================== === +**aai/aai-data** (deprecated) AAI Chef environment files. +**aai/aai-config** (deprecated) AAI Chef cookbooks. +**aai/aai-service** (deprecated) AAI REST based services. +**aai/oom** +**aai/test-config** Repository containing test configuration for use in continuous integration. +=================== === diff --git a/docs/platform/images/aai_components.png b/docs/platform/images/aai_components.png Binary files differnew file mode 100644 index 00000000..217225f0 --- /dev/null +++ b/docs/platform/images/aai_components.png |