aboutsummaryrefslogtreecommitdiffstats
path: root/aai-traversal/src/main/java
diff options
context:
space:
mode:
authorLaMont, William(wl2432) <wl2432@att.com>2020-06-22 12:50:38 -0400
committerLaMont, William(wl2432) <wl2432@att.com>2020-06-22 12:51:08 -0400
commitbd4c050748ac957f6bb6684915233e478d71c0a1 (patch)
treed5c9254a1123e49c18e7ef3e97aa7b9ca9afab2e /aai-traversal/src/main/java
parent02b1b37d795f0bccf4500e14de5586891e78d306 (diff)
traversal support for v20
Issue-ID: AAI-2933 Change-Id: I76f970d15ef911a3dd14d97f2fa050c8b6e29e96 Signed-off-by: LaMont, William(wl2432) <wl2432@att.com>
Diffstat (limited to 'aai-traversal/src/main/java')
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java38
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java23
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java24
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java75
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java12
5 files changed, 125 insertions, 47 deletions
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 6cb6565..b9295a9 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
@@ -23,6 +23,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.janusgraph.core.SchemaViolationException;
import org.onap.aai.concurrent.AaiCallable;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.ModelType;
@@ -49,12 +50,12 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.Status;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
+import java.util.stream.Collectors;
@Path("{version: v[1-9][0-9]*|latest}/dsl")
public class DslConsumer extends TraversalConsumer {
@@ -99,6 +100,7 @@ public class DslConsumer extends TraversalConsumer {
@DefaultValue("no_op") @QueryParam("subgraph") String subgraph,
@DefaultValue("all") @QueryParam("validate") String validate,
@Context HttpHeaders headers,
+ @Context HttpServletRequest req,
@Context UriInfo info,
@DefaultValue("-1") @QueryParam("resultIndex") String resultIndex,
@DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
@@ -111,14 +113,14 @@ public class DslConsumer extends TraversalConsumer {
new AaiCallable() {
@Override
public Response process() throws Exception {
- return (processExecuteQuery(content, versionParam, queryFormat, subgraph, validate, headers, info,
+ return (processExecuteQuery(content, req, versionParam, queryFormat, subgraph, validate, headers, info,
resultIndex, resultSize));
}
}
);
}
- public Response processExecuteQuery(String content, String versionParam, String queryFormat, String subgraph,
+ public Response processExecuteQuery(String content, HttpServletRequest req, String versionParam, String queryFormat, String subgraph,
String validate, HttpHeaders headers, UriInfo info, String resultIndex,
String resultSize) {
@@ -139,7 +141,8 @@ public class DslConsumer extends TraversalConsumer {
TransactionalGraphEngine dbEngine = null;
try {
- traversalUriHttpEntry.setHttpEntryProperties(version);
+ String serverBase = req.getRequestURL().toString().replaceAll("/(v[0-9]+|latest)/.*", "/");
+ traversalUriHttpEntry.setHttpEntryProperties(version, serverBase);
traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize);
dbEngine = traversalUriHttpEntry.getDbEngine();
JsonObject input = new JsonParser().parse(content).getAsJsonObject();
@@ -178,16 +181,20 @@ public class DslConsumer extends TraversalConsumer {
SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph);
List<Object> vertTemp = processor.execute(subGraphStyle);
+
+ // Dedup if duplicate objects are returned in each array in the aggregate format scenario.
+ List<Object> vertTempDedupedObjectList = dedupObjectInAggregateFormatResult(vertTemp);
+
List <Object> vertices;
if (isAggregate(format)){
- vertices = traversalUriHttpEntry.getPaginatedVertexListForAggregateFormat(vertTemp);
+ vertices = traversalUriHttpEntry.getPaginatedVertexListForAggregateFormat(vertTempDedupedObjectList);
} else {
vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp);
}
DBSerializer serializer = new DBSerializer(version, dbEngine, ModelType.MOXY, sourceOfTruth);
FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions,
- this.basePath);
+ this.basePath, serverBase);
MultivaluedMap<String, String> mvm = new MultivaluedHashMap<>();
mvm.putAll(info.getQueryParameters());
@@ -231,6 +238,9 @@ public class DslConsumer extends TraversalConsumer {
} catch (AAIException e) {
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, e);
+ } catch (SchemaViolationException sve) {
+ AAIException ex = new AAIException("AAI_4020", sve);
+ response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, ex);
} catch (Exception e) {
AAIException ex = new AAIException("AAI_4000", e);
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, ex);
@@ -243,4 +253,16 @@ public class DslConsumer extends TraversalConsumer {
return response;
}
+
+ private List<Object> dedupObjectInAggregateFormatResult(List<Object> vertTemp) {
+ List<Object> vertTempDedupedObjectList = new ArrayList<Object>();
+ Iterator<Object> itr = vertTemp.listIterator();
+ while (itr.hasNext()){
+ Object o = itr.next();
+ if (o instanceof ArrayList) {
+ vertTempDedupedObjectList.add(((ArrayList) o).stream().distinct().collect(Collectors.toList()));
+ }
+ }
+ return vertTempDedupedObjectList;
+ }
}
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 54e6d06..5297de5 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
@@ -47,13 +47,13 @@ import org.onap.aai.serialization.queryformats.SubGraphStyle;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
import org.onap.aai.transforms.XmlFormatTransformer;
-
import org.onap.aai.util.TraversalConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.Status;
@@ -97,6 +97,7 @@ public class QueryConsumer extends TraversalConsumer {
@DefaultValue("graphson") @QueryParam("format") String queryFormat,
@DefaultValue("no_op") @QueryParam("subgraph") String subgraph,
@Context HttpHeaders headers,
+ @Context HttpServletRequest req,
@Context UriInfo info,
@DefaultValue("-1") @QueryParam("resultIndex") String resultIndex,
@DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
@@ -109,19 +110,18 @@ public class QueryConsumer extends TraversalConsumer {
new AaiCallable<Response>() {
@Override
public Response process() {
- return processExecuteQuery(content, versionParam, queryFormat, subgraph, headers, info, resultIndex, resultSize);
+ return processExecuteQuery(content, req, versionParam, queryFormat, subgraph, headers, info, resultIndex, resultSize);
}
});
}
- public Response processExecuteQuery(String content, String versionParam, String queryFormat, String subgraph,
+ public Response processExecuteQuery(String content, HttpServletRequest req, String versionParam, String queryFormat, String subgraph,
HttpHeaders headers, UriInfo info, String resultIndex,
String resultSize) {
String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
String queryProcessor = headers.getRequestHeaders().getFirst("QueryProcessor");
QueryProcessorType processorType = this.processorType;
-
Response response;
TransactionalGraphEngine dbEngine = null;
@@ -143,7 +143,8 @@ public class QueryConsumer extends TraversalConsumer {
String gremlin = "";
SchemaVersion version = new SchemaVersion(versionParam);
- traversalUriHttpEntry.setHttpEntryProperties(version);
+ String serverBase = req.getRequestURL().toString().replaceAll("/(v[0-9]+|latest)/.*", "/");
+ traversalUriHttpEntry.setHttpEntryProperties(version, serverBase);
/*
* Changes for Pagination
*/
@@ -171,13 +172,13 @@ public class QueryConsumer extends TraversalConsumer {
CustomQueryConfig customQueryConfig = getCustomQueryConfig(queryURIObj);
if ( customQueryConfig != null ) {
- List<String> missingRequiredQueryParameters = checkForMissingQueryParameters( customQueryConfig.getQueryRequiredProperties(), URITools.getQueryMap(queryURIObj));
+ List<String> missingRequiredQueryParameters = checkForMissingQueryParameters( customQueryConfig.getQueryRequiredProperties(), URITools.getQueryMap(queryURIObj));
if ( !missingRequiredQueryParameters.isEmpty() ) {
return( createMessageMissingQueryRequiredParameters( missingRequiredQueryParameters, headers));
}
- List<String> invalidQueryParameters = checkForInvalidQueryParameters( customQueryConfig, URITools.getQueryMap(queryURIObj));
+ List<String> invalidQueryParameters = checkForInvalidQueryParameters( customQueryConfig, URITools.getQueryMap(queryURIObj));
if ( !invalidQueryParameters.isEmpty() ) {
return( createMessageInvalidQueryParameters( invalidQueryParameters, headers));
@@ -221,7 +222,7 @@ public class QueryConsumer extends TraversalConsumer {
List<Object> vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp);
DBSerializer serializer = new DBSerializer(version, dbEngine, ModelType.MOXY, sourceOfTruth);
- FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath);
+ FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath, serverBase);
MultivaluedMap<String, String> mvm = new MultivaluedHashMap<>();
mvm.putAll(info.getQueryParameters());
@@ -233,8 +234,6 @@ public class QueryConsumer extends TraversalConsumer {
String result = formatter.output(vertices).toString();
- //LOGGER.info ("Completed");
-
String acceptType = headers.getHeaderString("Accept");
if(acceptType == null){
@@ -325,7 +324,7 @@ public class QueryConsumer extends TraversalConsumer {
.entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e,
templateVars)).build();
}
-
+
private Response createMessageInvalidQuerySection(String invalidQuery, HttpHeaders headers) {
AAIException e = new AAIException("AAI_3014");
@@ -338,6 +337,7 @@ public class QueryConsumer extends TraversalConsumer {
templateVars)).build();
}
+
private List<String> checkForInvalidQueryParameters( CustomQueryConfig customQueryConfig, MultivaluedMap<String, String> queryParams) {
List<String> allParameters = new ArrayList<>();
@@ -353,7 +353,6 @@ public class QueryConsumer extends TraversalConsumer {
return queryParams.keySet().stream()
.filter(param -> !allParameters.contains(param))
.collect(Collectors.toList());
-
}
private Response createMessageInvalidQueryParameters(List<String> invalidQueryParams, HttpHeaders headers) {
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 86ed49d..f2b88f3 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
@@ -46,6 +46,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.Status;
@@ -55,8 +56,8 @@ import java.util.concurrent.TimeUnit;
@Path("/recents/{version: v[1-9][0-9]*|latest}")
public class RecentAPIConsumer extends RESTAPI {
- private static final String AAI_3021 = "AAI_3021";
-
+ private static final String AAI_3021 = "AAI_3021";
+
/** The introspector factory type. */
private ModelType introspectorFactoryType = ModelType.MOXY;
@@ -95,20 +96,24 @@ public class RecentAPIConsumer extends RESTAPI {
@Path("/{nodeType: .+}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
- public Response getRecentData(String content, @PathParam("version") String versionParam,
- @PathParam("nodeType") String nodeType, @Context HttpHeaders headers, @Context UriInfo info) {
+ public Response getRecentData(String content,
+ @PathParam("version") String versionParam,
+ @PathParam("nodeType") String nodeType,
+ @Context HttpHeaders headers,
+ @Context HttpServletRequest req,
+ @Context UriInfo info) {
return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED, TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP,
TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT, headers, info, HttpMethod.GET, new AaiCallable<Response>() {
@Override
public Response process() {
- return processRecentData(content, versionParam, nodeType, info, headers);
+ return processRecentData(content, req, versionParam, nodeType, info, headers);
}
});
}
- public Response processRecentData(String content, @PathParam("version") String versionParam,
+ public Response processRecentData(String content, HttpServletRequest req, @PathParam("version") String versionParam,
@PathParam("nodeType") String nodeType, @Context UriInfo info, @Context HttpHeaders headers) {
String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
@@ -124,8 +129,9 @@ public class RecentAPIConsumer extends RESTAPI {
SchemaVersion version = new SchemaVersion(versionParam);
this.checkVersion(version);
-
- traversalUriHttpEntry.setHttpEntryProperties(version);
+
+ String serverBase = req.getRequestURL().toString().replaceAll("/(v[0-9]+|latest)/.*", "/");
+ traversalUriHttpEntry.setHttpEntryProperties(version, serverBase);
dbEngine = traversalUriHttpEntry.getDbEngine();
/*
@@ -150,7 +156,7 @@ public class RecentAPIConsumer extends RESTAPI {
List<Object> vertices = processor.execute(subGraphStyle);
DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
- FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath);
+ FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath, serverBase);
Format format = Format.pathed_resourceversion;
Formatter formater = ff.get(format, info.getQueryParameters());
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 3d324ad..649826e 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
@@ -49,6 +49,7 @@ public class DslQueryBuilder {
private StringBuilder queryException;
private static final Logger LOGGER = LoggerFactory.getLogger(DslQueryBuilder.class);
+ private long selectCount = 0;
public DslQueryBuilder(EdgeIngestor edgeIngestor, Loader loader) {
this.edgeRules = edgeIngestor;
@@ -82,18 +83,15 @@ public class DslQueryBuilder {
* DSL always dedupes the results
*/
public DslQueryBuilder end(long selectCounter) {
+ selectCount = selectCounter;
if(selectCounter <= 0) {
return this.end();
} else {
- String selectStep = "step" + selectCounter;
- query.append(".as('").append(selectStep).append("')").append(".as('stepMain')" +
- ".select('").append(selectStep).append("')").append(".store('x')").append(".select('stepMain').fold().dedup()");
+ query.append(".select('stepMain').fold().dedup()");
}
return this;
}
-
-
public DslQueryBuilder end() {
query.append(".cap('x').unfold().dedup()");
return this;
@@ -241,7 +239,7 @@ public class DslQueryBuilder {
}
- public DslQueryBuilder select(boolean isNot, long selectCounter, List<String> keys) {
+ public DslQueryBuilder select(long selectCounter, List<String> keys) {
/*
* TODO : isNot should look at the vertex properties and include everything except the notKeys
*/
@@ -269,15 +267,19 @@ public class DslQueryBuilder {
if (alias.isPresent()) {
key = StringUtils.quote(alias.get());
}
-
+ String classType = obj.getType(trimSingleQuotes(key));
query.append(key);
- if (!values.isEmpty()) {
- if (values.size() > 1) {
+ if (values != null && !values.isEmpty()) {
+ if (values.size() > 1) { // values.size() > 1 indicates possibility of a list
+ // eliminate quotes from each element
+ for (int i = 0; i < values.size(); i++) {
+ values.set(i, getConvertedValue(classType, key, values.get(i)));
+ }
String valuesArray = String.join(",", values);
query.append(",").append(" new ArrayList<>(Arrays.asList(").append(valuesArray).append("))");
- } else {
- query.append(",").append(values.get(0));
+ } else { // otherwise values should only contain one value
+ query.append(",").append(getConvertedValue(classType, key, values.get(0)));
}
}
} catch (AAIUnknownObjectException e) {
@@ -286,6 +288,57 @@ public class DslQueryBuilder {
return this;
}
+ private String getConvertedValue(String classType, String key, String value) {
+ String convertedValue = value;
+ if (isTypeSensitive(classType)) {
+ convertedValue = trimSingleQuotes(value);
+ try {
+ // cast it to the corresponding type
+ if (classType.equals(Integer.class.getName())) {
+ int castInt = Integer.parseInt(convertedValue);
+ convertedValue = String.valueOf(castInt);
+ }
+ else if (classType.equals(Long.class.getName())) {
+ long castLong = Long.parseLong(convertedValue);
+ convertedValue = String.valueOf(castLong);
+ }
+ else if (classType.equals(Boolean.class.getName())) {
+ if (convertedValue.equals("1")) { // checking for integer true value
+ convertedValue = "true";
+ }
+ boolean castBoolean = Boolean.parseBoolean(convertedValue);
+ convertedValue = String.valueOf(castBoolean);
+ }
+ } catch (Exception e) {
+ queryException.append("AAI_4020 ").append(String.format("Value [%s] is not an instance of the expected data type for property key [%s] and cannot be converted. " +
+ "Expected: class %s, found: class %s", value, key, classType, String.class.getName()));
+ }
+ }
+ return convertedValue;
+ }
+
+ private boolean isTypeSensitive(String classType) {
+ if (classType.equals(Integer.class.getName()) ||
+ classType.equals(Boolean.class.getName()) ||
+ classType.equals(Long.class.getName())) {
+ return true;
+ }
+ return false;
+ }
+
+ private String trimSingleQuotes(String s) {
+ if (s == null || s.isEmpty()) {
+ return s;
+ }
+ String trimSingleQuotes = "";
+ if (s.startsWith("'") && s.endsWith("'")) {
+ trimSingleQuotes = s.substring(1, s.length() - 1);
+ } else {
+ trimSingleQuotes = s;
+ }
+ return trimSingleQuotes;
+ }
+
public DslQueryBuilder union() {
query.append(".union(");
return this;
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java
index 8f9f145..66ca8a1 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java
@@ -207,13 +207,13 @@ public class DslListener extends AAIDslBaseListener {
if (ctx.filter() != null) {
allKeys = ctx.filter().propertyFilter().stream().flatMap(
pf -> pf.key().stream()).map(
- e -> e.getText().replaceAll("\'", "")).collect(Collectors.toList());
+ e -> e.getText().replaceFirst("\'", "").substring(0, e.getText().length() - 2)).collect(Collectors.toList());
}
builder().validateFilter(ctx.label().getText(), allKeys);
}
if (ctx.store() != null) {
- if (isAggregate() && (selectCounter == nodeCount) && (nodeCount < traversedNodes.size())) {
- builder().select(false, selectCounter++, null);
+ if (isAggregate()) {
+ builder().select(selectCounter++, null);
}
builder().store();
hasReturnValue = true;
@@ -290,7 +290,7 @@ public class DslListener extends AAIDslBaseListener {
* Add all String values
*/
List<String> values = valueList.stream().filter(value -> !filterKey.equals(value.getText()))
- .map(value -> "'" + value.getText().replace("'", "") + "'").collect(Collectors.toList());
+ .map(value -> value.getText()).collect(Collectors.toList());
/*
* Add all numeric values
*/
@@ -312,8 +312,6 @@ public class DslListener extends AAIDslBaseListener {
List<AAIDslParser.KeyContext> keyList = ctx.key();
- boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
-
/*
* Add all String values
*/
@@ -322,7 +320,7 @@ public class DslListener extends AAIDslBaseListener {
setSelectKeys(traversedNodes.getFirst(), allKeys);
}
if (isAggregate() && (traversedNodes.size() == nodeCount)) {
- builder().select(isNot, selectCounter++, allKeys);
+ builder().select(selectCounter++, allKeys);
}
}