summaryrefslogtreecommitdiffstats
path: root/aai-core
diff options
context:
space:
mode:
Diffstat (limited to 'aai-core')
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java106
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java114
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java2
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/exceptions/AAIUnmarshallingException.java7
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java4
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java11
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/RestHandlerService.java11
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java32
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java29
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java5
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java44
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java2
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java12
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java268
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java45
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/TreeFormat.java344
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/UrlBuilder.java8
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java4
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/RestController.java58
-rw-r--r--aai-core/src/test/java/org/onap/aai/audit/ListEndpointsTest.java2
-rw-r--r--aai-core/src/test/java/org/onap/aai/dbmap/AAIGraphTest.java6
-rw-r--r--aai-core/src/test/java/org/onap/aai/logging/CustomLogPatternLayoutTest.java49
-rw-r--r--aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializerTest.java29
-rw-r--r--aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java4
-rw-r--r--aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java167
-rw-r--r--aai-core/src/test/java/org/onap/aai/serialization/queryformats/ResourceFormatTest.java2
-rw-r--r--aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java2
-rw-r--r--aai-core/src/test/java/org/onap/aai/serialization/queryformats/utils/UrlBuilderTest.java9
-rw-r--r--aai-core/src/test/resources/onap/oxm/v10/aai_oxm_v10.xml5
-rw-r--r--aai-core/src/test/resources/onap/oxm/v11/aai_oxm_v11.xml5
-rw-r--r--aai-core/src/test/resources/onap/oxm/v12/aai_oxm_v12.xml9
-rw-r--r--aai-core/src/test/resources/onap/oxm/v13/aai_oxm_v13.xml9
-rw-r--r--aai-core/src/test/resources/onap/oxm/v14/aai_oxm_v14.xml5
34 files changed, 1115 insertions, 300 deletions
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/prevalidation/ValidationService.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java
index 78083ecb..801561de 100644
--- a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java
@@ -78,8 +78,8 @@ public class ValidationService {
static final String REQUEST_TIMEOUT_STRING =
"Request to validation service took longer than the currently set timeout";
- static final String VALIDATION_ENDPOINT = "/v1/app/validate";
- static final String VALIDATION_HEALTH_ENDPOINT = "/v1/core/core-service/info";
+ static final String VALIDATION_ENDPOINT = "/v1/validate";
+ static final String VALIDATION_HEALTH_ENDPOINT = "/v1/info";
private static final String ENTITY_TYPE = "entity-type";
private static final String ACTION = "action";
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
index fcfeb268..712a1ddb 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
@@ -57,7 +57,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
private static final String ARGUMENT2 = "#!#argument#!#";
private static final String HAS = ".has('";
private static final String SINGLE_QUOTE = "'";
- private static final String ESCAPE_SINGLE_QUOTE = "\\'";
+ private static final String ESCAPE_SINGLE_QUOTE = "\\\'";
private GremlinGroovyShell gremlinGroovy = new GremlinGroovyShell();
private GraphTraversal<?, ?> completeTraversal = null;
protected List<String> list = null;
@@ -119,11 +119,20 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
String term = "";
if (value != null && !(value instanceof String)) {
String valueString = value.toString();
+
if (valueString.indexOf('\'') != -1) {
value = valueString.replace(SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE);
}
LOGGER.trace("Inside getVerticesByProperty(): key = {}, value = {}", key, value);
term = value.toString();
+ } else if (value != null && value instanceof String) {
+ String valueString = value.toString();
+
+ if (valueString.indexOf('\'') != -1) {
+ value = valueString.replace(SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE);
+ }
+ LOGGER.trace("Inside getVerticesByProperty(): key = {}, value = {}", key, value);
+ term = "'" + value + "'";
} else {
term = "'" + value + "'";
}
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/rest/db/HttpEntry.java b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
index 86d7e1b7..2899a812 100644
--- a/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
+++ b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
@@ -109,6 +109,8 @@ public class HttpEntry {
@Value("${delta.events.enabled:false}")
private boolean isDeltaEventsEnabled;
+ private String serverBase;
+
@Autowired
private XmlFormatTransformer xmlFormatTransformer;
@@ -150,6 +152,23 @@ public class HttpEntry {
return this;
}
+ public HttpEntry setHttpEntryProperties(SchemaVersion version, String serverBase) {
+ this.version = version;
+ this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
+ this.dbEngine = new JanusGraphDBEngine(queryStyle, loader);
+
+ getDbEngine().startTransaction();
+ this.notification = new UEBNotification(loader, loaderFactory, schemaVersions);
+ if("true".equals(AAIConfig.get("aai.notification.depth.all.enabled", "true"))){
+ this.notificationDepth = AAIProperties.MAXIMUM_DEPTH;
+ } else {
+ this.notificationDepth = AAIProperties.MINIMUM_DEPTH;
+ }
+
+ this.serverBase = serverBase;
+ return this;
+ }
+
public HttpEntry setHttpEntryProperties(SchemaVersion version, UEBNotification notification) {
this.version = version;
this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
@@ -322,7 +341,14 @@ public class HttpEntry {
public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth,
boolean enableResourceVersion) throws AAIException {
- DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, notificationDepth);
+ DBSerializer serializer = null;
+
+ if(serverBase != null){
+ serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, notificationDepth, serverBase);
+ } else {
+ serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, notificationDepth);
+ }
+
Response response;
Introspector obj;
QueryParser query;
@@ -465,7 +491,7 @@ public class HttpEntry {
}
} else {
FormatFactory ff =
- new FormatFactory(loader, serializer, schemaVersions, basePath + "/");
+ new FormatFactory(loader, serializer, schemaVersions, basePath + "/", serverBase);
Formatter formatter = ff.get(format, params);
result = formatter.output(vertices.stream().map(vertex -> (Object) vertex)
.collect(Collectors.toList())).toString();
@@ -503,7 +529,7 @@ public class HttpEntry {
}
} else {
FormatFactory ff =
- new FormatFactory(loader, serializer, schemaVersions, basePath + "/");
+ new FormatFactory(loader, serializer, schemaVersions, basePath + "/", serverBase);
Formatter formatter = ff.get(format, params);
result = formatter.output(vertices.stream().map(vertex -> (Object) vertex)
.collect(Collectors.toList())).toString();
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java b/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
index 14fb8cb5..7cd0e785 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
@@ -166,6 +166,29 @@ public class DBSerializer {
initBeans();
}
+ public DBSerializer(SchemaVersion version,
+ TransactionalGraphEngine engine,
+ ModelType introspectionType,
+ String sourceOfTruth,
+ int notificationDepth,
+ String serverBase) throws AAIException {
+ this.engine = engine;
+ this.sourceOfTruth = sourceOfTruth;
+ this.introspectionType = introspectionType;
+ this.schemaVersions = (SchemaVersions) SpringContextAware.getBean("schemaVersions");
+ SchemaVersion latestVersion = schemaVersions.getDefaultVersion();
+ this.latestLoader =
+ SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, latestVersion);
+ this.version = version;
+ this.loader =
+ SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, version);
+ this.namedPropNodes = this.latestLoader.getNamedPropNodes();
+ this.baseURL = serverBase;
+ this.currentTimeMillis = System.currentTimeMillis();
+ this.notificationDepth = notificationDepth;
+ initBeans();
+ }
+
private void initBeans() {
// TODO proper spring wiring, but that requires a lot of refactoring so for now we have this
ApplicationContext ctx = SpringContextAware.getApplicationContext();
@@ -1334,7 +1357,7 @@ public class DBSerializer {
Set<Vertex> seen = new HashSet<>();
int depth = 0;
StopWatch.conditionalStart();
- this.dbToObject(obj, v, seen, depth, false, FALSE);
+ this.dbToObject(obj, v, seen, depth, true, FALSE);
dbTimeMsecs += StopWatch.stopIfStarted();
return obj;
@@ -1470,9 +1493,9 @@ public class DBSerializer {
// only for the older apis and the new apis if the edge rule
// is removed will not be seen in the newer version of the API
- String bNodeType = null;
+ String bNodeType;
if (otherV.property(AAIProperties.NODE_TYPE).isPresent()) {
- bNodeType = otherV.property(AAIProperties.NODE_TYPE).value().toString();
+ bNodeType = otherV.value(AAIProperties.NODE_TYPE);
} else {
continue;
}
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 4c37aaa1..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
@@ -28,7 +28,10 @@ import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.logging.LogFormatTools;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
@@ -38,6 +41,7 @@ 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 java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -80,29 +84,25 @@ public class Aggregate extends MultiFormatMapper {
}
public Optional<JsonObject> createPropertiesObject(Vertex v) throws AAIFormatVertexException {
- JsonObject json = new JsonObject();
- Iterator<VertexProperty<Object>> iter = v.properties();
+ try {
+ final Introspector obj =
+ loader.introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
- while (iter.hasNext()) {
- VertexProperty<Object> prop = iter.next();
- if (prop.value() instanceof String) {
- json.addProperty(prop.key(), (String) prop.value());
- } else if (prop.value() instanceof Boolean) {
- json.addProperty(prop.key(), (Boolean) prop.value());
- } else if (prop.value() instanceof Number) {
- json.addProperty(prop.key(), (Number) prop.value());
- } else if (prop.value() instanceof List) {
- Gson gson = new Gson();
- String list = gson.toJson(prop.value());
-
- json.addProperty(prop.key(), list);
- } else {
- // throw exception?
- return null;
+ final List<Vertex> wrapper = new ArrayList<>();
+ wrapper.add(v);
+
+ try {
+ serializer.dbToObject(wrapper, obj, 0, true, "false");
+ } catch (AAIException | UnsupportedEncodingException e) {
+ throw new AAIFormatVertexException(
+ "Failed to format vertex - error while serializing: " + e.getMessage(), e);
}
- }
- return Optional.of(json);
+ final String json = obj.marshal(false);
+ return Optional.of(parser.parse(json).getAsJsonObject());
+ } catch (AAIUnknownObjectException e) {
+ return Optional.empty();
+ }
}
public Optional<JsonObject> createSelectedPropertiesObject(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException {
@@ -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/Format.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java
index f471b3c1..a4a5df2c 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java
@@ -23,7 +23,7 @@ package org.onap.aai.serialization.queryformats;
import org.onap.aai.exceptions.AAIException;
public enum Format {
- graphson, pathed, pathed_resourceversion, id, resource, simple, resource_and_url, console, raw, count, resource_with_sot, state, lifecycle, changes, aggregate;
+ graphson, pathed, pathed_resourceversion, id, resource, simple, resource_and_url, console, raw, count, resource_with_sot, state, lifecycle, changes, aggregate, tree;
public static Format getFormat(String format) throws AAIException {
try {
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java
index 0ae0c5fe..50aa8dd4 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java
@@ -46,6 +46,14 @@ public class FormatFactory {
this.injector = QueryParamInjector.getInstance();
}
+ public FormatFactory(Loader loader, DBSerializer serializer, SchemaVersions schemaVersions, String basePath, String serverBase)
+ throws AAIException {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = new UrlBuilder(loader.getVersion(), serializer, serverBase, schemaVersions, basePath);
+ this.injector = QueryParamInjector.getInstance();
+ }
+
public Formatter get(Format format) throws AAIException {
return get(format, new MultivaluedHashMap<>());
}
@@ -110,6 +118,10 @@ public class FormatFactory {
formatter =
new Formatter(inject(new LifecycleFormat.Builder(loader, serializer, urlBuilder), params).build(format));
break;
+ case tree:
+ formatter = new Formatter(
+ inject(new TreeFormat.Builder(loader, serializer, urlBuilder), params).build());
+ break;
default:
break;
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 b06ef7c3..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
@@ -21,33 +21,47 @@
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;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
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)
- throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
if (input instanceof Vertex) {
+ logger.debug("Formatting vertex object");
return this.getJsonFromVertex((Vertex) input);
} else if (input instanceof Tree) {
+ logger.debug("Formatting tree object");
if (isTree) {
- return this.getRelatedNodesFromTree((Tree<?>) input);
+ return this.getRelatedNodesFromTree((Tree<?>) input, null);
} else {
- return this.getJsonFomTree((Tree<?>) input);
+ return this.getJsonFromTree((Tree<?>) input);
}
} else if (input instanceof Path) {
+ logger.debug("Formatting path object");
return this.getJsonFromPath((Path) input);
} else {
throw new AAIFormatQueryResultFormatNotSupported();
@@ -58,14 +72,17 @@ public abstract class MultiFormatMapper implements FormatMapper {
public Optional<JsonObject> formatObject(Object input, Map<String, List<String>> properties)
throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
if (input instanceof Vertex) {
+ logger.debug("Formatting vertex object with properties map filter");
return this.getJsonFromVertex((Vertex) input, properties);
} else if (input instanceof Tree) {
+ logger.debug("Formatting tree object with properties map filter");
if (isTree) {
- return this.getRelatedNodesFromTree((Tree<?>) input);
+ return this.getRelatedNodesFromTree((Tree<?>) input, properties);
} else {
- return this.getJsonFomTree((Tree<?>) input);
+ return this.getJsonFromTree((Tree<?>) input);
}
} else if (input instanceof Path) {
+ logger.debug("Formatting path object");
return this.getJsonFromPath((Path) input);
} else {
throw new AAIFormatQueryResultFormatNotSupported();
@@ -92,58 +109,275 @@ public abstract class MultiFormatMapper implements FormatMapper {
return Optional.of(jo);
}
- protected Optional<JsonObject> getJsonFomTree(Tree<?> tree) throws AAIFormatVertexException {
-
+ /**
+ * Returns an Optional<JsonObject> object using "nodes" as a wrapper to encapsulate json objects
+ * @param tree
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ protected Optional<JsonObject> getJsonFromTree(Tree<?> tree) throws AAIFormatVertexException {
if (tree.isEmpty()) {
return Optional.of(new JsonObject());
}
+ String nodeIdentifier = "nodes";
JsonObject t = new JsonObject();
- JsonArray ja = this.getNodesArray(tree, "nodes");
+ JsonArray ja = this.getNodesArray(tree, null, nodeIdentifier);
if (ja.size() > 0) {
t.add("nodes", ja);
+ } else {
+ logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier);
}
return Optional.of(t);
}
- protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree) throws AAIFormatVertexException {
+ /**
+ * Returns an Optional<JsonObject> object using "related-nodes" to encapsulate nested json objects.
+ * Primarily intended to be utilized by the "as-tree" query parameter feature
+ * @param tree
+ * @param properties
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree, Map<String, List<String>> properties) throws AAIFormatVertexException {
if (tree.isEmpty()) {
return Optional.of(new JsonObject());
}
+ String nodeIdentifier = "related-nodes";
+
+ // Creating another DS to help with calls in O(1)
+ Map<String, Set<String>> filterPropertiesMap = createFilteredPropertyMap(properties);
JsonObject t = new JsonObject();
- JsonArray ja = this.getNodesArray(tree, "related-nodes");
+ JsonArray ja = this.getNodesArray(tree, filterPropertiesMap, nodeIdentifier);
if (ja.size() > 0) {
t.add("results", ja);
return Optional.of(t);
+ } else {
+ logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier);
}
return Optional.empty();
}
- protected JsonArray getNodesArray(Tree<?> tree, String nodeIdentifier) throws AAIFormatVertexException {
-
+ /**
+ * Returns JsonArray Object populated with nested json wrapped by the nodeIdentifier parameter
+ * @param tree
+ * @param filterPropertiesMap
+ * @param nodeIdentifier
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ protected JsonArray getNodesArray(Tree<?> tree, Map<String, Set<String>> filterPropertiesMap, String nodeIdentifier) throws AAIFormatVertexException {
JsonArray nodes = new JsonArray();
for (Map.Entry<?, ? extends Tree<?>> entry : tree.entrySet()) {
JsonObject me = new JsonObject();
if (entry.getKey() instanceof Vertex) {
Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) entry.getKey());
if (obj.isPresent()) {
- me = obj.get();
+ me = getPropertyFilteredObject(obj, filterPropertiesMap);
} else {
continue;
}
}
- JsonArray ja = this.getNodesArray(entry.getValue(), nodeIdentifier);
+ JsonArray ja = this.getNodesArray(entry.getValue(), filterPropertiesMap, nodeIdentifier);
if (ja.size() > 0) {
me.add(nodeIdentifier, ja);
+ } else {
+ logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier);
}
nodes.add(me);
}
return nodes;
}
+ /**
+ * Returns a Map<String, Set<String>> object through converting given map parameter
+ * @param properties
+ * @return
+ */
+ protected Map<String, Set<String>> createFilteredPropertyMap(Map<String, List<String>> properties) {
+ if (properties == null)
+ return new HashMap<>();
+
+ return properties.entrySet().stream()
+ .map(entry -> {
+ Set<String> newSet = entry.getValue().stream()
+ .map(this::truncateApostrophes)
+ .collect(Collectors.toSet());
+
+ return Pair.of(entry.getKey(), newSet);
+ }
+ ).collect(Collectors.toMap(Pair::getKey, Pair::getValue));
+ }
+
+ /**
+ * Returns a string with it's apostrophes truncated at the start and end.
+ * @param s
+ * @return
+ */
+ protected String truncateApostrophes(String s) {
+ if (s == null || s.isEmpty()) {
+ return s;
+ }
+ if (s.startsWith("'") && s.endsWith("'")) {
+ s = s.substring(1, s.length() - 1);
+ }
+ return s;
+ }
+
+ /**
+ * Filters the given Optional<JsonObject> with the properties under a properties field
+ * or the properties under its respective node type.
+ * @param obj
+ * @param filterPropertiesMap
+ * @return
+ */
+ 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;
+ }
+ }
+ ).orElseGet(JsonObject::new);
+ }
+
+ 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 ImmutableTriple.of(result, nodeType, properties);
+ }
+
+ /**
+ * Returns a JsonObject with filtered properties using "node-type" and "properties"
+ * Used for formats with payloads similar to simple and raw
+ * @param result
+ * @param nodeType
+ * @param properties
+ * @param filterPropertiesMap
+ * @return
+ */
+ private JsonObject filterByNodeTypeAndProperties(JsonObject result, String nodeType, JsonObject properties, Map<String, Set<String>> filterPropertiesMap) {
+ if (result == null || nodeType == null || nodeType.isEmpty() || properties == null || filterPropertiesMap == null) {
+ return result;
+ }
+ if (filterPropertiesMap.containsKey(nodeType)) { // filterPropertiesMap keys are nodeTypes - keys are obtained from the incoming query request
+ Set<String> filterSet = filterPropertiesMap.get(nodeType);
+ JsonObject filteredProperties = new JsonObject();
+ for (String property : filterSet) { // Each nodeType should have a set of properties to be retained in the response
+ if (properties.get(property) != null) {
+ filteredProperties.add(property, properties.get(property));
+ }
+ }
+ result.remove(PROPERTIES_KEY);
+ result.add(PROPERTIES_KEY, filteredProperties);
+ }
+ return result;
+ }
+
+ /**
+ * Returns a JsonObject with its properties filtered
+ * @param result
+ * @param jsonObj
+ * @param filterPropertiesMap
+ * @return
+ */
+ private JsonObject filterByJsonObj(JsonObject result, JsonObject jsonObj, Map<String, Set<String>> filterPropertiesMap) {
+ if (result == null || jsonObj == null || filterPropertiesMap == null) {
+ return result;
+ }
+
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) {
+ String key = mapEntry.getKey();
+ JsonElement value = mapEntry.getValue();
+ JsonObject filteredProperties = new JsonObject();
+ if (value != null && value.isJsonObject() && filterPropertiesMap.containsKey(key)) {
+ JsonObject joProperties = value.getAsJsonObject();
+ Set<String> filterSet = filterPropertiesMap.get(key);
+ for (String property : filterSet) {
+ if (joProperties.get(property) != null) {
+ filteredProperties.add(property, joProperties.get(property));
+ }
+ }
+ result.remove(key);
+ result.add(key, filteredProperties);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns a filtered JsonObject with properties contained in the parameter filterPropertiesMap
+ * @param properties
+ * @param filterPropertiesMap
+ * @return
+ */
+ 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 result = new JsonObject();
+ // clone the object
+ for (Map.Entry<String, JsonElement> mapEntry : jo.entrySet()) {
+ String key = mapEntry.getKey();
+ JsonElement value = mapEntry.getValue();
+ result.add(key, value);
+ }
+
+ // filter the object
+ if (filterPropertiesMap.containsKey(nodeType)) {
+ Set<String> filterSet = filterPropertiesMap.get(nodeType);
+ for (Map.Entry<String, JsonElement> mapEntry : jo.entrySet()) {
+ String key = mapEntry.getKey();
+ if (!filterSet.contains(key)) {
+ result.remove(key);
+ }
+ }
+ }
+ return result;
+ }).orElseGet(JsonObject::new);
+ }
+
@Override
public int parallelThreshold() {
return 100;
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java
index 417f73cd..e21be992 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java
@@ -60,6 +60,7 @@ public final class PathedURL extends MultiFormatMapper {
this.parser = new JsonParser();
this.loader = builder.getLoader();
this.isTree = builder.isTree();
+ this.includeUrl = builder.isIncludeUrl();
}
@Override
@@ -67,11 +68,6 @@ public final class PathedURL extends MultiFormatMapper {
return 20;
}
- public PathedURL includeUrl() {
- this.includeUrl = true;
- return this;
- }
-
@Override
protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java
index a53be6a3..f20ac317 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java
@@ -27,9 +27,7 @@ import com.google.gson.JsonParser;
import java.io.UnsupportedEncodingException;
import java.util.*;
-import java.util.stream.Stream;
-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;
import org.onap.aai.db.props.AAIProperties;
@@ -70,12 +68,15 @@ public class Resource extends MultiFormatMapper {
}
@Override
- protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree) throws AAIFormatVertexException {
+ protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree, Map<String, List<String>> properties) throws AAIFormatVertexException {
if (tree.isEmpty()) {
return Optional.of(new JsonObject());
}
+
+ Map<String, Set<String>> filterPropertiesMap = createFilteredPropertyMap(properties);
+
JsonObject t = new JsonObject();
- JsonArray ja = this.getRelatedNodesArray(tree, "related-nodes");
+ JsonArray ja = this.getRelatedNodesArray(tree, filterPropertiesMap,"related-nodes");
if (ja.size() > 0) {
t.add("results", ja);
return Optional.of(t);
@@ -84,7 +85,7 @@ public class Resource extends MultiFormatMapper {
return Optional.empty();
}
- protected JsonArray getRelatedNodesArray(Tree<?> tree, String nodeIdentifier) throws AAIFormatVertexException {
+ protected JsonArray getRelatedNodesArray(Tree<?> tree, Map<String, Set<String>> filterPropertiesMap, String nodeIdentifier) throws AAIFormatVertexException {
JsonArray nodes = new JsonArray();
if (tree.isEmpty()) {
return nodes;
@@ -97,16 +98,22 @@ public class Resource extends MultiFormatMapper {
obj = this.getJsonFromVertex((Vertex) entry.getKey());
}
if (obj != null && obj.isPresent()) {
- me = obj.get();
+ me = getPropertyFilteredObject(obj, filterPropertiesMap);
} else {
continue;
}
}
- JsonArray ja = this.getRelatedNodesArray(entry.getValue(), nodeIdentifier);
+ JsonArray ja = this.getRelatedNodesArray(entry.getValue(), filterPropertiesMap, nodeIdentifier);
if (ja.size() > 0) {
try {
- me.entrySet().stream().findFirst().get().getValue().getAsJsonObject().add(nodeIdentifier, ja);
+ for (Map.Entry<String, JsonElement> mapEntry : me.entrySet()) {
+ JsonElement value = mapEntry.getValue();
+ if (value != null && value.isJsonObject()) {
+ value.getAsJsonObject().add(nodeIdentifier, ja);
+ }
+ }
} catch(Exception e) {
+ logger.debug("Failed to add related-nodes array: {}", e.getMessage());
throw new AAIFormatVertexException("Failed to add related-nodes array: " + e.getMessage(), e);
}
}
@@ -133,8 +140,22 @@ public class Resource extends MultiFormatMapper {
}
@Override
- protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
- return Optional.empty();
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ JsonObject json = new JsonObject();
+
+ if (this.includeUrl) {
+ json.addProperty("url", this.urlBuilder.pathed(v));
+ }
+ Optional<JsonObject> jsonObject = this.vertexToJsonObject(v);
+ if (jsonObject.isPresent()) {
+ String nodeType = v.<String>value(AAIProperties.NODE_TYPE);
+ Map<String, Set<String>> filterPropertiesMap = createFilteredPropertyMap(properties); // this change is for resource_and_url with/out as-tree. and no as-tree req
+ JsonObject jo = filterProperties(jsonObject, nodeType, filterPropertiesMap);
+ json.add(v.<String>property(AAIProperties.NODE_TYPE).orElse(null), jo);
+ } else {
+ return Optional.empty();
+ }
+ return Optional.of(json);
}
protected Optional<JsonObject> vertexToJsonObject(Vertex v) throws AAIFormatVertexException {
@@ -143,7 +164,7 @@ public class Resource extends MultiFormatMapper {
}
try {
final Introspector obj =
- getLoader().introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
+ getLoader().introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
final List<Vertex> wrapper = new ArrayList<>();
@@ -153,7 +174,7 @@ public class Resource extends MultiFormatMapper {
getSerializer().dbToObject(wrapper, obj, this.depth, this.nodesOnly, "false", isSkipRelatedTo);
} catch (AAIException | UnsupportedEncodingException e) {
throw new AAIFormatVertexException(
- "Failed to format vertex - error while serializing: " + e.getMessage(), e);
+ "Failed to format vertex - error while serializing: " + e.getMessage(), e);
}
final String json = obj.marshal(false);
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
new file mode 100644
index 00000000..d94c4b92
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/TreeFormat.java
@@ -0,0 +1,344 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.serialization.queryformats;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+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;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.serialization.db.DBSerializer;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+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 java.io.UnsupportedEncodingException;
+import java.util.*;
+
+public class TreeFormat extends MultiFormatMapper {
+ 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;
+ protected final UrlBuilder urlBuilder;
+ protected final int depth;
+ protected final boolean nodesOnly;
+
+ protected TreeFormat(Builder builder) {
+ this.urlBuilder = builder.getUrlBuilder();
+ this.loader = builder.getLoader();
+ this.serializer = builder.getSerializer();
+ this.depth = builder.getDepth();
+ this.nodesOnly = builder.isNodesOnly();
+ }
+
+ @Override
+ public int parallelThreshold() {
+ return 100;
+ }
+
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder> {
+
+ protected final Loader loader;
+ protected final DBSerializer serializer;
+ protected final UrlBuilder urlBuilder;
+ protected boolean includeUrl = false;
+ protected boolean nodesOnly = false;
+ protected int depth = 1;
+ protected boolean modelDriven = false;
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ }
+
+ protected Loader getLoader() {
+ return this.loader;
+ }
+
+ protected DBSerializer getSerializer() {
+ return this.serializer;
+ }
+
+ protected UrlBuilder getUrlBuilder() {
+ return this.urlBuilder;
+ }
+
+ public Builder includeUrl() {
+ this.includeUrl = true;
+ return this;
+ }
+
+ public Builder nodesOnly(Boolean nodesOnly) {
+ this.nodesOnly = nodesOnly;
+ return this;
+ }
+
+ public boolean isNodesOnly() {
+ return this.nodesOnly;
+ }
+
+ public Builder depth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public int getDepth() {
+ return this.depth;
+ }
+
+ public boolean isIncludeUrl() {
+ return this.includeUrl;
+ }
+
+ public Builder modelDriven() {
+ this.modelDriven = true;
+ return this;
+ }
+
+ public boolean getModelDriven() {
+ return this.modelDriven;
+ }
+
+ public TreeFormat build() {
+ 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).orElseGet( () -> {
+ TREE_FORMAT_LOGGER.warn("Empty Optional returned by 'formatObjectToJsonArray'");
+ return body;
+ });
+ } catch (AAIFormatVertexException e) {
+ TREE_FORMAT_LOGGER.warn("Failed to format vertex, returning a partial list " + LogFormatTools.getStackTop(e));
+ } catch (AAIFormatQueryResultFormatNotSupported e) {
+ TREE_FORMAT_LOGGER.warn("Failed to format result type of the query " + LogFormatTools.getStackTop(e));
+ }
+ }
+ return body;
+ }
+
+ public Optional<JsonArray> formatObjectToJsonArray(Object input, Map<String, List<String>> properties)
+ throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ JsonArray json = new JsonArray();
+ if (input == null)
+ return Optional.of(json);
+ if (input instanceof Tree) {
+ return this.getJsonArrayFromTree((Tree<Object>) input);
+ } else {
+ throw new AAIFormatQueryResultFormatNotSupported();
+ }
+ }
+
+ protected Optional<JsonArray> getJsonArrayFromTree(Tree<Object> tree) throws AAIFormatVertexException {
+ if (tree.isEmpty()) {
+ return Optional.of(new JsonArray());
+ }
+
+ // DSL Query
+ JsonArray jsonArray = new JsonArray();
+ JsonObject jsonObject = new JsonObject();
+ for (Map.Entry<Object, Tree<Object>> entry : tree.entrySet()) {
+ Object o = entry.getKey();
+
+ // DSL Query
+ 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()) {
+ JsonElement jsonRootElementContents = mapEntry.getValue(); // getting everyObject inside
+ if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) {
+ JsonObject relatedJsonNode = (JsonObject) jsonRootElementContents;
+ addRelatedNodesToJsonObject(
+ jsonRootElementContents.getAsJsonObject(),
+ getRelatedNodes(relatedJsonNode)
+ );
+ }
+ }
+ jsonArray.add(jsonObject);
+ }
+ }
+ }
+ // Gremlin Query
+ else if (o instanceof Vertex) {
+ Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) o);
+ if (obj.isPresent()) {
+ jsonObject = obj.get();
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObject.entrySet()) {
+ JsonElement jsonRootElementContents = mapEntry.getValue();
+ if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) {
+ addRelatedNodesToJsonObject(
+ jsonRootElementContents.getAsJsonObject(),
+ getRelatedNodes(entry.getValue()));
+ }
+ }
+ jsonArray.add(jsonObject);
+ }
+ }
+ }
+ return Optional.of(jsonArray);
+ }
+
+ protected Optional<JsonArray> getRelatedNodes(JsonObject jsonObj) throws AAIFormatVertexException {
+ JsonArray relatedNodes = new JsonArray();
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) {
+ String s = mapEntry.getKey();
+ JsonElement jsonRootElementContents = jsonObj.get(s);
+ if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) {
+ JsonObject relatedJsonNode = jsonRootElementContents.getAsJsonObject();
+ addRelatedNodesToJsonObject(
+ relatedJsonNode,
+ this.getRelatedNodes(relatedJsonNode)
+ );
+ relatedNodes.add(relatedJsonNode);
+ }
+ }
+ return Optional.of(relatedNodes);
+ }
+
+ protected Optional<JsonArray> getRelatedNodes(Tree<Object> tree) throws AAIFormatVertexException {
+ JsonArray relatedNodes = new JsonArray();
+ for (Map.Entry<Object, Tree<Object>> entry : tree.entrySet()) {
+ Object o = entry.getKey();
+
+ if (o instanceof Vertex) {
+ 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.
+ * The fields returned are to record the time stamp of the creation/modification of the object, the user responsible
+ * for
+ * the change, and the last http method performed on the object.
+ *
+ * @param v
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
+
+ JsonObject json = new JsonObject();
+
+ Optional<JsonObject> jsonObject = this.vertexToJsonObject(v);
+ if (jsonObject.isPresent()) {
+ json.add(v.<String>property(AAIProperties.NODE_TYPE).orElse(null), jsonObject.get());
+ } else {
+ return Optional.empty();
+ }
+ return Optional.of(json);
+ }
+
+ protected Optional<JsonObject> vertexToJsonObject(Vertex v) throws AAIFormatVertexException {
+ try {
+ final Introspector obj =
+ getLoader().introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
+
+ final List<Vertex> wrapper = new ArrayList<>();
+
+ wrapper.add(v);
+
+ try {
+ getSerializer().dbToObject(wrapper, obj, this.depth, this.nodesOnly, "false");
+ } catch (AAIException | UnsupportedEncodingException e) {
+ throw new AAIFormatVertexException(
+ "Failed to format vertex - error while serializing: " + e.getMessage(), e);
+ }
+
+ final String json = obj.marshal(false);
+
+ return Optional.of(getParser().parse(json).getAsJsonObject());
+ } catch (AAIUnknownObjectException e) {
+ return Optional.empty();
+ }
+ }
+
+ private Loader getLoader() {
+ return loader;
+ }
+
+ private DBSerializer getSerializer() {
+ return serializer;
+ }
+
+ private JsonParser getParser() {
+ return parser;
+ }
+
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/UrlBuilder.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/UrlBuilder.java
index 9da82fe0..2d37f1b4 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/UrlBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/UrlBuilder.java
@@ -54,10 +54,14 @@ public class UrlBuilder {
}
public UrlBuilder(SchemaVersion version, DBSerializer serializer, String serverBase, SchemaVersions schemaVersions,
- String basePath) {
+ String basePath) throws AAIException {
this.serializer = serializer;
this.version = version;
- this.serverBase = serverBase;
+ if(serverBase == null){
+ this.serverBase = getServerBase();
+ } else {
+ this.serverBase = serverBase;
+ }
this.schemaVersions = schemaVersions;
if (!basePath.endsWith("/")) {
this.basePath = basePath + "/";
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/main/java/org/onap/aai/util/RestController.java b/aai-core/src/main/java/org/onap/aai/util/RestController.java
index 8527ffe5..433458ac 100644
--- a/aai-core/src/main/java/org/onap/aai/util/RestController.java
+++ b/aai-core/src/main/java/org/onap/aai/util/RestController.java
@@ -43,7 +43,7 @@ import org.onap.aai.exceptions.AAIException;
public class RestController implements RestControllerInterface {
private static final String TARGET_NAME = "AAI";
- private static Logger LOGGER = LoggerFactory.getLogger(RestController.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class);
private static Client client = null;
@@ -85,10 +85,6 @@ public class RestController implements RestControllerInterface {
public static final String REST_APIPATH_LOGICALLINKS = "network/logical-links/";
public static final String REST_APIPATH_LOGICALLINK = "network/logical-links/logical-link/";
- public RestController() throws AAIException {
- this.initRestClient();
- }
-
public RestController(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws AAIException {
this.initRestClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
}
@@ -97,22 +93,6 @@ public class RestController implements RestControllerInterface {
*
* @throws AAIException the AAI exception
*/
- public void initRestClient() throws AAIException {
- if (client == null) {
- try {
- client = getHttpsAuthClient();
- } catch (KeyManagementException e) {
- throw new AAIException("AAI_7117", "KeyManagementException in REST call to DB: " + e.toString());
- } catch (Exception e) {
- throw new AAIException("AAI_7117", " Exception in REST call to DB: " + e.toString());
- }
- }
- }
- /**
- * Inits the rest client.
- *
- * @throws AAIException the AAI exception
- */
public void initRestClient(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws AAIException {
if (client == null) {
try {
@@ -355,6 +335,42 @@ public class RestController implements RestControllerInterface {
+ cres.getEntity(String.class));
}
}
+
+ /**
+ * Put.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param sourceID the source ID
+ * @param transId the trans id
+ * @param path the path
+ * @param apiVersion version number
+ * @throws AAIException the AAI exception
+ */
+ public <T> void Put(T t, String sourceID, String transId, String path, String apiVersion)
+ throws AAIException {
+ String methodName = "Put";
+ String url = "";
+ transId += ":" + UUID.randomUUID().toString();
+
+ LOGGER.debug(methodName + " start");
+
+ url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
+
+ ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
+ .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
+ .put(ClientResponse.class);
+
+ // System.out.println("cres.tostring()="+cres.toString());
+
+ int statuscode = cres.getStatus();
+ if (statuscode >= 200 && statuscode <= 299) {
+ LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
+ } else {
+ throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
+ + cres.getEntity(String.class));
+ }
+ }
public void Delete(String sourceID, String transId, String path) throws AAIException {
Delete(sourceID, transId, path, AAIConstants.AAI_RESOURCES_PORT);
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-core/src/test/java/org/onap/aai/logging/CustomLogPatternLayoutTest.java b/aai-core/src/test/java/org/onap/aai/logging/CustomLogPatternLayoutTest.java
deleted file mode 100644
index 250cdda8..00000000
--- a/aai-core/src/test/java/org/onap/aai/logging/CustomLogPatternLayoutTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 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.logging;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class CustomLogPatternLayoutTest {
-
- /**
- * Test null when defaultConverterMap doesn't have corresponding entry.
- */
- @Test
- public void testNull() {
- String s = CustomLogPatternLayout.defaultConverterMap.get("z");
- assertFalse("Entry not found for key 'z'", CNName.class.getName().equals(s));
- }
-
- /**
- * Test defaultConverterMap when valid entry exists.
- */
- @Test
- public void testEntryFor_Z() {
- CustomLogPatternLayout layout = new CustomLogPatternLayout();
- String s = CustomLogPatternLayout.defaultConverterMap.get("z");
- assertTrue("Entry not found for key 'z'", CNName.class.getName().equals(s));
- }
-
-}
diff --git a/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializerTest.java b/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializerTest.java
index dd4454d5..511b2118 100644
--- a/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializerTest.java
+++ b/aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializerTest.java
@@ -616,13 +616,30 @@ public class DbSerializerTest extends AAISetup {
public void getVertexPropertiesTest() throws AAIException, UnsupportedEncodingException {
engine.startTransaction();
- Vertex cr =
- engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
+ Vertex gvnf = engine.tx().addVertex("aai-node-type", "generic-vnf", "vnf-id", "myvnf", "aai-uri",
+ "/network/generic-vnfs/generic-vnf/myvnf",
+ AAIProperties.AAI_UUID, UUID.randomUUID().toString(),
+ AAIProperties.CREATED_TS, 123L,
+ AAIProperties.SOURCE_OF_TRUTH, "sot",
+ AAIProperties.RESOURCE_VERSION, "123",
+ AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot",
+ AAIProperties.LAST_MOD_TS, 333L);
+ Vertex vnfc = engine.tx().addVertex("aai-node-type", "vnfc", "vnfc-name", "a-name", "aai-uri",
+ "/network/vnfcs/vnfc/a-name",
+ AAIProperties.AAI_UUID, UUID.randomUUID().toString(),
+ AAIProperties.CREATED_TS, 123L,
+ AAIProperties.SOURCE_OF_TRUTH, "sot",
+ AAIProperties.RESOURCE_VERSION, "123",
+ AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot",
+ AAIProperties.LAST_MOD_TS, 333L);
+
+ edgeSer.addEdge(engine.tx().traversal(), gvnf, vnfc);
+
+ Introspector vnf = dbser.getVertexProperties(gvnf);
+ assertEquals("generic-vnf", vnf.getDbName());
+ assertEquals("myvnf", vnf.getValue("vnf-id"));
- Introspector crIntro = dbser.getVertexProperties(cr);
- assertEquals("cloud-region", crIntro.getDbName());
- assertEquals("me", crIntro.getValue("cloud-owner"));
- assertEquals("123", crIntro.getValue("cloud-region-id"));
+ assertFalse(vnf.marshal(false).contains("relationship-list"));
}
diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java
index a59b1147..0904ceb3 100644
--- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java
+++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java
@@ -80,8 +80,8 @@ public class MultiFormatTest extends AAISetup {
"{\"path\":[{\"resource-type\":\"generic-vnf\"},{\"resource-type\":\"vserver\"},{\"resource-type\":\"pserver\"},{\"resource-type\":\"complex\"}]}")
.getAsJsonObject();
private JsonObject expectedAsTreeWithResourceFormat = new JsonParser().parse(
- "{\"results\":[{\"generic-vnf\":{\"vnf-id\":\"vnf-id-1\",\"vnf-name\":\"vnf-name-1\",\"related-nodes\":[{\"vserver\":{\"vserver-id\":\"vserver-id-1\",\"vserver-name\":\"vserver-name-1\",\"related-nodes\":[{\"pserver\":{\"hostname\":\"hostname-1\"}}]}},{\"pserver\":{\"hostname\":\"hostname-2\",\"related-nodes\":[{\"complex\":{\"physical-location-id\":\"physical-location-id-2\",\"country\":\"US\"}}]}}]}}]}")
- .getAsJsonObject();
+ "{\"results\":[{\"generic-vnf\":{\"vnf-id\":\"vnf-id-1\",\"vnf-name\":\"vnf-name-1\",\"related-nodes\":[{\"vserver\":{\"vserver-id\":\"vserver-id-1\",\"vserver-name\":\"vserver-name-1\",\"related-nodes\":[{\"pserver\":{\"hostname\":\"hostname-1\"}}]}},{\"pserver\":{\"hostname\":\"hostname-2\",\"related-nodes\":[{\"complex\":{\"physical-location-id\":\"physical-location-id-2\",\"country\":\"US\"}}]}}]}}]}")
+ .getAsJsonObject();
private JsonObject expectedAsTreeWithSimpleFormat = new JsonParser().parse(
"{\"results\":[{\"id\":\"0\",\"node-type\":\"generic-vnf\",\"url\":null,\"properties\":{\"vnf-id\":\"vnf-id-1\",\"vnf-name\":\"vnf-name-1\"},\"related-to\":[{\"id\":\"1\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"vserver\",\"url\":null},{\"id\":\"5\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"pserver\",\"url\":null}],\"related-nodes\":[{\"id\":\"1\",\"node-type\":\"vserver\",\"url\":null,\"properties\":{\"vserver-id\":\"vserver-id-1\",\"vserver-name\":\"vserver-name-1\"},\"related-to\":[{\"id\":\"0\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"generic-vnf\",\"url\":null},{\"id\":\"2\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"pserver\",\"url\":null}],\"related-nodes\":[{\"id\":\"2\",\"node-type\":\"pserver\",\"url\":null,\"properties\":{\"hostname\":\"hostname-1\"},\"related-to\":[{\"id\":\"1\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"vserver\",\"url\":null},{\"id\":\"3\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\",\"node-type\":\"complex\",\"url\":null}]}]},{\"id\":\"5\",\"node-type\":\"pserver\",\"url\":null,\"properties\":{\"hostname\":\"hostname-2\"},\"related-to\":[{\"id\":\"0\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"generic-vnf\",\"url\":null},{\"id\":\"6\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\",\"node-type\":\"complex\",\"url\":null}],\"related-nodes\":[{\"id\":\"6\",\"node-type\":\"complex\",\"url\":null,\"properties\":{\"physical-location-id\":\"physical-location-id-2\",\"country\":\"US\"},\"related-to\":[{\"id\":\"5\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\",\"node-type\":\"pserver\",\"url\":null}]}]}]}]}")
.getAsJsonObject();
diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java
new file mode 100644
index 00000000..199939ed
--- /dev/null
+++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/PathedURLTest.java
@@ -0,0 +1,167 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.serialization.queryformats;
+
+import com.google.gson.JsonObject;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.aai.AAISetup;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.serialization.db.DBSerializer;
+import org.onap.aai.serialization.db.EdgeSerializer;
+import org.onap.aai.serialization.engines.JanusGraphDBEngine;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+import org.onap.aai.setup.SchemaVersion;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.Optional;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
+public class PathedURLTest extends AAISetup {
+
+ @Mock
+ private UrlBuilder urlBuilder;
+
+ private Graph graph;
+ private TransactionalGraphEngine dbEngine;
+ private Loader loader;
+ private PathedURL pathedURL;
+ private final ModelType factoryType = ModelType.MOXY;
+
+ @Autowired
+ private EdgeSerializer rules;
+
+ private SchemaVersion version;
+ private Vertex pserver;
+ private Vertex complex;
+ private DBSerializer serializer;
+
+ @Before
+ public void setUp() throws Exception {
+
+ version = schemaVersions.getDefaultVersion();
+
+ MockitoAnnotations.initMocks(this);
+
+ graph = TinkerGraph.open();
+
+ Vertex pserver1 =
+ graph.addVertex(
+ T.label, "pserver",
+ T.id, "2",
+ "aai-node-type", "pserver",
+ "hostname", "hostname-1",
+ "resource-version", System.currentTimeMillis()
+ );
+
+ Vertex complex1 = graph.addVertex(T.label, "complex", T.id, "3", "aai-node-type", "complex",
+ "physical-location-id", "physical-location-id-1", "country", "US");
+
+ GraphTraversalSource g = graph.traversal();
+ rules.addEdge(g, pserver1, complex1);
+
+ pserver = pserver1;
+ complex = complex1;
+
+ System.setProperty("AJSC_HOME", ".");
+ System.setProperty("BUNDLECONFIG_DIR", "src/test/resources/bundleconfig-local");
+
+ createLoaderEngineSetup();
+ }
+
+ private void createLoaderEngineSetup() throws AAIException {
+
+ if (loader == null) {
+ loader = loaderFactory.createLoaderForVersion(factoryType, version);
+ dbEngine = spy(new JanusGraphDBEngine(QueryStyle.TRAVERSAL, loader));
+ serializer = new DBSerializer(version, dbEngine, factoryType, "Junit");
+
+ TransactionalGraphEngine.Admin spyAdmin = spy(dbEngine.asAdmin());
+
+ when(dbEngine.tx()).thenReturn(graph);
+ when(dbEngine.asAdmin()).thenReturn(spyAdmin);
+
+ when(spyAdmin.getReadOnlyTraversalSource())
+ .thenReturn(graph.traversal().withStrategies(ReadOnlyStrategy.instance()));
+ when(spyAdmin.getTraversalSource()).thenReturn(graph.traversal());
+ }
+ }
+
+ @Test
+ public void testPathedUrlReturnsResourceVersionWhenSet() throws AAIFormatVertexException, AAIException {
+
+ pathedURL = new PathedURL.Builder(loader, serializer, urlBuilder).includeUrl().build();
+ when(urlBuilder.pathed(pserver)).thenReturn("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1");
+ Optional<JsonObject> jsonObjectOptional = pathedURL.getJsonFromVertex(pserver);
+
+ if(!jsonObjectOptional.isPresent()){
+ fail("Expecting an json object returned from pathed url but returned none");
+ }
+
+ JsonObject pserverObject = jsonObjectOptional.get();
+
+ assertNotNull("Expecting the pserver object to contain resource type", pserverObject.get("resource-type"));
+ assertThat(pserverObject.get("resource-type").getAsString(), CoreMatchers.is("pserver"));
+ assertNotNull("Expecting the pserver object to contain resource link", pserverObject.get("resource-link"));
+ assertThat(pserverObject.get("resource-link").getAsString(), CoreMatchers.is("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1"));
+ assertNotNull("Expecting the pserver object to contain resource version", pserverObject.get("resource-version"));
+ }
+
+ @Test
+ public void testPathedUrlReturnsResourceVersionWhenIncludeUrlIsNotSet() throws AAIFormatVertexException, AAIException {
+
+ pathedURL = new PathedURL.Builder(loader, serializer, urlBuilder).build();
+ when(urlBuilder.pathed(pserver)).thenReturn("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1");
+ Optional<JsonObject> jsonObjectOptional = pathedURL.getJsonFromVertex(pserver);
+
+ if(!jsonObjectOptional.isPresent()){
+ fail("Expecting an json object returned from pathed url but returned none");
+ }
+
+ JsonObject pserverObject = jsonObjectOptional.get();
+
+ assertNotNull("Expecting the pserver object to contain resource type", pserverObject.get("resource-type"));
+ assertThat(pserverObject.get("resource-type").getAsString(), CoreMatchers.is("pserver"));
+ assertNotNull("Expecting the pserver object to contain resource link", pserverObject.get("resource-link"));
+ assertThat(pserverObject.get("resource-link").getAsString(), CoreMatchers.is("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1"));
+ assertNull("Expecting the pserver object to not contain resource version", pserverObject.get("resource-version"));
+ }
+}
diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/ResourceFormatTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/ResourceFormatTest.java
index a891230c..781656e1 100644
--- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/ResourceFormatTest.java
+++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/ResourceFormatTest.java
@@ -126,7 +126,7 @@ public class ResourceFormatTest extends AAISetup {
createLoaderEngineSetup();
serializer = new DBSerializer(schemaVersions.getAppRootVersion(), dbEngine, factoryType, "Junit");
- FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath);
+ FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath, "https://localhost:8447/aai/");
MultivaluedMap mvm = new MultivaluedHashMap();
mvm.add("depth", "0");
Formatter formatter = ff.get(Format.resource, mvm);
diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java
index 886a660b..3b356178 100644
--- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java
+++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java
@@ -131,7 +131,7 @@ public class SimpleFormatTest extends AAISetup {
createLoaderEngineSetup();
serializer = new DBSerializer(schemaVersions.getRelatedLinkVersion(), dbEngine, factoryType, "Junit");
- FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath);
+ FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath, "https://localhost:8447/aai/");
MultivaluedMap mvm = new MultivaluedHashMap();
mvm.add("depth", "0");
Formatter formatter = ff.get(Format.simple, mvm);
diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/utils/UrlBuilderTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/utils/UrlBuilderTest.java
index 08d29cd3..d19ed1a7 100644
--- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/utils/UrlBuilderTest.java
+++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/utils/UrlBuilderTest.java
@@ -34,6 +34,7 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.onap.aai.AAISetup;
+import org.onap.aai.exceptions.AAIException;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
import org.onap.aai.setup.SchemaVersion;
@@ -58,7 +59,7 @@ public class UrlBuilderTest extends AAISetup {
}
@Test
- public void v11Pathed() throws AAIFormatVertexException {
+ public void v11Pathed() throws AAIFormatVertexException, AAIException {
SchemaVersion version = new SchemaVersion("v11");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.pathed(v);
@@ -68,7 +69,7 @@ public class UrlBuilderTest extends AAISetup {
}
@Test
- public void v11Id() {
+ public void v11Id() throws AAIException {
SchemaVersion version = new SchemaVersion("v11");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.id(v);
@@ -78,7 +79,7 @@ public class UrlBuilderTest extends AAISetup {
}
@Test
- public void beforeV11Pathed() throws AAIFormatVertexException {
+ public void beforeV11Pathed() throws AAIFormatVertexException, AAIException {
SchemaVersion version = new SchemaVersion("v10");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.pathed(v);
@@ -88,7 +89,7 @@ public class UrlBuilderTest extends AAISetup {
}
@Test
- public void beforeV11Id() {
+ public void beforeV11Id() throws AAIException {
SchemaVersion version = new SchemaVersion("v10");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.id(v);
diff --git a/aai-core/src/test/resources/onap/oxm/v10/aai_oxm_v10.xml b/aai-core/src/test/resources/onap/oxm/v10/aai_oxm_v10.xml
index 71ab3dd5..ae66e211 100644
--- a/aai-core/src/test/resources/onap/oxm/v10/aai_oxm_v10.xml
+++ b/aai-core/src/test/resources/onap/oxm/v10/aai_oxm_v10.xml
@@ -141,6 +141,11 @@
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
diff --git a/aai-core/src/test/resources/onap/oxm/v11/aai_oxm_v11.xml b/aai-core/src/test/resources/onap/oxm/v11/aai_oxm_v11.xml
index 490fd7b5..8094f07e 100644
--- a/aai-core/src/test/resources/onap/oxm/v11/aai_oxm_v11.xml
+++ b/aai-core/src/test/resources/onap/oxm/v11/aai_oxm_v11.xml
@@ -142,6 +142,11 @@
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
diff --git a/aai-core/src/test/resources/onap/oxm/v12/aai_oxm_v12.xml b/aai-core/src/test/resources/onap/oxm/v12/aai_oxm_v12.xml
index 33f8f17d..275e8872 100644
--- a/aai-core/src/test/resources/onap/oxm/v12/aai_oxm_v12.xml
+++ b/aai-core/src/test/resources/onap/oxm/v12/aai_oxm_v12.xml
@@ -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
-
+
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.
@@ -138,6 +138,11 @@
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
diff --git a/aai-core/src/test/resources/onap/oxm/v13/aai_oxm_v13.xml b/aai-core/src/test/resources/onap/oxm/v13/aai_oxm_v13.xml
index 1a20b993..930c35c2 100644
--- a/aai-core/src/test/resources/onap/oxm/v13/aai_oxm_v13.xml
+++ b/aai-core/src/test/resources/onap/oxm/v13/aai_oxm_v13.xml
@@ -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
-
+
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.
@@ -138,6 +138,11 @@
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
diff --git a/aai-core/src/test/resources/onap/oxm/v14/aai_oxm_v14.xml b/aai-core/src/test/resources/onap/oxm/v14/aai_oxm_v14.xml
index 08a6cd52..8436fac2 100644
--- a/aai-core/src/test/resources/onap/oxm/v14/aai_oxm_v14.xml
+++ b/aai-core/src/test/resources/onap/oxm/v14/aai_oxm_v14.xml
@@ -139,6 +139,11 @@
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>