From 47f4b66b45250e00260905ac3ec34b9ddb1a5362 Mon Sep 17 00:00:00 2001 From: "Maharajh, Robby (rx2202)" Date: Tue, 2 Jan 2018 13:05:03 -0500 Subject: [PATCH] Add new query format count and support for path/tree Issue-ID: AAI-602 Change-Id: I3e1bac256e679c0466fc3eceb52d440095b272d8 Signed-off-by: Maharajh, Robby (rx2202) --- .../onap/aai/serialization/queryformats/Count.java | 83 ++++++++++ .../aai/serialization/queryformats/Format.java | 7 +- .../serialization/queryformats/FormatFactory.java | 23 +-- .../serialization/queryformats/FormatMapper.java | 5 +- .../aai/serialization/queryformats/Formatter.java | 83 ++++++---- .../onap/aai/serialization/queryformats/IdURL.java | 6 +- .../queryformats/MultiFormatMapper.java | 110 +++++++++++++ .../aai/serialization/queryformats/PathedURL.java | 6 +- .../aai/serialization/queryformats/RawFormat.java | 30 ++-- .../aai/serialization/queryformats/Resource.java | 6 +- .../AAIFormatQueryResultFormatNotSupported.java | 13 +- .../queryformats/CountQuerySupportTest.java | 164 ++++++++++++++++++++ .../queryformats/MultiFormatTest.java | 172 +++++++++++++++++++++ .../serialization/queryformats/RawFormatTest.java | 20 +-- .../queryformats/SimpleFormatTest.java | 4 +- 15 files changed, 640 insertions(+), 92 deletions(-) create mode 100644 aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java create mode 100644 aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java create mode 100644 aai-core/src/test/java/org/onap/aai/serialization/queryformats/CountQuerySupportTest.java create mode 100644 aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java new file mode 100644 index 00000000..aea4ba12 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java @@ -0,0 +1,83 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.serialization.queryformats; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.tinkerpop.gremlin.process.traversal.Path; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.javatuples.Pair; +import org.onap.aai.db.props.AAIProperties; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; + +import com.google.gson.JsonObject; + +public class Count implements FormatMapper { + + @Override + public JsonObject formatObject(Object o) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported { + @SuppressWarnings("unchecked") + List list = (List) o; + + final JsonObject countResult = new JsonObject(); + + list.stream().map(this::getCount) + .filter( Optional>::isPresent ) + .map(Optional>::get) + .collect( Collectors.toConcurrentMap( Pair::getValue0, Pair::getValue1, Long::sum ) ) + .forEach( (k,v) -> countResult.addProperty(k, v) ); + + return countResult; + } + + @Override + public int parallelThreshold() { + return 20; + } + + private Optional> getCount(Object o){ + + Pair pair = null; + + if (o instanceof Vertex) { + Vertex v = (Vertex) o; + pair = Pair.with(v.property(AAIProperties.NODE_TYPE).value().toString(), 1L); + } else if (o instanceof Tree) { + pair = Pair.with("trees", 1L); + } else if (o instanceof Path) { + pair = Pair.with("paths", 1L); + } else if (o instanceof Long) { + pair = Pair.with("count", (Long)o); + } + + if (pair == null) { + return Optional.>empty(); + } + + return Optional.>of(pair); + } + +} diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java index 2904cce6..04f4d1c1 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java @@ -23,9 +23,12 @@ package org.onap.aai.serialization.queryformats; public enum Format { graphson, - pathed, id, resource, + pathed, + id, + resource, simple, resource_and_url, console, - raw + raw, + count } diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java index b19e0c3e..21a7e0fe 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java @@ -53,39 +53,42 @@ public class FormatFactory { public Formatter get(Format format, MultivaluedMap params) throws AAIException { - Formatter formattter = null; + Formatter formatter = null; switch (format) { case graphson : - formattter = new Formatter(inject(new GraphSON(), params)); + formatter = new Formatter(inject(new GraphSON(), params)); break; case pathed : - formattter = new Formatter(inject(new PathedURL(loader, urlBuilder), params)); + formatter = new Formatter(inject(new PathedURL(loader, urlBuilder), params)); break; case id : - formattter = new Formatter(inject(new IdURL(loader, urlBuilder), params)); + formatter = new Formatter(inject(new IdURL(loader, urlBuilder), params)); break; case resource : - formattter = new Formatter(inject(new Resource.Builder(loader, serializer, urlBuilder), params).build()); + formatter = new Formatter(inject(new Resource.Builder(loader, serializer, urlBuilder), params).build()); break; case resource_and_url : - formattter = new Formatter(inject(new Resource.Builder(loader, serializer, urlBuilder).includeUrl(), params).build()); + formatter = new Formatter(inject(new Resource.Builder(loader, serializer, urlBuilder).includeUrl(), params).build()); break; case raw : - formattter = new Formatter(inject(new RawFormat.Builder(loader, serializer, urlBuilder), params).build()); + formatter = new Formatter(inject(new RawFormat.Builder(loader, serializer, urlBuilder), params).build()); break; case simple : - formattter = new Formatter(inject(new RawFormat.Builder(loader, serializer, urlBuilder).depth(0).modelDriven(), params).build()); + formatter = new Formatter(inject(new RawFormat.Builder(loader, serializer, urlBuilder).depth(0).modelDriven(), params).build()); break; case console : - formattter = new Formatter(inject(new Console(), params)); + formatter = new Formatter(inject(new Console(), params)); + break; + case count : + formatter = new Formatter(inject(new Count(), params)); break; default : break; } - return formattter; + return formatter; } private T inject (T obj, MultivaluedMap params) throws QueryParamInjectionException { diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java index fb822dd9..27d204a6 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java @@ -21,12 +21,13 @@ */ package org.onap.aai.serialization.queryformats; -import com.google.gson.JsonObject; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported; import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; +import com.google.gson.JsonObject; public interface FormatMapper { - public JsonObject formatObject(Object v) throws AAIFormatVertexException; + public JsonObject formatObject(Object o) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported; public int parallelThreshold(); } diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java index 50042b76..b145d423 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java @@ -21,16 +21,18 @@ */ package org.onap.aai.serialization.queryformats; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; + import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; public class Formatter { @@ -38,43 +40,60 @@ public class Formatter { protected JsonParser parser = new JsonParser(); protected final FormatMapper format; - public Formatter (FormatMapper format) { + + public Formatter(FormatMapper format) { this.format = format; } - - public JsonObject output(List vertices) { + + public JsonObject output(List queryResults) { + Stream stream = null; JsonObject result = new JsonObject(); JsonArray body = new JsonArray(); - if (vertices.size() >= format.parallelThreshold()) { - stream = vertices.parallelStream(); - } else { - stream = vertices.stream(); - } - final boolean isParallel = stream.isParallel(); - stream.map(v -> { + + if (this.format instanceof Count) { + JsonObject countResult; try { - return Optional.of(format.formatObject(v)); - } catch (AAIFormatVertexException e) { - LOGGER.warn("Failed to format vertex, returning a partial list", e); + countResult = format.formatObject(queryResults); + body.add(countResult); + } catch (Exception e) { + LOGGER.warn("Failed to format result type of the query", e); } + } else { + if (queryResults.size() >= format.parallelThreshold()) { + stream = queryResults.parallelStream(); + } else { + stream = queryResults.stream(); + } + + final boolean isParallel = stream.isParallel(); + + stream.map(o -> { + try { + return Optional.of(format.formatObject(o)); + } catch (AAIFormatVertexException e) { + LOGGER.warn("Failed to format vertex, returning a partial list", e); + } catch (AAIFormatQueryResultFormatNotSupported e) { + LOGGER.warn("Failed to format result type of the query", e); + } - return Optional.empty(); - }).forEach(obj -> { - if (obj.isPresent()) { - if (isParallel) { - synchronized (body) { - body.add(obj.get()); + return Optional.empty(); + }) + .filter(Optional::isPresent) + .map(Optional::get) + .forEach(json -> { + if (isParallel) { + synchronized (body) { + body.add(json); + } + } else { + body.add(json); } - } else { - body.add(obj.get()); - } - } - }); - + }); + + } result.add("results", body); - return result.getAsJsonObject(); } - + } diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java index 320cd616..4395c8c9 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java @@ -32,7 +32,7 @@ import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; import org.onap.aai.serialization.queryformats.utils.UrlBuilder; -public class IdURL implements FormatMapper { +public class IdURL extends MultiFormatMapper { private final UrlBuilder urlBuilder; private final JsonParser parser; @@ -50,8 +50,8 @@ public class IdURL implements FormatMapper { } @Override - public JsonObject formatObject(Object input) throws AAIFormatVertexException { - Vertex v = (Vertex)input; + protected JsonObject getJsonFromVertex(Vertex v) throws AAIFormatVertexException { + try { final Introspector searchResult = this.loader.introspectorFromName("result-data"); diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java new file mode 100644 index 00000000..e4b5fc17 --- /dev/null +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java @@ -0,0 +1,110 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.serialization.queryformats; + +import java.util.Iterator; +import java.util.List; + +import org.apache.tinkerpop.gremlin.process.traversal.Path; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +public abstract class MultiFormatMapper implements FormatMapper { + + @Override + public JsonObject formatObject(Object input) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported { + if (input instanceof Vertex) { + return this.getJsonFromVertex((Vertex) input); + } else if (input instanceof Tree) { + return this.getJsonFomTree((Tree) input); + } else if (input instanceof Path) { + return this.getJsonFromPath((Path) input); + } else { + throw new AAIFormatQueryResultFormatNotSupported(); + } + } + + protected abstract JsonObject getJsonFromVertex(Vertex input) throws AAIFormatVertexException; + + protected JsonObject getJsonFromPath(Path input) throws AAIFormatVertexException { + List path = input.objects(); + + JsonObject jo = new JsonObject(); + JsonArray ja = new JsonArray(); + + for (Object o : path) { + if (o instanceof Vertex) { + ja.add(this.getJsonFromVertex((Vertex)o)); + } + } + + jo.add("path", ja); + return jo; + } + + protected JsonObject getJsonFomTree(Tree tree) throws AAIFormatVertexException { + + if (tree.isEmpty()) { + return new JsonObject(); + } + + JsonObject t = new JsonObject(); + JsonArray ja = this.getNodesArray(tree); + if (ja.size() > 0) { + t.add("nodes", ja); + } + + return t; + } + + private JsonArray getNodesArray (Tree tree) throws AAIFormatVertexException { + + JsonArray nodes = new JsonArray(); + Iterator it = tree.keySet().iterator(); + + while (it.hasNext()) { + Object o = it.next(); + JsonObject me = new JsonObject(); + if (o instanceof Vertex) { + me = this.getJsonFromVertex((Vertex) o); + } + JsonArray ja = this.getNodesArray((Tree) tree.get(o)); + if (ja.size() > 0) { + me.add("nodes", ja); + } + nodes.add(me); + } + return nodes; + } + + + @Override + public int parallelThreshold() { + return 100; + } + +} diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java index 8b9d5058..759f9c50 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java @@ -32,7 +32,7 @@ import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; import org.onap.aai.serialization.queryformats.utils.UrlBuilder; -public final class PathedURL implements FormatMapper { +public final class PathedURL extends MultiFormatMapper { private final UrlBuilder urlBuilder; private final JsonParser parser; @@ -50,8 +50,8 @@ public final class PathedURL implements FormatMapper { } @Override - public JsonObject formatObject(Object input) throws AAIFormatVertexException { - Vertex v = (Vertex)input; + protected JsonObject getJsonFromVertex(Vertex v) throws AAIFormatVertexException { + try { final Introspector searchResult = this.loader.introspectorFromName("result-data"); diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java index 3477a748..425c6edf 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java @@ -42,7 +42,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; -public class RawFormat implements FormatMapper { +public class RawFormat extends MultiFormatMapper { protected JsonParser parser = new JsonParser(); protected final DBSerializer serializer; protected final Loader loader; @@ -57,20 +57,6 @@ public class RawFormat implements FormatMapper { this.nodesOnly = builder.isNodesOnly(); } - @Override - public JsonObject formatObject(Object input) throws AAIFormatVertexException { - Vertex v = (Vertex)input; - JsonObject json = new JsonObject(); - json.addProperty("id", v.id().toString()); - json.addProperty("node-type", v.value(AAIProperties.NODE_TYPE)); - json.addProperty("url", this.urlBuilder.pathed(v)); - json.add("properties", this.createPropertiesObject(v)); - if (!nodesOnly) { - json.add("related-to", this.createRelationshipObject(v)); - } - return json; - } - @Override public int parallelThreshold() { return 100; @@ -200,4 +186,18 @@ public class RawFormat implements FormatMapper { } } } + + @Override + protected JsonObject getJsonFromVertex(Vertex v) throws AAIFormatVertexException { + + JsonObject json = new JsonObject(); + json.addProperty("id", v.id().toString()); + json.addProperty("node-type", v.value(AAIProperties.NODE_TYPE)); + json.addProperty("url", this.urlBuilder.pathed(v)); + json.add("properties", this.createPropertiesObject(v)); + if (!nodesOnly) { + json.add("related-to", this.createRelationshipObject(v)); + } + return json; + } } diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java index 649971be..429530c8 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java @@ -40,7 +40,7 @@ import org.onap.aai.serialization.queryformats.utils.UrlBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -public class Resource implements FormatMapper { +public class Resource extends MultiFormatMapper { private final Loader loader; private final DBSerializer serializer; @@ -60,8 +60,8 @@ public class Resource implements FormatMapper { } @Override - public JsonObject formatObject(Object input) throws AAIFormatVertexException { - Vertex v = (Vertex)input; + protected JsonObject getJsonFromVertex(Vertex v) throws AAIFormatVertexException { + JsonObject json = new JsonObject(); if (this.includeUrl) { diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/exceptions/AAIFormatQueryResultFormatNotSupported.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/exceptions/AAIFormatQueryResultFormatNotSupported.java index 726116a0..8d8e6835 100644 --- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/exceptions/AAIFormatQueryResultFormatNotSupported.java +++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/exceptions/AAIFormatQueryResultFormatNotSupported.java @@ -1,23 +1,24 @@ -/*- +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 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 - * + * + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ - package org.onap.aai.serialization.queryformats.exceptions; public class AAIFormatQueryResultFormatNotSupported extends Exception { diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/CountQuerySupportTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/CountQuerySupportTest.java new file mode 100644 index 00000000..488064e6 --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/CountQuerySupportTest.java @@ -0,0 +1,164 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.serialization.queryformats; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.List; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.aai.AAISetup; +import org.onap.aai.dbmap.DBConnectionType; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; +import org.onap.aai.introspection.Version; +import org.onap.aai.serialization.db.DBSerializer; +import org.onap.aai.serialization.db.EdgeRules; +import org.onap.aai.serialization.engines.QueryStyle; +import org.onap.aai.serialization.engines.TitanDBEngine; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; +import org.onap.aai.serialization.queryformats.utils.UrlBuilder; + +import com.google.gson.JsonObject; + +public class CountQuerySupportTest extends AAISetup { + + @Mock + private UrlBuilder urlBuilder; + + private Graph graph; + private TransactionalGraphEngine dbEngine; + private Loader loader; + private final ModelType factoryType = ModelType.MOXY; + private final EdgeRules rules = EdgeRules.getInstance(); + private Version version = Version.getLatest(); + Vertex pserver1; + Vertex complex1; + Vertex complex2; + + private DBSerializer serializer; + + private FormatFactory ff; + private Formatter formatter; + + @Before + public void setUp() throws Exception { + + MockitoAnnotations.initMocks(this); + + graph = TinkerGraph.open(); + + pserver1 = graph.addVertex(T.label, "pserver", T.id, "2", "aai-node-type", "pserver", "hostname", + "hostname-1"); + complex1 = graph.addVertex(T.label, "complex", T.id, "3", "aai-node-type", "complex", + "physical-location-id", "physical-location-id-1", "country", "US"); + + complex2 = graph.addVertex(T.label, "complex", T.id, "4", "aai-node-type", "complex", + "physical-location-id", "physical-location-id-2", "country", "US"); + + GraphTraversalSource g = graph.traversal(); + rules.addEdge(g, pserver1, complex1); + + createLoaderEngineSetup(); + + } + + @After + public void tearDown() throws Exception { + graph.close(); + } + + @Test + public void verifyComplexVertexCountTest1() throws AAIFormatVertexException, AAIException, AAIFormatQueryResultFormatNotSupported { + List complexList = Arrays.asList(this.complex1, this.complex2 ); + JsonObject jo = this.formatter.output(complexList); + assertEquals(2, jo.get("results").getAsJsonArray().get(0).getAsJsonObject().get("complex").getAsInt()); + } + + @Test + public void verifyPserverVertexCountTest1() throws AAIFormatVertexException, AAIException, AAIFormatQueryResultFormatNotSupported { + List pserverList = Arrays.asList(this.pserver1 ); + JsonObject jo = this.formatter.output(pserverList); + assertEquals(1, jo.get("results").getAsJsonArray().get(0).getAsJsonObject().get("pserver").getAsInt()); + } + + @Test + public void verifyComplexVertexCountTest2() throws AAIFormatVertexException, AAIException, AAIFormatQueryResultFormatNotSupported { + List list = Arrays.asList(this.complex1, this.pserver1, this.complex2 ); + JsonObject jo = this.formatter.output(list); + assertEquals(2, jo.get("results").getAsJsonArray().get(0).getAsJsonObject().get("complex").getAsInt()); + } + + @Test + public void verifyPserverVertexCountTest2() throws AAIFormatVertexException, AAIException, AAIFormatQueryResultFormatNotSupported { + List list = Arrays.asList(this.complex1, this.pserver1, this.complex2 ); + JsonObject jo = this.formatter.output(list); + assertEquals(1, jo.get("results").getAsJsonArray().get(0).getAsJsonObject().get("pserver").getAsInt()); + } + + @Test + public void verifyLongTest() throws AAIFormatVertexException, AAIException, AAIFormatQueryResultFormatNotSupported { + List complexList = Arrays.asList(Long.valueOf(22L) ); + JsonObject jo = this.formatter.output(complexList); + assertEquals(22, jo.get("results").getAsJsonArray().get(0).getAsJsonObject().get("count").getAsInt()); + } + + + public void createLoaderEngineSetup() throws AAIException { + + if (loader == null) { + loader = LoaderFactory.createLoaderForVersion(factoryType, version); + dbEngine = spy(new TitanDBEngine(QueryStyle.TRAVERSAL, DBConnectionType.CACHED, loader)); + serializer = new DBSerializer(version, dbEngine, factoryType, "Junit"); + + ff = new FormatFactory(loader, serializer); + formatter = ff.get(Format.count); + + + TransactionalGraphEngine.Admin spyAdmin = spy(dbEngine.asAdmin()); + + when(dbEngine.tx()).thenReturn(graph); + when(dbEngine.asAdmin()).thenReturn(spyAdmin); + + when(spyAdmin.getReadOnlyTraversalSource()) + .thenReturn(graph.traversal(GraphTraversalSource.build().with(ReadOnlyStrategy.instance()))); + when(spyAdmin.getTraversalSource()).thenReturn(graph.traversal()); + } + } +} diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java new file mode 100644 index 00000000..fde1307e --- /dev/null +++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/MultiFormatTest.java @@ -0,0 +1,172 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.serialization.queryformats; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.io.UnsupportedEncodingException; + +import org.apache.tinkerpop.gremlin.process.traversal.Path; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.aai.AAISetup; +import org.onap.aai.dbmap.DBConnectionType; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.LoaderFactory; +import org.onap.aai.introspection.ModelType; +import org.onap.aai.introspection.Version; +import org.onap.aai.serialization.db.DBSerializer; +import org.onap.aai.serialization.db.EdgeRules; +import org.onap.aai.serialization.engines.QueryStyle; +import org.onap.aai.serialization.engines.TitanDBEngine; +import org.onap.aai.serialization.engines.TransactionalGraphEngine; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported; +import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; +import org.onap.aai.serialization.queryformats.utils.UrlBuilder; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class MultiFormatTest extends AAISetup { + + @Mock + private UrlBuilder urlBuilder; + + private Graph graph; + private TransactionalGraphEngine dbEngine; + private Loader loader; + private IdURL idFormat; + private final ModelType factoryType = ModelType.MOXY; + private final EdgeRules rules = EdgeRules.getInstance(); + private Tree resultTree; + private Path resultPath; + private Version version = Version.v11; + private JsonObject expectedTreeIdFormat = new JsonParser() + .parse("{\"nodes\":[{\"resource-type\":\"generic-vnf\",\"nodes\":[{\"resource-type\":\"vserver\",\"nodes\":[{\"resource-type\":\"pserver\"}]},{\"resource-type\":\"pserver\",\"nodes\":[{\"resource-type\":\"complex\"}]}]}]}").getAsJsonObject(); + private JsonObject expectedPathIdFormat = new JsonParser() + .parse("{\"path\":[{\"resource-type\":\"generic-vnf\"},{\"resource-type\":\"vserver\"},{\"resource-type\":\"pserver\"},{\"resource-type\":\"complex\"}]}").getAsJsonObject(); + + @Before + public void setUp() throws Exception { + + MockitoAnnotations.initMocks(this); + + graph = TinkerGraph.open(); + + Vertex gnvf1 = graph.addVertex(T.label, "generic-vnf", T.id, "0", "aai-node-type", "generic-vnf", "vnf-id", + "vnf-id-1", "vnf-name", "vnf-name-1"); + Vertex vserver1 = graph.addVertex(T.label, "vserver", T.id, "1", "aai-node-type", "vserver", "vserver-id", + "vserver-id-1", "vserver-name", "vserver-name-1"); + Vertex pserver1 = graph.addVertex(T.label, "pserver", T.id, "2", "aai-node-type", "pserver", "hostname", + "hostname-1"); + Vertex complex1 = graph.addVertex(T.label, "complex", T.id, "3", "aai-node-type", "complex", + "physical-location-id", "physical-location-id-1", "country", "US"); + + Vertex pserver2 = graph.addVertex(T.label, "pserver", T.id, "5", "aai-node-type", "pserver", "hostname", + "hostname-2"); + Vertex complex2 = graph.addVertex(T.label, "complex", T.id, "6", "aai-node-type", "complex", + "physical-location-id", "physical-location-id-2", "country", "US"); + + GraphTraversalSource g = graph.traversal(); + rules.addEdge(g, gnvf1, vserver1); + rules.addEdge(g, vserver1, pserver1); + rules.addEdge(g, pserver1, complex1); + rules.addEdge(g, gnvf1, pserver2); + rules.addEdge(g, pserver2, complex2); + + resultTree = graph.traversal().V("0").out().out().tree().next(); + resultPath = graph.traversal().V("0").out().hasId("1").out().hasId("2").out().hasId("3").path().next(); + } + + @Test + public void testTreeResultQueryIdFormat() + throws AAIFormatVertexException, AAIException, AAIFormatQueryResultFormatNotSupported { + + createLoaderEngineSetup(); + idFormat = new IdURL(loader, urlBuilder); + + assertNotNull(dbEngine.tx()); + assertNotNull(dbEngine.asAdmin()); + + JsonObject json = idFormat.formatObject(resultTree); + + assertEquals(this.expectedTreeIdFormat, json); + + } + + @Test + public void testPathResultQueryIdFormat() + throws AAIFormatVertexException, AAIException, AAIFormatQueryResultFormatNotSupported { + + createLoaderEngineSetup(); + idFormat = new IdURL(loader, urlBuilder); + + assertNotNull(dbEngine.tx()); + assertNotNull(dbEngine.asAdmin()); + + JsonObject json = idFormat.formatObject(resultPath); + + assertEquals(this.expectedPathIdFormat, json); + + } + + + @Test(expected = AAIFormatQueryResultFormatNotSupported.class) + public void testThrowsExceptionIfObjectNotSupported() throws AAIFormatVertexException, + AAIException, UnsupportedEncodingException, AAIFormatQueryResultFormatNotSupported { + + loader = mock(Loader.class); + idFormat = new IdURL(loader, urlBuilder); + idFormat.formatObject(new String()); + } + + public void createLoaderEngineSetup() { + + if (loader == null) { + loader = LoaderFactory.createLoaderForVersion(factoryType, version); + dbEngine = spy(new TitanDBEngine(QueryStyle.TRAVERSAL, DBConnectionType.CACHED, loader)); + + TransactionalGraphEngine.Admin spyAdmin = spy(dbEngine.asAdmin()); + + when(dbEngine.tx()).thenReturn(graph); + when(dbEngine.asAdmin()).thenReturn(spyAdmin); + + when(spyAdmin.getReadOnlyTraversalSource()) + .thenReturn(graph.traversal(GraphTraversalSource.build().with(ReadOnlyStrategy.instance()))); + when(spyAdmin.getTraversalSource()).thenReturn(graph.traversal()); + } + } +} diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/RawFormatTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/RawFormatTest.java index 37a2a4f0..a33349fd 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/RawFormatTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/RawFormatTest.java @@ -1,14 +1,14 @@ -/*- +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 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 + * 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, @@ -16,22 +16,16 @@ * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ - package org.onap.aai.serialization.queryformats; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import java.io.UnsupportedEncodingException; - -import org.apache.tinkerpop.gremlin.process.traversal.Path; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; -import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.T; @@ -53,14 +47,10 @@ import org.onap.aai.serialization.db.EdgeRules; import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TitanDBEngine; import org.onap.aai.serialization.engines.TransactionalGraphEngine; -import org.onap.aai.serialization.queryformats.RawFormat.Builder; import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported; import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException; import org.onap.aai.serialization.queryformats.utils.UrlBuilder; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - public class RawFormatTest extends AAISetup { @Mock diff --git a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java index 5e400116..ec89aa30 100644 --- a/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java +++ b/aai-core/src/test/java/org/onap/aai/serialization/queryformats/SimpleFormatTest.java @@ -19,6 +19,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + package org.onap.aai.serialization.queryformats; import com.google.gson.JsonObject; @@ -33,6 +34,7 @@ import org.junit.Ignore; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.onap.aai.AAISetup; import org.onap.aai.dbmap.DBConnectionType; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Loader; @@ -56,7 +58,7 @@ import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.*; -public class SimpleFormatTest { +public class SimpleFormatTest extends AAISetup { @Mock private UrlBuilder urlBuilder; -- 2.16.6