summaryrefslogtreecommitdiffstats
path: root/aai-traversal/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'aai-traversal/src/main/java')
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java2116
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java536
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/util/GenericQueryBuilder.java114
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/util/NodesQueryBuilder.java106
4 files changed, 1523 insertions, 1349 deletions
diff --git a/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java b/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java
index 0221d8a..a8f0153 100644
--- a/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java
+++ b/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java
@@ -37,6 +37,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilderException;
import javax.xml.bind.JAXBException;
+import org.apache.commons.lang3.StringUtils;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
@@ -75,7 +76,7 @@ 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.SchemaVersions;
-import org.onap.aai.util.StoreNotificationEvent;
+import org.onap.aai.util.NodesQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import com.att.eelf.configuration.EELFLogger;
@@ -86,1068 +87,1065 @@ import edu.emory.mathcs.backport.java.util.Collections;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
-import com.jcabi.log.Logger;
+import org.onap.aai.util.GenericQueryBuilder;
-/**
- * Database Mapping class which acts as the middle man between the REST interface objects
- * for the Search namespace
+/**
+ * Database Mapping class which acts as the middle man between the REST interface objects for the
+ * Search namespace
+ *
*/
public class SearchGraph {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchGraph.class);
-
- private LoaderFactory loaderFactory;
-
- private EdgeIngestor edgeIngestor;
-
- private SchemaVersions schemaVersions;
-
- @Autowired
- public SearchGraph(LoaderFactory loaderFactory, EdgeIngestor edgeIngestor, SchemaVersions schemaVersions){
- this.loaderFactory = loaderFactory;
- this.edgeIngestor = edgeIngestor;
- this.schemaVersions = schemaVersions;
- }
- /**
- * Get the search result based on the includeNodeType and depth provided.
- *
- * @param fromAppId the from app id
- * @param transId the trans id
- * @param startNodeType the start node type
- * @param startNodeKeyParams the start node key params
- * @param includeNodeTypes the include node types
- * @param depth the depth
- * @param aaiExtMap the aai ext map
- * @return Response
- * @throws AAIException the AAI exception
- */
- public Response runGenericQuery (
- HttpHeaders headers,
- String startNodeType,
- List <String> startNodeKeyParams,
- List <String> includeNodeTypes,
- final int depth,
- TransactionalGraphEngine dbEngine,
- Loader loader,
- UrlBuilder urlBuilder) throws AAIException {
- Response response = null;
- boolean success = true;
- String result = "";
- try {
- dbEngine.startTransaction();
-
- if( startNodeType == null ){
- throw new AAIException("AAI_6120", "null start-node-type passed to the generic query");
- }
-
- if( startNodeKeyParams == null ){
- throw new AAIException("AAI_6120", "no key param passed to the generic query");
- }
-
- if( includeNodeTypes == null ){
- throw new AAIException("AAI_6120", "no include params passed to the generic query");
- }
-
- if (depth > 6) {
- throw new AAIException("AAI_6120", "The maximum depth supported by the generic query is 6");
- }
- final QueryBuilder queryBuilder;
-
- // there is an issue with service-instance - it is a unique node but still dependent
- // for now query it directly without attempting to craft a valid URI
- if (startNodeType.equalsIgnoreCase("service-instance") && startNodeKeyParams.size() == 1) {
- Introspector obj = loader.introspectorFromName(startNodeType);
- // Build a hash with keys to uniquely identify the start Node
- String keyName = null;
- String keyValue = null;
-
- QueryBuilder builder = dbEngine.getQueryBuilder().getVerticesByIndexedProperty(AAIProperties.NODE_TYPE, "service-instance");
- for( String keyData : startNodeKeyParams ){
- int colonIndex = keyData.indexOf(":");
- if( colonIndex <= 0 ){
- throw new AAIException("AAI_6120", "Bad key param passed in: [" + keyData + "]");
- }
- else {
- keyName = keyData.substring(0, colonIndex).split("\\.")[1];
- keyValue = keyData.substring(colonIndex + 1);
- builder.getVerticesByProperty(keyName, keyValue);
- }
- }
-
- queryBuilder = builder;
- } else {
- URI uri = craftUriFromQueryParams(loader, startNodeType, startNodeKeyParams);
- queryBuilder = dbEngine.getQueryBuilder().createQueryFromURI(uri).getQueryBuilder();
- }
- List<Vertex> results = queryBuilder.toList();
- if( results.isEmpty()){
- throw new AAIException("AAI_6114", "No Node of type " +
- startNodeType +
- " found for properties: " +
- startNodeKeyParams.toString());
- } else if (results.size() > 1) {
- String detail = "More than one Node found by getUniqueNode for params: " + startNodeKeyParams.toString() + "\n";
- throw new AAIException("AAI_6112", detail);
- }
-
- Vertex startNode = results.get(0);
-
- Collection <Vertex> ver = new HashSet <>();
- List<Vertex> queryResults = new ArrayList<>();
- GraphTraversalSource traversalSource = dbEngine.asAdmin().getReadOnlyTraversalSource();
- GraphTraversal<Vertex, Vertex> traversal;
- if (includeNodeTypes.contains(startNodeType) || depth == 0 || includeNodeTypes.contains("all") )
- ver.add(startNode);
-
- // Now look for a node of includeNodeType within a given depth
- traversal = traversalSource.withSideEffect("x", ver).V(startNode)
- .times(depth).repeat(__.both().store("x")).cap("x").unfold();
-
- if (!includeNodeTypes.contains("all")) {
- traversal.where(__.has(AAIProperties.NODE_TYPE, P.within(includeNodeTypes)));
- }
- queryResults = traversal.toList();
-
-
- if( queryResults.isEmpty()){
- LOGGER.warn("No nodes found - apipe was null/empty");
- }
- else {
-
- Introspector searchResults = createSearchResults(loader, urlBuilder, queryResults);
-
- String outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
- org.onap.aai.introspection.MarshallerProperties properties = new org.onap.aai.introspection.MarshallerProperties.Builder(
- org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build();
-
- result = searchResults.marshal(properties);
- response = Response.ok().entity(result).build();
-
- LOGGER.debug(ver.size() + " node(s) traversed, " + queryResults.size() + " found");
- }
- success = true;
- } catch (AAIException e) {
- success = false;
- throw e;
- } catch (Exception e) {
- success = false;
- throw new AAIException("AAI_5105", e);
- } finally {
- if (dbEngine != null) {
- if (success) {
- dbEngine.commit();
- } else {
- dbEngine.rollback();
- }
- }
-
- }
-
- return response;
- }
-
- private URI craftUriFromQueryParams(Loader loader, String startNodeType, List<String> startNodeKeyParams) throws UnsupportedEncodingException, IllegalArgumentException, UriBuilderException, AAIException {
- Introspector relationship = loader.introspectorFromName("relationship");
-
- relationship.setValue("related-to", startNodeType);
- List<Object> relationshipDataList = relationship.getValue("relationship-data");
-
- for( String keyData : startNodeKeyParams ){
- int colonIndex = keyData.indexOf(":");
- if( colonIndex <= 0 ){
- throw new AAIException("AAI_6120", "Bad key param passed in: [" + keyData + "]");
- }
- else {
- Introspector data = loader.introspectorFromName("relationship-data");
- data.setValue("relationship-key", keyData.substring(0, colonIndex));
- data.setValue("relationship-value", keyData.substring(colonIndex + 1));
- relationshipDataList.add(data.getUnderlyingObject());
- }
- }
-
- RelationshipToURI parser = new RelationshipToURI(loader, relationship);
-
- return parser.getUri();
- }
-
- /**
- * Run nodes query.
- *
- * @param fromAppId the from app id
- * @param transId the trans id
- * @param targetNodeType the target node type
- * @param edgeFilterParams the edge filter params
- * @param filterParams the filter params
- * @param aaiExtMap the aai ext map
- * @return Response
- * @throws AAIException the AAI exception
- */
- public Response runNodesQuery (
- HttpHeaders headers,
- String targetNodeType,
- List <String> edgeFilterParams,
- List <String> filterParams,
- TransactionalGraphEngine dbEngine,
- Loader loader,
- UrlBuilder urlBuilder) throws AAIException {
-
- Response response = null;
- boolean success = true;
+ private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchGraph.class);
+
+ private LoaderFactory loaderFactory;
+
+ private EdgeIngestor edgeIngestor;
+
+ private SchemaVersions schemaVersions;
+
+ @Autowired
+ public SearchGraph(LoaderFactory loaderFactory, EdgeIngestor edgeIngestor, SchemaVersions schemaVersions) {
+ this.loaderFactory = loaderFactory;
+ this.edgeIngestor = edgeIngestor;
+ this.schemaVersions = schemaVersions;
+ }
+
+ /**
+ * Get the search result based on the includeNodeType and depth provided.
+ *
+ * @param genericQueryBuilder
+ */
+ public Response runGenericQuery(GenericQueryBuilder genericQueryBuilder) throws AAIException {
+ Response response = null;
+ boolean success = true;
+ String result = "";
+ try {
+ genericQueryBuilder.getDbEngine().startTransaction();
+
+ if (genericQueryBuilder.getStartNodeType() == null) {
+ throw new AAIException("AAI_6120", "null start-node-type passed to the generic query");
+ }
+
+ if (genericQueryBuilder.getStartNodeKeyParams() == null) {
+ throw new AAIException("AAI_6120", "no key param passed to the generic query");
+ }
+
+ if (genericQueryBuilder.getIncludeNodeTypes() == null) {
+ throw new AAIException("AAI_6120", "no include params passed to the generic query");
+ }
+
+ if (genericQueryBuilder.getDepth() > 6) {
+ throw new AAIException("AAI_6120", "The maximum depth supported by the generic query is 6");
+ }
+ final QueryBuilder queryBuilder;
+
+ // there is an issue with service-instance - it is a unique node but still dependent
+ // for now query it directly without attempting to craft a valid URI
+ if (genericQueryBuilder.getStartNodeType().equalsIgnoreCase("service-instance")
+ && genericQueryBuilder.getStartNodeKeyParams().size() == 1) {
+ Introspector obj =
+ genericQueryBuilder.getLoader().introspectorFromName(genericQueryBuilder.getStartNodeType());
+ // Build a hash with keys to uniquely identify the start Node
+ String keyName = null;
+ String keyValue = null;
+
+ QueryBuilder builder = genericQueryBuilder.getDbEngine().getQueryBuilder()
+ .getVerticesByIndexedProperty(AAIProperties.NODE_TYPE, "service-instance");
+ for (String keyData : genericQueryBuilder.getStartNodeKeyParams()) {
+ int colonIndex = keyData.indexOf(":");
+ if (colonIndex <= 0) {
+ throw new AAIException("AAI_6120", "Bad key param passed in: [" + keyData + "]");
+ } else {
+ keyName = keyData.substring(0, colonIndex).split("\\.")[1];
+ keyValue = keyData.substring(colonIndex + 1);
+ builder.getVerticesByProperty(keyName, keyValue);
+ }
+ }
+
+ queryBuilder = builder;
+ } else {
+ URI uri = craftUriFromQueryParams(genericQueryBuilder.getLoader(),
+ genericQueryBuilder.getStartNodeType(), genericQueryBuilder.getStartNodeKeyParams());
+ queryBuilder =
+ genericQueryBuilder.getDbEngine().getQueryBuilder().createQueryFromURI(uri).getQueryBuilder();
+ }
+ List<Vertex> results = queryBuilder.toList();
+ if (results.isEmpty()) {
+ String errorMessage = String.format("No Node of type %s ", genericQueryBuilder.getStartNodeType(),
+ " found for properties: %s", genericQueryBuilder.getStartNodeKeyParams().toString());
+ throw new AAIException("AAI_6114", errorMessage);
+ } else if (results.size() > 1) {
+ String detail = "More than one Node found by getUniqueNode for params: "
+ + genericQueryBuilder.getStartNodeKeyParams().toString() + "\n";
+ throw new AAIException("AAI_6112", detail);
+ }
+
+ Vertex startNode = results.get(0);
+
+ Collection<Vertex> ver = new HashSet<>();
+ List<Vertex> queryResults = new ArrayList<>();
+ GraphTraversalSource traversalSource =
+ genericQueryBuilder.getDbEngine().asAdmin().getReadOnlyTraversalSource();
+ GraphTraversal<Vertex, Vertex> traversal;
+ if (genericQueryBuilder.getIncludeNodeTypes().contains(genericQueryBuilder.getStartNodeType())
+ || genericQueryBuilder.getDepth() == 0 || genericQueryBuilder.getIncludeNodeTypes().contains("all"))
+ ver.add(startNode);
+
+ // Now look for a node of includeNodeType within a given depth
+ traversal = traversalSource.withSideEffect("x", ver).V(startNode).times(genericQueryBuilder.getDepth())
+ .repeat(__.both().store("x")).cap("x").unfold();
+
+ if (!genericQueryBuilder.getIncludeNodeTypes().contains("all")) {
+ traversal.where(__.has(AAIProperties.NODE_TYPE, P.within(genericQueryBuilder.getIncludeNodeTypes())));
+ }
+ queryResults = traversal.toList();
+
+
+ if (queryResults.isEmpty()) {
+ LOGGER.warn("No nodes found - apipe was null/empty");
+ } else {
+
+ Introspector searchResults = createSearchResults(genericQueryBuilder.getLoader(),
+ genericQueryBuilder.getUrlBuilder(), queryResults);
+
+ String outputMediaType = getMediaType(genericQueryBuilder.getHeaders().getAcceptableMediaTypes());
+ org.onap.aai.introspection.MarshallerProperties properties =
+ new org.onap.aai.introspection.MarshallerProperties.Builder(
+ org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build();
+
+ result = searchResults.marshal(properties);
+ response = Response.ok().entity(result).build();
+
+ LOGGER.debug(ver.size() + " node(s) traversed, " + queryResults.size() + " found");
+ }
+ success = true;
+ } catch (AAIException e) {
+ success = false;
+ throw e;
+ } catch (Exception e) {
+ success = false;
+ throw new AAIException("AAI_5105", e);
+ } finally {
+ if (genericQueryBuilder.getDbEngine() != null) {
+ if (success) {
+ genericQueryBuilder.getDbEngine().commit();
+ } else {
+ genericQueryBuilder.getDbEngine().rollback();
+ }
+ }
+
+ }
+
+ return response;
+ }
+
+ private URI craftUriFromQueryParams(Loader loader, String startNodeType, List<String> startNodeKeyParams)
+ throws UnsupportedEncodingException, IllegalArgumentException, UriBuilderException, AAIException {
+ Introspector relationship = loader.introspectorFromName("relationship");
+
+ relationship.setValue("related-to", startNodeType);
+ List<Object> relationshipDataList = relationship.getValue("relationship-data");
+
+ for (String keyData : startNodeKeyParams) {
+ int colonIndex = keyData.indexOf(":");
+ if (colonIndex <= 0) {
+ throw new AAIException("AAI_6120", "Bad key param passed in: [" + keyData + "]");
+ } else {
+ Introspector data = loader.introspectorFromName("relationship-data");
+ data.setValue("relationship-key", keyData.substring(0, colonIndex));
+ data.setValue("relationship-value", keyData.substring(colonIndex + 1));
+ relationshipDataList.add(data.getUnderlyingObject());
+ }
+ }
+
+ RelationshipToURI parser = new RelationshipToURI(loader, relationship);
+
+ return parser.getUri();
+ }
+
+ /**
+ * Run nodes query.
+ *
+ * @param nodesQuery
+ * @throws AAIException the AAI exception
+ */
+ public Response runNodesQuery(NodesQueryBuilder nodesQuery) throws AAIException {
+
+ Response response = null;
+ boolean success = true;
String result = "";
- final String EQUALS = "EQUALS";
- final String DOES_NOT_EQUAL = "DOES-NOT-EQUAL";
- final String EXISTS = "EXISTS";
- final String DOES_NOT_EXIST = "DOES-NOT-EXIST";
- try {
-
- dbEngine.startTransaction();
-
- Introspector target;
-
- if( targetNodeType == null || targetNodeType == "" ){
- throw new AAIException("AAI_6120", "null or empty target-node-type passed to the node query");
- }
-
- try {
- target = loader.introspectorFromName(targetNodeType);
- } catch (AAIUnknownObjectException e) {
- throw new AAIException("AAI_6115", "Unrecognized nodeType [" + targetNodeType + "] passed to node query.");
- }
-
- if( filterParams.isEmpty() && edgeFilterParams.isEmpty()){
- // For now, it's ok to pass no filter params. We'll just return ALL the nodes of the requested type.
- LOGGER.warn("No filters passed to the node query");
- }
-
- StringBuilder queryStringForMsg = new StringBuilder();
- GraphTraversal<Vertex, Vertex> traversal = dbEngine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE, targetNodeType);
- queryStringForMsg.append("has(\"aai-node-type\"," + targetNodeType + ")");
-
- for( String filter : filterParams ) {
- String [] pieces = filter.split(":");
- if( pieces.length < 2 ){
- throw new AAIException("AAI_6120", "bad filter passed to node query: [" + filter + "]");
- }
- else {
- String propName = this.findDbPropName(target, pieces[0]);
- String filterType = pieces[1];
- if( filterType.equals(EQUALS)){
- if( pieces.length < 3 ){
- throw new AAIException("AAI_6120", "No value passed for filter: [" + filter + "]");
- }
- String value = "?";
- if( pieces.length == 3 ){
- value = pieces[2];
- }
- else if( pieces.length > 3 ){
- // When a ipv6 address comes in as a value, it has colons in it which require us to
- // pull the "value" off the end of the filter differently
- int startPos4Value = propName.length() + filterType.length() + 3;
- value = filter.substring(startPos4Value);
- }
- queryStringForMsg.append(".has(" + propName + "," + value + ")");
- traversal.has(propName,value);
- }
- else if( filterType.equals(DOES_NOT_EQUAL)){
- if( pieces.length < 3 ){
- throw new AAIException("AAI_6120", "No value passed for filter: [" + filter + "]");
- }
- String value = "?";
- if( pieces.length == 3 ){
- value = pieces[2];
- }
- else if( pieces.length > 3 ){
- // When a ipv6 address comes in as a value, it has colons in it which require us to
- // pull the "value" off the end of the filter differently
- int startPos4Value = propName.length() + filterType.length() + 3;
- value = filter.substring(startPos4Value);
- }
- queryStringForMsg.append(".hasNot(" + propName + "," + value + ")");
- traversal.not(__.has(propName,value));
- }
- else if( filterType.equals(EXISTS)){
- queryStringForMsg.append(".has(" + propName + ")");
- traversal.has(propName);
- }
- else if( filterType.equals(DOES_NOT_EXIST)){
- queryStringForMsg.append(".hasNot(" + propName + ")");
- traversal.hasNot(propName);
- }
- else {
- throw new AAIException("AAI_6120", "bad filterType passed: [" + filterType + "]");
- }
- }
- }
-
- if (!edgeFilterParams.isEmpty()) {
- // edge-filter=pserver:EXISTS: OR pserver:EXISTS:hostname:XXX
- // edge-filter=pserver:DOES-NOT-EXIST: OR pserver:DOES-NOT-EXIST:hostname:XXX
- String filter = edgeFilterParams.get(0); // we process and allow only one edge filter for now
- String [] pieces = filter.split(":");
- if( pieces.length < 2 || pieces.length == 3 || pieces.length > 4){
- throw new AAIException("AAI_6120", "bad edge-filter passed: [" + filter + "]");
- } else {
- String nodeType = pieces[0].toLowerCase();
- String filterType = pieces[1].toUpperCase();
- Introspector otherNode;
- if (!filterType.equals(EXISTS) && !filterType.equals(DOES_NOT_EXIST)) {
- throw new AAIException("AAI_6120", "bad filterType passed: [" + filterType + "]");
- }
- try {
- otherNode = loader.introspectorFromName(nodeType);
- } catch (AAIUnknownObjectException e) {
- throw new AAIException("AAI_6115", "Unrecognized nodeType [" + nodeType + "] passed to node query.");
- }
- String propName = null;
- String propValue = null;
- if ( pieces.length >= 3) {
- propName = this.findDbPropName(otherNode, pieces[2].toLowerCase());
- propValue = pieces[3];
- }
- String[] edgeLabels = getEdgeLabel(targetNodeType, nodeType);
-
- GraphTraversal<Vertex, Vertex> edgeSearch = __.start();
-
- edgeSearch.both(edgeLabels).has(AAIProperties.NODE_TYPE, nodeType);
- if (propName != null) {
- // check for matching property
- if (propValue != null) {
- edgeSearch.has(propName, propValue);
- } else {
- edgeSearch.has(propName);
- }
- }
-
- if( filterType.equals(DOES_NOT_EXIST)){
- traversal.where(__.not(edgeSearch));
- } else if (filterType.equals(EXISTS)) {
- traversal.where(edgeSearch);
- }
- }
- }
-
- List<Vertex> results = traversal.toList();
- Introspector searchResults = createSearchResults(loader, urlBuilder, results);
-
- String outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
- org.onap.aai.introspection.MarshallerProperties properties = new org.onap.aai.introspection.MarshallerProperties.Builder(
- org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build();
-
- result = searchResults.marshal(properties);
- response = Response.ok().entity(result).build();
-
- success = true;
- } catch (AAIException e) {
- success = false;
- throw e;
- } catch (Exception e) {
- success = false;
- throw new AAIException("AAI_5105", e);
- } finally {
- if (dbEngine != null) {
- if (success) {
- dbEngine.commit();
- } else {
- dbEngine.rollback();
- }
- }
- }
-
- return response;
- }
-
- protected Introspector createSearchResults(Loader loader, UrlBuilder urlBuilder, List<Vertex> results)
- throws AAIUnknownObjectException {
- Introspector searchResults = loader.introspectorFromName("search-results");
- List<Object> resultDataList = searchResults.getValue("result-data");
- Stream<Vertex> stream;
- if (results.size() >= 50) {
- stream = results.parallelStream();
- } else {
- stream = results.stream();
- }
- boolean isParallel = stream.isParallel();
- stream.forEach(v -> {
- String nodeType = v.<String>property(AAIProperties.NODE_TYPE).orElse(null);
-
- String thisNodeURL;
- try {
- thisNodeURL = urlBuilder.pathed(v);
- Introspector resultData = loader.introspectorFromName("result-data");
-
- resultData.setValue("resource-type", nodeType);
- resultData.setValue("resource-link", thisNodeURL);
- if (isParallel) {
- synchronized (resultDataList) {
- resultDataList.add(resultData.getUnderlyingObject());
- }
- } else {
- resultDataList.add(resultData.getUnderlyingObject());
- }
- } catch (AAIException | AAIFormatVertexException e) {
- throw new RuntimeException(e);
- }
-
- });
- return searchResults;
- }
-
- private String findDbPropName(Introspector obj, String propName) {
-
- Optional<String> result = obj.getPropertyMetadata(propName, PropertyMetadata.DB_ALIAS);
- if (result.isPresent()) {
- return result.get();
- } else {
- return propName;
- }
- }
-
-
- /**
- * Gets the edge label.
- *
- * @param targetNodeType the target node type
- * @param nodeType the node type
- * @return the edge label
- * @throws AAIException the AAI exception
- * @throws EdgeRuleNotFoundException
- */
- public String[] getEdgeLabel(String targetNodeType, String nodeType) throws AAIException, EdgeRuleNotFoundException{
-
-
- EdgeRuleQuery query = new EdgeRuleQuery.Builder(targetNodeType, nodeType).build();
- Multimap<String, EdgeRule> edgeRules = ArrayListMultimap.create();
- edgeRules = edgeIngestor.getRules(query);
-
- //Map<String, EdgeRule> rules = EdgeRules.getInstance().getEdgeRules(targetNodeType, nodeType);
- String[] results = edgeRules.values().stream().map(rule -> rule.getLabel()).collect(Collectors.toList()).toArray(new String[0]);
- return results;
- }
-
-
- /**
- * Run named query.
- *
- * @param fromAppId the from app id
- * @param transId the trans id
- * @param queryParameters the query parameters
- * @param aaiExtMap the aai ext map
- * @return the response
- * @throws JAXBException the JAXB exception
- * @throws AAIException the AAI exception
- */
- public Response runNamedQuery(String fromAppId, String transId, String queryParameters,
- DBConnectionType connectionType,
- AAIExtensionMap aaiExtMap) throws JAXBException, AAIException {
-
- Introspector inventoryItems;
- boolean success = true;
- TransactionalGraphEngine dbEngine = null;
- try {
-
- MoxyLoader loader = (MoxyLoader)loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
- DynamicJAXBContext jaxbContext = loader.getJAXBContext();
- dbEngine = new JanusGraphDBEngine(
- QueryStyle.TRAVERSAL,
- connectionType,
- loader);
- DBSerializer serializer = new DBSerializer(schemaVersions.getDefaultVersion(), dbEngine, ModelType.MOXY, fromAppId);
- ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
-
- dbEngine.startTransaction();
- org.onap.aai.restcore.MediaType mediaType = org.onap.aai.restcore.MediaType.APPLICATION_JSON_TYPE;
- String contentType = aaiExtMap.getHttpServletRequest().getContentType();
- if (contentType != null && contentType.contains("application/xml")) {
- mediaType = org.onap.aai.restcore.MediaType.APPLICATION_XML_TYPE;
- }
-
- if (queryParameters.length() == 0) {
- queryParameters = "{}";
- }
-
- DynamicEntity modelAndNamedQuerySearch = (DynamicEntity)loader.unmarshal("ModelAndNamedQuerySearch", queryParameters, mediaType).getUnderlyingObject();
- if (modelAndNamedQuerySearch == null) {
- throw new AAIException("AAI_5105");
- }
- HashMap<String,Object> namedQueryLookupHash = new HashMap<String,Object>();
-
- DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
- String namedQueryUuid = null;
- if ((qp != null) && qp.isSet("namedQuery")) {
- DynamicEntity namedQuery = (DynamicEntity) qp.get("namedQuery");
-
- if (namedQuery.isSet("namedQueryUuid")) {
- namedQueryUuid = namedQuery.get("namedQueryUuid");
- }
- if (namedQuery.isSet("namedQueryName")) {
- namedQueryLookupHash.put("named-query-name", namedQuery.get("namedQueryName"));
- }
- if (namedQuery.isSet("namedQueryVersion")) {
- namedQueryLookupHash.put("named-query-version", namedQuery.get("namedQueryVersion"));
- }
- }
-
- if (namedQueryUuid == null) {
-
- DbMethHelper dbMethHelper = new DbMethHelper(loader, dbEngine);
- List<Vertex> namedQueryVertices = dbMethHelper.locateUniqueVertices("named-query", namedQueryLookupHash);
- for (Vertex vert : namedQueryVertices) {
- namedQueryUuid = vert.<String>property("named-query-uuid").orElse(null);
- // there should only be one, we'll pick the first if not
- break;
- }
- }
-
- String secondaryFilterCutPoint = null;
-
- if (modelAndNamedQuerySearch.isSet("secondaryFilterCutPoint")) {
- secondaryFilterCutPoint = modelAndNamedQuerySearch.get("secondaryFilterCutPoint");
- }
-
- List<Map<String,Object>> startNodeFilterHash = new ArrayList<>();
-
- mapInstanceFilters((DynamicEntity)modelAndNamedQuerySearch.get("instanceFilters"),
- startNodeFilterHash, jaxbContext);
-
- Map<String,Object> secondaryFilterHash = new HashMap<>();
-
- mapSecondaryFilters((DynamicEntity)modelAndNamedQuerySearch.get("secondaryFilts"),
- secondaryFilterHash, jaxbContext);
-
- List<ResultSet> resultSet = processor.queryByNamedQuery(transId, fromAppId,
- namedQueryUuid, startNodeFilterHash, aaiExtMap.getApiVersion(), secondaryFilterCutPoint, secondaryFilterHash);
-
- inventoryItems = loader.introspectorFromName("inventory-response-items");
-
- List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
-
- inventoryItems.setValue("inventory-response-item", invItemList);
- success = true;
- } catch (AAIException e) {
- success = false;
- throw e;
- } catch (Exception e) {
- success = false;
- throw new AAIException("AAI_5105", e);
- } finally {
- if (dbEngine != null) {
- if (success) {
- dbEngine.commit();
- } else {
- dbEngine.rollback();
- }
- }
- }
-
- return getResponseFromIntrospector(inventoryItems, aaiExtMap.getHttpHeaders());
- }
-
- /**
- * Execute model operation.
- *
- * @param fromAppId the from app id
- * @param transId the trans id
- * @param queryParameters the query parameters
- * @param isDelete the is delete
- * @param aaiExtMap the aai ext map
- * @return the response
- * @throws JAXBException the JAXB exception
- * @throws AAIException the AAI exception
- * @throws DynamicException the dynamic exception
- * @throws UnsupportedEncodingException the unsupported encoding exception
- */
- public Response executeModelOperation(String fromAppId, String transId, String queryParameters,
- DBConnectionType connectionType,
- boolean isDelete,
- AAIExtensionMap aaiExtMap) throws JAXBException, AAIException, DynamicException, UnsupportedEncodingException {
- Response response;
- boolean success = true;
- TransactionalGraphEngine dbEngine = null;
- try {
-
- MoxyLoader loader = (MoxyLoader) loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
- DynamicJAXBContext jaxbContext = loader.getJAXBContext();
- dbEngine = new JanusGraphDBEngine(
- QueryStyle.TRAVERSAL,
- connectionType,
- loader);
- DBSerializer serializer = new DBSerializer(schemaVersions.getDefaultVersion(), dbEngine, ModelType.MOXY, fromAppId);
- ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
- dbEngine.startTransaction();
-
-
- org.onap.aai.restcore.MediaType mediaType = org.onap.aai.restcore.MediaType.APPLICATION_JSON_TYPE;
- String contentType = aaiExtMap.getHttpServletRequest().getContentType();
- if (contentType != null && contentType.contains("application/xml")) {
- mediaType = org.onap.aai.restcore.MediaType.APPLICATION_XML_TYPE;
- }
-
- if (queryParameters.length() == 0) {
- queryParameters = "{}";
- }
-
- DynamicEntity modelAndNamedQuerySearch = (DynamicEntity)loader.unmarshal("ModelAndNamedQuerySearch", queryParameters, mediaType).getUnderlyingObject();
- if (modelAndNamedQuerySearch == null) {
- throw new AAIException("AAI_5105");
- }
-
- Map<String,Object> modelQueryLookupHash = new HashMap<>();
-
- String modelVersionId = null;
- String modelName = null;
- String modelInvariantId = null;
- String modelVersion = null;
- String topNodeType = null;
-
- if (modelAndNamedQuerySearch.isSet("topNodeType")) {
- topNodeType = modelAndNamedQuerySearch.get("topNodeType");
- }
-
- // the ways to get a model:
-
- // 1. model-version-id (previously model-name-version-id
- // 2. model-invariant-id (previously model-id) + model-version
- // 3. model-name + model-version
-
- // we will support both using the OverloadedModel object in the v9 oxm. This allows us to unmarshal
- // either an old-style model or new-style model + model-ver object
- if (modelAndNamedQuerySearch.isSet("queryParameters")) {
- DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
-
- if (qp.isSet("model")) {
- DynamicEntity model = (DynamicEntity) qp.get("model");
-
- // on an old-style model object, the following 4 attrs were all present
- if (model.isSet("modelNameVersionId")) {
- modelVersionId = model.get("modelNameVersionId");
- }
- if (model.isSet("modelId")) {
- modelInvariantId = model.get("modelId");
- }
- if (model.isSet("modelName")) {
- modelName = model.get("modelName");
- }
- if (model.isSet("modelVersion")) {
- modelVersion = model.get("modelVersion");
- }
-
- // new style splits model-invariant-id from the other 3 attrs. This is
- // the only way to directly look up the model object
- if (model.isSet("modelInvariantId")) {
- modelInvariantId = model.get("modelInvariantId");
- }
-
- if (model.isSet("modelVers")) {
- // we know that this is new style, because modelVers was not an option
- // before v9
- DynamicEntity modelVers = (DynamicEntity) model.get("modelVers");
- if (modelVers.isSet("modelVer")) {
- List<DynamicEntity> modelVerList = modelVers.get("modelVer");
- // if they send more than one, too bad, they get the first one
- DynamicEntity modelVer = modelVerList.get(0);
- if (modelVer.isSet("modelName")) {
- modelName = modelVer.get("modelName");
- }
- if (modelVer.isSet("modelVersionId")) {
- modelVersionId = modelVer.get("modelVersionId");
- }
- if (modelVer.isSet("modelVersion")) {
- modelVersion = modelVer.get("modelVersion");
- }
- }
- }
- }
- }
-
- List<Map<String,Object>> startNodeFilterHash = new ArrayList<>();
-
- String resourceVersion = mapInstanceFilters((DynamicEntity)modelAndNamedQuerySearch.get("instanceFilters"),
- startNodeFilterHash, jaxbContext);
-
- if (isDelete) {
-
- List<ResultSet> resultSet = processor.queryByModel(transId, fromAppId,
- modelVersionId, modelInvariantId, modelName, topNodeType, startNodeFilterHash, aaiExtMap.getApiVersion() );
-
- Map<Object,String> objectToVertMap = new HashMap<>();
- List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
-
- ResultSet rs = resultSet.get(0);
-
- Vertex firstVert = rs.getVert();
- String restURI = serializer.getURIForVertex(firstVert).toString();
- String notificationVersion = schemaVersions.getDefaultVersion().toString();
- Map<String,String> delResult = processor.runDeleteByModel( transId, fromAppId,
- modelVersionId, topNodeType, startNodeFilterHash.get(0), aaiExtMap.getApiVersion(), resourceVersion );
-
- String resultStr = "";
- for (Map.Entry<String,String> ent : delResult.entrySet()) {
- resultStr += "v[" + ent.getKey() + "] " + ent.getValue() + ",\n";
- }
- resultStr.trim();
-
- // Note - notifications are now done down in the individual "remove" calls done in runDeleteByModel() above.
-
- response = Response.ok(resultStr).build();
-
- } else {
- List<ResultSet> resultSet = processor.queryByModel( transId, fromAppId,
- modelVersionId, modelInvariantId, modelName, topNodeType, startNodeFilterHash, aaiExtMap.getApiVersion() );
-
- Introspector inventoryItems = loader.introspectorFromName("inventory-response-items");
-
- List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
-
- inventoryItems.setValue("inventory-response-item", invItemList);
-
- response = getResponseFromIntrospector(inventoryItems, aaiExtMap.getHttpHeaders());
- }
- success = true;
- } catch (AAIException e) {
- success = false;
- throw e;
- } catch (Exception e) {
- success = false;
- throw new AAIException("AAI_5105", e);
- } finally {
- if (dbEngine != null) {
- if (success) {
- dbEngine.commit();
- } else {
- dbEngine.rollback();
- }
- }
- }
-
- return response;
- }
-
- private Response getResponseFromIntrospector(Introspector obj, HttpHeaders headers) {
- boolean isJson = false;
- for (MediaType mt : headers.getAcceptableMediaTypes()) {
- if (MediaType.APPLICATION_JSON_TYPE.isCompatible(mt)) {
- isJson = true;
- break;
- }
- }
- org.onap.aai.introspection.MarshallerProperties properties;
- if (isJson) {
- properties =
- new org.onap.aai.introspection.MarshallerProperties.Builder(org.onap.aai.restcore.MediaType.APPLICATION_JSON_TYPE).build();
- } else {
- properties =
- new org.onap.aai.introspection.MarshallerProperties.Builder(org.onap.aai.restcore.MediaType.APPLICATION_XML_TYPE).build();
- }
-
- String marshalledObj = obj.marshal(properties);
- return Response.ok().entity(marshalledObj).build();
- }
-
- /**
- * Map instance filters.
- *
- * @param instanceFilters the instance filters
- * @param startNodeFilterHash the start node filter hash
- * @param jaxbContext the jaxb context
- * @return the string
- */
- private String mapInstanceFilters(DynamicEntity instanceFilters, List<Map<String,Object>> startNodeFilterHash, DynamicJAXBContext jaxbContext) {
-
- if (instanceFilters == null || !instanceFilters.isSet("instanceFilter")) {
- return null;
- }
- @SuppressWarnings("unchecked")
- List<DynamicEntity> instanceFilter = (ArrayList<DynamicEntity>)instanceFilters.get("instanceFilter");
- String resourceVersion = null;
-
- for (DynamicEntity instFilt : instanceFilter) {
- List<DynamicEntity> any = instFilt.get("any");
- HashMap<String,Object> thisNodeFilterHash = new HashMap<String,Object>();
- for (DynamicEntity anyEnt : any) {
- String clazz = anyEnt.getClass().getCanonicalName();
- String simpleClazz = anyEnt.getClass().getSimpleName();
-
- String nodeType = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, simpleClazz);
-
- DynamicType anyEntType = jaxbContext.getDynamicType(clazz);
-
- for (String propName : anyEntType.getPropertiesNames()) {
- // hyphencase the prop and throw it on the hash
- if (anyEnt.isSet(propName)) {
- thisNodeFilterHash.put(nodeType + "." + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propName), anyEnt.get(propName));
- if (propName.equals("resourceVersion") && resourceVersion == null) {
- resourceVersion = (String)anyEnt.get(propName);
- }
- }
- }
- }
- startNodeFilterHash.add(thisNodeFilterHash);
- }
- return resourceVersion;
- }
-
- /**
- * Map secondary filters.
- *
- * @param secondaryFilts the secondary filters
- * @param secondaryFilterHash the secondary filter hash
- * @param jaxbContext the jaxb context
- * @return the string
- */
- private void mapSecondaryFilters(DynamicEntity secondaryFilts, Map<String,Object> secondaryFilterHash, DynamicJAXBContext jaxbContext) {
-
- if (secondaryFilts == null || !secondaryFilts.isSet("secondaryFilt")) {
- return;
- }
- @SuppressWarnings("unchecked")
- List<DynamicEntity> secondaryFilter = (ArrayList<DynamicEntity>)secondaryFilts.get("secondaryFilt");
-
- for (DynamicEntity secondaryFilt : secondaryFilter) {
- List<DynamicEntity> any = secondaryFilt.get("any");
-
- for (DynamicEntity anyEnt : any) {
- String clazz = anyEnt.getClass().getCanonicalName();
- String simpleClazz = anyEnt.getClass().getSimpleName();
-
- String nodeType = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, simpleClazz);
-
- DynamicType anyEntType = jaxbContext.getDynamicType(clazz);
-
- for (String propName : anyEntType.getPropertiesNames()) {
- // hyphencase the prop and throw it on the hash
- if (anyEnt.isSet(propName)) {
- secondaryFilterHash.put(nodeType + "." + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propName), anyEnt.get(propName));
- }
- }
- }
- }
- }
-
- /**
- * Remap inventory items.
- *
- * @param invResultItem the inv result item
- * @param jaxbContext the jaxb context
- * @param includeTheseVertices the include these vertices
- * @param objectToVertMap the object to vert map
- * @param aaiExtMap the aai ext map
- * @return the dynamic entity
- */
- private DynamicEntity remapInventoryItems(DynamicEntity invResultItem, DynamicJAXBContext jaxbContext,
- Map<String,String> includeTheseVertices, Map<Object,String> objectToVertMap, AAIExtensionMap aaiExtMap) {
-
-
- DynamicEntity inventoryItem = jaxbContext.newDynamicEntity("inventory.aai.onap.org." + aaiExtMap.getApiVersion() + ".InventoryResponseItem");
- Object item = invResultItem.get("item");
- inventoryItem.set("modelName", invResultItem.get("modelName"));
- inventoryItem.set("item", item);
- inventoryItem.set("extraProperties", invResultItem.get("extraProperties"));
-
- String vertexId = "";
-
- if (objectToVertMap.containsKey(item)) {
- vertexId = objectToVertMap.get(item);
- }
-
- if (includeTheseVertices.containsKey(vertexId)) {
- if (invResultItem.isSet("inventoryResponseItems")) {
- List<DynamicEntity> invItemList = new ArrayList<DynamicEntity>();
- DynamicEntity inventoryItems = jaxbContext.newDynamicEntity("inventory.aai.att.com." + aaiExtMap.getApiVersion() + ".InventoryResponseItems");
- DynamicEntity subInventoryResponseItems = invResultItem.get("inventoryResponseItems");
- List<DynamicEntity> subInventoryResponseItemList = subInventoryResponseItems.get("inventoryResponseItem");
- for (DynamicEntity ent : subInventoryResponseItemList) {
- DynamicEntity invItem = remapInventoryItems(ent, jaxbContext, includeTheseVertices, objectToVertMap, aaiExtMap);
- if (invItem != null) {
- invItemList.add(invItem);
- }
- }
- inventoryItems.set("inventoryResponseItem", invItemList);
- inventoryItem.set("inventoryResponseItems", inventoryItems);
- }
- }
- return inventoryItem;
- }
-
- /**
- * Unpack result set.
- *
- * @param g the g
- * @param resultSetList the result set list
- * @param jaxbContext the jaxb context
- * @param aaiResources the aai resources
- * @param objectToVertMap the object to vert map
- * @param aaiExtMap the aai ext map
- * @return the array list
- * @throws AAIException the AAI exception
- */
- // this should return an inventoryItem
- private List<Object> unpackResultSet(List<ResultSet> resultSetList,
- TransactionalGraphEngine engine,
- Loader loader,
- DBSerializer serializer) throws AAIException {
-
- List<Object> resultList = new ArrayList<>();
-
- for (ResultSet resultSet : resultSetList) {
-
- if( resultSet.getVert() == null ){
- continue;
- }
-
- Introspector inventoryItem = loader.introspectorFromName("inventory-response-item");
- Introspector inventoryItems = loader.introspectorFromName("inventory-response-items");
- // add this inventoryItem to the resultList for this level
- resultList.add(inventoryItem.getUnderlyingObject());
-
- Vertex vert = resultSet.getVert();
-
- String aaiNodeType = vert.<String>property("aai-node-type").orElse(null);
-
- if (aaiNodeType != null) {
- Introspector thisObj = loader.introspectorFromName(aaiNodeType);
-
- if (resultSet.getExtraPropertyHash() != null) {
- Map<String,Object> extraProperties = resultSet.getExtraPropertyHash();
-
- Introspector extraPropertiesEntity = loader.introspectorFromName("extra-properties");
-
- List<Object> extraPropsList = extraPropertiesEntity.getValue("extra-property");
-
- for (Map.Entry<String,Object> ent : extraProperties.entrySet()) {
- String propName = ent.getKey();
- Object propVal = ent.getValue();
-
- Introspector extraPropEntity = loader.introspectorFromName("extra-property");
-
- extraPropEntity.setValue("property-name", propName);
- extraPropEntity.setValue("property-value", propVal);
-
- extraPropsList.add(extraPropEntity.getUnderlyingObject());
-
- }
- inventoryItem.setValue("extra-properties", extraPropertiesEntity.getUnderlyingObject());
- }
-
- try {
- serializer.dbToObject(Collections.singletonList(vert), thisObj, 0, true, "false");
- } catch (UnsupportedEncodingException e1) {
- throw new AAIException("AAI_5105");
- }
- PropertyLimitDesc propertyLimitDesc = resultSet.getPropertyLimitDesc();
-
- if (propertyLimitDesc != null) {
-
- if (PropertyLimitDesc.SHOW_NONE.equals(propertyLimitDesc)) {
- HashMap<String,Object> emptyPropertyOverRideHash = new HashMap<String,Object>();
- for (String key : thisObj.getAllKeys()) {
- emptyPropertyOverRideHash.put(key, null);
- }
- filterProperties(thisObj, emptyPropertyOverRideHash);
- } else if (PropertyLimitDesc.SHOW_ALL.equals(propertyLimitDesc)) {
- //keep everything
- } else if (PropertyLimitDesc.SHOW_NAME_AND_KEYS_ONLY.equals(propertyLimitDesc)) {
- HashMap<String,Object> keysAndNamesPropHash = new HashMap<String,Object>();
-
- for (String key : thisObj.getAllKeys()) {
- keysAndNamesPropHash.put(key, null);
- }
- String namePropMetaData = thisObj.getMetadata(ObjectMetadata.NAME_PROPS);
- if (namePropMetaData != null) {
- String[] nameProps = namePropMetaData.split(",");
- for (String names : nameProps) {
- keysAndNamesPropHash.put(names, null);
- }
- }
- filterProperties(thisObj, keysAndNamesPropHash);
- }
- } else {
- if (resultSet.getPropertyOverRideHash() != null && resultSet.getPropertyOverRideHash().size() > 0) {
- Map<String,Object> propertyOverRideHash = resultSet.getPropertyOverRideHash();
- if (propertyOverRideHash.containsKey("persona-model-id")) {
- propertyOverRideHash.remove("persona-model-id");
- propertyOverRideHash.put("model-invariant-id", null);
- }
- for (String key : thisObj.getAllKeys()) {
- propertyOverRideHash.put(key, null);
- }
- filterProperties(thisObj, propertyOverRideHash);
- } else {
- //keep everything
- }
- }
-
- if (thisObj != null) {
- inventoryItem.setValue("item", thisObj.getUnderlyingObject());
-
- String modelName = null;
- try {
- // Try to get the modelName if we can. Otherwise, do not fail, just return what we have already.
- String modelInvariantIdLocal = (String)vert.<String>property("model-invariant-id-local").orElse(null); // this one points at a model
- String modelVersionIdLocal = (String)vert.<String>property("model-version-id-local").orElse(null); // this one points at a model-ver
-
- if ( (modelInvariantIdLocal != null && modelVersionIdLocal != null)
- && (modelInvariantIdLocal.length() > 0 && modelVersionIdLocal.length() > 0) ) {
- Introspector modelVer = loader.introspectorFromName("model-ver");
- modelVer.setValue("model-version-id", modelVersionIdLocal);
- QueryBuilder builder = engine.getQueryBuilder().createDBQuery(modelVer);
- List<Vertex> modelVerVerts = builder.toList();
- if( (modelVerVerts != null) && (modelVerVerts.size() == 1) ) {
- Vertex modelVerVert = modelVerVerts.get(0);
- modelName = modelVerVert.<String>property("model-name").orElse(null);
- if (modelName != null && modelName.length() > 0) {
- inventoryItem.setValue("model-name", modelName);
- }
- }
- }
- } catch (DynamicException e) {
- ; // it's ok, dynamic object might not have these fields
- } catch (Exception e) {
- ; // it's ok, couldn't find a matching model
- }
-
- if (resultSet.getSubResultSet() != null) {
- List<ResultSet> subResultSet = resultSet.getSubResultSet();
- if (subResultSet != null && subResultSet.size() > 0 ) {
- List<Object> res = unpackResultSet(subResultSet, engine, loader, serializer);
- if (res.size() > 0) {
- inventoryItems.setValue("inventory-response-item", res);
- inventoryItem.setValue("inventory-response-items", inventoryItems.getUnderlyingObject());
- }
- }
- }
- }
- }
- }
-
- return resultList;
- }
-
- private void filterProperties(Introspector thisObj, Map<String, Object> override) {
-
- thisObj.getProperties().stream().filter(x -> {
- return !override.containsKey(x);
- }).forEach(prop -> {
- if (thisObj.isSimpleType(prop)) {
- thisObj.setValue(prop, null);
- }
- });
-
- }
-
- /**
- * Gets the media type.
- *
- * @param mediaTypeList the media type list
- * @return the media type
- */
- protected String getMediaType(List <MediaType> mediaTypeList) {
- String mediaType = MediaType.APPLICATION_JSON; // json is the default
- for (MediaType mt : mediaTypeList) {
- if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt)) {
- mediaType = MediaType.APPLICATION_XML;
- }
- }
- return mediaType;
- }
+ final String EQUALS = "EQUALS";
+ final String DOES_NOT_EQUAL = "DOES-NOT-EQUAL";
+ final String EXISTS = "EXISTS";
+ final String DOES_NOT_EXIST = "DOES-NOT-EXIST";
+ try {
+
+ nodesQuery.getDbEngine().startTransaction();
+
+ Introspector target;
+
+ if (StringUtils.isBlank(nodesQuery.getTargetNodeType())
+ || StringUtils.isBlank(nodesQuery.getTargetNodeType())) {
+ throw new AAIException("AAI_6120", "null or empty target-node-type passed to the node query");
+ }
+
+ try {
+ target = nodesQuery.getLoader().introspectorFromName(nodesQuery.getTargetNodeType());
+ } catch (AAIUnknownObjectException e) {
+ throw new AAIException("AAI_6115",
+ "Unrecognized nodeType [" + nodesQuery.getTargetNodeType() + "] passed to node query.");
+ }
+
+ if (nodesQuery.getFilterParams().isEmpty() && nodesQuery.getEdgeFilterParams().isEmpty()) {
+ // For now, it's ok to pass no filter params. We'll just return ALL the nodes of the requested type.
+ LOGGER.warn("No filters passed to the node query");
+ }
+
+ StringBuilder queryStringForMsg = new StringBuilder();
+ GraphTraversal<Vertex, Vertex> traversal = nodesQuery.getDbEngine().asAdmin().getReadOnlyTraversalSource()
+ .V().has(AAIProperties.NODE_TYPE, nodesQuery.getTargetNodeType());
+ queryStringForMsg.append("has(\"aai-node-type\"," + nodesQuery.getTargetNodeType() + ")");
+
+ for (String filter : nodesQuery.getFilterParams()) {
+ String[] pieces = filter.split(":");
+ if (pieces.length < 2) {
+ throw new AAIException("AAI_6120", "bad filter passed to node query: [" + filter + "]");
+ } else {
+ String propName = this.findDbPropName(target, pieces[0]);
+ String filterType = pieces[1];
+ if (filterType.equals(EQUALS)) {
+ if (pieces.length < 3) {
+ throw new AAIException("AAI_6120", "No value passed for filter: [" + filter + "]");
+ }
+ String value = "?";
+ if (pieces.length == 3) {
+ value = pieces[2];
+ } else if (pieces.length > 3) {
+ // When a ipv6 address comes in as a value, it has colons in it which require us to
+ // pull the "value" off the end of the filter differently
+ int startPos4Value = propName.length() + filterType.length() + 3;
+ value = filter.substring(startPos4Value);
+ }
+ queryStringForMsg.append(".has(" + propName + "," + value + ")");
+ traversal.has(propName, value);
+ } else if (filterType.equals(DOES_NOT_EQUAL)) {
+ if (pieces.length < 3) {
+ throw new AAIException("AAI_6120", "No value passed for filter: [" + filter + "]");
+ }
+ String value = "?";
+ if (pieces.length == 3) {
+ value = pieces[2];
+ } else if (pieces.length > 3) {
+ // When a ipv6 address comes in as a value, it has colons in it which require us to
+ // pull the "value" off the end of the filter differently
+ int startPos4Value = propName.length() + filterType.length() + 3;
+ value = filter.substring(startPos4Value);
+ }
+ queryStringForMsg.append(".hasNot(" + propName + "," + value + ")");
+ traversal.not(__.has(propName, value));
+ } else if (filterType.equals(EXISTS)) {
+ queryStringForMsg.append(".has(" + propName + ")");
+ traversal.has(propName);
+ } else if (filterType.equals(DOES_NOT_EXIST)) {
+ queryStringForMsg.append(".hasNot(" + propName + ")");
+ traversal.hasNot(propName);
+ } else {
+ throw new AAIException("AAI_6120", "bad filterType passed: [" + filterType + "]");
+ }
+ }
+ }
+
+ if (!nodesQuery.getEdgeFilterParams().isEmpty()) {
+ // edge-filter=pserver:EXISTS: OR pserver:EXISTS:hostname:XXX
+ // edge-filter=pserver:DOES-NOT-EXIST: OR pserver:DOES-NOT-EXIST:hostname:XXX
+ String filter = nodesQuery.getEdgeFilterParams().get(0); // we process and allow only one edge filter
+ // for now
+ String[] pieces = filter.split(":");
+ if (pieces.length < 2 || pieces.length == 3 || pieces.length > 4) {
+ throw new AAIException("AAI_6120", "bad edge-filter passed: [" + filter + "]");
+ } else {
+ String nodeType = pieces[0].toLowerCase();
+ String filterType = pieces[1].toUpperCase();
+ Introspector otherNode;
+ if (!filterType.equals(EXISTS) && !filterType.equals(DOES_NOT_EXIST)) {
+ throw new AAIException("AAI_6120", "bad filterType passed: [" + filterType + "]");
+ }
+ try {
+ otherNode = nodesQuery.getLoader().introspectorFromName(nodeType);
+ } catch (AAIUnknownObjectException e) {
+ throw new AAIException("AAI_6115",
+ "Unrecognized nodeType [" + nodeType + "] passed to node query.");
+ }
+ String propName = null;
+ String propValue = null;
+ if (pieces.length >= 3) {
+ propName = this.findDbPropName(otherNode, pieces[2].toLowerCase());
+ propValue = pieces[3];
+ }
+ String[] edgeLabels = getEdgeLabel(nodesQuery.getTargetNodeType(), nodeType);
+
+ GraphTraversal<Vertex, Vertex> edgeSearch = __.start();
+
+ edgeSearch.both(edgeLabels).has(AAIProperties.NODE_TYPE, nodeType);
+ if (propName != null) {
+ // check for matching property
+ if (propValue != null) {
+ edgeSearch.has(propName, propValue);
+ } else {
+ edgeSearch.has(propName);
+ }
+ }
+
+ if (filterType.equals(DOES_NOT_EXIST)) {
+ traversal.where(__.not(edgeSearch));
+ } else if (filterType.equals(EXISTS)) {
+ traversal.where(edgeSearch);
+ }
+ }
+ }
+
+ List<Vertex> results = traversal.toList();
+ Introspector searchResults =
+ createSearchResults(nodesQuery.getLoader(), nodesQuery.getUrlBuilder(), results);
+
+ String outputMediaType = getMediaType(nodesQuery.getHeaders().getAcceptableMediaTypes());
+ org.onap.aai.introspection.MarshallerProperties properties =
+ new org.onap.aai.introspection.MarshallerProperties.Builder(
+ org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build();
+
+ result = searchResults.marshal(properties);
+ response = Response.ok().entity(result).build();
+
+ success = true;
+ } catch (AAIException e) {
+ success = false;
+ throw e;
+ } catch (Exception e) {
+ success = false;
+ throw new AAIException("AAI_5105", e);
+ } finally {
+ if (nodesQuery.getDbEngine() != null) {
+ if (success) {
+ nodesQuery.getDbEngine().commit();
+ } else {
+ nodesQuery.getDbEngine().rollback();
+ }
+ }
+ }
+
+ return response;
+ }
+
+ protected Introspector createSearchResults(Loader loader, UrlBuilder urlBuilder, List<Vertex> results)
+ throws AAIUnknownObjectException {
+ Introspector searchResults = loader.introspectorFromName("search-results");
+ List<Object> resultDataList = searchResults.getValue("result-data");
+ Stream<Vertex> stream;
+ if (results.size() >= 50) {
+ stream = results.parallelStream();
+ } else {
+ stream = results.stream();
+ }
+ boolean isParallel = stream.isParallel();
+ stream.forEach(v -> {
+ String nodeType = v.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+
+ String thisNodeURL;
+ try {
+ thisNodeURL = urlBuilder.pathed(v);
+ Introspector resultData = loader.introspectorFromName("result-data");
+
+ resultData.setValue("resource-type", nodeType);
+ resultData.setValue("resource-link", thisNodeURL);
+ if (isParallel) {
+ synchronized (resultDataList) {
+ resultDataList.add(resultData.getUnderlyingObject());
+ }
+ } else {
+ resultDataList.add(resultData.getUnderlyingObject());
+ }
+ } catch (AAIException | AAIFormatVertexException e) {
+ throw new RuntimeException(e);
+ }
+
+ });
+ return searchResults;
+ }
+
+ private String findDbPropName(Introspector obj, String propName) {
+
+ Optional<String> result = obj.getPropertyMetadata(propName, PropertyMetadata.DB_ALIAS);
+ if (result.isPresent()) {
+ return result.get();
+ } else {
+ return propName;
+ }
+ }
+
+
+ /**
+ * Gets the edge label.
+ *
+ * @param targetNodeType the target node type
+ * @param nodeType the node type
+ * @return the edge label
+ * @throws AAIException the AAI exception
+ * @throws EdgeRuleNotFoundException
+ */
+ public String[] getEdgeLabel(String targetNodeType, String nodeType)
+ throws AAIException, EdgeRuleNotFoundException {
+
+
+ EdgeRuleQuery query = new EdgeRuleQuery.Builder(targetNodeType, nodeType).build();
+ Multimap<String, EdgeRule> edgeRules = ArrayListMultimap.create();
+ edgeRules = edgeIngestor.getRules(query);
+
+ // Map<String, EdgeRule> rules = EdgeRules.getInstance().getEdgeRules(targetNodeType, nodeType);
+ String[] results = edgeRules.values().stream().map(rule -> rule.getLabel()).collect(Collectors.toList())
+ .toArray(new String[0]);
+ return results;
+ }
+
+
+ /**
+ * Run named query.
+ *
+ * @param fromAppId the from app id
+ * @param transId the trans id
+ * @param queryParameters the query parameters
+ * @param aaiExtMap the aai ext map
+ * @return the response
+ * @throws JAXBException the JAXB exception
+ * @throws AAIException the AAI exception
+ */
+ public Response runNamedQuery(String fromAppId, String transId, String queryParameters,
+ DBConnectionType connectionType, AAIExtensionMap aaiExtMap) throws JAXBException, AAIException {
+
+ Introspector inventoryItems;
+ boolean success = true;
+ TransactionalGraphEngine dbEngine = null;
+ try {
+
+ MoxyLoader loader = (MoxyLoader) loaderFactory.createLoaderForVersion(ModelType.MOXY,
+ schemaVersions.getDefaultVersion());
+ DynamicJAXBContext jaxbContext = loader.getJAXBContext();
+ dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, connectionType, loader);
+ DBSerializer serializer =
+ new DBSerializer(schemaVersions.getDefaultVersion(), dbEngine, ModelType.MOXY, fromAppId);
+ ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
+
+ dbEngine.startTransaction();
+ org.onap.aai.restcore.MediaType mediaType = org.onap.aai.restcore.MediaType.APPLICATION_JSON_TYPE;
+ String contentType = aaiExtMap.getHttpServletRequest().getContentType();
+ if (contentType != null && contentType.contains("application/xml")) {
+ mediaType = org.onap.aai.restcore.MediaType.APPLICATION_XML_TYPE;
+ }
+
+ if (queryParameters.length() == 0) {
+ queryParameters = "{}";
+ }
+
+ DynamicEntity modelAndNamedQuerySearch = (DynamicEntity) loader
+ .unmarshal("ModelAndNamedQuerySearch", queryParameters, mediaType).getUnderlyingObject();
+ if (modelAndNamedQuerySearch == null) {
+ throw new AAIException("AAI_5105");
+ }
+ HashMap<String, Object> namedQueryLookupHash = new HashMap<String, Object>();
+
+ DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
+ String namedQueryUuid = null;
+ if ((qp != null) && qp.isSet("namedQuery")) {
+ DynamicEntity namedQuery = (DynamicEntity) qp.get("namedQuery");
+
+ if (namedQuery.isSet("namedQueryUuid")) {
+ namedQueryUuid = namedQuery.get("namedQueryUuid");
+ }
+ if (namedQuery.isSet("namedQueryName")) {
+ namedQueryLookupHash.put("named-query-name", namedQuery.get("namedQueryName"));
+ }
+ if (namedQuery.isSet("namedQueryVersion")) {
+ namedQueryLookupHash.put("named-query-version", namedQuery.get("namedQueryVersion"));
+ }
+ }
+
+ if (namedQueryUuid == null) {
+
+ DbMethHelper dbMethHelper = new DbMethHelper(loader, dbEngine);
+ List<Vertex> namedQueryVertices =
+ dbMethHelper.locateUniqueVertices("named-query", namedQueryLookupHash);
+ for (Vertex vert : namedQueryVertices) {
+ namedQueryUuid = vert.<String>property("named-query-uuid").orElse(null);
+ // there should only be one, we'll pick the first if not
+ break;
+ }
+ }
+
+ String secondaryFilterCutPoint = null;
+
+ if (modelAndNamedQuerySearch.isSet("secondaryFilterCutPoint")) {
+ secondaryFilterCutPoint = modelAndNamedQuerySearch.get("secondaryFilterCutPoint");
+ }
+
+ List<Map<String, Object>> startNodeFilterHash = new ArrayList<>();
+
+ mapInstanceFilters((DynamicEntity) modelAndNamedQuerySearch.get("instanceFilters"), startNodeFilterHash,
+ jaxbContext);
+
+ Map<String, Object> secondaryFilterHash = new HashMap<>();
+
+ mapSecondaryFilters((DynamicEntity) modelAndNamedQuerySearch.get("secondaryFilts"), secondaryFilterHash,
+ jaxbContext);
+
+ List<ResultSet> resultSet = processor.queryByNamedQuery(transId, fromAppId, namedQueryUuid,
+ startNodeFilterHash, aaiExtMap.getApiVersion(), secondaryFilterCutPoint, secondaryFilterHash);
+
+ inventoryItems = loader.introspectorFromName("inventory-response-items");
+
+ List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
+
+ inventoryItems.setValue("inventory-response-item", invItemList);
+ success = true;
+ } catch (AAIException e) {
+ success = false;
+ throw e;
+ } catch (Exception e) {
+ success = false;
+ throw new AAIException("AAI_5105", e);
+ } finally {
+ if (dbEngine != null) {
+ if (success) {
+ dbEngine.commit();
+ } else {
+ dbEngine.rollback();
+ }
+ }
+ }
+
+ return getResponseFromIntrospector(inventoryItems, aaiExtMap.getHttpHeaders());
+ }
+
+ /**
+ * Execute model operation.
+ *
+ * @param fromAppId the from app id
+ * @param transId the trans id
+ * @param queryParameters the query parameters
+ * @param isDelete the is delete
+ * @param aaiExtMap the aai ext map
+ * @return the response
+ * @throws JAXBException the JAXB exception
+ * @throws AAIException the AAI exception
+ * @throws DynamicException the dynamic exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ public Response executeModelOperation(String fromAppId, String transId, String queryParameters,
+ DBConnectionType connectionType, boolean isDelete, AAIExtensionMap aaiExtMap)
+ throws JAXBException, AAIException, DynamicException, UnsupportedEncodingException {
+ Response response;
+ boolean success = true;
+ TransactionalGraphEngine dbEngine = null;
+ try {
+
+ MoxyLoader loader = (MoxyLoader) loaderFactory.createLoaderForVersion(ModelType.MOXY,
+ schemaVersions.getDefaultVersion());
+ DynamicJAXBContext jaxbContext = loader.getJAXBContext();
+ dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, connectionType, loader);
+ DBSerializer serializer =
+ new DBSerializer(schemaVersions.getDefaultVersion(), dbEngine, ModelType.MOXY, fromAppId);
+ ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
+ dbEngine.startTransaction();
+
+
+ org.onap.aai.restcore.MediaType mediaType = org.onap.aai.restcore.MediaType.APPLICATION_JSON_TYPE;
+ String contentType = aaiExtMap.getHttpServletRequest().getContentType();
+ if (contentType != null && contentType.contains("application/xml")) {
+ mediaType = org.onap.aai.restcore.MediaType.APPLICATION_XML_TYPE;
+ }
+
+ if (queryParameters.length() == 0) {
+ queryParameters = "{}";
+ }
+
+ DynamicEntity modelAndNamedQuerySearch = (DynamicEntity) loader
+ .unmarshal("ModelAndNamedQuerySearch", queryParameters, mediaType).getUnderlyingObject();
+ if (modelAndNamedQuerySearch == null) {
+ throw new AAIException("AAI_5105");
+ }
+
+ Map<String, Object> modelQueryLookupHash = new HashMap<>();
+
+ String modelVersionId = null;
+ String modelName = null;
+ String modelInvariantId = null;
+ String modelVersion = null;
+ String topNodeType = null;
+
+ if (modelAndNamedQuerySearch.isSet("topNodeType")) {
+ topNodeType = modelAndNamedQuerySearch.get("topNodeType");
+ }
+
+ // the ways to get a model:
+
+ // 1. model-version-id (previously model-name-version-id
+ // 2. model-invariant-id (previously model-id) + model-version
+ // 3. model-name + model-version
+
+ // we will support both using the OverloadedModel object in the v9 oxm. This allows us to unmarshal
+ // either an old-style model or new-style model + model-ver object
+ if (modelAndNamedQuerySearch.isSet("queryParameters")) {
+ DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
+
+ if (qp.isSet("model")) {
+ DynamicEntity model = (DynamicEntity) qp.get("model");
+
+ // on an old-style model object, the following 4 attrs were all present
+ if (model.isSet("modelNameVersionId")) {
+ modelVersionId = model.get("modelNameVersionId");
+ }
+ if (model.isSet("modelId")) {
+ modelInvariantId = model.get("modelId");
+ }
+ if (model.isSet("modelName")) {
+ modelName = model.get("modelName");
+ }
+ if (model.isSet("modelVersion")) {
+ modelVersion = model.get("modelVersion");
+ }
+
+ // new style splits model-invariant-id from the other 3 attrs. This is
+ // the only way to directly look up the model object
+ if (model.isSet("modelInvariantId")) {
+ modelInvariantId = model.get("modelInvariantId");
+ }
+
+ if (model.isSet("modelVers")) {
+ // we know that this is new style, because modelVers was not an option
+ // before v9
+ DynamicEntity modelVers = (DynamicEntity) model.get("modelVers");
+ if (modelVers.isSet("modelVer")) {
+ List<DynamicEntity> modelVerList = modelVers.get("modelVer");
+ // if they send more than one, too bad, they get the first one
+ DynamicEntity modelVer = modelVerList.get(0);
+ if (modelVer.isSet("modelName")) {
+ modelName = modelVer.get("modelName");
+ }
+ if (modelVer.isSet("modelVersionId")) {
+ modelVersionId = modelVer.get("modelVersionId");
+ }
+ if (modelVer.isSet("modelVersion")) {
+ modelVersion = modelVer.get("modelVersion");
+ }
+ }
+ }
+ }
+ }
+
+ List<Map<String, Object>> startNodeFilterHash = new ArrayList<>();
+
+ String resourceVersion = mapInstanceFilters((DynamicEntity) modelAndNamedQuerySearch.get("instanceFilters"),
+ startNodeFilterHash, jaxbContext);
+
+ if (isDelete) {
+
+ List<ResultSet> resultSet = processor.queryByModel(transId, fromAppId, modelVersionId, modelInvariantId,
+ modelName, topNodeType, startNodeFilterHash, aaiExtMap.getApiVersion());
+
+ Map<Object, String> objectToVertMap = new HashMap<>();
+ List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
+
+ ResultSet rs = resultSet.get(0);
+
+ Vertex firstVert = rs.getVert();
+ String restURI = serializer.getURIForVertex(firstVert).toString();
+ String notificationVersion = schemaVersions.getDefaultVersion().toString();
+ Map<String, String> delResult = processor.runDeleteByModel(transId, fromAppId, modelVersionId,
+ topNodeType, startNodeFilterHash.get(0), aaiExtMap.getApiVersion(), resourceVersion);
+
+ String resultStr = "";
+ for (Map.Entry<String, String> ent : delResult.entrySet()) {
+ resultStr += "v[" + ent.getKey() + "] " + ent.getValue() + ",\n";
+ }
+ resultStr.trim();
+
+ // Note - notifications are now done down in the individual "remove" calls done in
+ // runDeleteByModel() above.
+
+ response = Response.ok(resultStr).build();
+
+ } else {
+ List<ResultSet> resultSet = processor.queryByModel(transId, fromAppId, modelVersionId, modelInvariantId,
+ modelName, topNodeType, startNodeFilterHash, aaiExtMap.getApiVersion());
+
+ Introspector inventoryItems = loader.introspectorFromName("inventory-response-items");
+
+ List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
+
+ inventoryItems.setValue("inventory-response-item", invItemList);
+
+ response = getResponseFromIntrospector(inventoryItems, aaiExtMap.getHttpHeaders());
+ }
+ success = true;
+ } catch (AAIException e) {
+ success = false;
+ throw e;
+ } catch (Exception e) {
+ success = false;
+ throw new AAIException("AAI_5105", e);
+ } finally {
+ if (dbEngine != null) {
+ if (success) {
+ dbEngine.commit();
+ } else {
+ dbEngine.rollback();
+ }
+ }
+ }
+
+ return response;
+ }
+
+ private Response getResponseFromIntrospector(Introspector obj, HttpHeaders headers) {
+ boolean isJson = false;
+ for (MediaType mt : headers.getAcceptableMediaTypes()) {
+ if (MediaType.APPLICATION_JSON_TYPE.isCompatible(mt)) {
+ isJson = true;
+ break;
+ }
+ }
+ org.onap.aai.introspection.MarshallerProperties properties;
+ if (isJson) {
+ properties = new org.onap.aai.introspection.MarshallerProperties.Builder(
+ org.onap.aai.restcore.MediaType.APPLICATION_JSON_TYPE).build();
+ } else {
+ properties = new org.onap.aai.introspection.MarshallerProperties.Builder(
+ org.onap.aai.restcore.MediaType.APPLICATION_XML_TYPE).build();
+ }
+
+ String marshalledObj = obj.marshal(properties);
+ return Response.ok().entity(marshalledObj).build();
+ }
+
+ /**
+ * Map instance filters.
+ *
+ * @param instanceFilters the instance filters
+ * @param startNodeFilterHash the start node filter hash
+ * @param jaxbContext the jaxb context
+ * @return the string
+ */
+ private String mapInstanceFilters(DynamicEntity instanceFilters, List<Map<String, Object>> startNodeFilterHash,
+ DynamicJAXBContext jaxbContext) {
+
+ if (instanceFilters == null || !instanceFilters.isSet("instanceFilter")) {
+ return null;
+ }
+ @SuppressWarnings("unchecked")
+ List<DynamicEntity> instanceFilter = (ArrayList<DynamicEntity>) instanceFilters.get("instanceFilter");
+ String resourceVersion = null;
+
+ for (DynamicEntity instFilt : instanceFilter) {
+ List<DynamicEntity> any = instFilt.get("any");
+ HashMap<String, Object> thisNodeFilterHash = new HashMap<String, Object>();
+ for (DynamicEntity anyEnt : any) {
+ String clazz = anyEnt.getClass().getCanonicalName();
+ String simpleClazz = anyEnt.getClass().getSimpleName();
+
+ String nodeType = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, simpleClazz);
+
+ DynamicType anyEntType = jaxbContext.getDynamicType(clazz);
+
+ for (String propName : anyEntType.getPropertiesNames()) {
+ // hyphencase the prop and throw it on the hash
+ if (anyEnt.isSet(propName)) {
+ thisNodeFilterHash.put(
+ nodeType + "." + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propName),
+ anyEnt.get(propName));
+ if (propName.equals("resourceVersion") && resourceVersion == null) {
+ resourceVersion = (String) anyEnt.get(propName);
+ }
+ }
+ }
+ }
+ startNodeFilterHash.add(thisNodeFilterHash);
+ }
+ return resourceVersion;
+ }
+
+ /**
+ * Map secondary filters.
+ *
+ * @param secondaryFilts the secondary filters
+ * @param secondaryFilterHash the secondary filter hash
+ * @param jaxbContext the jaxb context
+ * @return the string
+ */
+ private void mapSecondaryFilters(DynamicEntity secondaryFilts, Map<String, Object> secondaryFilterHash,
+ DynamicJAXBContext jaxbContext) {
+
+ if (secondaryFilts == null || !secondaryFilts.isSet("secondaryFilt")) {
+ return;
+ }
+ @SuppressWarnings("unchecked")
+ List<DynamicEntity> secondaryFilter = (ArrayList<DynamicEntity>) secondaryFilts.get("secondaryFilt");
+
+ for (DynamicEntity secondaryFilt : secondaryFilter) {
+ List<DynamicEntity> any = secondaryFilt.get("any");
+
+ for (DynamicEntity anyEnt : any) {
+ String clazz = anyEnt.getClass().getCanonicalName();
+ String simpleClazz = anyEnt.getClass().getSimpleName();
+
+ String nodeType = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, simpleClazz);
+
+ DynamicType anyEntType = jaxbContext.getDynamicType(clazz);
+
+ for (String propName : anyEntType.getPropertiesNames()) {
+ // hyphencase the prop and throw it on the hash
+ if (anyEnt.isSet(propName)) {
+ secondaryFilterHash.put(
+ nodeType + "." + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propName),
+ anyEnt.get(propName));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Remap inventory items.
+ *
+ * @param invResultItem the inv result item
+ * @param jaxbContext the jaxb context
+ * @param includeTheseVertices the include these vertices
+ * @param objectToVertMap the object to vert map
+ * @param aaiExtMap the aai ext map
+ * @return the dynamic entity
+ */
+ private DynamicEntity remapInventoryItems(DynamicEntity invResultItem, DynamicJAXBContext jaxbContext,
+ Map<String, String> includeTheseVertices, Map<Object, String> objectToVertMap, AAIExtensionMap aaiExtMap) {
+
+
+ DynamicEntity inventoryItem = jaxbContext
+ .newDynamicEntity("inventory.aai.onap.org." + aaiExtMap.getApiVersion() + ".InventoryResponseItem");
+ Object item = invResultItem.get("item");
+ inventoryItem.set("modelName", invResultItem.get("modelName"));
+ inventoryItem.set("item", item);
+ inventoryItem.set("extraProperties", invResultItem.get("extraProperties"));
+
+ String vertexId = "";
+
+ if (objectToVertMap.containsKey(item)) {
+ vertexId = objectToVertMap.get(item);
+ }
+
+ if (includeTheseVertices.containsKey(vertexId)) {
+ if (invResultItem.isSet("inventoryResponseItems")) {
+ List<DynamicEntity> invItemList = new ArrayList<DynamicEntity>();
+ DynamicEntity inventoryItems = jaxbContext.newDynamicEntity(
+ "inventory.aai.att.com." + aaiExtMap.getApiVersion() + ".InventoryResponseItems");
+ DynamicEntity subInventoryResponseItems = invResultItem.get("inventoryResponseItems");
+ List<DynamicEntity> subInventoryResponseItemList =
+ subInventoryResponseItems.get("inventoryResponseItem");
+ for (DynamicEntity ent : subInventoryResponseItemList) {
+ DynamicEntity invItem =
+ remapInventoryItems(ent, jaxbContext, includeTheseVertices, objectToVertMap, aaiExtMap);
+ if (invItem != null) {
+ invItemList.add(invItem);
+ }
+ }
+ inventoryItems.set("inventoryResponseItem", invItemList);
+ inventoryItem.set("inventoryResponseItems", inventoryItems);
+ }
+ }
+ return inventoryItem;
+ }
+
+ /**
+ * Unpack result set.
+ *
+ * @param g the g
+ * @param resultSetList the result set list
+ * @param jaxbContext the jaxb context
+ * @param aaiResources the aai resources
+ * @param objectToVertMap the object to vert map
+ * @param aaiExtMap the aai ext map
+ * @return the array list
+ * @throws AAIException the AAI exception
+ */
+ // this should return an inventoryItem
+ private List<Object> unpackResultSet(List<ResultSet> resultSetList, TransactionalGraphEngine engine, Loader loader,
+ DBSerializer serializer) throws AAIException {
+
+ List<Object> resultList = new ArrayList<>();
+
+ for (ResultSet resultSet : resultSetList) {
+
+ if (resultSet.getVert() == null) {
+ continue;
+ }
+
+ Introspector inventoryItem = loader.introspectorFromName("inventory-response-item");
+ Introspector inventoryItems = loader.introspectorFromName("inventory-response-items");
+ // add this inventoryItem to the resultList for this level
+ resultList.add(inventoryItem.getUnderlyingObject());
+
+ Vertex vert = resultSet.getVert();
+
+ String aaiNodeType = vert.<String>property("aai-node-type").orElse(null);
+
+ if (aaiNodeType != null) {
+ Introspector thisObj = loader.introspectorFromName(aaiNodeType);
+
+ if (resultSet.getExtraPropertyHash() != null) {
+ Map<String, Object> extraProperties = resultSet.getExtraPropertyHash();
+
+ Introspector extraPropertiesEntity = loader.introspectorFromName("extra-properties");
+
+ List<Object> extraPropsList = extraPropertiesEntity.getValue("extra-property");
+
+ for (Map.Entry<String, Object> ent : extraProperties.entrySet()) {
+ String propName = ent.getKey();
+ Object propVal = ent.getValue();
+
+ Introspector extraPropEntity = loader.introspectorFromName("extra-property");
+
+ extraPropEntity.setValue("property-name", propName);
+ extraPropEntity.setValue("property-value", propVal);
+
+ extraPropsList.add(extraPropEntity.getUnderlyingObject());
+
+ }
+ inventoryItem.setValue("extra-properties", extraPropertiesEntity.getUnderlyingObject());
+ }
+
+ try {
+ serializer.dbToObject(Collections.singletonList(vert), thisObj, 0, true, "false");
+ } catch (UnsupportedEncodingException e1) {
+ throw new AAIException("AAI_5105");
+ }
+ PropertyLimitDesc propertyLimitDesc = resultSet.getPropertyLimitDesc();
+
+ if (propertyLimitDesc != null) {
+
+ if (PropertyLimitDesc.SHOW_NONE.equals(propertyLimitDesc)) {
+ HashMap<String, Object> emptyPropertyOverRideHash = new HashMap<String, Object>();
+ for (String key : thisObj.getAllKeys()) {
+ emptyPropertyOverRideHash.put(key, null);
+ }
+ filterProperties(thisObj, emptyPropertyOverRideHash);
+ } else if (PropertyLimitDesc.SHOW_ALL.equals(propertyLimitDesc)) {
+ // keep everything
+ } else if (PropertyLimitDesc.SHOW_NAME_AND_KEYS_ONLY.equals(propertyLimitDesc)) {
+ HashMap<String, Object> keysAndNamesPropHash = new HashMap<String, Object>();
+
+ for (String key : thisObj.getAllKeys()) {
+ keysAndNamesPropHash.put(key, null);
+ }
+ String namePropMetaData = thisObj.getMetadata(ObjectMetadata.NAME_PROPS);
+ if (namePropMetaData != null) {
+ String[] nameProps = namePropMetaData.split(",");
+ for (String names : nameProps) {
+ keysAndNamesPropHash.put(names, null);
+ }
+ }
+ filterProperties(thisObj, keysAndNamesPropHash);
+ }
+ } else {
+ if (resultSet.getPropertyOverRideHash() != null && resultSet.getPropertyOverRideHash().size() > 0) {
+ Map<String, Object> propertyOverRideHash = resultSet.getPropertyOverRideHash();
+ if (propertyOverRideHash.containsKey("persona-model-id")) {
+ propertyOverRideHash.remove("persona-model-id");
+ propertyOverRideHash.put("model-invariant-id", null);
+ }
+ for (String key : thisObj.getAllKeys()) {
+ propertyOverRideHash.put(key, null);
+ }
+ filterProperties(thisObj, propertyOverRideHash);
+ } else {
+ // keep everything
+ }
+ }
+
+ if (thisObj != null) {
+ inventoryItem.setValue("item", thisObj.getUnderlyingObject());
+
+ String modelName = null;
+ try {
+ // Try to get the modelName if we can. Otherwise, do not fail, just return what we have already.
+ String modelInvariantIdLocal =
+ (String) vert.<String>property("model-invariant-id-local").orElse(null); // this one
+ // points at a
+ // model
+ String modelVersionIdLocal =
+ (String) vert.<String>property("model-version-id-local").orElse(null); // this one
+ // points at a
+ // model-ver
+
+ if ((modelInvariantIdLocal != null && modelVersionIdLocal != null)
+ && (modelInvariantIdLocal.length() > 0 && modelVersionIdLocal.length() > 0)) {
+ Introspector modelVer = loader.introspectorFromName("model-ver");
+ modelVer.setValue("model-version-id", modelVersionIdLocal);
+ QueryBuilder builder = engine.getQueryBuilder().createDBQuery(modelVer);
+ List<Vertex> modelVerVerts = builder.toList();
+ if ((modelVerVerts != null) && (modelVerVerts.size() == 1)) {
+ Vertex modelVerVert = modelVerVerts.get(0);
+ modelName = modelVerVert.<String>property("model-name").orElse(null);
+ if (modelName != null && modelName.length() > 0) {
+ inventoryItem.setValue("model-name", modelName);
+ }
+ }
+ }
+ } catch (DynamicException e) {
+ ; // it's ok, dynamic object might not have these fields
+ } catch (Exception e) {
+ ; // it's ok, couldn't find a matching model
+ }
+
+ if (resultSet.getSubResultSet() != null) {
+ List<ResultSet> subResultSet = resultSet.getSubResultSet();
+ if (subResultSet != null && subResultSet.size() > 0) {
+ List<Object> res = unpackResultSet(subResultSet, engine, loader, serializer);
+ if (res.size() > 0) {
+ inventoryItems.setValue("inventory-response-item", res);
+ inventoryItem.setValue("inventory-response-items",
+ inventoryItems.getUnderlyingObject());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return resultList;
+ }
+
+ private void filterProperties(Introspector thisObj, Map<String, Object> override) {
+
+ thisObj.getProperties().stream().filter(x -> {
+ return !override.containsKey(x);
+ }).forEach(prop -> {
+ if (thisObj.isSimpleType(prop)) {
+ thisObj.setValue(prop, null);
+ }
+ });
+
+ }
+
+ /**
+ * Gets the media type.
+ *
+ * @param mediaTypeList the media type list
+ * @return the media type
+ */
+ protected String getMediaType(List<MediaType> mediaTypeList) {
+ String mediaType = MediaType.APPLICATION_JSON; // json is the default
+ for (MediaType mt : mediaTypeList) {
+ if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt)) {
+ mediaType = MediaType.APPLICATION_XML;
+ }
+ }
+ return mediaType;
+ }
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java
index f61e342..8c97c0a 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java
@@ -22,7 +22,6 @@ package org.onap.aai.rest.search;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
-
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -35,7 +34,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
-
import org.onap.aai.dbgraphmap.SearchGraph;
import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.exceptions.AAIException;
@@ -54,304 +52,262 @@ import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
-import org.onap.aai.util.AAIConstants;
+import org.onap.aai.util.GenericQueryBuilder;
+import org.onap.aai.util.NodesQueryBuilder;
import org.onap.aai.util.TraversalConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.onap.aai.concurrent.AaiCallable;
-
import com.att.eelf.configuration.EELFLogger;
import com.att.eelf.configuration.EELFManager;
import org.springframework.beans.factory.annotation.Value;
/**
- * Implements the search subdomain in the REST API. All API calls must include
- * X-FromAppId and X-TransactionId in the header.
+ * Implements the search subdomain in the REST API. All API calls must include X-FromAppId and
+ * X-TransactionId in the header.
*/
@Path("/{version: v[1-9][0-9]*|latest}/search")
public class SearchProvider extends RESTAPI {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchProvider.class);
-
- public static final String GENERIC_QUERY = "/generic-query";
-
- public static final String NODES_QUERY = "/nodes-query";
-
- public static final String TARGET_ENTITY = "DB";
-
- private SearchGraph searchGraph;
-
- private LoaderFactory loaderFactory;
-
- private SchemaVersions schemaVersions;
-
- private String basePath;
-
- @Autowired
- public SearchProvider(
- LoaderFactory loaderFactory,
- SearchGraph searchGraph,
- SchemaVersions schemaVersions,
- @Value("${schema.uri.base.path}") String basePath
- ){
- this.loaderFactory = loaderFactory;
- this.searchGraph = searchGraph;
- this.schemaVersions = schemaVersions;
- this.basePath = basePath;
- }
-
- /**
- * Gets the generic query response.
- *
- * @param headers the headers
- * @param req the req
- * @param startNodeType the start node type
- * @param startNodeKeyParams the start node key params
- * @param includeNodeTypes the include node types
- * @param depth the depth
- * @return the generic query response
- */
- /* ---------------- Start Generic Query --------------------- */
- @GET
- @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
- @Path(GENERIC_QUERY)
- public Response getGenericQueryResponse(@Context HttpHeaders headers,
- @Context HttpServletRequest req,
- @QueryParam("start-node-type") final String startNodeType,
- @QueryParam("key") final List<String> startNodeKeyParams,
- @QueryParam("include") final List<String> includeNodeTypes,
- @QueryParam("depth") final int depth,
- @PathParam("version")String versionParam,
- @Context UriInfo info
- ) {
- return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED,
- TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP,
- TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT,
- headers,
- info,
- HttpMethod.GET,
- new AaiCallable<Response>() {
- @Override
- public Response process() {
- return processGenericQueryResponse(headers, req, startNodeType, startNodeKeyParams, includeNodeTypes, depth, versionParam);
- }
- }
- );
- }
-
- public Response processGenericQueryResponse(@Context HttpHeaders headers,
- @Context HttpServletRequest req,
- @QueryParam("start-node-type") final String startNodeType,
- @QueryParam("key") final List<String> startNodeKeyParams,
- @QueryParam("include") final List<String> includeNodeTypes,
- @QueryParam("depth") final int depth,
- @PathParam("version")String versionParam
- ) {
-
- String methodName = "getGenericQueryResponse";
- AAIException ex = null;
- Response searchResult = null;
- String fromAppId = null;
- String transId = null;
- String rqstTm = genDate();
- ArrayList<String> templateVars = new ArrayList<String>();
- double dbTimeMsecs = 0;
- try {
- LoggingContext.save();
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
-
- fromAppId = getFromAppId(headers);
- transId = getTransId(headers);
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
- //only consider header value for search
- DBConnectionType type = this.determineConnectionType("force-cache", realTime);
-
- final SchemaVersion version = new SchemaVersion(versionParam);
-
- final ModelType factoryType = ModelType.MOXY;
- Loader loader = loaderFactory.createLoaderForVersion(factoryType, version);
- TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(
- QueryStyle.TRAVERSAL,
- type,
- loader);
- DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
- UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer, schemaVersions, this.basePath);
- LoggingContext.startTime();
- StopWatch.conditionalStart();
- searchResult = searchGraph.runGenericQuery(
- headers,
- startNodeType,
- startNodeKeyParams,
- includeNodeTypes,
- depth,
- dbEngine,
- loader,
- urlBuilder
-
- );
- dbTimeMsecs += StopWatch.stopIfStarted();
-
- LoggingContext.successStatusFields();
- LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
-
- LOGGER.info ("Completed");
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
-
- String respTm = genDate();
-
- } catch (AAIException e) {
- LoggingContext.restoreIfPossible();
- // send error response
- ex = e;
- templateVars.add("GET Search");
- templateVars.add("getGenericQueryResponse");
- searchResult = Response
- .status(e.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
- .build();
- } catch (Exception e) {
- LoggingContext.restoreIfPossible();
- // send error response
- ex = new AAIException("AAI_4000", e);
- templateVars.add("GET Search");
- templateVars.add("getGenericQueryResponse");
- searchResult = Response
- .status(Status.INTERNAL_SERVER_ERROR)
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
- .build();
- } finally {
- // log success or failure
- if (ex != null){
- ErrorLogHelper.logException(ex);
- }
- }
-
- return searchResult;
- }
-
- /* ---------------- End Generic Query --------------------- */
-
- /**
- * Gets the nodes query response.
- *
- * @param headers the headers
- * @param req the req
- * @param searchNodeType the search node type
- * @param edgeFilterList the edge filter list
- * @param filterList the filter list
- * @return the nodes query response
- */
- /* ---------------- Start Nodes Query --------------------- */
- @GET
- @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
- @Path(NODES_QUERY)
- public Response getNodesQueryResponse(@Context HttpHeaders headers,
- @Context HttpServletRequest req,
- @QueryParam("search-node-type") final String searchNodeType,
- @QueryParam("edge-filter") final List<String> edgeFilterList,
- @QueryParam("filter") final List<String> filterList,
- @PathParam("version")String versionParam,
- @Context UriInfo info)
-
- {
- return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED,
- TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP,
- TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT,
- headers,
- info,
- HttpMethod.GET,
- new AaiCallable<Response>() {
- @Override
- public Response process() {
- return processNodesQueryResponse(headers, req, searchNodeType, edgeFilterList, filterList, versionParam);
- }
- }
- );
- }
- public Response processNodesQueryResponse(@Context HttpHeaders headers,
- @Context HttpServletRequest req,
- @QueryParam("search-node-type") final String searchNodeType,
- @QueryParam("edge-filter") final List<String> edgeFilterList,
- @QueryParam("filter") final List<String> filterList,
- @PathParam("version")String versionParam) {
- String methodName = "getNodesQueryResponse";
- AAIException ex = null;
- Response searchResult = null;
- String fromAppId = null;
- String transId = null;
- String rqstTm = genDate();
- ArrayList<String> templateVars = new ArrayList<String>();
- double dbTimeMsecs = 0;
- try {
- LoggingContext.save();
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
-
- fromAppId = getFromAppId(headers);
- transId = getTransId(headers);
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
- //only consider header value for search
- DBConnectionType type = this.determineConnectionType("force-cache", realTime);
-
- final SchemaVersion version = new SchemaVersion(versionParam);
-
- final ModelType factoryType = ModelType.MOXY;
- Loader loader = loaderFactory.createLoaderForVersion(factoryType, version);
- TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(
- QueryStyle.TRAVERSAL,
- type,
- loader);
- DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
- UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer, schemaVersions, this.basePath);
-
- LoggingContext.startTime();
- StopWatch.conditionalStart();
- searchResult = searchGraph.runNodesQuery(headers,
- searchNodeType,
- edgeFilterList,
- filterList,
- dbEngine,
- loader,
- urlBuilder);
- dbTimeMsecs += StopWatch.stopIfStarted();
- LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
- LoggingContext.successStatusFields();
- LOGGER.info ("Completed");
-
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
-
- String respTm = genDate();
- } catch (AAIException e) {
- LoggingContext.restoreIfPossible();
- // send error response
- ex = e;
- templateVars.add("GET Search");
- templateVars.add("getNodesQueryResponse");
- searchResult = Response
- .status(e.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
- .build();
- } catch (Exception e) {
- LoggingContext.restoreIfPossible();
- // send error response
- ex = new AAIException("AAI_4000", e);
- templateVars.add("GET Search");
- templateVars.add("getNodesQueryResponse");
- searchResult = Response
- .status(Status.INTERNAL_SERVER_ERROR)
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
- .build();
- } finally {
- // log success or failure
- if (ex != null){
- ErrorLogHelper.logException(ex);
- }
- }
- return searchResult;
- }
-
-
-
+ private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchProvider.class);
+
+ public static final String GENERIC_QUERY = "/generic-query";
+
+ public static final String NODES_QUERY = "/nodes-query";
+
+ public static final String TARGET_ENTITY = "DB";
+
+ private SearchGraph searchGraph;
+
+ private LoaderFactory loaderFactory;
+
+ private SchemaVersions schemaVersions;
+
+ private String basePath;
+
+ @Autowired
+ public SearchProvider(LoaderFactory loaderFactory, SearchGraph searchGraph, SchemaVersions schemaVersions,
+ @Value("${schema.uri.base.path}") String basePath) {
+ this.loaderFactory = loaderFactory;
+ this.searchGraph = searchGraph;
+ this.schemaVersions = schemaVersions;
+ this.basePath = basePath;
+ }
+
+ /**
+ * Gets the generic query response.
+ *
+ * @param headers the headers
+ * @param req the req
+ * @param startNodeType the start node type
+ * @param startNodeKeyParams the start node key params
+ * @param includeNodeTypes the include node types
+ * @param depth the depth
+ * @return the generic query response
+ */
+ /* ---------------- Start Generic Query --------------------- */
+ @GET
+ @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+ @Path(GENERIC_QUERY)
+ public Response getGenericQueryResponse(@Context HttpHeaders headers, @Context HttpServletRequest req,
+ @QueryParam("start-node-type") final String startNodeType,
+ @QueryParam("key") final List<String> startNodeKeyParams,
+ @QueryParam("include") final List<String> includeNodeTypes, @QueryParam("depth") final int depth,
+ @PathParam("version") String versionParam, @Context UriInfo info) {
+ return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED, TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP,
+ TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT, headers, info, HttpMethod.GET,
+ new AaiCallable<Response>() {
+ @Override
+ public Response process() {
+ return processGenericQueryResponse(headers, req, startNodeType, startNodeKeyParams,
+ includeNodeTypes, depth, versionParam);
+ }
+ });
+ }
+
+ public Response processGenericQueryResponse(@Context HttpHeaders headers, @Context HttpServletRequest req,
+ @QueryParam("start-node-type") final String startNodeType,
+ @QueryParam("key") final List<String> startNodeKeyParams,
+ @QueryParam("include") final List<String> includeNodeTypes, @QueryParam("depth") final int depth,
+ @PathParam("version") String versionParam) {
+
+ String methodName = "getGenericQueryResponse";
+ AAIException ex = null;
+ Response searchResult = null;
+ String fromAppId = null;
+ String transId = null;
+ String rqstTm = genDate();
+ ArrayList<String> templateVars = new ArrayList<String>();
+ double dbTimeMsecs = 0;
+ try {
+ LoggingContext.save();
+ LoggingContext.targetEntity(TARGET_ENTITY);
+ LoggingContext.targetServiceName(methodName);
+
+ fromAppId = getFromAppId(headers);
+ transId = getTransId(headers);
+ String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+ // only consider header value for search
+ DBConnectionType type = this.determineConnectionType("force-cache", realTime);
+
+ final SchemaVersion version = new SchemaVersion(versionParam);
+
+ final ModelType factoryType = ModelType.MOXY;
+ Loader loader = loaderFactory.createLoaderForVersion(factoryType, version);
+ TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, type, loader);
+ DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
+ UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer, schemaVersions, this.basePath);
+ LoggingContext.startTime();
+ StopWatch.conditionalStart();
+ searchResult = searchGraph
+ .runGenericQuery(new GenericQueryBuilder().setHeaders(headers).setStartNodeType(startNodeType)
+ .setStartNodeKeyParams(startNodeKeyParams).setIncludeNodeTypes(includeNodeTypes)
+ .setDepth(depth).setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder));
+ dbTimeMsecs += StopWatch.stopIfStarted();
+
+ LoggingContext.successStatusFields();
+ LoggingContext.elapsedTime((long) dbTimeMsecs, TimeUnit.MILLISECONDS);
+
+ LOGGER.info("Completed");
+ LoggingContext.restoreIfPossible();
+ LoggingContext.successStatusFields();
+
+ String respTm = genDate();
+
+ } catch (AAIException e) {
+ LoggingContext.restoreIfPossible();
+ // send error response
+ ex = e;
+ templateVars.add("GET Search");
+ templateVars.add("getGenericQueryResponse");
+ searchResult = Response.status(e.getErrorObject().getHTTPResponseCode())
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
+ .build();
+ } catch (Exception e) {
+ LoggingContext.restoreIfPossible();
+ // send error response
+ ex = new AAIException("AAI_4000", e);
+ templateVars.add("GET Search");
+ templateVars.add("getGenericQueryResponse");
+ searchResult = Response.status(Status.INTERNAL_SERVER_ERROR)
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+ .build();
+ } finally {
+ // log success or failure
+ if (ex != null) {
+ ErrorLogHelper.logException(ex);
+ }
+ }
+
+ return searchResult;
+ }
+
+ /* ---------------- End Generic Query --------------------- */
+
+ /**
+ * Gets the nodes query response.
+ *
+ * @param headers the headers
+ * @param req the req
+ * @param searchNodeType the search node type
+ * @param edgeFilterList the edge filter list
+ * @param filterList the filter list
+ * @return the nodes query response
+ */
+ /* ---------------- Start Nodes Query --------------------- */
+ @GET
+ @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+ @Path(NODES_QUERY)
+ public Response getNodesQueryResponse(@Context HttpHeaders headers, @Context HttpServletRequest req,
+ @QueryParam("search-node-type") final String searchNodeType,
+ @QueryParam("edge-filter") final List<String> edgeFilterList,
+ @QueryParam("filter") final List<String> filterList, @PathParam("version") String versionParam,
+ @Context UriInfo info)
+
+ {
+ return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED, TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP,
+ TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT, headers, info, HttpMethod.GET,
+ new AaiCallable<Response>() {
+ @Override
+ public Response process() {
+ return processNodesQueryResponse(headers, req, searchNodeType, edgeFilterList, filterList,
+ versionParam);
+ }
+ });
+ }
+
+ public Response processNodesQueryResponse(@Context HttpHeaders headers, @Context HttpServletRequest req,
+ @QueryParam("search-node-type") final String searchNodeType,
+ @QueryParam("edge-filter") final List<String> edgeFilterList,
+ @QueryParam("filter") final List<String> filterList, @PathParam("version") String versionParam) {
+ String methodName = "getNodesQueryResponse";
+ AAIException ex = null;
+ Response searchResult = null;
+ String fromAppId = null;
+ String transId = null;
+ String rqstTm = genDate();
+ ArrayList<String> templateVars = new ArrayList<String>();
+ double dbTimeMsecs = 0;
+ try {
+ LoggingContext.save();
+ LoggingContext.targetEntity(TARGET_ENTITY);
+ LoggingContext.targetServiceName(methodName);
+
+ fromAppId = getFromAppId(headers);
+ transId = getTransId(headers);
+ String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+ // only consider header value for search
+ DBConnectionType type = this.determineConnectionType("force-cache", realTime);
+
+ final SchemaVersion version = new SchemaVersion(versionParam);
+
+ final ModelType factoryType = ModelType.MOXY;
+ Loader loader = loaderFactory.createLoaderForVersion(factoryType, version);
+ TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, type, loader);
+ DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
+ UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer, schemaVersions, this.basePath);
+
+ LoggingContext.startTime();
+ StopWatch.conditionalStart();
+ searchResult = searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(headers)
+ .setTargetNodeType(searchNodeType).setEdgeFilterParams(edgeFilterList).setFilterParams(filterList)
+ .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder));
+
+ dbTimeMsecs += StopWatch.stopIfStarted();
+ LoggingContext.elapsedTime((long) dbTimeMsecs, TimeUnit.MILLISECONDS);
+ LoggingContext.successStatusFields();
+ LOGGER.info("Completed");
+
+ LoggingContext.restoreIfPossible();
+ LoggingContext.successStatusFields();
+
+ String respTm = genDate();
+ } catch (AAIException e) {
+ LoggingContext.restoreIfPossible();
+ // send error response
+ ex = e;
+ templateVars.add("GET Search");
+ templateVars.add("getNodesQueryResponse");
+ searchResult = Response.status(e.getErrorObject().getHTTPResponseCode())
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
+ .build();
+ } catch (Exception e) {
+ LoggingContext.restoreIfPossible();
+ // send error response
+ ex = new AAIException("AAI_4000", e);
+ templateVars.add("GET Search");
+ templateVars.add("getNodesQueryResponse");
+ searchResult = Response.status(Status.INTERNAL_SERVER_ERROR)
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+ .build();
+ } finally {
+ // log success or failure
+ if (ex != null) {
+ ErrorLogHelper.logException(ex);
+ }
+ }
+ return searchResult;
+ }
+
+
+
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/util/GenericQueryBuilder.java b/aai-traversal/src/main/java/org/onap/aai/util/GenericQueryBuilder.java
new file mode 100644
index 0000000..8570fe4
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/util/GenericQueryBuilder.java
@@ -0,0 +1,114 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Samsung Electronics Co., Ltd. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.util;
+
+import javax.ws.rs.core.HttpHeaders;
+import java.util.List;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+/**
+ * Builder Class used to minimize number of formal parameters.
+ */
+
+public class GenericQueryBuilder {
+
+ private HttpHeaders headers;
+ private String startNodeType;
+ private List<String> startNodeKeyParams;
+ private List<String> includeNodeTypes;
+ private int depth;
+ private TransactionalGraphEngine dbEngine;
+ private Loader loader;
+ private UrlBuilder urlBuilder;
+
+ public HttpHeaders getHeaders() {
+ return headers;
+ }
+
+ public String getStartNodeType() {
+ return startNodeType;
+ }
+
+ public List<String> getStartNodeKeyParams() {
+ return startNodeKeyParams;
+ }
+
+ public List<String> getIncludeNodeTypes() {
+ return includeNodeTypes;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public TransactionalGraphEngine getDbEngine() {
+ return dbEngine;
+ }
+
+ public Loader getLoader() {
+ return loader;
+ }
+
+ public UrlBuilder getUrlBuilder() {
+ return urlBuilder;
+ }
+
+ public GenericQueryBuilder setHeaders(HttpHeaders headers) {
+ this.headers = headers;
+ return this;
+ }
+
+ public GenericQueryBuilder setStartNodeType(String startNodeType) {
+ this.startNodeType = startNodeType;
+ return this;
+ }
+
+ public GenericQueryBuilder setStartNodeKeyParams(List<String> startNodeKeyParams) {
+ this.startNodeKeyParams = startNodeKeyParams;
+ return this;
+ }
+
+ public GenericQueryBuilder setIncludeNodeTypes(List<String> includeNodeTypes) {
+ this.includeNodeTypes = includeNodeTypes;
+ return this;
+ }
+
+ public GenericQueryBuilder setDepth(int depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public GenericQueryBuilder setDbEngine(TransactionalGraphEngine dbEngine) {
+ this.dbEngine = dbEngine;
+ return this;
+ }
+
+ public GenericQueryBuilder setLoader(Loader loader) {
+ this.loader = loader;
+ return this;
+ }
+
+ public GenericQueryBuilder setUrlBuilder(UrlBuilder urlBuilder) {
+ this.urlBuilder = urlBuilder;
+ return this;
+ }
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/util/NodesQueryBuilder.java b/aai-traversal/src/main/java/org/onap/aai/util/NodesQueryBuilder.java
new file mode 100644
index 0000000..978e484
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/util/NodesQueryBuilder.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Samsung Electronics Co., Ltd. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.util;
+
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import javax.ws.rs.core.HttpHeaders;
+import java.util.List;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+
+/**
+ * Builder Class used to minimize number of formal parameters.
+ */
+
+public class NodesQueryBuilder {
+
+ private HttpHeaders headers;
+ private List<String> edgeFilterParams;
+ private List<String> filterParams;
+ private TransactionalGraphEngine dbEngine;
+ private Loader loader;
+ private UrlBuilder urlBuilder;
+ private String targetNodeType;
+
+ public HttpHeaders getHeaders() {
+ return headers;
+ }
+
+ public NodesQueryBuilder setHeaders(HttpHeaders headers) {
+ this.headers = headers;
+ return this;
+ }
+
+ public String getTargetNodeType() {
+ return targetNodeType;
+ }
+
+ public NodesQueryBuilder setTargetNodeType(String targetNodeType) {
+ this.targetNodeType = targetNodeType;
+ return this;
+ }
+
+ public List<String> getEdgeFilterParams() {
+ return edgeFilterParams;
+ }
+
+ public NodesQueryBuilder setEdgeFilterParams(List<String> edgeFilterParams) {
+ this.edgeFilterParams = edgeFilterParams;
+ return this;
+ }
+
+ public List<String> getFilterParams() {
+ return filterParams;
+ }
+
+ public NodesQueryBuilder setFilterParams(List<String> filterParams) {
+ this.filterParams = filterParams;
+ return this;
+ }
+
+ public TransactionalGraphEngine getDbEngine() {
+ return dbEngine;
+ }
+
+ public NodesQueryBuilder setDbEngine(TransactionalGraphEngine dbEngine) {
+ this.dbEngine = dbEngine;
+ return this;
+ }
+
+ public Loader getLoader() {
+ return loader;
+ }
+
+ public NodesQueryBuilder setLoader(Loader loader) {
+ this.loader = loader;
+ return this;
+ }
+
+ public UrlBuilder getUrlBuilder() {
+ return urlBuilder;
+ }
+
+ public NodesQueryBuilder setUrlBuilder(UrlBuilder urlBuilder) {
+ this.urlBuilder = urlBuilder;
+ return this;
+ }
+
+}