diff options
author | LaMont, William (wl2432) <wl2432@att.com> | 2019-01-11 15:21:39 -0500 |
---|---|---|
committer | LaMont, William (wl2432) <wl2432@us.att.com> | 2019-01-16 11:56:04 -0500 |
commit | 16b48ab05e63fca707585b4ecee466b8b7721a1b (patch) | |
tree | bca44c248860f73d65031162a6f5581c4fef649b /aai-traversal/src/main | |
parent | c0365f15a25aed95f7e812dc1d7e7ac588ebbed5 (diff) |
Update traversal to support v15
Issue-ID: AAI-2073
Change-Id: I1c3df218d1333bdebc984947edc100607958ab60
Signed-off-by: LaMont, William (wl2432) <wl2432@us.att.com>
Diffstat (limited to 'aai-traversal/src/main')
28 files changed, 730 insertions, 201 deletions
diff --git a/aai-traversal/src/main/docker/docker-entrypoint.sh b/aai-traversal/src/main/docker/docker-entrypoint.sh index c9e76ec..c4c4a03 100644 --- a/aai-traversal/src/main/docker/docker-entrypoint.sh +++ b/aai-traversal/src/main/docker/docker-entrypoint.sh @@ -65,7 +65,6 @@ if [ -f ${APP_HOME}/aai.sh ]; then exit 0; fi; - fi; if [ -z ${DISABLE_UPDATE_QUERY} ]; then @@ -83,8 +82,7 @@ fi; MIN_HEAP_SIZE=${MIN_HEAP_SIZE:-512m}; MAX_HEAP_SIZE=${MAX_HEAP_SIZE:-1024m}; -MAX_PERM_SIZE=${MAX_PERM_SIZE:-512m}; -PERM_SIZE=${PERM_SIZE:-512m} +MAX_METASPACE_SIZE=${MAX_METASPACE_SIZE:-512m}; JAVA_CMD="exec gosu aaiadmin java"; @@ -95,8 +93,7 @@ JVM_OPTS="${JVM_OPTS} -Xmx${MAX_HEAP_SIZE}"; JVM_OPTS="${JVM_OPTS} -XX:+PrintGCDetails"; JVM_OPTS="${JVM_OPTS} -XX:+PrintGCTimeStamps"; -JVM_OPTS="${JVM_OPTS} -XX:MaxPermSize=${MAX_PERM_SIZE}"; -JVM_OPTS="${JVM_OPTS} -XX:PermSize=${PERM_SIZE}"; +JVM_OPTS="${JVM_OPTS} -XX:MaxMetaspaceSize=${MAX_METASPACE_SIZE}"; JVM_OPTS="${JVM_OPTS} -server"; JVM_OPTS="${JVM_OPTS} -XX:NewSize=512m"; @@ -128,6 +125,7 @@ JAVA_OPTS="${JAVA_OPTS} -DAAI_BUILD_VERSION=${AAI_BUILD_VERSION}"; JAVA_OPTS="${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom"; JAVA_OPTS="${JAVA_OPTS} -Dlogback.configurationFile=./resources/logback.xml"; JAVA_OPTS="${JAVA_OPTS} -Dloader.path=$APP_HOME/resources"; +JAVA_OPTS="${JAVA_OPTS} -Dgroovy.use.classvalue=true"; JAVA_OPTS="${JAVA_OPTS} ${POST_JAVA_OPTS}"; JAVA_MAIN_JAR=$(ls lib/aai-traversal*.jar); diff --git a/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java b/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java index 2797545..64a3b44 100644 --- a/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java +++ b/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java @@ -21,10 +21,12 @@ package org.onap.aai; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.onap.aai.config.PropertyPasswordConfiguration; import org.onap.aai.config.SpringContextAware; import org.onap.aai.dbmap.AAIGraph; import org.onap.aai.exceptions.AAIException; +import org.onap.aai.logging.ErrorLogHelper; import org.onap.aai.logging.LoggingContext; import org.onap.aai.logging.LoggingContext.StatusCode; import org.onap.aai.nodes.NodeIngestor; @@ -56,7 +58,8 @@ import java.util.Map; "org.onap.aai.setup", "org.onap.aai.tasks", "org.onap.aai.service", - "org.onap.aai.rest" + "org.onap.aai.rest", + "org.onap.aai.rest-client" }) @EnableAutoConfiguration(exclude = { @@ -122,14 +125,40 @@ public class TraversalApp { AAIGraph.getInstance().graphShutdown(); } - public static void main(String[] args) { + public static void main(String[] args) throws AAIException{ + + setDefaultProps(); + + LoggingContext.save(); + LoggingContext.component("init"); + LoggingContext.partnerName("NA"); + LoggingContext.targetEntity(APP_NAME); + LoggingContext.requestId(UUID.randomUUID().toString()); + LoggingContext.serviceName(APP_NAME); + LoggingContext.targetServiceName("contextInitialized"); + LoggingContext.statusCode(StatusCode.COMPLETE); + Environment env =null; + AAIConfig.init(); + + try{ + SpringApplication app = new SpringApplication(TraversalApp.class); + app.setLogStartupInfo(false); + app.setRegisterShutdownHook(true); + app.addInitializers(new PropertyPasswordConfiguration()); + env = app.run(args).getEnvironment(); + } + catch(Exception ex){ + AAIException aai = schemaServiceExceptionTranslator(ex); + LoggingContext.statusCode(LoggingContext.StatusCode.ERROR); + LoggingContext.responseCode(LoggingContext.DATA_ERROR); + logger.error("Problems starting Traversal "+aai.getMessage()); + ErrorLogHelper.logException(aai); + ErrorLogHelper.logError(aai.getCode(), ex.getMessage() + ", resolve and restart Traversal"); + //ErrorLogHelper.logError(aai.getCode(), aai.getMessage() + aai.getCause().toString()); + throw aai; + } + - setDefaultProps(); - SpringApplication app = new SpringApplication(TraversalApp.class); - app.setLogStartupInfo(false); - app.setRegisterShutdownHook(true); - app.addInitializers(new PropertyPasswordConfiguration()); - Environment env = app.run(args).getEnvironment(); MDC.setContextMap (contextMap); logger.info( "Application '{}' is running on {}!" , @@ -166,4 +195,25 @@ public class TraversalApp { } } + private static AAIException schemaServiceExceptionTranslator(Exception ex) { + AAIException aai = null; + logger.info("Error Message is "+ ExceptionUtils.getRootCause(ex).toString() + " details - "+ExceptionUtils.getRootCause(ex).getMessage()); + if(ExceptionUtils.getRootCause(ex).getMessage().contains("NodeIngestor")){ + aai = new AAIException("AAI_3026","Error reading OXM from SchemaService - Investigate"); + } + else if(ExceptionUtils.getRootCause(ex).getMessage().contains("EdgeIngestor")){ + aai = new AAIException("AAI_3027","Error reading EdgeRules from SchemaService - Investigate"); + } + else if(ExceptionUtils.getRootCause(ex).getMessage().contains("stored-queries")){ + aai = new AAIException("AAI_3027","Error reading EdgeRules from SchemaService - Investigate"); + } + else if(ExceptionUtils.getRootCause(ex).getMessage().contains("Connection refused")){ + aai = new AAIException("AAI_3025","Error connecting to SchemaService - Investigate"); + } + else { + aai = new AAIException("AAI_3025","Error connecting to SchemaService - Please Investigate"); + } + + return aai; + } } diff --git a/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java index 74bc046..311dd99 100644 --- a/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java +++ b/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java @@ -20,8 +20,10 @@ package org.onap.aai.config; import org.onap.aai.edges.EdgeIngestor; +import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.rest.dsl.DslListener; import org.onap.aai.rest.dsl.DslQueryProcessor; +import org.onap.aai.setup.SchemaVersions; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -32,8 +34,8 @@ public class DslConfiguration { @Bean @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public DslListener dslListener(EdgeIngestor edgeIngestor){ - return new DslListener(edgeIngestor); + public DslListener dslListener(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory){ + return new DslListener(edgeIngestor, schemaVersions, loaderFactory); } @Bean diff --git a/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java index bef10d0..0b8238b 100644 --- a/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java +++ b/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java @@ -25,17 +25,30 @@ import org.onap.aai.edges.EdgeIngestor; import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.rest.dsl.DslListener; import org.onap.aai.rest.dsl.DslQueryProcessor; +import org.onap.aai.rest.search.CQConfig; import org.onap.aai.rest.search.GremlinServerSingleton; +import org.onap.aai.rest.search.LocalCQConfig; +import org.onap.aai.rest.search.SchemaServiceCQConfig; import org.onap.aai.setup.SchemaVersions; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Scope; @Configuration +@PropertySource(value = "classpath:schema-ingest.properties", ignoreResourceNotFound = true) +@PropertySource(value = "file:${schema.ingest.file}", ignoreResourceNotFound = true) + public class SearchConfiguration { + private static final String CONFIG_TRANSLATOR = "config"; + private static final String SCHEMA_SERVICE_TRANSLATOR = "schema-service"; + + @Value("${schema.translator.list}") + private String translator; + @Bean public SearchGraph searchGraph(LoaderFactory loaderFactory, EdgeIngestor edgeIngestor, SchemaVersions schemaVersions) { SearchGraph searchGraph = new SearchGraph(loaderFactory, edgeIngestor, schemaVersions); @@ -44,7 +57,18 @@ public class SearchConfiguration { @Bean public GremlinServerSingleton gremlinServerSingleton(){ - return new GremlinServerSingleton(); + return new GremlinServerSingleton(getCustomQueryConfig()); } + + @Bean + public CQConfig getCustomQueryConfig(){ + if(translator.equals(SCHEMA_SERVICE_TRANSLATOR)) { + return new SchemaServiceCQConfig(); + } + return new LocalCQConfig(); + } + + + } 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 0725802..0221d8a 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 @@ -28,6 +28,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import java.util.stream.Stream; import javax.ws.rs.core.HttpHeaders; @@ -520,7 +521,7 @@ public class SearchGraph { edgeRules = edgeIngestor.getRules(query); //Map<String, EdgeRule> rules = EdgeRules.getInstance().getEdgeRules(targetNodeType, nodeType); - String[] results = edgeRules.keySet().toArray(new String[0]); + String[] results = edgeRules.values().stream().map(rule -> rule.getLabel()).collect(Collectors.toList()).toArray(new String[0]); return results; } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java index bdca63b..ad5fffb 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java @@ -59,6 +59,7 @@ import org.onap.aai.serialization.queryformats.Formatter; import org.onap.aai.serialization.queryformats.SubGraphStyle; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.setup.SchemaVersions; +import org.onap.aai.util.AAIConfig; import org.onap.aai.util.TraversalConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -104,14 +105,14 @@ public class DslConsumer extends RESTAPI { public Response executeQuery(String content, @PathParam("version") String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat, @DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, - @Context UriInfo info, @Context HttpServletRequest req) { + @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) { return runner(TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_ENABLED, TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_APP, TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_LIMIT, headers, info, HttpMethod.PUT, new AaiCallable<Response>() { @Override public Response process() { return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info, - req); + req, resultIndex, resultSize); } }); } @@ -119,10 +120,11 @@ public class DslConsumer extends RESTAPI { public Response processExecuteQuery(String content, @PathParam("version") String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat, @DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, - @Context UriInfo info, @Context HttpServletRequest req) { + @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) { String methodName = "executeDslQuery"; String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); + String dslOverride = headers.getRequestHeaders().getFirst("X-DslOverride"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); Response response; SchemaVersion version = new SchemaVersion(versionParam); @@ -132,6 +134,7 @@ public class DslConsumer extends RESTAPI { LoggingContext.save(); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); traversalUriHttpEntry.setHttpEntryProperties(version, type); + traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize); dbEngine = traversalUriHttpEntry.getDbEngine(); JsonObject input = new JsonParser().parse(content).getAsJsonObject(); JsonElement dslElement = input.get("dsl"); @@ -145,29 +148,46 @@ public class DslConsumer extends RESTAPI { LoggingContext.startTime(); StopWatch.conditionalStart(); + boolean isDslOverride = dslOverride != null && !AAIConfig.get(TraversalConstants.DSL_OVERRIDE).equals("false") + && dslOverride.equals(AAIConfig.get(TraversalConstants.DSL_OVERRIDE)); + + if(isDslOverride) + dslQueryProcessor.setValidationFlag(false); + GenericQueryProcessor processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton) .queryFrom(dsl, "dsl").queryProcessor(dslQueryProcessor).processWith(processorType).create(); - + String result = ""; SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph); - List<Object> vertices = processor.execute(subGraphStyle); - + List<Object> vertTemp = processor.execute(subGraphStyle); + List<Object> vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp); DBSerializer serializer = new DBSerializer(version, dbEngine, ModelType.MOXY, sourceOfTruth); Format format = Format.getFormat(queryFormat); FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath); - + Formatter formater = ff.get(format, info.getQueryParameters()); result = formater.output(vertices).toString(); - + double msecs = StopWatch.stopIfStarted(); LoggingContext.elapsedTime((long) msecs, TimeUnit.MILLISECONDS); LoggingContext.successStatusFields(); LOGGER.info("Completed"); - - response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(result).build(); - + + if(traversalUriHttpEntry.isPaginated()){ + response = Response.status(Status.OK) + .type(MediaType.APPLICATION_JSON) + .header("total-results", traversalUriHttpEntry.getTotalVertices()) + .header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets()) + .entity(result) + .build(); + }else { + response = Response.status(Status.OK) + .type(MediaType.APPLICATION_JSON) + .entity(result).build(); + } + } catch (AAIException e) { response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, e); } catch (Exception e) { diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java index 7ce61e3..633bc9c 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java @@ -23,8 +23,10 @@ import java.net.URI; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -118,7 +120,7 @@ public class QueryConsumer extends RESTAPI { @PUT @Consumes({ MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON}) - public Response executeQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req){ + public Response executeQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize){ return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED, TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP, TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT, @@ -128,14 +130,13 @@ public class QueryConsumer extends RESTAPI { new AaiCallable<Response>() { @Override public Response process() { - return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info, req); + return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info, req, resultIndex, resultSize); } } ); } - public Response processExecuteQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) { - + public Response processExecuteQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) { String methodName = "executeQuery"; String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); String realTime = headers.getRequestHeaders().getFirst("Real-Time"); @@ -165,6 +166,11 @@ public class QueryConsumer extends RESTAPI { SchemaVersion version = new SchemaVersion(versionParam); DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime); traversalUriHttpEntry.setHttpEntryProperties(version, type); + /* + * Changes for Pagination + */ + + traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize); dbEngine = traversalUriHttpEntry.getDbEngine(); if (startElement != null) { @@ -188,9 +194,17 @@ public class QueryConsumer extends RESTAPI { CustomQueryConfig customQueryConfig = getCustomQueryConfig(queryURIObj); if ( customQueryConfig != null ) { List<String> missingRequiredQueryParameters = checkForMissingQueryParameters( customQueryConfig.getQueryRequiredProperties(), URITools.getQueryMap(queryURIObj)); + if ( !missingRequiredQueryParameters.isEmpty() ) { return( createMessageMissingQueryRequiredParameters( missingRequiredQueryParameters, headers, info, req)); } + + List<String> invalidQueryParameters = checkForInvalidQueryParameters( customQueryConfig, URITools.getQueryMap(queryURIObj)); + + if ( !invalidQueryParameters.isEmpty() ) { + return( createMessageInvalidQueryParameters( invalidQueryParameters, headers, info, req)); + } + } else if ( queryElement != null ) { return( createMessageInvalidQuerySection( queryURI, headers, info, req)); } @@ -227,8 +241,9 @@ public class QueryConsumer extends RESTAPI { .processWith(processorType).create(); } String result = ""; - List<Object> vertices = processor.execute(subGraphStyle); - + List<Object> vertTemp = processor.execute(subGraphStyle); + List<Object> vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp); + DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth); FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath); @@ -240,12 +255,19 @@ public class QueryConsumer extends RESTAPI { LoggingContext.elapsedTime((long)msecs,TimeUnit.MILLISECONDS); LoggingContext.successStatusFields(); LOGGER.info ("Completed"); - - - response = Response.status(Status.OK) - .type(MediaType.APPLICATION_JSON) - .entity(result).build(); + if(traversalUriHttpEntry.isPaginated()){ + response = Response.status(Status.OK) + .type(MediaType.APPLICATION_JSON) + .header("total-results", traversalUriHttpEntry.getTotalVertices()) + .header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets()) + .entity(result) + .build(); + }else { + response = Response.status(Status.OK) + .type(MediaType.APPLICATION_JSON) + .entity(result).build(); + } } catch (AAIException e) { response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, e); } catch (Exception e ) { @@ -340,6 +362,44 @@ public class QueryConsumer extends RESTAPI { return response; } + + + public List<String> checkForInvalidQueryParameters( CustomQueryConfig customQueryConfig, MultivaluedMap<String, String> queryParams) { + + List<String> allParameters = new ArrayList<String>(); + /* + * Add potential Required and Optional to allParameters + */ + Optional.ofNullable(customQueryConfig.getQueryOptionalProperties()).ifPresent(allParameters::addAll); + Optional.ofNullable(customQueryConfig.getQueryRequiredProperties()).ifPresent(allParameters::addAll); + + if(queryParams.isEmpty()) + return new ArrayList<>(); + List<String> invalidParameters = queryParams.keySet().stream() + .filter(param -> !allParameters.contains(param)) + .collect(Collectors.toList()); + + return invalidParameters; + + } + + private Response createMessageInvalidQueryParameters(List<String> invalidQueryParams, HttpHeaders headers, UriInfo info, HttpServletRequest req) { + AAIException e = new AAIException("AAI_3022"); + + ArrayList<String> templateVars = new ArrayList<>(); + + if (templateVars.isEmpty()) { + templateVars.add(invalidQueryParams.toString()); + } + + Response response = Response + .status(e.getErrorObject().getHTTPResponseCode()) + .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, + templateVars)).build(); + + return response; + } + } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java index 46bccdf..3154087 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java @@ -224,8 +224,13 @@ public class RecentAPIConsumer extends RESTAPI { if (params != null && params.containsKey("hours") && params.getFirst("hours").matches("-?\\d+")) { isHoursParameter = true; - - Long hours = Long.parseLong(params.getFirst("hours")); + Long hours = 0L; + try{ + hours = Long.parseLong(params.getFirst("hours")); + } + catch(NumberFormatException ex){ + throw new AAIException("AAI_3021", " Invalid Hours. Valid values for hours are 1 to " + AAIConstants.HISTORY_MAX_HOURS); + } if (hours < 1 || hours > AAIConstants.HISTORY_MAX_HOURS) { throw new AAIException("AAI_3021", " Valid values for hours are 1 to " + AAIConstants.HISTORY_MAX_HOURS); } @@ -233,7 +238,13 @@ public class RecentAPIConsumer extends RESTAPI { if (params != null && params.containsKey("date-time") && params.getFirst("date-time").matches("-?\\d+")) { isDateTimeParameter = true; Long minStartTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(AAIConstants.HISTORY_MAX_HOURS); - Long startTime = Long.parseLong(params.getFirst("date-time")); + Long startTime = 0L; + try{ + startTime = Long.parseLong(params.getFirst("date-time")); + } + catch(NumberFormatException ex){ + throw new AAIException("AAI_3021", " Invalid Data-time. Valid values for date-time are "+minStartTime+" to " + System.currentTimeMillis() ); + } if (startTime < minStartTime) { throw new AAIException("AAI_3021", " Valid values for date-time are "+minStartTime+" to " + System.currentTimeMillis() ); } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java index 3a3cc96..9ffa69b 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java @@ -19,8 +19,10 @@ */ package org.onap.aai.rest.dsl; +import java.util.ArrayList; import java.util.Deque; import java.util.LinkedList; +import java.util.List; import org.antlr.v4.runtime.ParserRuleContext; @@ -28,8 +30,12 @@ public class DslContext { private ParserRuleContext ctx; + private boolean validationFlag = true; + private boolean isStartNode = false; + private String startNode = ""; + private List<String> startNodeKeys = new ArrayList<String>(); + private String currentNode; - private String previousNode; private boolean isTraversal = false; @@ -38,7 +44,7 @@ public class DslContext { private boolean isUnionStart = false; private String whereStartNode = ""; - + private Deque<String> unionStartNodes = new LinkedList<String>(); /* @@ -55,6 +61,26 @@ public class DslContext { this.ctx = ctx; } + public boolean isStartNode() { + return isStartNode; + } + + public void setStartNodeFlag(boolean isStartNode) { + this.isStartNode = isStartNode; + } + + public String getStartNode() { + return startNode; + } + + public void setStartNode(String startNode) { + this.startNode = startNode; + } + + public List<String> getStartNodeKeys() { + return startNodeKeys; + } + public String getCurrentNode() { return currentNode; } @@ -126,5 +152,13 @@ public class DslContext { public void setLimitQuery(StringBuilder limitQuery) { this.limitQuery = limitQuery; } + + public boolean isValidationFlag() { + return validationFlag; + } + + public void setValidationFlag(boolean validationFlag) { + this.validationFlag = validationFlag; + } } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java index ecd04ac..a6be24c 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java @@ -29,9 +29,17 @@ import java.util.List; import org.antlr.v4.runtime.tree.TerminalNode; import org.onap.aai.AAIDslParser; +import org.onap.aai.config.SpringContextAware; import org.onap.aai.edges.EdgeRuleQuery; import org.onap.aai.edges.enums.EdgeType; import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; +import org.onap.aai.logging.LogFormatTools; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.setup.SchemaVersions; import org.springframework.beans.factory.annotation.Autowired; import org.onap.aai.AAIDslBaseListener; import org.onap.aai.edges.EdgeIngestor; @@ -54,18 +62,32 @@ public class DslListener extends AAIDslBaseListener { * Instantiates a new DslListener. */ @Autowired - public DslListener(EdgeIngestor edgeIngestor) { + public DslListener(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory) { this.edgeRules = edgeIngestor; context = new DslContext(); - dslBuilder = new DslQueryBuilder(edgeIngestor); + + Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion()); + dslBuilder = new DslQueryBuilder(edgeIngestor, loader); } - public String getQuery() { + public String getQuery() throws AAIException { + if (!getException().isEmpty()) { + LOGGER.error("Exception in the DSL Query" + getException()); + throw new AAIException("AAI_6149", getException()); + } return dslBuilder.getQuery().toString(); } + public String getException() { + return dslBuilder.getQueryException().toString(); + } + @Override public void enterAaiquery(AAIDslParser.AaiqueryContext ctx) { + /* + * This is my start-node, have some validations here + */ + context.setStartNodeFlag(true); dslBuilder.start(); } @@ -131,6 +153,14 @@ public class DslListener extends AAIDslBaseListener { @Override public void exitSingleNodeStep(AAIDslParser.SingleNodeStepContext ctx) { + if (context.isStartNode() && isValidationFlag()) { + try { + dslBuilder.validateFilter(context); + } catch (AAIException e) { + LOGGER.error("AAIException in DslListener" + LogFormatTools.getStackTop(e)); + } + } + context.setStartNodeFlag(false); context.setCtx(ctx); dslBuilder.store(context); } @@ -186,6 +216,7 @@ public class DslListener extends AAIDslBaseListener { @Override public void enterFilterStep(AAIDslParser.FilterStepContext ctx) { + context.setCtx(ctx); dslBuilder.filter(context); } @@ -210,4 +241,13 @@ public class DslListener extends AAIDslBaseListener { context.setCtx(ctx); dslBuilder.limit(context); } + + public void setValidationFlag(boolean validationFlag) { + this.context.setValidationFlag(validationFlag); + } + + public boolean isValidationFlag() { + return this.context.isValidationFlag(); + } + } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java index 59f4443..fce8a98 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java @@ -21,6 +21,7 @@ package org.onap.aai.rest.dsl; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.antlr.v4.runtime.tree.TerminalNode; @@ -32,15 +33,24 @@ import org.onap.aai.edges.EdgeIngestor; import org.onap.aai.edges.EdgeRuleQuery; import org.onap.aai.edges.enums.EdgeType; import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; + +import com.jcabi.log.Logger; public class DslQueryBuilder { private StringBuilder query; + private StringBuilder queryException; private final EdgeIngestor edgeRules; + private final Loader loader; - public DslQueryBuilder(EdgeIngestor edgeIngestor) { + public DslQueryBuilder(EdgeIngestor edgeIngestor, Loader loader) { this.edgeRules = edgeIngestor; + this.loader = loader; query = new StringBuilder(); + queryException = new StringBuilder(); } public StringBuilder getQuery() { @@ -51,6 +61,14 @@ public class DslQueryBuilder { this.query = query; } + public StringBuilder getQueryException() { + return queryException; + } + + public void setQueryException(StringBuilder queryException) { + this.queryException = queryException; + } + public DslQueryBuilder start() { query.append("builder"); return this; @@ -68,6 +86,8 @@ public class DslQueryBuilder { public DslQueryBuilder nodeQuery(DslContext context) { query.append(".getVerticesByProperty('aai-node-type', '").append(context.getCurrentNode()).append("')"); + if(context.isStartNode() && context.getStartNode().isEmpty()) + context.setStartNode(context.getCurrentNode()); return this; } @@ -76,7 +96,7 @@ public class DslQueryBuilder { String edgeType = ""; if (!edgeRules.hasRule(baseQ.build())) { throw new AAIException("AAI_6120", "No EdgeRule found for passed nodeTypes: " + context.getPreviousNode() - + ", " + context.getCurrentNode()); + + ", " + context.getCurrentNode()); } else if (edgeRules.hasRule(baseQ.edgeType(EdgeType.TREE).build())) { edgeType = "EdgeType.TREE"; } else if (edgeRules.hasRule(baseQ.edgeType(EdgeType.COUSIN).build())) { @@ -85,7 +105,7 @@ public class DslQueryBuilder { edgeType = "EdgeType.COUSIN"; query.append(".createEdgeTraversal(").append(edgeType).append(", '").append(context.getPreviousNode()) - .append("','").append(context.getCurrentNode()).append("')"); + .append("','").append(context.getCurrentNode()).append("')"); return this; } @@ -142,21 +162,53 @@ public class DslQueryBuilder { } + public DslQueryBuilder validateFilter(DslContext context) throws AAIException { + Introspector obj = loader.introspectorFromName(context.getStartNode()); + if(context.getStartNodeKeys().isEmpty()){ + queryException.append("No keys sent. Valid keys for " + context.getStartNode() + " are " + + String.join(",", obj.getIndexedProperties())); + return this; + } + boolean notIndexed = context.getStartNodeKeys().stream() + .filter((prop) -> obj.getIndexedProperties().contains(prop)).collect(Collectors.toList()).isEmpty(); + if (notIndexed) + queryException.append("Non indexed keys sent. Valid keys for " + context.getStartNode() + " " + + String.join(",", obj.getIndexedProperties())); + + return this; + } + public DslQueryBuilder filterPropertyKeys(DslContext context) { AAIDslParser.FilterStepContext ctx = (AAIDslParser.FilterStepContext) context.getCtx(); final String key = ctx.KEY(0).getText(); - - query.append(key); + /* + * This key should be indexed if it is start node + */ + if (context.isStartNode() && context.getStartNodeKeys().isEmpty()) { + // check if key is not indexed, then throw exception + context.getStartNodeKeys().add(key.replaceAll("'", "")); + } + query.append(key); List<TerminalNode> nodes = ctx.KEY(); + List<TerminalNode> numberValues = ctx.NODE(); + /* + * Add all String values + */ List<String> valuesArray = nodes.stream().filter((node) -> !key.equals(node.getText())) - .map((node) -> "'" + node.getText().replace("'", "").trim() + "'") - .collect(Collectors.toList()); + .map((node) -> "'" + node.getText().replace("'", "").trim() + "'").collect(Collectors.toList()); + + /* + * Add all numeric values + */ + valuesArray.addAll(numberValues.stream().filter((node) -> !key.equals(node.getText()) ) + .map((node) -> node.getText()).collect(Collectors.toList())); + /* - * The whole point of doing this to separate P.within from key-value search - * For a list of values QB uses P.within - * For just a single value QB uses key,value check + * The whole point of doing this to separate P.within from key-value + * search For a list of values QB uses P.within For just a single value + * QB uses key,value check */ if (nodes.size() > 2) { String values = String.join(",", valuesArray); diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java index b2be402..d9ce63e 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java @@ -30,7 +30,7 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.onap.aai.AAIDslLexer; import org.onap.aai.AAIDslParser; - +import org.onap.aai.exceptions.AAIException; import org.onap.aai.rest.dsl.DslListener; import org.antlr.v4.runtime.Token; @@ -46,13 +46,14 @@ public class DslQueryProcessor { private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DslQueryProcessor.class); private DslListener dslListener; + private boolean validationFlag = true; @Autowired - public DslQueryProcessor(DslListener dslListener){ + public DslQueryProcessor(DslListener dslListener) { this.dslListener = dslListener; } - public String parseAaiQuery(String aaiQuery) { + public String parseAaiQuery(String aaiQuery) throws AAIException { try { // Create a input stream that reads our string InputStream stream = new ByteArrayInputStream(aaiQuery.getBytes(StandardCharsets.UTF_8)); @@ -63,10 +64,10 @@ public class DslQueryProcessor { // Get a list of tokens pulled from the lexer CommonTokenStream tokens = new CommonTokenStream(lexer); - // Parser that feeds off of the tokens buffer AAIDslParser parser = new AAIDslParser(tokens); + dslListener.setValidationFlag(isValidationFlag()); // Specify our entry point ParseTree ptree = parser.aaiquery(); LOGGER.info("QUERY-interim" + ptree.toStringTree(parser)); @@ -82,9 +83,17 @@ public class DslQueryProcessor { * */ return dslListener.getQuery(); + } catch (AAIException e) { + throw new AAIException("AAI_6149", "Error while processing the query :" + e.getMessage()); } catch (Exception e) { - LOGGER.error("Error while processing the query"+e.getMessage()); + throw new AAIException("AAI_6149","Error while processing the query :" + e.getMessage()); } - return ""; + } + public boolean isValidationFlag() { + return validationFlag; + } + + public void setValidationFlag(boolean validationFlag) { + this.validationFlag = validationFlag; } } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/CQConfig.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/CQConfig.java new file mode 100644 index 0000000..d17fb2b --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/CQConfig.java @@ -0,0 +1,28 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.search; + +public abstract class CQConfig { + protected GetCustomQueryConfig queryConfig; + + public GetCustomQueryConfig getCustomQueryConfig(){ + return queryConfig; + } +} diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java index fd9d53b..56b748c 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java @@ -27,11 +27,10 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.javatuples.Pair; -import org.onap.aai.config.SpringContextAware; import org.onap.aai.exceptions.AAIException; import org.onap.aai.query.builder.MissingOptionalParameter; import org.onap.aai.rest.dsl.DslQueryProcessor; -import org.onap.aai.restcore.search.GroovyQueryBuilderSingleton; +import org.onap.aai.restcore.search.GroovyQueryBuilder; import org.onap.aai.restcore.util.URITools; import org.onap.aai.serialization.engines.TransactionalGraphEngine; import org.onap.aai.serialization.queryformats.SubGraphStyle; @@ -55,7 +54,7 @@ public abstract class GenericQueryProcessor { protected Optional<String> gremlin; protected final TransactionalGraphEngine dbEngine; protected GremlinServerSingleton gremlinServerSingleton; - protected static GroovyQueryBuilderSingleton queryBuilderSingleton = GroovyQueryBuilderSingleton.getInstance(); + protected GroovyQueryBuilder groovyQueryBuilder = new GroovyQueryBuilder(); protected final boolean isGremlin; protected Optional<DslQueryProcessor> dslQueryProcessorOptional; /* dsl parameters to store dsl query and to check @@ -130,7 +129,7 @@ public abstract class GenericQueryProcessor { String dslUserQuery = dsl.get(); if(dslQueryProcessorOptional.isPresent()){ String dslQuery = dslQueryProcessorOptional.get().parseAaiQuery(dslUserQuery); - query = queryBuilderSingleton.executeTraversal(dbEngine, dslQuery, params); + query = groovyQueryBuilder.executeTraversal(dbEngine, dslQuery, params); String startPrefix = "g.V()"; query = startPrefix + query; } @@ -179,7 +178,7 @@ public abstract class GenericQueryProcessor { if (query == null) { query = ""; } else { - query = queryBuilderSingleton.executeTraversal(dbEngine, query, params); + query = groovyQueryBuilder.executeTraversal(dbEngine, query, params); } String startPrefix = "g.V(startVertexes)"; diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java index 20a18d9..9ae3dec 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java @@ -25,6 +25,7 @@ import org.onap.aai.util.FileWatcher; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; import org.apache.tinkerpop.gremlin.driver.Cluster; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import javax.annotation.PostConstruct; @@ -47,11 +48,8 @@ public class GremlinServerSingleton { private boolean timerSet; private Timer timer; - private GetCustomQueryConfig queryConfig; - - @Value("${schema.queries.location}") - private String storedQueriesLocation; + CQConfig customQueryInfo; /** * Initializes the gremlin server singleton * Loads the configuration of the gremlin server and creates a cluster @@ -61,41 +59,9 @@ public class GremlinServerSingleton { * the properties object * */ - @PostConstruct - public void init() { - - try { - String filepath = storedQueriesLocation + AAIConstants.AAI_FILESEP + "stored-queries.json"; - Path path = Paths.get(filepath); - String customQueryConfigJson = new String(Files.readAllBytes(path)); - - - queryConfig = new GetCustomQueryConfig(customQueryConfigJson); - } catch (IOException e) { - logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e)); - } - - - TimerTask task = new FileWatcher(new File(storedQueriesLocation)) { - @Override - protected void onChange(File file) { - try { - String filepath = storedQueriesLocation; - Path path = Paths.get(filepath); - String customQueryConfigJson = new String(Files.readAllBytes(path)); - queryConfig = new GetCustomQueryConfig(customQueryConfigJson); - } catch (IOException e) { - logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e)); - } - } - }; - - if (!timerSet) { - timerSet = true; - timer = new Timer(); - timer.schedule( task , new Date(), 10000 ); - } - + @Autowired + public GremlinServerSingleton(CQConfig customQueryInfo){ + this.customQueryInfo = customQueryInfo; } /** @@ -104,6 +70,8 @@ public class GremlinServerSingleton { * @return */ public String getStoredQueryFromConfig(String key){ + GetCustomQueryConfig queryConfig = customQueryInfo.getCustomQueryConfig(); + CustomQueryConfig customQueryConfig = queryConfig.getStoredQuery(key); if ( customQueryConfig == null ) { return null; @@ -112,6 +80,7 @@ public class GremlinServerSingleton { } public CustomQueryConfig getCustomQueryConfig(String key) { + GetCustomQueryConfig queryConfig = customQueryInfo.getCustomQueryConfig(); return queryConfig.getStoredQuery(key); } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java index de59262..712d7f0 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java @@ -23,7 +23,7 @@ import java.util.Map; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; -import org.onap.aai.restcore.search.GremlinGroovyShellSingleton; +import org.onap.aai.restcore.search.GremlinGroovyShell; public class GroovyShellImpl extends GenericQueryProcessor { @@ -36,7 +36,7 @@ public class GroovyShellImpl extends GenericQueryProcessor { params.put("g", this.dbEngine.asAdmin().getTraversalSource()); - GremlinGroovyShellSingleton shell = GremlinGroovyShellSingleton.getInstance(); + GremlinGroovyShell shell = new GremlinGroovyShell(); return shell.executeTraversal(query, params); } diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java new file mode 100644 index 0000000..bcd4c4e --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java @@ -0,0 +1,85 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.search; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.onap.aai.logging.LogFormatTools; +import org.onap.aai.util.AAIConstants; +import org.onap.aai.util.FileWatcher; +import org.springframework.beans.factory.annotation.Value; + +import javax.annotation.PostConstruct; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +public class LocalCQConfig extends CQConfig { + private static EELFLogger logger = EELFManager.getInstance().getLogger(LocalCQConfig.class); + + @Value("${schema.queries.location}") + private String storedQueriesLocation; + + private boolean timerSet; + private Timer timer; + + @PostConstruct + public void init() { + + try { + String filepath = storedQueriesLocation + AAIConstants.AAI_FILESEP + "stored-queries.json"; + logger.info("Using the Local stored queries"); + Path path = Paths.get(filepath); + String customQueryConfigJson = new String(Files.readAllBytes(path)); + queryConfig = new GetCustomQueryConfig(customQueryConfigJson); + + } catch (IOException e) { + logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e)); + } + + TimerTask task = new FileWatcher(new File(storedQueriesLocation)) { + @Override + protected void onChange(File file) { + try { + String filepath = storedQueriesLocation; + Path path = Paths.get(filepath); + String customQueryConfigJson = new String(Files.readAllBytes(path)); + queryConfig = new GetCustomQueryConfig(customQueryConfigJson); + + } catch (IOException e) { + logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e)); + } + } + }; + + if (!timerSet) { + timerSet = true; + timer = new Timer(); + timer.schedule(task, new Date(), 10000); + } + + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java index 0126162..6421f67 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java @@ -28,7 +28,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.javatuples.Pair; import org.onap.aai.exceptions.AAIException; -import org.onap.aai.restcore.search.GroovyQueryBuilderSingleton; +import org.onap.aai.restcore.search.GroovyQueryBuilder; import org.onap.aai.serialization.engines.TransactionalGraphEngine; import org.onap.aai.serialization.queryformats.SubGraphStyle; @@ -49,7 +49,7 @@ public class NodeQueryProcessor extends GroovyShellImpl { protected static Pattern p = Pattern.compile("query/(.*+)"); protected Optional<String> gremlin; protected final TransactionalGraphEngine dbEngine; - protected static GroovyQueryBuilderSingleton queryBuilderSingleton = GroovyQueryBuilderSingleton.getInstance();; + protected GroovyQueryBuilder queryBuilder = new GroovyQueryBuilder();; protected NodeQueryProcessor(Builder builder) { super(builder); @@ -82,7 +82,7 @@ public class NodeQueryProcessor extends GroovyShellImpl { params.put("startTime", startTime); params.put("nodeType", nodeType); - query = queryBuilderSingleton.executeTraversal(dbEngine, query, params); + query = queryBuilder.executeTraversal(dbEngine, query, params); String startPrefix = "g.V()"; diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java new file mode 100644 index 0000000..6e55246 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java @@ -0,0 +1,64 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest.search; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.onap.aai.restclient.RestClient; +import org.onap.aai.restclient.RestClientFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.Map; + +public class SchemaServiceCQConfig extends CQConfig { + + private static EELFLogger logger = EELFManager.getInstance().getLogger(SchemaServiceCQConfig.class); + private static final String SCHEMA_SERVICE = "schema-service"; + + @Value("${schema.service.custom.queries.endpoint}") + private String customQueriesUri; + + @Autowired + private RestClientFactory restClientFactory; + + @PostConstruct + public void initialize() { + //Call SchemaService to get custom queries + retrieveCustomQueries(); + } + + public void retrieveCustomQueries() { + /* + Call Schema MS to get custom queries using RestTemplate + */ + logger.info("Calling the SchemaService to retrieve stored queries"); + String content = ""; + Map<String, String> headersMap = new HashMap<>(); + RestClient restClient = restClientFactory + .getRestClient(SCHEMA_SERVICE); + + ResponseEntity<String> schemaResponse = restClient.getGetRequest(content, customQueriesUri, headersMap); + queryConfig = new GetCustomQueryConfig(schemaResponse.getBody()); + } +} diff --git a/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java b/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java index 69e1e9f..4b5ebfe 100644 --- a/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java +++ b/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java @@ -29,6 +29,8 @@ public final class TraversalConstants { public static final String AAI_TRAVERSAL_DSL_TIMEOUT_LIMIT = "aai.traversal.dsl.timeoutlimit"; public static final String AAI_TRAVERSAL_DSL_TIMEOUT_ENABLED = "aai.traversal.dsl.timeoutenabled"; public static final String AAI_TRAVERSAL_DSL_TIMEOUT_APP = "aai.traversal.dsl.timeout.appspecific"; + public static final String DSL_NOVALIDATION_CLIENTS = "aai.traversal.dsl.novalidation.clients"; + public static final String DSL_OVERRIDE = "aai.dsl.override"; public static final long HISTORY_MAX_HOURS = 192; diff --git a/aai-traversal/src/main/resources/antlr4/org/onap/aai/AAIDsl.g4 b/aai-traversal/src/main/resources/antlr4/org/onap/aai/AAIDsl.g4 index f0c866a..cf34571 100644 --- a/aai-traversal/src/main/resources/antlr4/org/onap/aai/AAIDsl.g4 +++ b/aai-traversal/src/main/resources/antlr4/org/onap/aai/AAIDsl.g4 @@ -14,7 +14,7 @@ traverseStep: (TRAVERSE ( singleNodeStep | unionQueryStep)); singleNodeStep: NODE STORE? (filterStep | filterTraverseStep)*; -filterStep: NOT? (LPAREN KEY (COMMA KEY)* RPAREN); +filterStep: NOT? (LPAREN KEY (COMMA (KEY | NODE))* RPAREN); filterTraverseStep: (LPAREN traverseStep* RPAREN); limitStep: LIMIT NODE; @@ -47,13 +47,13 @@ RBRACKET: [\]]; NOT: [!]; -VALUE: DIGIT; +VALUE: [DIGIT]+; fragment LOWERCASE : [a-z] ; fragment UPPERCASE : [A-Z] ; fragment DIGIT : [0-9] ; ID - : ( LOWERCASE | UPPERCASE | DIGIT) ( LOWERCASE | UPPERCASE | DIGIT | '-' |'.' |'_')* + : ( LOWERCASE | UPPERCASE | DIGIT) ( LOWERCASE | UPPERCASE | DIGIT | '-' | '.' | '_' | '/')* ; WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines diff --git a/aai-traversal/src/main/resources/application.properties b/aai-traversal/src/main/resources/application.properties index 1769c9f..54fcc55 100644 --- a/aai-traversal/src/main/resources/application.properties +++ b/aai-traversal/src/main/resources/application.properties @@ -26,6 +26,10 @@ server.basic.auth.location=${server.local.startpath}etc/auth/realm.properties server.port=8446 server.ssl.enabled-protocols=TLSv1.1,TLSv1.2 + +# By default spring boot jetty will exclude the following ciphers +# We need to specifically add this to support tls v1.1 +server.ssl.ciphers=^.*_(MD5|SHA|SHA1)$ server.ssl.client-auth=want server.ssl.key-store-type=JKS @@ -36,7 +40,7 @@ server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0) server.ssl.trust-store=${server.local.startpath}etc/auth/aai_keystore server.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0) -schema.version.list=v8,v9,v10,v11,v12,v13,v14 +schema.version.list=v8,v9,v10,v11,v12,v13,v14,v15 # Specifies which component should the oxm be looking at schema.source.name=onap # End of Internal Specific Properties @@ -46,7 +50,6 @@ jms.bind.address=tcp://localhost:61646 dmaap.ribbon.listOfServers=localhost:3904 -# Lists all of the versions in the schema # Schema related attributes for the oxm and edges # Any additional schema related attributes should start with prefix schema @@ -74,4 +77,16 @@ schema.version.namespace.change.start=v12 # Specifies from which version should the client start seeing the edge label in payload schema.version.edge.label.start=v12 # Specifies the version that the application should default to -schema.version.api.default=v14 +schema.version.api.default=v15 + +schema.translator.list=config +schema.service.base.url=https://localhost:8452/aai/schema-service/v1/ +schema.service.nodes.endpoint=nodes?version= +schema.service.edges.endpoint=edgerules?version= +schema.service.versions.endpoint=versions +schema.service.custom.queries.endpoint=stored-queries + +schema.service.ssl.key-store=${server.local.startpath}etc/auth/aai_keystore +schema.service.ssl.trust-store=${server.local.startpath}etc/auth/aai_keystore +schema.service.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0) +schema.service.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0) diff --git a/aai-traversal/src/main/resources/etc/appprops/aaiconfig.properties b/aai-traversal/src/main/resources/etc/appprops/aaiconfig.properties index d384727..a07e985 100644 --- a/aai-traversal/src/main/resources/etc/appprops/aaiconfig.properties +++ b/aai-traversal/src/main/resources/etc/appprops/aaiconfig.properties @@ -31,23 +31,23 @@ aai.transaction.logging.get=true aai.transaction.logging.post=true aai.server.url.base=https://localhost:8443/aai/ -aai.server.url=https://localhost:8443/aai/v14/ +aai.server.url=https://localhost:8443/aai/v15/ aai.global.callback.url=https://localhost:8443/aai/ -aai.notification.current.version=v14 +aai.notification.current.version=v15 aai.notificationEvent.default.status=UNPROCESSED aai.notificationEvent.default.eventType=AAI-EVENT aai.notificationEvent.default.domain=devINT1 aai.notificationEvent.default.sourceName=aai aai.notificationEvent.default.sequenceNumber=0 aai.notificationEvent.default.severity=NORMAL -aai.notificationEvent.default.version=v14 +aai.notificationEvent.default.version=v15 # This one lets us enable/disable resource-version checking on updates/deletes aai.resourceversion.enableflag=true # This will specify how deep the stack trace should be logged aai.logging.maxStackTraceEntries=10 -aai.default.api.version=v14 +aai.default.api.version=v15 # Used by Model-processing code aai.model.query.resultset.maxcount=50 @@ -59,7 +59,7 @@ aai.jms.enable=false aai.traversal.timeoutenabled=true aai.traversal.dsl.timeoutenabled=true #timeout app specific -1 to bypass for that app id, a whole number to override the timeout with that value (in ms) -aai.traversal.timeout.appspecific=JUNITTESTAPP1,1|JUNITTESTAPP2,-1|DCAE-CCS,-1|DCAES,-1|AAI-FILEGEN-GFPIP,-1|FitNesse-Test-PS2418,-1|FitNesse-Test-jenkins,-1|FitNesse-Test-ps2418,-1|FitNesse-Relationship-Test-PS2418,-1|FitNesse-Relationship-Test-ps2418,-1|FitNesse-Relationship-Test-jenkins,-1|VPESAT,-1|AAIRctFeed,-1|NewvceCreator,-1|IANewvceCreator,-1|AAI-CSIOVALS,-1 +aai.traversal.timeout.appspecific=JUNITTESTAPP1,1|JUNITTESTAPP2,-1|DCAE-CCS,-1|DCAES,-1|AAI-FILEGEN-GFPIP,-1|FitNesse-Test-PS2418,-1|FitNesse-Test-jenkins,-1|FitNesse-Test-ps2418,-1|FitNesse-Relationship-Test-PS2418,-1|FitNesse-Relationship-Test-ps2418,-1|FitNesse-Relationship-Test-jenkins,-1|VPESAT,-1|AAIRctFeed,-1|NewvceCreator,-1|IANewvceCreator,-1|AAI-CSIOVALS,-1|AaiVnfGet,-1 aai.traversal.dsl.timeout.appspecific=JUNITTESTAPP1,1|JUNITTESTAPP2,-1|DCAE-CCS,-1|DCAES,-1|AAI-FILEGEN-GFPIP,-1|FitNesse-Test-PS2418,-1|FitNesse-Test-jenkins,-1|FitNesse-Test-ps2418,-1|FitNesse-Relationship-Test-PS2418,-1|FitNesse-Relationship-Test-ps2418,-1|FitNesse-Relationship-Test-jenkins,-1|VPESAT,-1|AAIRctFeed,-1|NewvceCreator,-1|IANewvceCreator,-1|AAI-CSIOVALS,-1 #default timeout limit added for traversal if not overridden (in ms) @@ -67,3 +67,11 @@ aai.traversal.timeoutlimit=180000 aai.traversal.dsl.timeoutlimit=180000 aai.realtime.clients=SDNC,SO,MSO + +#DSL Override property - when running on dev uncomment and use the value +#aai.dsl.override=D5D0158NMWN14NYBA0H5F2S2L5JYD07RXJ4P1FB +aai.dsl.override=false + +# Threshold for margin of error (in ms) for resources_with_sot format to derive the most recent http method performed +aai.resource.formatter.threshold=10 + diff --git a/aai-traversal/src/main/resources/etc/appprops/error.properties b/aai-traversal/src/main/resources/etc/appprops/error.properties index d1e39cc..1ef789e 100644 --- a/aai-traversal/src/main/resources/etc/appprops/error.properties +++ b/aai-traversal/src/main/resources/etc/appprops/error.properties @@ -36,6 +36,11 @@ AAI_3018=5:6:WARN:3018:400:3018:Query URI missing required parameters AAI_3019=5:6:WARN:3019:400:3019:Query URI sending conflicting parameters AAI_3020=5:6:WARN:3020:400:3020:Query URI parameters outside bounds AAI_3021=5:6:WARN:3021:400:3021:Invalid parameters to Recents API +AAI_3022=5:6:WARN:3022:400:3022:Query payload includes extra/unrecognized parameters %1 +AAI_3025=5:4:FATAL:3025:500:3025:Error connecting to Schema Service +AAI_3026=5:4:FATAL:3026:500:3026:Error reading OXM from Schema Service +AAI_3027=5:4:FATAL:3026:500:3026:Error reading EdgeRules from Schema Service +AAI_3028=5:4:FATAL:3026:500:3026:Error reading stored-queries from Schema Service # pol errors AAI_3100=5:1:WARN:3100:400:3100:Unsupported operation %1 @@ -118,6 +123,8 @@ AAI_6145=5:4:ERROR:6145:400:3000:Cannot create a nested/containment edge via rel AAI_6146=5:4:ERROR:6146:400:3000:Ambiguous identity map found, use a URI instead AAI_6147=5:4:ERROR:6147:400:3000:Payload Limit Reached, reduce payload AAI_6148=5:4:INFO:6148:404:3001:Node Not Found. Start URI returned no vertexes, please check the start URI +AAI_6149=5:4:INFO:6149:404:6149:DSL Query Error +AAI_6150=5:4:INFO:6150:404:6150:Pagination Error #--- aaicsvp: 7101-7199 AAI_7101=5:4:ERROR:7101:500:3002:Unexpected error in CSV file processing diff --git a/aai-traversal/src/main/resources/etc/appprops/janusgraph-cached.properties b/aai-traversal/src/main/resources/etc/appprops/janusgraph-cached.properties index 2fb4940..d032dd0 100644 --- a/aai-traversal/src/main/resources/etc/appprops/janusgraph-cached.properties +++ b/aai-traversal/src/main/resources/etc/appprops/janusgraph-cached.properties @@ -45,7 +45,7 @@ load.snapshot.file=false #storage.cql.keyspace=aaigraph_single_dc #storage.cql.only-use-local-consistency-for-system-operations=true #storage.cql.cluster-name=clusterName -#storage.cql.local-datacenter=dataCenter +#storage.cql.local-datacenter=dataCenterName #storage.cql.read-consistency-level=QUORUM #storage.cql.write-consistency-level=QUORUM #storage.connection-timeout=100000 diff --git a/aai-traversal/src/main/resources/etc/appprops/janusgraph-realtime.properties b/aai-traversal/src/main/resources/etc/appprops/janusgraph-realtime.properties index fbb2090..b55897c 100644 --- a/aai-traversal/src/main/resources/etc/appprops/janusgraph-realtime.properties +++ b/aai-traversal/src/main/resources/etc/appprops/janusgraph-realtime.properties @@ -36,13 +36,13 @@ load.snapshot.file=false #storage.hostname=host1,host2,host3 #storage.cql.replication-strategy-class=NetworkTopologyStrategy #storage.cql.replication-strategy-options=options -# for single datacenter cluster +#for single datacenter cluster #storage.cql.replication-factor=3 #storage.cql.keyspace=aaigraph_single_dc #storage.cql.only-use-local-consistency-for-system-operations=true #storage.cql.cluster-name=clusterName -#storage.cql.local-datacenter=dataCenter +#storage.cql.local-datacenter=localDataCenter #storage.cql.read-consistency-level=QUORUM #storage.cql.write-consistency-level=QUORUM #storage.connection-timeout=100000 diff --git a/aai-traversal/src/main/resources/etc/scriptdata/widget-model-json/collection-1.0.json b/aai-traversal/src/main/resources/etc/scriptdata/widget-model-json/collection-1.0.json new file mode 100644 index 0000000..269f860 --- /dev/null +++ b/aai-traversal/src/main/resources/etc/scriptdata/widget-model-json/collection-1.0.json @@ -0,0 +1,11 @@ +{ + "model-invariant-id" : "8bac3599-9a1c-4b7f-80e5-c1838f744c23", + "model-type" : "widget", + "model-vers" : { + "model-ver" : [ { + "model-version-id" : "3f908abc-3a15-40d0-b674-2a639e52884d", + "model-name" : "collection", + "model-version" : "1.0" + } ] + } +} diff --git a/aai-traversal/src/main/resources/schema/onap/query/stored-queries.json b/aai-traversal/src/main/resources/schema/onap/query/stored-queries.json index a3f6a62..edbeff8 100644 --- a/aai-traversal/src/main/resources/schema/onap/query/stored-queries.json +++ b/aai-traversal/src/main/resources/schema/onap/query/stored-queries.json @@ -59,7 +59,7 @@ }, "stored-query":"builder.createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'pnf').getVerticesByProperty('equip-vendor', equipVendor).getVerticesByProperty('equip-model', equipModel).store('x').cap('x').unfold().dedup()" } - },{ + },{ "pnf-fromModel-byRegion":{ "query":{ "required-properties":["equipVendor","equipModel","cloudRegionId"] @@ -95,6 +95,13 @@ "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'logical-link').where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'l-interface').getVerticesByProperty('interface-id', interfaceId).store('x')).union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vserver').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pnf').store('x')).cap('x').unfold().dedup()" } },{ + "pserver-fromConfigurationFilterInterfaceId":{ + "query":{ + "required-properties":["interfaceId"] + }, + "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'logical-link').where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'l-interface').getVerticesByProperty('interface-id', interfaceId).store('x')).union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vserver').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pnf').store('x')).cap('x').unfold().dedup()" + } + },{ "cloudRegion-fromCountry":{ "stored-query":"builder.createEdgeTraversal(EdgeType.COUSIN, 'complex', 'cloud-region').store('x').cap('x').unfold().dedup()" } @@ -196,7 +203,7 @@ } },{ "topology-summary":{ - "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnfc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'image').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'flavor').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex').store('x'))).cap('x').unfold().dedup()" + "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnfc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'line-of-business').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'platform').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'owning-entity').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'project').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'image').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'flavor').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex').store('x'))).cap('x').unfold().dedup()" } },{ "topology-detail":{ @@ -250,34 +257,34 @@ "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnfc').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vnfc', 'vip-ipv4-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'vip-ipv4-address-list', 'subnet').store('x').createEdgeTraversal(EdgeType.TREE, 'subnet', 'l3-network').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vnfc', 'vip-ipv6-address-list').store('x').createEdgeTraversal(EdgeType.COUSIN, 'vip-ipv6-address-list', 'subnet').store('x').createEdgeTraversal(EdgeType.TREE, 'subnet', 'l3-network').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vnfc', 'l3-interface-ipv4-address-list').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'subnet').store('x').createEdgeTraversal(EdgeType.TREE, 'subnet', 'l3-network').store('x') ), builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vnfc', 'l3-interface-ipv6-address-list').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'subnet').store('x').createEdgeTraversal(EdgeType.TREE, 'subnet', 'l3-network').store('x') ) ), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.TREE,'vserver','tenant').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'l3-network').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv4-address-list', 'subnet').store('x').createEdgeTraversal(EdgeType.TREE, 'subnet', 'l3-network').store('x') ), builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x').union( builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'l3-network').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-interface-ipv6-address-list', 'subnet').store( 'x').createEdgeTraversal(EdgeType.TREE, 'subnet', 'l3-network').store('x') ) ), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x') ), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pserver').store('x').createEdgeTraversal(EdgeType.TREE, 'pserver', 'p-interface').store('x').createEdgeTraversal(EdgeType.COUSIN, 'p-interface', 'physical-link').store('x') ).cap('x').unfold().dedup()" } },{ - "access-service-fromServiceInstance":{ - "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').store('x').createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'forwarding-path').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarding-path', 'configuration').store('x').createEdgeTraversal(EdgeType.TREE, 'configuration', 'evc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'forwarding-path', 'forwarder').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarder', 'configuration').store('x').createEdgeTraversal(EdgeType.TREE, 'configuration', 'forwarder-evc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarder', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE, 'p-interface', 'pnf').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarder', 'lag-interface').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'lag-interface', 'pnf').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'lag-interface', 'logical-link').getVerticesByProperty('link-type', 'LAG').store('x'))))).cap('x').unfold().dedup()" + "access-service-fromServiceInstance":{ + "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').store('x').createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'forwarding-path').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarding-path', 'configuration').store('x').createEdgeTraversal(EdgeType.TREE, 'configuration', 'evc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'forwarding-path', 'forwarder').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarder', 'configuration').store('x').createEdgeTraversal(EdgeType.TREE, 'configuration', 'forwarder-evc').store('x').createEdgeTraversal(EdgeType.TREE, 'forwarder-evc', 'vlan-mapping').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarder', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE, 'p-interface', 'pnf').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'forwarder', 'lag-interface').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'lag-interface', 'pnf').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'lag-interface', 'logical-link').getVerticesByProperty('link-type', 'LAG').store('x'))))).cap('x').unfold().dedup()" } },{ - "count-vnf-byVnfType":{ + "count-vnf-byVnfType":{ "stored-query":"builder.getVerticesByProperty('aai-node-type', 'generic-vnf').groupCount().by('vnf-type').store('x').unfold()" - } + } },{ - "pservers-withNoComplex":{ + "pservers-withNoComplex":{ "stored-query":"builder.getVerticesByProperty('aai-node-type', 'pserver').where(builder.newInstance().not(builder.newInstance().both().getVerticesByProperty('aai-node-type', 'complex'))).store('x').unfold()" - } + } },{ "gfp-vserver-data":{ "stored-query":"builder.createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').store('x')).cap('x').unfold().dedup()" } },{ - "gfp-vnf-data":{ + "gfp-vnf-data":{ "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list').store('x'))),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'lag-interface').createEdgeTraversal(EdgeType.TREE, 'lag-interface', 'l-interface').store('x').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnf-image').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'network-profile').store('x')).cap('x').unfold().dedup()" } },{ - "related-to":{ "query":{ - "required-properties":["startingNodeType","relatedToNodeType"] + "required-properties":["startingNodeType","relatedToNodeType"], + "optional-properties":["edgeType"] }, - "stored-query":"builder.createEdgeTraversal(startingNodeType, relatedToNodeType).store('x').cap('x').unfold().dedup()" + "stored-query":"builder.createEdgeTraversal(edgeType, startingNodeType, relatedToNodeType).store('x').cap('x').unfold().dedup()" } - },{ + },{ "gfp-vserver":{ "stored-query":"builder.where(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant'))" } @@ -292,35 +299,52 @@ }, "stored-query":"builder.where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vnfc', 'vserver').createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').getVerticesByProperty('network-name',networkName)).createEdgeTraversal(EdgeType.COUSIN, 'vnfc', 'vserver').store('x').createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').getVerticesByProperty('network-name',networkName).store('x').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l-interface').store('x').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').store('x').cap('x').unfold().dedup()" } - },{ - "vnfs-vlans-fromServiceInstance":{ - "stored-query":"builder.createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'configuration').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'generic-vnf').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').store('x')).cap('x').unfold().dedup()" - } - },{ - "getClfiRoadmTailSummary":{ - "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE,'p-interface', 'pnf').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'logical-link').store('x').createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'service-instance').store('x').createEdgeTraversal(EdgeType.TREE,'service-instance', 'service-subscription').store('x').createEdgeTraversal(EdgeType.TREE,'service-subscription', 'customer').store('x')).cap('x').unfold().dedup()" + },{ + "containment-path":{ + "stored-query":"builder.until(builder.newInstance().not(builder.newInstance().getParentEdge())).repeat(builder.newInstance().getParentVertex()).path()" } - },{ - "getRouterRoadmTailSummary":{ - "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.TREE,'pnf', 'p-interface').store('x').createEdgeTraversal(EdgeType.COUSIN,'p-interface', 'logical-link').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE,'p-interface', 'pnf').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'logical-link').store('x').createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'service-instance').store('x').createEdgeTraversal(EdgeType.TREE,'service-instance', 'service-subscription').store('x').createEdgeTraversal(EdgeType.TREE,'service-subscription', 'customer').store('x')).cap('x').unfold().dedup()" + }, + { + "getSvcSubscriberModelInfo":{ + "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').store('x'),builder.newInstance().createPrivateEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'model-ver').store('x')).cap('x').unfold().dedup()" } - },{ - "topology-summary-fromCloudRegion":{ - "stored-query": "builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'cloud-region', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnfc').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'cloud-region', 'pserver').store('x')).cap('x').unfold().dedup()" + }, + { + "vnf-vserver-fromCustomer":{ + "stored-query":"builder.createEdgeTraversal(EdgeType.TREE, 'customer', 'service-subscription').createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'service-instance').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').cap('x').unfold().dedup()" } - }, { - "vservers-fromPserver-tree": { - "stored-query": "builder.createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'vserver').tree()" - } + }, + { + "getCustomerVPNBondingServiceDetails":{ + "stored-query":"builder.union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'customer').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'service-instance').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'configuration').getVerticesByProperty('configuration-type', 'VLAN-NETWORK-RECEPTOR').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'generic-vnf').store('x').createEdgeTraversalWithLabels(EdgeType.COUSIN, 'generic-vnf', 'instance-group', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.MemberOf'))).store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'l3-network').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l3-network', 'subnet').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'subnet', 'l3-interface-ipv6-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'subnet', 'l3-interface-ipv4-address-list').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'vpn-binding').store('x').createEdgeTraversal(EdgeType.TREE, 'vpn-binding', 'route-target').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'l-interface').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l-interface').store('x'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'configuration').getVerticesByProperty('configuration-type', 'VRF ENTRY').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'vpn-binding').store('x').createEdgeTraversal(EdgeType.TREE, 'vpn-binding', 'route-target').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'configuration', 'pnf').getVerticesByProperty('nf-role','D2IPE').store('x')))).cap('x').unfold().dedup()" + } + }, + { + "vnf-summary-fromVnf": { + "stored-query": "builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'platform').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'line-of-business').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'owning-entity').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'project').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pserver').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x')).cap('x').unfold().dedup()" + } + }, + { + "getComplexAndPservers":{ + "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'complex','pserver').store('x').cap('x').unfold().dedup()" + } },{ "cloud-region-and-source-FromConfiguration":{ "stored-query":"builder.createEdgeTraversal(EdgeType.COUSIN, 'configuration','logical-link').createEdgeTraversalWithLabels(EdgeType.COUSIN, 'logical-link', 'l-interface',new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.Source'))).createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vserver').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vf-module').createEdgeTraversal(EdgeType.TREE, 'vf-module', 'generic-vnf').store('x')).cap('x').unfold().dedup()" } },{ - "destination-FromConfiguration":{ - "stored-query":"builder.createEdgeTraversal(EdgeType.COUSIN, 'configuration','logical-link').union(builder.newInstance().createEdgeTraversalWithLabels(EdgeType.COUSIN, 'logical-link', 'l-interface', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.Destination'))).createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vserver').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vf-module').createEdgeTraversal(EdgeType.TREE, 'vf-module', 'generic-vnf').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'generic-vnf').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pnf').store('x')).cap('x').unfold().dedup()" + "getClfiRoadmTailSummary":{ + "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE,'p-interface', 'pnf').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'logical-link').createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'service-instance').store('x').createEdgeTraversal(EdgeType.TREE,'service-instance', 'service-subscription').store('x').createEdgeTraversal(EdgeType.TREE,'service-subscription', 'customer').store('x')).cap('x').unfold().dedup()" + } + },{ + "getRouterRoadmTailSummary":{ + "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.TREE,'pnf', 'p-interface').store('x').createEdgeTraversal(EdgeType.COUSIN,'p-interface', 'logical-link').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE,'p-interface', 'pnf').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'logical-link').createEdgeTraversal(EdgeType.COUSIN,'logical-link', 'service-instance').store('x').createEdgeTraversal(EdgeType.TREE,'service-instance', 'service-subscription').store('x').createEdgeTraversal(EdgeType.TREE,'service-subscription', 'customer').store('x')).cap('x').unfold().dedup()" } },{ + "vservers-fromPserver-tree": { + "stored-query": "builder.createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'vserver').tree()" + } + },{ "topology-summary-fromTenant":{ "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'tenant', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'generic-vnf').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'))).cap('x').unfold().dedup()" } @@ -328,7 +352,11 @@ "vfModule-fromServiceInstance":{ "stored-query":"builder.createEdgeTraversal(EdgeType.COUSIN, 'service-instance','generic-vnf').createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'vf-module').store('x').cap('x').unfold().dedup()" } - },{ + },{ + "topology-summary-fromCloudRegion":{ + "stored-query": "builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'cloud-region', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnfc').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'cloud-region', 'pserver').store('x')).cap('x').unfold().dedup()" + } + }, { "getComplexByPnfName":{ "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN,'pnf', 'complex').store('x').cap('x').unfold().dedup()" } @@ -347,43 +375,41 @@ "network-collection-ByServiceInstance":{ "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'collection').store('x').createEdgeTraversal(EdgeType.COUSIN, 'collection', 'instance-group').store('x').createEdgeTraversal(EdgeType.COUSIN, 'instance-group', 'l3-network').store('x').cap('x').unfold().dedup()" } + },{ + "getServiceTopology":{ + "stored-query":"builder.union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'allotted-resource').createEdgeTraversal(EdgeType.TREE, 'allotted-resource', 'service-instance').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list')))))).tree()"} + }, + { + "getL3networkCloudRegionByNetworkRole": { + "stored-query": "builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x').cap('x').unfold().dedup()" + } },{ - "containment-path":{ - "stored-query":"builder.until(builder.newInstance().not(builder.newInstance().getParentEdge())).repeat(builder.newInstance().getParentVertex()).path()" - } - },{ - "getSvcSubscriberModelInfo":{ - "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').store('x'),builder.newInstance().createPrivateEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'model-ver').store('x')).cap('x').unfold().dedup()" - } - }, - { + "getNetworks": { + "query":{ + "required-properties":["networkRole","cloudRegionId"] + }, + "stored-query": "builder.createEdgeTraversal(EdgeType.COUSIN, 'owning-entity','service-instance').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'l3-network').getVerticesByProperty('network-role', networkRole).where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'cloud-region').getVerticesByProperty('cloud-region-id', cloudRegionId)).store('x').cap('x').unfold().dedup()" + } + },{ "getLogicalLinkByCloudRegionId": { "stored-query": "builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'cloud-region', 'logical-link').store('x').cap('x').unfold().dedup()" } - },{ + },{ "getPinterfacePhysicalLinkBySvcInstId":{ "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN,'service-instance', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN,'generic-vnf', 'vserver').store('x').createEdgeTraversal(EdgeType.COUSIN,'vserver', 'pserver').store('x').createEdgeTraversal(EdgeType.TREE,'pserver', 'p-interface').store('x').createEdgeTraversal(EdgeType.COUSIN,'p-interface', 'physical-link').store('x').cap('x').unfold().dedup()" } - },{ + },{ + "getNetworksByServiceInstance": { + "stored-query": "builder.createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'l3-network').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'vlan-tag').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'l3-network').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'vlan-tag').store('x')).cap('x').unfold().dedup()" + } + }, + { "topology-detail-fromVnf":{ "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x').createEdgeTraversal(EdgeType.TREE, 'cloud-region', 'availability-zone').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'image').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'flavor').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').store('x').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface','l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'vf-module').createEdgeTraversal(EdgeType.COUSIN, 'vf-module', 'volume-group').store('x')).cap('x').unfold().dedup()"} },{ "vnf-to-service-instance":{ "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'service-instance').store('x').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').store('x').cap('x').unfold().dedup()"} - },{ - "getServiceTopology":{ - "stored-query":"builder.union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'pserver').createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'complex'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'allotted-resource').createEdgeTraversal(EdgeType.TREE, 'allotted-resource', 'service-instance').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list'))),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list')))))).tree()"} - }, - { - "getL3networkCloudRegionByNetworkRole": { - "stored-query": "builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'generic-vnf').store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x').cap('x').unfold().dedup()" - } - },{ - "getDHVLogicalLink": { - "stored-query": "builder.createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').createEdgeTraversal(EdgeType.COUSIN, 'vlan', 'logical-link').tree()" - } - }, - { + },{ "pserver-fromHostnameFirstToken": { "query":{ "required-properties":["hostnameFirstToken","sourcesOfTruth"] @@ -391,7 +417,7 @@ "stored-query": "builder.getVerticesStartsWithProperty('hostname', hostnameFirstToken).getVerticesByProperty('source-of-truth', new ArrayList<>(Arrays.asList(sourcesOfTruth)))" } }, - { + { "pserver-fromFqdnFirstToken": { "query":{ "required-properties":["fqdnFirstToken","sourcesOfTruth"] @@ -399,6 +425,25 @@ "stored-query": "builder.getVerticesStartsWithProperty('fqdn', fqdnFirstToken).getVerticesByProperty('source-of-truth', new ArrayList<>(Arrays.asList(sourcesOfTruth)))" } }, + { + "cloud-regions-by-generic-vnf-HG-pairs": { + "stored-query": "builder.createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'service-instance').as('a').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'allotted-resource').createEdgeTraversal(EdgeType.TREE, 'allotted-resource', 'service-instance').createEdgeTraversal(EdgeType.TREE, 'service-instance', 'service-subscription').getVerticesByProperty('service-type', 'HNGATEWAY').createEdgeTraversal(EdgeType.TREE, 'service-subscription', 'service-instance').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'generic-vnf').getVerticesByProperty('vnf-type', 'HG').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').as('b').select('a','b').by('aai-uri')" + } + }, + { + "getDHVLogicalLink": { + "stored-query": "builder.createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').createEdgeTraversal(EdgeType.COUSIN, 'vlan', 'logical-link').tree()" + } + }, + { + "destination-FromConfiguration":{ + "stored-query":"builder.createEdgeTraversal(EdgeType.COUSIN, 'configuration','logical-link').union(builder.newInstance().createEdgeTraversalWithLabels(EdgeType.COUSIN, 'logical-link', 'l-interface', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.Destination'))).createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vserver').createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vf-module').createEdgeTraversal(EdgeType.TREE, 'vf-module', 'generic-vnf').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'logical-link', 'generic-vnf').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'pnf').store('x')).cap('x').unfold().dedup()" + } + },{ + "fabric-information-fromVnf":{ + "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'sriov-vf').createEdgeTraversal(EdgeType.COUSIN, 'sriov-vf', 'sriov-pf').createEdgeTraversal(EdgeType.TREE, 'sriov-pf', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE, 'p-interface', 'pserver').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').store('x').createEdgeTraversal(EdgeType.TREE, 'vnfc', 'cp').createEdgeTraversal(EdgeType.COUSIN, 'cp', 'vlan-tag').store('x')).cap('x').unfold().dedup()" + } + }, { "getLinterface-fromNewvce": { "query":{ @@ -415,23 +460,18 @@ "stored-query": "builder.union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vnfc', 'cp').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'cp', 'vlan-tag').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'cp', 'l3-network').getVerticesByBooleanProperty('is-provider-network', isProviderNetwork).store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vnfc', 'vserver').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').store('x'))).cap('x').unfold().dedup()" } }, - { - "getNetworks": { - "query":{ - "required-properties":["networkRole","cloudRegionId"] - }, - "stored-query": "builder.createEdgeTraversal(EdgeType.COUSIN, 'owning-entity','service-instance').createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'l3-network').getVerticesByProperty('network-role', networkRole).where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'cloud-region').getVerticesByProperty('cloud-region-id', cloudRegionId)).store('x').cap('x').unfold().dedup()" - } - }, - { - "fabric-information-fromVnf":{ - "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vserver', 'l-interface').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'sriov-vf').createEdgeTraversal(EdgeType.COUSIN, 'sriov-vf', 'sriov-pf').createEdgeTraversal(EdgeType.TREE, 'sriov-pf', 'p-interface').store('x').createEdgeTraversal(EdgeType.TREE, 'p-interface', 'pserver').store('x'), builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver', 'vnfc').createEdgeTraversal(EdgeType.TREE, 'vnfc', 'cp').createEdgeTraversal(EdgeType.COUSIN, 'cp', 'vlan-tag').store('x')).cap('x').unfold().dedup()" + { + "vnf-to-esr-system-info":{ + "stored-query":"builder.store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vserver').store('x').createEdgeTraversal(EdgeType.TREE, 'vserver', 'tenant').store('x').createEdgeTraversal(EdgeType.TREE, 'tenant', 'cloud-region').store('x').createEdgeTraversal(EdgeType.TREE, 'cloud-region', 'esr-system-info').store('x').cap('x').unfold().dedup()" } - }, - { - "getNetworksByServiceInstance": { - "stored-query": "builder.createEdgeTraversal(EdgeType.COUSIN, 'service-instance', 'l3-network').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'vlan-tag').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'l3-network').store('x').createEdgeTraversal(EdgeType.COUSIN, 'l3-network', 'vlan-tag').store('x')).cap('x').unfold().dedup()" + }, + { + "genericVnfs-fromPserver":{ + "query":{ + "optional-properties":["vnfType","nfFunction","nfRole","nfNamingCode"] + }, + "stored-query":"builder.union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'generic-vnf'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'pserver', 'vserver').createEdgeTraversal('vserver','generic-vnf')).getVerticesByProperty('vnf-type',vnfType).getVerticesByProperty('nf-function',nfFunction).getVerticesByProperty('nf-role',nfRole).getVerticesByProperty('nf-naming-code',nfNamingCode).store('x').cap('x').unfold().dedup()" } } - ] + ] } |