aboutsummaryrefslogtreecommitdiffstats
path: root/aai-core/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'aai-core/src/main')
-rw-r--r--aai-core/src/main/java/org/onap/aai/config/SwaggerGenerationConfiguration.java47
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialIO.java158
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java354
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java8
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java149
-rw-r--r--aai-core/src/main/java/org/onap/aai/extensions/OrphanLInterfaceHandler.java110
-rw-r--r--aai-core/src/main/java/org/onap/aai/ingestModel/CreateWidgetModels.java16
-rw-r--r--aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java15
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java226
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java198
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java47
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java339
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/HttpMethod.java3
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java58
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java74
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java53
-rw-r--r--aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java56
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/AAIConstants.java19
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/GenerateXsd.java50
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/genxsd/NodesYAMLfromOXM.java13
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/genxsd/OxmFileProcessor.java82
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/genxsd/PutOperation.java14
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/genxsd/XSDElement.java36
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/genxsd/YAMLfromOXM.java19
-rw-r--r--aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java2
-rw-r--r--aai-core/src/main/resources/schema-ingest.properties1
26 files changed, 1673 insertions, 474 deletions
diff --git a/aai-core/src/main/java/org/onap/aai/config/SwaggerGenerationConfiguration.java b/aai-core/src/main/java/org/onap/aai/config/SwaggerGenerationConfiguration.java
index 9aae5a62..dea284c8 100644
--- a/aai-core/src/main/java/org/onap/aai/config/SwaggerGenerationConfiguration.java
+++ b/aai-core/src/main/java/org/onap/aai/config/SwaggerGenerationConfiguration.java
@@ -37,31 +37,28 @@ import org.springframework.context.annotation.Scope;
@Configuration
public class SwaggerGenerationConfiguration {
- @Value("${schema.uri.base.path}")
- private String basePath;
+ @Value("${schema.uri.base.path}")
+ private String basePath;
- @Value("${schema.xsd.maxoccurs:5000}")
- private String maxOccurs;
-
- @Bean
- @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public NodesYAMLfromOXM nodesYamlFromOXM(SchemaVersions schemaVersions, NodeIngestor nodeIngestor, EdgeIngestor edgeIngestor) {
- NodesYAMLfromOXM nodesYamlFromOXM = new NodesYAMLfromOXM(basePath, schemaVersions, nodeIngestor, edgeIngestor);
- return nodesYamlFromOXM;
- }
-
- @Bean
- @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public HTMLfromOXM htmlFromOXM(SchemaVersions schemaVersions, NodeIngestor nodeIngestor, EdgeIngestor edgeIngestor) {
- HTMLfromOXM htmlFromOXM = new HTMLfromOXM(maxOccurs, schemaVersions, nodeIngestor, edgeIngestor);
- return htmlFromOXM;
- }
-
- @Bean
- @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public YAMLfromOXM yamlFromOXM(SchemaVersions schemaVersions, NodeIngestor nodeIngestor, EdgeIngestor edgeIngestor) {
- YAMLfromOXM yamlFromOXM = new YAMLfromOXM(basePath, schemaVersions, nodeIngestor, edgeIngestor);
- return yamlFromOXM;
- }
+ @Value("${schema.xsd.maxoccurs:5000}")
+ private String maxOccurs;
+
+ @Bean
+ @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public NodesYAMLfromOXM nodesYamlFromOXM(SchemaVersions schemaVersions, NodeIngestor nodeIngestor, EdgeIngestor edgeIngestor) {
+ return new NodesYAMLfromOXM(basePath, schemaVersions, nodeIngestor, edgeIngestor);
+ }
+
+ @Bean
+ @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public HTMLfromOXM htmlFromOXM(SchemaVersions schemaVersions, NodeIngestor nodeIngestor, EdgeIngestor edgeIngestor) {
+ return new HTMLfromOXM(maxOccurs, schemaVersions, nodeIngestor, edgeIngestor);
+ }
+
+ @Bean
+ @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public YAMLfromOXM yamlFromOXM(SchemaVersions schemaVersions, NodeIngestor nodeIngestor, EdgeIngestor edgeIngestor) {
+ return new YAMLfromOXM(basePath, schemaVersions, nodeIngestor, edgeIngestor);
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialIO.java b/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialIO.java
new file mode 100644
index 00000000..915db69c
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialIO.java
@@ -0,0 +1,158 @@
+/**
+ * ============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.dbgen;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.Io;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
+import org.apache.tinkerpop.gremlin.structure.io.Mapper;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * Constructs GraphSON IO implementations given a {@link Graph} and {@link IoRegistry}. Implementers of the {@link Graph}
+ * interfaces should see the {@link GraphSONMapper} for information on the expectations for the {@link IoRegistry}.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class GraphSONPartialIO implements Io<GraphSONPartialReader.Builder, GraphSONWriter.Builder, GraphSONMapper.Builder> {
+ private final IoRegistry registry;
+ private final Graph graph;
+ private final Optional<Consumer<Mapper.Builder>> onMapper;
+ private final GraphSONVersion version;
+
+ private GraphSONPartialIO(final Builder builder) {
+ this.registry = builder.registry;
+ this.graph = builder.graph;
+ this.onMapper = Optional.ofNullable(builder.onMapper);
+ this.version = builder.version;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GraphSONPartialReader.Builder reader() {
+ return GraphSONPartialReader.build().mapper(mapper().create());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GraphSONWriter.Builder writer() {
+ return GraphSONWriter.build().mapper(mapper().create());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GraphSONMapper.Builder mapper() {
+ final GraphSONMapper.Builder builder = (null == this.registry) ?
+ GraphSONMapper.build().version(version) : GraphSONMapper.build().version(version).addRegistry(this.registry);
+ onMapper.ifPresent(c -> c.accept(builder));
+ return builder;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeGraph(final String file) throws IOException {
+ try (final OutputStream out = new FileOutputStream(file)) {
+ writer().create().writeGraph(out, graph);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void readGraph(final String file) throws IOException {
+ try (final InputStream in = new FileInputStream(file)) {
+ reader().create().readGraph(in, graph);
+ }
+ }
+
+ /**
+ * Create a new builder using the default version of GraphSON.
+ */
+ public static Io.Builder<GraphSONPartialIO> build() {
+ return build(GraphSONVersion.V1_0);
+ }
+
+ /**
+ * Create a new builder using the specified version of GraphSON.
+ */
+ public static Io.Builder<GraphSONPartialIO> build(final GraphSONVersion version) {
+ return new Builder(version);
+ }
+
+ public final static class Builder implements Io.Builder<GraphSONPartialIO> {
+
+ private IoRegistry registry = null;
+ private Graph graph;
+ private Consumer<Mapper.Builder> onMapper = null;
+ private final GraphSONVersion version;
+
+ Builder(final GraphSONVersion version) {
+ this.version = version;
+ }
+
+ /**
+ * @deprecated As of release 3.2.2, replaced by {@link #onMapper(Consumer)}.
+ */
+ @Deprecated
+ @Override
+ public Io.Builder<GraphSONPartialIO> registry(final IoRegistry registry) {
+ this.registry = registry;
+ return this;
+ }
+
+ @Override
+ public Io.Builder<? extends Io> onMapper(final Consumer<Mapper.Builder> onMapper) {
+ this.onMapper = onMapper;
+ return this;
+ }
+
+ @Override
+ public Io.Builder<GraphSONPartialIO> graph(final Graph g) {
+ this.graph = g;
+ return this;
+ }
+
+ @Override
+ public GraphSONPartialIO create() {
+ if (null == graph) throw new IllegalArgumentException("The graph argument was not specified");
+ return new GraphSONPartialIO(this);
+ }
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java b/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java
new file mode 100644
index 00000000..2088286d
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java
@@ -0,0 +1,354 @@
+/**
+ * ============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.dbgen;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.GraphReader;
+import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
+import org.apache.tinkerpop.gremlin.structure.io.Mapper;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion;
+import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoWriter;
+import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+import org.apache.tinkerpop.gremlin.structure.util.Host;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
+import org.apache.tinkerpop.gremlin.util.function.FunctionUtils;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.type.TypeReference;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
+import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.apache.tinkerpop.shaded.jackson.databind.node.JsonNodeType;
+import org.onap.aai.dbmap.InMemoryGraph;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * This is a Wrapper around the GraphsonReader class
+ * The idea is to rewrite methods that are customized for A&AI
+ * GraphsonReader is a final class . hence the use of the Wrapper
+ * instead of inheriting-overwriting
+ *
+ *
+ */
+public final class GraphSONPartialReader implements GraphReader {
+ private final ObjectMapper mapper ;
+ private final long batchSize ;
+ private final GraphSONVersion version ;
+ private boolean unwrapAdjacencyList = false;
+ private final GraphSONReader reader;
+
+ private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(InMemoryGraph.class);
+
+ final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {
+ };
+
+ private GraphSONPartialReader(final Builder builder) {
+ mapper = builder.mapper.createMapper();
+ batchSize = builder.batchSize;
+ unwrapAdjacencyList = builder.unwrapAdjacencyList;
+ version = ((GraphSONMapper)builder.mapper).getVersion();
+ reader = GraphSONReader.build().create();
+ }
+
+ /**
+ * Read data into a {@link Graph} from output generated by any of the {@link GraphSONWriter} {@code writeVertex} or
+ * {@code writeVertices} methods or by {@link GryoWriter#writeGraph(OutputStream, Graph)}.
+ *
+ * @param inputStream a stream containing an entire graph of vertices and edges as defined by the accompanying
+ * {@link GraphSONWriter#writeGraph(OutputStream, Graph)}.
+ * @param graphToWriteTo the graph to write to when reading from the stream.
+ */
+ @Override
+ public void readGraph(final InputStream inputStream, final Graph graphToWriteTo) throws IOException {
+ // dual pass - create all vertices and store to cache the ids. then create edges. as long as we don't
+ // have vertex labels in the output we can't do this single pass
+ LOGGER.info("Read the Partial Graph");
+ final Map<StarGraph.StarVertex,Vertex> cache = new HashMap<>();
+ final AtomicLong counter = new AtomicLong(0);
+
+ final boolean supportsTx = graphToWriteTo.features().graph().supportsTransactions();
+ final Graph.Features.EdgeFeatures edgeFeatures = graphToWriteTo.features().edge();
+
+ readVertexStrings(inputStream).<Vertex>map(FunctionUtils.wrapFunction(line -> readVertex(new ByteArrayInputStream(line.getBytes()), null, null, Direction.IN))).forEach(vertex -> {
+ try{
+ final Attachable<Vertex> attachable = (Attachable<Vertex>) vertex;
+ cache.put((StarGraph.StarVertex) attachable.get(), attachable.attach(Attachable.Method.create(graphToWriteTo)));
+ if (supportsTx && counter.incrementAndGet() % batchSize == 0)
+ graphToWriteTo.tx().commit();
+ }
+ catch(Exception ex){
+ LOGGER.info("Error in reading vertex from graphson"+vertex.toString());
+ }
+ });
+
+ cache.entrySet().forEach(kv -> kv.getKey().edges(Direction.IN).forEachRemaining(e -> {
+ try{
+ // can't use a standard Attachable attach method here because we have to use the cache for those
+ // graphs that don't support userSuppliedIds on edges. note that outVertex/inVertex methods return
+ // StarAdjacentVertex whose equality should match StarVertex.
+ final Vertex cachedOutV = cache.get(e.outVertex());
+ final Vertex cachedInV = cache.get(e.inVertex());
+
+ if(cachedOutV != null && cachedInV != null){
+
+ final Edge newEdge = edgeFeatures.willAllowId(e.id()) ? cachedOutV.addEdge(e.label(), cachedInV, T.id, e.id()) : cachedOutV.addEdge(e.label(), cachedInV);
+ e.properties().forEachRemaining(p -> newEdge.property(p.key(), p.value()));
+ }
+ else{
+ LOGGER.debug("Ghost edges from "+ cachedOutV + " to "+ cachedInV);
+
+ }
+ if (supportsTx && counter.incrementAndGet() % batchSize == 0)
+ graphToWriteTo.tx().commit();
+ }
+ catch(Exception ex){
+ LOGGER.info("Error in writing vertex into graph"+e.toString());
+ }
+ }));
+
+ if (supportsTx) graphToWriteTo.tx().commit();
+ }
+
+ /**
+ * Read {@link Vertex} objects from output generated by any of the {@link GraphSONWriter} {@code writeVertex} or
+ * {@code writeVertices} methods or by {@link GraphSONWriter#writeGraph(OutputStream, Graph)}.
+ *
+ * @param inputStream a stream containing at least one {@link Vertex} as defined by the accompanying
+ * {@link GraphWriter#writeVertices(OutputStream, Iterator, Direction)} or
+ * {@link GraphWriter#writeVertices(OutputStream, Iterator)} methods.
+ * @param vertexAttachMethod a function that creates re-attaches a {@link Vertex} to a {@link Host} object.
+ * @param edgeAttachMethod a function that creates re-attaches a {@link Edge} to a {@link Host} object.
+ * @param attachEdgesOfThisDirection only edges of this direction are passed to the {@code edgeMaker}.
+ */
+ @Override
+ public Iterator<Vertex> readVertices(final InputStream inputStream,
+ final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
+ final Function<Attachable<Edge>, Edge> edgeAttachMethod,
+ final Direction attachEdgesOfThisDirection) throws IOException {
+ // return readVertexStrings(inputStream).<Vertex>map(FunctionUtils.wrapFunction(line -> readVertex(new ByteArrayInputStream(line.getBytes()), vertexAttachMethod, edgeAttachMethod, attachEdgesOfThisDirection))).iterator();
+ return reader.readVertices(inputStream, vertexAttachMethod, edgeAttachMethod, attachEdgesOfThisDirection);
+
+ }
+
+ /**
+ * Read a {@link Vertex} from output generated by any of the {@link GraphSONWriter} {@code writeVertex} or
+ * {@code writeVertices} methods or by {@link GraphSONWriter#writeGraph(OutputStream, Graph)}.
+ *
+ * @param inputStream a stream containing at least a single vertex as defined by the accompanying
+ * {@link GraphWriter#writeVertex(OutputStream, Vertex)}.
+ * @param vertexAttachMethod a function that creates re-attaches a {@link Vertex} to a {@link Host} object.
+ */
+ @Override
+ public Vertex readVertex(final InputStream inputStream, final Function<Attachable<Vertex>, Vertex> vertexAttachMethod) throws IOException {
+ return reader.readVertex(inputStream, vertexAttachMethod);
+ }
+
+ /**
+ * Read a {@link Vertex} from output generated by any of the {@link GraphSONWriter} {@code writeVertex} or
+ * {@code writeVertices} methods or by {@link GraphSONWriter#writeGraph(OutputStream, Graph)}.
+ *
+ * @param inputStream a stream containing at least one {@link Vertex} as defined by the accompanying
+ * {@link GraphWriter#writeVertices(OutputStream, Iterator, Direction)} method.
+ * @param vertexAttachMethod a function that creates re-attaches a {@link Vertex} to a {@link Host} object.
+ * @param edgeAttachMethod a function that creates re-attaches a {@link Edge} to a {@link Host} object.
+ * @param attachEdgesOfThisDirection only edges of this direction are passed to the {@code edgeMaker}.
+ */
+ @Override
+ public Vertex readVertex(final InputStream inputStream,
+ final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
+ final Function<Attachable<Edge>, Edge> edgeAttachMethod,
+ final Direction attachEdgesOfThisDirection) throws IOException {
+
+ return reader.readVertex(inputStream, vertexAttachMethod, edgeAttachMethod, attachEdgesOfThisDirection);
+ }
+
+ /**
+ * Read an {@link Edge} from output generated by {@link GraphSONWriter#writeEdge(OutputStream, Edge)} or via
+ * an {@link Edge} passed to {@link GraphSONWriter#writeObject(OutputStream, Object)}.
+ *
+ * @param inputStream a stream containing at least one {@link Edge} as defined by the accompanying
+ * {@link GraphWriter#writeEdge(OutputStream, Edge)} method.
+ * @param edgeAttachMethod a function that creates re-attaches a {@link Edge} to a {@link Host} object.
+ */
+ @Override
+ public Edge readEdge(final InputStream inputStream, final Function<Attachable<Edge>, Edge> edgeAttachMethod) throws IOException {
+ /*if (version == GraphSONVersion.v1_0) {
+ final Map<String, Object> edgeData = mapper.readValue(inputStream, mapTypeReference);
+
+ final Map<String, Object> edgeProperties = edgeData.containsKey(GraphSONTokens.PROPERTIES) ?
+ (Map<String, Object>) edgeData.get(GraphSONTokens.PROPERTIES) : Collections.EMPTY_MAP;
+ final DetachedEdge edge = new DetachedEdge(edgeData.get(GraphSONTokens.ID),
+ edgeData.get(GraphSONTokens.LABEL).toString(),
+ edgeProperties,
+ Pair.with(edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString()),
+ Pair.with(edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString()));
+
+ return edgeAttachMethod.apply(edge);
+ } else {
+ return edgeAttachMethod.apply((DetachedEdge) mapper.readValue(inputStream, Edge.class));
+ }*/
+ return reader.readEdge(inputStream, edgeAttachMethod);
+ }
+
+ /**
+ * Read a {@link VertexProperty} from output generated by
+ * {@link GraphSONWriter#writeVertexProperty(OutputStream, VertexProperty)} or via an {@link VertexProperty} passed
+ * to {@link GraphSONWriter#writeObject(OutputStream, Object)}.
+ *
+ * @param inputStream a stream containing at least one {@link VertexProperty} as written by the accompanying
+ * {@link GraphWriter#writeVertexProperty(OutputStream, VertexProperty)} method.
+ * @param vertexPropertyAttachMethod a function that creates re-attaches a {@link VertexProperty} to a
+ * {@link Host} object.
+ */
+ @Override
+ public VertexProperty readVertexProperty(final InputStream inputStream,
+ final Function<Attachable<VertexProperty>, VertexProperty> vertexPropertyAttachMethod) throws IOException {
+ /*if (version == GraphSONVersion.v1_0) {
+ final Map<String, Object> vpData = mapper.readValue(inputStream, mapTypeReference);
+ final Map<String, Object> metaProperties = (Map<String, Object>) vpData.get(GraphSONTokens.PROPERTIES);
+ final DetachedVertexProperty vp = new DetachedVertexProperty(vpData.get(GraphSONTokens.ID),
+ vpData.get(GraphSONTokens.LABEL).toString(),
+ vpData.get(GraphSONTokens.VALUE), metaProperties);
+ return vertexPropertyAttachMethod.apply(vp);
+ } else {
+ return vertexPropertyAttachMethod.apply((DetachedVertexProperty) mapper.readValue(inputStream, VertexProperty.class));
+ }*/
+ return reader.readVertexProperty(inputStream, vertexPropertyAttachMethod);
+ }
+
+ /**
+ * Read a {@link Property} from output generated by {@link GraphSONWriter#writeProperty(OutputStream, Property)} or
+ * via an {@link Property} passed to {@link GraphSONWriter#writeObject(OutputStream, Object)}.
+ *
+ * @param inputStream a stream containing at least one {@link Property} as written by the accompanying
+ * {@link GraphWriter#writeProperty(OutputStream, Property)} method.
+ * @param propertyAttachMethod a function that creates re-attaches a {@link Property} to a {@link Host} object.
+ */
+ @Override
+ public Property readProperty(final InputStream inputStream,
+ final Function<Attachable<Property>, Property> propertyAttachMethod) throws IOException {
+ /*if (version == GraphSONVersion.v1_0) {
+ final Map<String, Object> propertyData = mapper.readValue(inputStream, mapTypeReference);
+ final DetachedProperty p = new DetachedProperty(propertyData.get(GraphSONTokens.KEY).toString(), propertyData.get(GraphSONTokens.VALUE));
+ return propertyAttachMethod.apply(p);
+ } else {
+ return propertyAttachMethod.apply((DetachedProperty) mapper.readValue(inputStream, Property.class));
+ }*/
+ return reader.readProperty(inputStream, propertyAttachMethod);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C> C readObject(final InputStream inputStream, final Class<? extends C> clazz) throws IOException {
+ return mapper.readValue(inputStream, clazz);
+ }
+
+ private Stream<String> readVertexStrings(final InputStream inputStream) throws IOException {
+ if (unwrapAdjacencyList) {
+ final JsonNode root = mapper.readTree(inputStream);
+ final JsonNode vertices = root.get(GraphSONTokens.VERTICES);
+ if (!vertices.getNodeType().equals(JsonNodeType.ARRAY)) throw new IOException(String.format("The '%s' key must be an array", GraphSONTokens.VERTICES));
+ return IteratorUtils.stream(vertices.elements()).map(Object::toString);
+ } else {
+ final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
+ return br.lines();
+ }
+
+ }
+
+
+ public static Builder build() {
+ return new Builder();
+ }
+
+ public final static class Builder implements ReaderBuilder<GraphSONPartialReader> {
+ private long batchSize = 10000;
+
+ private Mapper<ObjectMapper> mapper = GraphSONMapper.build().create();
+ private boolean unwrapAdjacencyList = false;
+
+
+ private Builder() {}
+
+ /**
+ * Number of mutations to perform before a commit is executed when using
+ * {@link GraphSONPartialReader#readGraph(InputStream, Graph)}.
+ */
+ public Builder batchSize(final long batchSize) {
+ this.batchSize = batchSize;
+ return this;
+ }
+
+ /**
+ * Override all of the {@link GraphSONMapper} builder
+ * options with this mapper. If this value is set to something other than null then that value will be
+ * used to construct the writer.
+ */
+ public Builder mapper(final Mapper<ObjectMapper> mapper) {
+ this.mapper = mapper;
+ return this;
+ }
+
+ /**
+ * If the adjacency list is wrapped in a JSON object, as is done when writing a graph with
+ * {@link GraphSONWriter.Builder#wrapAdjacencyList} set to {@code true}, this setting needs to be set to
+ * {@code true} to properly read it. By default, this value is {@code false} and the adjacency list is
+ * simply read as line delimited vertices.
+ * <p/>
+ * By setting this value to {@code true}, the generated JSON is no longer "splittable" by line and thus not
+ * suitable for OLAP processing. Furthermore, reading this format of the JSON with
+ * {@link GraphSONPartialReader#readGraph(InputStream, Graph)} or
+ * {@link GraphSONPartialReader#readVertices(InputStream, Function, Function, Direction)} requires that the
+ * entire JSON object be read into memory, so it is best saved for "small" graphs.
+ */
+ public Builder unwrapAdjacencyList(final boolean unwrapAdjacencyList) {
+ this.unwrapAdjacencyList = unwrapAdjacencyList;
+ return this;
+ }
+
+ public GraphSONPartialReader create() {
+ return new GraphSONPartialReader(this);
+ }
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java
index d2f60f11..1f7f5dbc 100644
--- a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java
+++ b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java
@@ -132,8 +132,8 @@ public class SchemaGenerator {
if (alias.isPresent()) {
dbPropName = alias.get();
}
- if (graphMgmt.containsRelationType(propName)) {
- String dmsg = " PropertyKey [" + propName + "] already existed in the DB. ";
+ if (graphMgmt.containsRelationType(dbPropName)) {
+ String dmsg = " PropertyKey [" + dbPropName + "] already existed in the DB. ";
LOGGER.debug(dmsg);
} else {
Class<?> type = obj.getClass(propName);
@@ -164,8 +164,8 @@ public class SchemaGenerator {
String dmsg = " Index [" + dbPropName + "] already existed in the DB. ";
LOGGER.debug(dmsg);
} else {
- if (obj.getIndexedProperties().contains(propName)) {
- if (obj.getUniqueProperties().contains(propName)) {
+ if (obj.getIndexedProperties().contains(dbPropName)) {
+ if (obj.getUniqueProperties().contains(dbPropName)) {
imsg = "Add Unique index for PropertyKey: [" + dbPropName + "]";
LOGGER.info(imsg);
graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).unique()
diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java b/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java
new file mode 100644
index 00000000..84e15479
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java
@@ -0,0 +1,149 @@
+/**
+ * ============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.dbmap;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.tinkerpop.gremlin.structure.io.IoCore;
+import org.onap.aai.dbgen.GraphSONPartialIO;
+import org.onap.aai.dbgen.SchemaGenerator;
+import org.onap.aai.logging.LogFormatTools;
+
+import org.janusgraph.core.JanusGraphFactory;
+import org.janusgraph.core.JanusGraph;
+import org.janusgraph.core.JanusGraphTransaction;
+import org.janusgraph.core.schema.JanusGraphManagement;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class InMemoryGraph {
+
+ private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(InMemoryGraph.class);
+ private JanusGraph graph = null;
+
+
+ public InMemoryGraph(Builder builder) throws IOException {
+ /*
+ * Create a In-memory graph
+ */
+ InputStream is = new FileInputStream(builder.propertyFile);
+ try {
+ graph = JanusGraphFactory.open(builder.propertyFile);
+
+ Properties graphProps = new Properties();
+ graphProps.load(is);
+ JanusGraphManagement graphMgt = graph.openManagement();
+ if(builder.isSchemaEnabled){
+ LOGGER.info("Schema Enabled");
+ SchemaGenerator.loadSchemaIntoJanusGraph(graph, graphMgt, graphProps.getProperty("storage.backend"));
+ }
+ JanusGraphTransaction transaction = graph.newTransaction();
+ LOGGER.info("Loading snapshot");
+ if(builder.isPartialGraph){
+ if ( (builder.graphsonLocation != null) && (builder.graphsonLocation.length() > 0) ) {
+ transaction.io(GraphSONPartialIO.build()).readGraph(builder.graphsonLocation);
+ }
+ else {
+ transaction.io(GraphSONPartialIO.build()).reader().create().readGraph(builder.seqInputStream, graph);
+ }
+ }
+ else{
+ if ( (builder.graphsonLocation != null) && (builder.graphsonLocation.length() > 0) ) {
+ transaction.io(IoCore.graphson()).readGraph(builder.graphsonLocation);
+ }
+ else {
+ transaction.io(IoCore.graphson()).reader().create().readGraph(builder.seqInputStream, graph);
+ }
+ }
+ transaction.commit();
+
+ } catch (Exception e) {
+ // TODO : Changesysout to logger
+ e.printStackTrace();
+ LOGGER.error(
+ "ERROR: Could not load datasnapshot to in memory graph. \n" + LogFormatTools.getStackTop(e));
+ throw new IllegalStateException("Could not load datasnapshot to in memory graph");
+
+ }
+ finally{
+ is.close();
+ }
+
+ }
+
+ public static class Builder {
+ private String graphsonLocation = "";
+ private String propertyFile = "";
+ private boolean isSchemaEnabled = false;
+ private InputStream seqInputStream = null;
+ private boolean isPartialGraph = false;
+
+
+ /*
+ * Builder constructor doesnt do anything
+ */
+ public Builder() {
+ //Do nothing
+ }
+
+ public InMemoryGraph build(String graphsonFile, String propertyFile, boolean isSchemaEnabled) throws IOException {
+ this.graphsonLocation = graphsonFile;
+ this.propertyFile = propertyFile;
+ this.isSchemaEnabled = isSchemaEnabled;
+ return new InMemoryGraph(this);
+ }
+
+ public InMemoryGraph build(InputStream sis, String propertyFile, boolean isSchemaEnabled) throws IOException {
+ this.graphsonLocation = null;
+ this.propertyFile = propertyFile;
+ this.isSchemaEnabled = isSchemaEnabled;
+ this.seqInputStream = sis;
+ return new InMemoryGraph(this);
+ }
+
+ public InMemoryGraph build(String graphsonFile, String propertyFile, boolean isSchemaEnabled, boolean isPartialGraph) throws IOException {
+ this.graphsonLocation = graphsonFile;
+ this.propertyFile = propertyFile;
+ this.isSchemaEnabled = isSchemaEnabled;
+ this.isPartialGraph = isPartialGraph;
+ return new InMemoryGraph(this);
+ }
+
+ public InMemoryGraph build(InputStream sis, String propertyFile, boolean isSchemaEnabled, boolean isPartialGraph) throws IOException {
+ this.graphsonLocation = null;
+ this.propertyFile = propertyFile;
+ this.isSchemaEnabled = isSchemaEnabled;
+ this.seqInputStream = sis;
+ this.isPartialGraph = isPartialGraph;
+ return new InMemoryGraph(this);
+ }
+ }
+
+ public JanusGraph getGraph() {
+ return graph;
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/extensions/OrphanLInterfaceHandler.java b/aai-core/src/main/java/org/onap/aai/extensions/OrphanLInterfaceHandler.java
new file mode 100644
index 00000000..128945d3
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/extensions/OrphanLInterfaceHandler.java
@@ -0,0 +1,110 @@
+/**
+ * ============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.extensions;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.parsers.query.QueryParser;
+import org.onap.aai.query.builder.QueryBuilder;
+import org.onap.aai.rest.db.DBRequest;
+import org.onap.aai.restcore.HttpMethod;
+import org.onap.aai.edges.enums.EdgeType;
+
+public class OrphanLInterfaceHandler {
+
+ private QueryBuilder<Vertex> createLInterfaceQuery(AAIExtensionMap aaiReqMap, Introspector newvceObj) throws AAIException {
+ Introspector uplinkLInterfaceTraversalIntro = aaiReqMap.getLoader().introspectorFromName("l-interface");
+
+ Introspector customerUplinkLInterfaceTraversalIntro = aaiReqMap.getLoader().introspectorFromName("l-interface");
+
+ Introspector logLinkIntroForTraversal = aaiReqMap.getLoader().introspectorFromName("logical-link");
+
+ QueryBuilder<Vertex> query = aaiReqMap.getTransactionalGraphEngine().getQueryBuilder()
+ .exactMatchQuery(newvceObj)
+ .createEdgeTraversal(EdgeType.TREE, newvceObj, uplinkLInterfaceTraversalIntro)
+ .getVerticesByProperty("interface-role", "UPLINK")
+ .createEdgeTraversal(EdgeType.COUSIN, uplinkLInterfaceTraversalIntro, logLinkIntroForTraversal)
+ .createEdgeTraversal(EdgeType.COUSIN, logLinkIntroForTraversal, customerUplinkLInterfaceTraversalIntro)
+ .getVerticesByProperty("interface-role", "CUSTOMER-UPLINK").dedup();
+ return query;
+ }
+
+ private URI buildLInterfaceURI(Vertex linterface, AAIExtensionMap aaiReqMap) throws UnsupportedEncodingException, AAIException, URISyntaxException {
+ Loader loader = aaiReqMap.getLoader();
+ Introspector lint = loader.introspectorFromName("l-interface");
+ lint.setValue("interface-name", (String)linterface.property("interface-name").value());
+ String lintSegment = lint.getURI();
+
+ Introspector lagInterfaceForTrav = loader.introspectorFromName("lag-interface");
+ QueryBuilder<Vertex> lagIntQuery = aaiReqMap.getTransactionalGraphEngine().getQueryBuilder()
+ .exactMatchQuery(lint)
+ .createEdgeTraversal(EdgeType.TREE, linterface, lagInterfaceForTrav).dedup();
+ List<Vertex> lagInterfaces = lagIntQuery.toList();
+ if (lagInterfaces.isEmpty()) {
+ throw new AAIException("AAI_6114");
+ } else if (lagInterfaces.size() > 1) {
+ throw new AAIException("AAI_6140");
+ }
+ Vertex lagInt = lagInterfaces.get(0);
+ lagInterfaceForTrav.setValue("interface-name", (String)lagInt.property("interface-name").value());
+ String lagSegment = lagInterfaceForTrav.getURI();
+
+ Introspector gvVPEforTrav = loader.introspectorFromName("generic-vnf");
+ QueryBuilder<Vertex> gvVPEquery = aaiReqMap.getTransactionalGraphEngine().getQueryBuilder()
+ .exactMatchQuery(lagInterfaceForTrav)
+ .createEdgeTraversal(EdgeType.TREE, lagInterfaceForTrav, gvVPEforTrav).dedup();
+ List<Vertex> genvnfs = gvVPEquery.toList();
+ if (genvnfs.isEmpty()) {
+ throw new AAIException("AAI_6114");
+ } else if (genvnfs.size() > 1) {
+ throw new AAIException("AAI_6140");
+ }
+ Vertex genvnf = genvnfs.get(0);
+ gvVPEforTrav.setValue("vnf-id", (String)genvnf.property("vnf-id").value());
+ String gvSegment = gvVPEforTrav.getURI();
+
+ return new URI(gvSegment + lagSegment + lintSegment);
+ }
+
+ public List<DBRequest> createOrphanLInterfaceDelRequests(AAIExtensionMap aaiReqMap, Introspector newvce) throws AAIException, UnsupportedEncodingException, URISyntaxException{
+ List<DBRequest> requests = new ArrayList<>();
+ QueryBuilder<Vertex> query = createLInterfaceQuery(aaiReqMap, newvce);
+ List<Vertex> linterfaces = query.toList();
+
+ for (Vertex lint : linterfaces) {
+ URI lintURI = buildLInterfaceURI(lint, aaiReqMap);
+ QueryParser parser = createLInterfaceQuery(aaiReqMap, newvce).createQueryFromObjectName("l-interface");
+ DBRequest originalDbRequest = aaiReqMap.getDbRequest();
+ DBRequest request = new DBRequest.Builder(HttpMethod.DELETE, lintURI, parser, newvce, originalDbRequest.getHeaders(), originalDbRequest.getInfo(), originalDbRequest.getTransactionId()).build();
+ requests.add(request);
+ }
+
+ return requests;
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/ingestModel/CreateWidgetModels.java b/aai-core/src/main/java/org/onap/aai/ingestModel/CreateWidgetModels.java
index d5921c19..5f641025 100644
--- a/aai-core/src/main/java/org/onap/aai/ingestModel/CreateWidgetModels.java
+++ b/aai-core/src/main/java/org/onap/aai/ingestModel/CreateWidgetModels.java
@@ -24,6 +24,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.UUID;
import javax.xml.transform.stream.StreamSource;
@@ -36,6 +37,7 @@ import org.onap.aai.introspection.ModelType;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.AAIConstants;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* The Class CreateWidgetModels.
@@ -74,7 +76,13 @@ public class CreateWidgetModels
System.exit(0);
}
- Loader loader = SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY, new SchemaVersion(_apiVersion));
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
+ "org.onap.aai.config",
+ "org.onap.aai.setup"
+ );
+
+ LoaderFactory loaderFactory = ctx.getBean(LoaderFactory.class);
+ Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, new SchemaVersion(_apiVersion));
// iterate the collection of resources
@@ -91,6 +99,12 @@ public class CreateWidgetModels
if (processedWidgets.contains(resource)) {
continue;
}
+
+ Set<String> introspectorProperties = aaiRes.getProperties();
+
+ if(!(introspectorProperties.contains("model-version-id") && introspectorProperties.contains("model-invariant-id"))){
+ System.out.println(aaiRes.getDbName() + " does not contain model properties so skipping");
+ }
processedWidgets.add(resource);
String widgetName = resource;
diff --git a/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java b/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java
index 6e6ba844..5aece21c 100644
--- a/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java
+++ b/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java
@@ -66,14 +66,7 @@ public class URIParser {
public URIParser(Loader loader, URI uri) {
this.uri = uri;
- String currentVersion = "v7";
this.originalLoader = loader;
- try {
- currentVersion = AAIConfig.get("aai.default.api.version");
- } catch (AAIException e) {
- ErrorLogHelper.logException(e);
- }
-
//Load the latest version because we need it for cloud region
this.loader = loader;
@@ -156,10 +149,13 @@ public class URIParser {
}
if (introspector.isContainer()) {
boolean isFinalContainer = i == parts.length-2;
- p.processContainer(introspector, EdgeType.COUSIN, uriKeys, isFinalContainer);
+ /*
+ * Related-to could be COUSIN OR TREE and in some cases BOTH. So Let EdgeRuleBuilder use all the edgeTypes
+ */
+ p.processContainer(introspector, EdgeType.ALL, uriKeys, isFinalContainer);
}
previousObj = introspector;
- type = EdgeType.COUSIN;
+ type = EdgeType.ALL;
i+=2;
continue;
}
@@ -215,7 +211,6 @@ public class URIParser {
}
}
p.processContainer(introspector, type, uriKeys, isFinalContainer);
-
i++;
} else {
p.processNamespace(introspector);
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java
index d5faf052..80122296 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java
@@ -63,11 +63,11 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
*/
public GraphTraversalBuilder(Loader loader, GraphTraversalSource source) {
super(loader, source);
-
+
traversal = (GraphTraversal<Vertex, E>) __.<E>start();
-
+
}
-
+
/**
* Instantiates a new graph traversal builder.
*
@@ -76,42 +76,42 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
*/
public GraphTraversalBuilder(Loader loader, GraphTraversalSource source, Vertex start) {
super(loader, source, start);
-
+
traversal = (GraphTraversal<Vertex, E>) __.__(start);
-
+
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getVerticesByProperty(String key, Object value) {
-
+
// correct value call because the index is registered as an Integer
traversal.has(key, this.correctObjectType(value));
-
+
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getVerticesByProperty(final String key, final List<?> values) {
-
+
//this is because the index is registered as an Integer
List<Object> correctedValues = new ArrayList<>();
for (Object item : values) {
correctedValues.add(this.correctObjectType(item));
}
-
+
traversal.has(key, P.within(correctedValues));
-
+
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@@ -124,79 +124,79 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getVerticesByProperty(String key) {
-
+
traversal.has(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key) {
-
+
traversal.hasNot(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, Object value) {
-
+
// correct value call because the index is registered as an Integer
traversal.has(key, P.neq(this.correctObjectType(value)));
-
+
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getVerticesExcludeByProperty(final String key, final List<?> values) {
-
+
//this is because the index is registered as an Integer
List<Object> correctedValues = new ArrayList<>();
for (Object item : values) {
correctedValues.add(this.correctObjectType(item));
}
-
+
traversal.has(key, P.without(correctedValues));
-
+
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@Override
public QueryBuilder<Vertex> getVerticesGreaterThanProperty(final String key, Object value) {
-
+
traversal.has(key, P.gte(this.correctObjectType(value)));
-
+
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<Vertex> getVerticesLessThanProperty(final String key, Object value) {
-
+
traversal.has(key, P.lte(this.correctObjectType(value)));
-
+
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
@@ -213,7 +213,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map) {
-
+
for (Map.Entry<String, String> es : map.entrySet()) {
traversal.has(es.getKey(), es.getValue());
stepIndex++;
@@ -273,7 +273,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
this.createContainerQuery(obj);
return (QueryBuilder<Vertex>) this;
}
-
+
private void allPropertiesQuery(Introspector obj) {
Set<String> props = obj.getProperties();
Set<String> keys = obj.getKeys();
@@ -298,12 +298,12 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
}
}
}
-
+
/**
* @{inheritDoc}
*/
@Override
-
+
public QueryBuilder<Vertex> createContainerQuery(Introspector obj) {
String type = obj.getChildDBName();
String abstractType = obj.getMetadata(ObjectMetadata.ABSTRACT);
@@ -319,8 +319,8 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
}
/**
- * @throws NoEdgeRuleFoundException
- * @throws AAIException
+ * @throws NoEdgeRuleFoundException
+ * @throws AAIException
* @{inheritDoc}
*/
@Override
@@ -423,10 +423,10 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
}
this.traversal.union(traversals);
stepIndex++;
-
+
return this;
}
-
+
/**
* @{inheritDoc}
*/
@@ -454,101 +454,101 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
return this;
}
-
+
@Override
public QueryBuilder<E> store(String name) {
-
+
this.traversal.store(name);
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> cap(String name) {
this.traversal.cap(name);
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> unfold() {
this.traversal.unfold();
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> dedup() {
-
+
this.traversal.dedup();
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> emit() {
-
+
this.traversal.emit();
stepIndex++;
-
+
return this;
-
+
}
-
+
@Override
public QueryBuilder<E> repeat(QueryBuilder<E> builder) {
-
+
this.traversal.repeat((GraphTraversal<Vertex, E>)builder.getQuery());
stepIndex++;
return this;
}
-
+
@Override
public QueryBuilder<E> until(QueryBuilder<E> builder) {
this.traversal.until((GraphTraversal<Vertex,E>)builder.getQuery());
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> groupCount() {
this.traversal.groupCount();
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> both() {
this.traversal.both();
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<Tree> tree() {
-
+
this.traversal.tree();
stepIndex++;
-
+
return (QueryBuilder<Tree>)this;
}
-
+
@Override
public QueryBuilder<E> by(String name) {
this.traversal.by(name);
stepIndex++;
-
+
return this;
}
-
+
/**
* {@inheritDoc}
*/
@@ -568,72 +568,90 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Path>)this;
}
-
+
@Override
public QueryBuilder<Edge> outE() {
this.traversal.outE();
stepIndex++;
return (QueryBuilder<Edge>)this;
}
-
+
@Override
public QueryBuilder<Edge> inE() {
this.traversal.inE();
stepIndex++;
return (QueryBuilder<Edge>)this;
}
-
+
@Override
public QueryBuilder<Vertex> outV() {
this.traversal.outV();
stepIndex++;
return (QueryBuilder<Vertex>)this;
}
-
+
@Override
public QueryBuilder<Vertex> inV() {
this.traversal.inV();
stepIndex++;
return (QueryBuilder<Vertex>)this;
}
-
+
@Override
public QueryBuilder<E> as(String name) {
this.traversal.as(name);
-
+
stepIndex++;
return this;
}
-
+
@Override
public QueryBuilder<E> not(QueryBuilder<E> builder) {
this.traversal.not(builder.getQuery());
-
+
stepIndex++;
return this;
}
-
+
@Override
public QueryBuilder<E> select(String name) {
this.traversal.select(name);
-
+
+ stepIndex++;
+
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> select(String... names) {
+ if(names.length == 1) {
+ this.traversal.select(names[0]);
+ }
+ else if(names.length == 2) {
+ this.traversal.select(names[0], names[1]);
+ }
+ else if(names.length > 2){
+ String[] otherNames = Arrays.copyOfRange(names, 2, names.length);
+ this.traversal.select(names[0], names[1], otherNames);
+ }
+
stepIndex++;
-
+
return this;
}
-
+
/**
* Edge query.
*
* @param outObj the out type
* @param inObj the in type
- * @throws NoEdgeRuleFoundException
- * @throws AAIException
+ * @throws NoEdgeRuleFoundException
+ * @throws AAIException
*/
private void edgeQueryToVertex(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels) throws AAIException {
String outType = outObj.getDbName();
String inType = inObj.getDbName();
-
+
if (outObj.isContainer()) {
outType = outObj.getChildDBName();
}
@@ -685,35 +703,35 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
traversal.out(outLabels.toArray(new String[outLabels.size()]));
} else if (outLabels.isEmpty() && !inLabels.isEmpty()) {
traversal.in(inLabels.toArray(new String[inLabels.size()]));
- } else {
+ } else {
traversal.union(__.out(outLabels.toArray(new String[outLabels.size()])), __.in(inLabels.toArray(new String[inLabels.size()])));
}
-
+
stepIndex++;
this.createContainerQuery(inObj);
-
+
}
-
+
/**
* Edge query.
*
* @param outObj the out type
* @param inObj the in type
- * @throws NoEdgeRuleFoundException
- * @throws AAIException
+ * @throws NoEdgeRuleFoundException
+ * @throws AAIException
*/
private void edgeQuery(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels) throws AAIException {
String outType = outObj.getDbName();
String inType = inObj.getDbName();
-
+
if (outObj.isContainer()) {
outType = outObj.getChildDBName();
}
if (inObj.isContainer()) {
inType = inObj.getChildDBName();
}
-
+
markParentBoundary();
Multimap<String, EdgeRule> rules = ArrayListMultimap.create();
EdgeRuleQuery.Builder qB = new EdgeRuleQuery.Builder(outType, inType).edgeType(type);
@@ -729,7 +747,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
} catch (EdgeRuleNotFoundException e) {
throw new NoEdgeRuleFoundException(e);
}
-
+
final List<String> inLabels = new ArrayList<>();
final List<String> outLabels = new ArrayList<>();
@@ -749,11 +767,11 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
traversal.outE(outLabels.toArray(new String[outLabels.size()]));
} else if (outLabels.isEmpty() && !inLabels.isEmpty()) {
traversal.inE(inLabels.toArray(new String[inLabels.size()]));
- } else {
+ } else {
traversal.union(__.outE(outLabels.toArray(new String[outLabels.size()])), __.inE(inLabels.toArray(new String[inLabels.size()])));
}
}
-
+
@Override
public QueryBuilder<E> limit(long amount) {
traversal.limit(amount);
@@ -767,7 +785,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
public <E2> E2 getQuery() {
return (E2)this.traversal;
}
-
+
/**
* @{inheritDoc}
*/
@@ -776,17 +794,17 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
return cloneQueryAtStep(parentStepIndex);
}
-
+
@Override
public QueryBuilder<E> getContainerQuery() {
-
+
if (this.parentStepIndex == 0) {
return removeQueryStepsBetween(0, containerStepIndex);
} else {
return cloneQueryAtStep(containerStepIndex);
}
}
-
+
/**
* @{inheritDoc}
*/
@@ -794,13 +812,13 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
public void markParentBoundary() {
parentStepIndex = stepIndex;
}
-
+
@Override
public void markContainer() {
containerStepIndex = stepIndex;
}
-
-
+
+
/**
* @{inheritDoc}
*/
@@ -823,7 +841,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
/**
* end is exclusive
- *
+ *
* @param start
* @param end
* @return
@@ -850,19 +868,19 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
if (this.completeTraversal == null) {
executeQuery();
}
-
+
return this.completeTraversal.hasNext();
}
-
+
@Override
public E next() {
if (this.completeTraversal == null) {
executeQuery();
}
-
+
return this.completeTraversal.next();
}
-
+
@Override
public List<E> toList() {
if (this.completeTraversal == null) {
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
index 2cc78f44..43925f49 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
@@ -36,7 +36,7 @@ import org.onap.aai.db.props.AAIProperties;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
-import org.onap.aai.restcore.search.GremlinGroovyShellSingleton;
+import org.onap.aai.restcore.search.GremlinGroovyShell;
import org.onap.aai.schema.enums.ObjectMetadata;
import org.onap.aai.edges.EdgeRule;
import org.onap.aai.edges.EdgeRuleQuery;
@@ -53,7 +53,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
private static final String ARGUMENT2 = "#!#argument#!#";
private static final String HAS = ".has('";
- private GremlinGroovyShellSingleton gremlinGroovy = GremlinGroovyShellSingleton.getInstance();
+ private GremlinGroovyShell gremlinGroovy = new GremlinGroovyShell();
private GraphTraversal<?, ?> completeTraversal = null;
protected List<String> list = null;
@@ -103,6 +103,16 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
return (QueryBuilder<Vertex>) this;
}
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, Object value) {
+ list.add(HAS + key + "', " + value + ")");
+ stepIndex++;
+ return (QueryBuilder<Vertex>) this;
+ }
+
@Override
public QueryBuilder<Vertex> getVerticesByBooleanProperty(String key, Object value) {
boolean bValue = false;
@@ -139,7 +149,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@@ -150,7 +160,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@@ -199,7 +209,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@@ -221,7 +231,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<Vertex> getVerticesGreaterThanProperty(String key, Object value) {
String predicate = "P.gte(#!#argument1#!#)";
@@ -236,7 +246,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<Vertex> getVerticesLessThanProperty(String key, Object value) {
String predicate = "P.lte(#!#argument1#!#)";
@@ -251,10 +261,10 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
-
+
+
/**
* @{inheritDoc}
*/
@@ -263,13 +273,13 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
//TODO
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map) {
-
+
for (Map.Entry<String, String> es : map.entrySet()) {
list.add(HAS + es.getKey() + "', '" + es.getValue() + "')");
stepIndex++;
@@ -278,7 +288,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
-
+
/**
* @{inheritDoc}
*/
@@ -287,16 +297,16 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
Set<String> keys = obj.getKeys();
for (String key : keys) {
-
+
this.getVerticesByProperty(key, obj.<Object>getValue(key));
-
- }
+
+ }
return (QueryBuilder<Vertex>) this;
}
-
+
/**
- * @throws NoEdgeRuleFoundException
- * @throws AAIException
+ * @throws NoEdgeRuleFoundException
+ * @throws AAIException
* @{inheritDoc}
*/
@Override
@@ -311,7 +321,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
}
this.edgeQueryToVertex(type, parentName, childName, null);
return this;
-
+
}
@Override
@@ -390,8 +400,14 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
} else {
if (Direction.IN.equals(rule.getDirection())) {
inLabels.add(rule.getLabel());
+ if(inType.equals(outType)) {//code to handle when a type edges to itself, to add both in and out
+ outLabels.add(rule.getLabel());
+ }
} else {
outLabels.add(rule.getLabel());
+ if(inType.equals(outType)) {//code to handle when a type edges to itself, to add both in and out
+ inLabels.add(rule.getLabel());
+ }
}
}
}
@@ -408,16 +424,16 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
list.add(HAS + AAIProperties.NODE_TYPE + "', '" + inType + "')");
stepIndex++;
-
+
}
-
+
/**
* Edge query.
*
* @param outType the out type
* @param inType the in type
- * @throws NoEdgeRuleFoundException
- * @throws AAIException
+ * @throws NoEdgeRuleFoundException
+ * @throws AAIException
*/
private void edgeQuery(EdgeType type, String outType, String inType, List<String> labels) throws AAIException {
markParentBoundary();
@@ -434,7 +450,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
} catch (EdgeRuleNotFoundException e) {
throw new NoEdgeRuleFoundException(e);
}
-
+
final List<String> inLabels = new ArrayList<>();
final List<String> outLabels = new ArrayList<>();
@@ -459,9 +475,9 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
} else {
list.add(".union(__.inE('" + String.join("','", inLabels) + "')" + ", __.outE('" + String.join("','", outLabels) + "'))");
}
-
+
stepIndex++;
-
+
}
@Override
public QueryBuilder<E> limit(long amount) {
@@ -486,7 +502,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
command.append(Joiner.on(",").join(wrapped));
command.append(")");
list.add(".has('aai-node-type', " + command + ")");
-
+
} else {
list.add(".has('aai-node-type', '" + type + "')");
}
@@ -494,7 +510,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
this.markContainer();
return (QueryBuilder<Vertex>) this;
}
-
+
@Override
public QueryBuilder<E> union(QueryBuilder<E>... builder) {
markParentBoundary();
@@ -508,10 +524,10 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
command.append(")");
list.add(command.toString());
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> where(QueryBuilder<E>... builder) {
markParentBoundary();
@@ -521,8 +537,8 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
}
list.addAll(traversals);
-
-
+
+
return this;
}
@@ -542,95 +558,95 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
return this;
}
-
+
@Override
public QueryBuilder<E> store(String name) {
this.list.add(".store('"+ name + "')");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> cap(String name) {
this.list.add(".cap('"+ name + "')");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> unfold() {
this.list.add(".unfold()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> dedup() {
this.list.add(".dedup()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> emit() {
this.list.add(".emit()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> repeat(QueryBuilder<E> builder) {
this.list.add(".repeat(__" + builder.getQuery() + ")");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> until(QueryBuilder<E> builder) {
this.list.add(".until(__" + builder.getQuery() + ")");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> groupCount() {
this.list.add(".groupCount()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> both() {
this.list.add(".both()");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<Tree> tree() {
this.list.add(".tree()");
stepIndex++;
-
+
return (QueryBuilder<Tree>)this;
}
-
+
@Override
public QueryBuilder<E> by(String name) {
this.list.add(".by('"+ name + "')");
stepIndex++;
-
+
return this;
}
-
+
/**
* {@inheritDoc}
*/
@@ -650,60 +666,76 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
stepIndex++;
return (QueryBuilder<Path>)this;
}
-
+
@Override
public QueryBuilder<Edge> outE() {
this.list.add(".outE()");
stepIndex++;
-
+
return (QueryBuilder<Edge>)this;
}
-
+
@Override
public QueryBuilder<Edge> inE() {
this.list.add(".inE()");
stepIndex++;
-
+
return (QueryBuilder<Edge>)this;
}
-
+
@Override
public QueryBuilder<Vertex> outV() {
this.list.add(".outV()");
stepIndex++;
-
+
return (QueryBuilder<Vertex>)this;
}
-
+
@Override
public QueryBuilder<Vertex> inV() {
this.list.add(".inV()");
stepIndex++;
-
+
return (QueryBuilder<Vertex>)this;
}
-
+
@Override
public QueryBuilder<E> not(QueryBuilder<E> builder) {
this.list.add(".not(" + "__" + builder.getQuery() + ")");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> as(String name) {
this.list.add(".as('" + name + "')");
stepIndex++;
-
+
return this;
}
-
+
@Override
public QueryBuilder<E> select(String name) {
this.list.add(".select('" + name + "')");
stepIndex++;
-
+
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> select(String... names) {
+ String stepString = ".select('";
+ for(int i = 0; i<names.length; i++) {
+ stepString = stepString + names[i] +"'";
+ if(i!=(names.length-1)) {
+ stepString = stepString + ",'";
+ }
+ }
+ stepString = stepString + ")";
+ this.list.add(stepString);
+ stepIndex++;
+
return this;
}
/**
@@ -713,26 +745,26 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
public QueryBuilder<E> getParentQuery() {
return cloneQueryAtStep(parentStepIndex);
}
-
+
@Override
public QueryBuilder<E> getContainerQuery() {
return cloneQueryAtStep(containerStepIndex);
}
-
+
/**
* @{inheritDoc}
*/
@Override
public <T2> T2 getQuery() {
StringBuilder sb = new StringBuilder();
-
+
for (String piece : this.list) {
sb.append(piece);
}
-
+
return (T2)sb.toString();
}
-
+
/**
* @{inheritDoc}
*/
@@ -740,12 +772,12 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
public void markParentBoundary() {
parentStepIndex = stepIndex;
}
-
+
@Override
public void markContainer() {
this.containerStepIndex = stepIndex;
}
-
+
/**
* @{inheritDoc}
*/
@@ -765,7 +797,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
protected int getStepIndex() {
return stepIndex;
}
-
+
private void executeQuery() {
String queryString = "g" + Joiner.on("").join(list);
Map<String, Object> params = new HashMap<>();
@@ -781,25 +813,25 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
if (this.completeTraversal == null) {
executeQuery();
}
-
+
return this.completeTraversal.hasNext();
}
-
+
@Override
public E next() {
if (this.completeTraversal == null) {
executeQuery();
}
-
+
return (E)this.completeTraversal.next();
}
-
+
@Override
public List<E> toList() {
if (this.completeTraversal == null) {
executeQuery();
}
-
+
return (List<E>)this.completeTraversal.toList();
}
@@ -808,5 +840,5 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
return (QueryBuilder<Edge>)this;
}
-
+
}
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java
index f4ffac0e..777204f2 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java
@@ -293,6 +293,40 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
return createEdgeTraversal(type, out, in);
}
+ /**
+ *
+ * @param edgeType
+ * @param outNodeType
+ * @param inNodeType
+ * @return
+ * @throws AAIException
+ */
+ public QueryBuilder<Vertex> createEdgeTraversal(String edgeType, String outNodeType, String inNodeType) throws AAIException {
+ /*
+ * When the optional parameter edgetype is sent it is a string that needs to be converted to Enum
+ */
+ EdgeType type = EdgeType.valueOf(edgeType);
+ Introspector out = loader.introspectorFromName(outNodeType);
+ Introspector in = loader.introspectorFromName(inNodeType);
+
+ return createEdgeTraversal(type, out, in);
+ }
+
+ /**
+ *
+ * @param MissingOptionalParameter
+ * @param outNodeType
+ * @param inNodeType
+ * @return
+ * @throws AAIException
+ */
+ public QueryBuilder<Vertex> createEdgeTraversal(MissingOptionalParameter edgeType, String outNodeType, String inNodeType) throws AAIException {
+ /*
+ * When no optional parameter edgetype is sent get all edges between the 2 nodetypes
+ */
+ return this.createEdgeTraversal(outNodeType, inNodeType);
+ }
+
public QueryBuilder<Vertex> createEdgeTraversal(String outNodeType, String inNodeType) throws AAIException {
Introspector out = loader.introspectorFromName(outNodeType);
@@ -506,6 +540,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
public abstract QueryBuilder<E> not(QueryBuilder<E> builder);
public abstract QueryBuilder<E> as(String name);
public abstract QueryBuilder<E> select(String name);
+ public abstract QueryBuilder<E> select(String... names);
public abstract QueryBuilder<E> until(QueryBuilder<E> builder);
public abstract QueryBuilder<E> groupCount();
public abstract QueryBuilder<E> by(String name);
@@ -574,4 +609,16 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
protected void setEdgeIngestor(EdgeIngestor ei) {
this.edgeRules = ei;
}
+
+ public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, Object value) {
+ return getVerticesByProperty(key, value);
+ }
+
+ public QueryBuilder<Vertex> getVerticesByNumberProperty(String key) {
+ return getVerticesByProperty(key);
+ }
+
+ public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, MissingOptionalParameter value) {
+ return getVerticesByProperty(key, value);
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
index bd7f1b91..6f551de7 100644
--- a/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
+++ b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
@@ -8,7 +8,7 @@
* 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,
@@ -53,6 +53,8 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.janusgraph.core.JanusGraphException;
import org.javatuples.Pair;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.onap.aai.db.props.AAIProperties;
import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.domain.responseMessage.AAIResponseMessage;
@@ -94,9 +96,9 @@ public class HttpEntry {
private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(HttpEntry.class);
private static final String TARGET_ENTITY = "DB";
- private ModelType introspectorFactoryType;
+ private ModelType introspectorFactoryType;
- private QueryStyle queryStyle;
+ private QueryStyle queryStyle;
private SchemaVersion version;
@@ -123,7 +125,7 @@ public class HttpEntry {
@Value("${schema.uri.base.path}")
private String basePath;
- private UEBNotification notification;
+ private UEBNotification notification;
/**
* Instantiates a new http entry.
@@ -136,13 +138,13 @@ public class HttpEntry {
this.queryStyle = queryStyle;
}
- public HttpEntry setHttpEntryProperties(SchemaVersion version, DBConnectionType connectionType){
+ public HttpEntry setHttpEntryProperties(SchemaVersion version, DBConnectionType connectionType) {
this.version = version;
this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
this.dbEngine = new JanusGraphDBEngine(
- queryStyle,
- connectionType,
- loader);
+ queryStyle,
+ connectionType,
+ loader);
getDbEngine().startTransaction();
this.notification = new UEBNotification(loader, loaderFactory, schemaVersions);
@@ -150,13 +152,13 @@ public class HttpEntry {
}
- public HttpEntry setHttpEntryProperties(SchemaVersion version, DBConnectionType connectionType, UEBNotification notification){
+ public HttpEntry setHttpEntryProperties(SchemaVersion version, DBConnectionType connectionType, UEBNotification notification) {
this.version = version;
this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
this.dbEngine = new JanusGraphDBEngine(
- queryStyle,
- connectionType,
- loader);
+ queryStyle,
+ connectionType,
+ loader);
this.notification = notification;
//start transaction on creation
@@ -210,7 +212,7 @@ public class HttpEntry {
return dbEngine;
}
- public Pair<Boolean, List<Pair<URI, Response>>> process (List<DBRequest> requests, String sourceOfTruth) throws AAIException {
+ public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth) throws AAIException {
return this.process(requests, sourceOfTruth, true);
}
@@ -221,24 +223,32 @@ public class HttpEntry {
*
* @return a boolean true/false of whether the user requested paginated results
*/
- public boolean isPaginated(){
+ public boolean isPaginated() {
return this.paginationBucket > -1 && this.paginationIndex > -1;
}
/**
+ * Returns the pagination size
+ * @return integer of the size of results to be returned when paginated
+ */
+ public int getPaginationBucket() {
+ return this.paginationBucket;
+ }
+
+ /**
* Setter for the pagination bucket variable which stores in this object the size of results to return
* @param pb
*/
- public void setPaginationBucket(int pb){
+ public void setPaginationBucket(int pb) {
this.paginationBucket = pb;
}
/**
- * Returns the pagination size
- * @return integer of the size of results to be returned when paginated
+ * Getter to return the pagination index requested by the user when requesting paginated results
+ * @return
*/
- public int getPaginationBucket(){
- return this.paginationBucket;
+ public int getPaginationIndex() {
+ return this.paginationIndex;
}
/**
@@ -246,32 +256,24 @@ public class HttpEntry {
* paginated
* @param pi
*/
- public void setPaginationIndex(int pi){
- if(pi == 0){
+ public void setPaginationIndex(int pi) {
+ if (pi == 0) {
pi = 1;
}
this.paginationIndex = pi;
}
/**
- * Getter to return the pagination index requested by the user when requesting paginated results
- * @return
- */
- public int getPaginationIndex(){
- return this.paginationIndex;
- }
-
- /**
* Sets the total vertices variables and calculates the amount of pages based on size and total vertices
* @param totalVertices
* @param paginationBucketSize
*/
- public void setTotalsForPaging(int totalVertices, int paginationBucketSize){
+ public void setTotalsForPaging(int totalVertices, int paginationBucketSize) {
this.totalVertices = totalVertices;
//set total number of buckets equal to full pages
- this.totalPaginationBuckets = totalVertices/paginationBucketSize;
+ this.totalPaginationBuckets = totalVertices / paginationBucketSize;
//conditionally add a page for the remainder
- if(totalVertices % paginationBucketSize > 0){
+ if (totalVertices % paginationBucketSize > 0) {
this.totalPaginationBuckets++;
}
}
@@ -279,7 +281,7 @@ public class HttpEntry {
/**
* @return the total amount of pages
*/
- public int getTotalPaginationBuckets(){
+ public int getTotalPaginationBuckets() {
return this.totalPaginationBuckets;
}
@@ -287,7 +289,7 @@ public class HttpEntry {
*
* @return the total number of vertices when paginated
*/
- public int getTotalVertices(){
+ public int getTotalVertices() {
return this.totalVertices;
}
@@ -299,7 +301,7 @@ public class HttpEntry {
* @return the pair
* @throws AAIException the AAI exception
*/
- public Pair<Boolean, List<Pair<URI, Response>>> process (List<DBRequest> requests, String sourceOfTruth, boolean enableResourceVersion) throws AAIException {
+ public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth, boolean enableResourceVersion) throws AAIException {
DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
String methodName = "process";
@@ -310,7 +312,7 @@ public class HttpEntry {
String transactionId = null;
int depth = AAIProperties.MAXIMUM_DEPTH;
Format format = null;
- List<Pair<URI,Response>> responses = new ArrayList<>();
+ List<Pair<URI, Response>> responses = new ArrayList<>();
MultivaluedMap<String, String> params = null;
HttpMethod method = null;
String uriTemp = "";
@@ -339,11 +341,11 @@ public class HttpEntry {
LoggingContext.startTime();
List<Vertex> vertTemp;
List<Vertex> vertices;
- if(this.isPaginated()) {
+ if (this.isPaginated()) {
vertTemp = query.getQueryBuilder().toList();
this.setTotalsForPaging(vertTemp.size(), this.paginationBucket);
vertices = vertTemp.subList(((this.paginationIndex - 1) * this.paginationBucket), Math.min((this.paginationBucket * this.paginationIndex), vertTemp.size()));
- }else{
+ } else {
vertices = query.getQueryBuilder().toList();
}
boolean isNewVertex = false;
@@ -364,7 +366,7 @@ public class HttpEntry {
if (cleanUp == null) {
cleanUp = "false";
}
- if (vertices.size() > 1 && processSingle && !method.equals(HttpMethod.GET)) {
+ if (vertices.size() > 1 && processSingle && !(method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP))) {
if (method.equals(HttpMethod.DELETE)) {
LoggingContext.restoreIfPossible();
throw new AAIException("AAI_6138");
@@ -374,7 +376,7 @@ public class HttpEntry {
}
}
if (method.equals(HttpMethod.PUT)) {
- String resourceVersion = (String)obj.getValue("resource-version");
+ String resourceVersion = (String) obj.getValue("resource-version");
if (vertices.isEmpty()) {
if (enableResourceVersion) {
serializer.verifyResourceVersion("create", query.getResultType(), "", resourceVersion, obj.getURI());
@@ -399,17 +401,17 @@ public class HttpEntry {
v = vertices.get(0);
}
HashMap<String, Introspector> relatedObjects = new HashMap<>();
+ String nodeOnly = params.getFirst("nodes-only");
+ boolean isNodeOnly = nodeOnly != null;
switch (method) {
case GET:
- String nodeOnly = params.getFirst("nodes-only");
- boolean isNodeOnly = nodeOnly != null;
if (format == null) {
obj = this.getObjectFromDb(vertices, serializer, query, obj, request.getUri(), depth, isNodeOnly, cleanUp);
LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
- LOGGER.info ("Completed");
+ LOGGER.info("Completed");
LoggingContext.restoreIfPossible();
if (obj != null) {
@@ -424,12 +426,40 @@ public class HttpEntry {
}
} else {
FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath + "/");
- Formatter formatter = ff.get(format, params);
+ Formatter formatter = ff.get(format, params);
result = formatter.output(vertices.stream().map(vertex -> (Object) vertex).collect(Collectors.toList())).toString();
status = Status.OK;
}
break;
+ case GET_RELATIONSHIP:
+ if (format == null) {
+ obj = this.getRelationshipObjectFromDb(vertices, serializer, query, request.getInfo().getRequestUri());
+
+ LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
+ LOGGER.info("Completed");
+ LoggingContext.restoreIfPossible();
+
+ if (obj != null) {
+ status = Status.OK;
+ MarshallerProperties properties;
+ if (!request.getMarshallerProperties().isPresent()) {
+ properties = new MarshallerProperties.Builder(org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build();
+ } else {
+ properties = request.getMarshallerProperties().get();
+ }
+ result = obj.marshal(properties);
+ } else {
+ String msg = createRelationshipNotFoundMessage(query.getResultType(), request.getUri());
+ throw new AAIException("AAI_6149", msg);
+ }
+ } else {
+ FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath + "/");
+ Formatter formatter = ff.get(format, params);
+ result = formatter.output(vertices.stream().map(vertex -> (Object) vertex).collect(Collectors.toList())).toString();
+ status = Status.OK;
+ }
+ break;
case PUT:
response = this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth, version, loader, obj, uri, true);
if (isNewVertex) {
@@ -445,9 +475,9 @@ public class HttpEntry {
if (query.isDependent()) {
relatedObjects = this.getRelatedObjects(serializer, queryEngine, v, obj, this.loader);
}
- LoggingContext.elapsedTime((long)serializer.getDBTimeMsecs() +
- (long)queryEngine.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
- LOGGER.info ("Completed ");
+ LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs() +
+ (long) queryEngine.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
+ LOGGER.info("Completed ");
LoggingContext.restoreIfPossible();
notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj, relatedObjects, basePath);
@@ -457,14 +487,14 @@ public class HttpEntry {
this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth, version, loader, obj, uri, true);
serializer.createEdge(obj, v);
- LoggingContext.elapsedTime((long)serializer.getDBTimeMsecs(),TimeUnit.MILLISECONDS);
- LOGGER.info ("Completed");
+ LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
+ LOGGER.info("Completed");
LoggingContext.restoreIfPossible();
status = Status.OK;
notification.createNotificationEvent(transactionId, sourceOfTruth, status, new URI(uri.toString().replace("/relationship-list/relationship", "")), serializer.getLatestVersionView(v), relatedObjects, basePath);
break;
case MERGE_PATCH:
- Introspector existingObj = loader.introspectorFromName(obj.getDbName());
+ Introspector existingObj = loader.introspectorFromName(obj.getDbName());
existingObj = this.getObjectFromDb(vertices, serializer, query, existingObj, request.getUri(), 0, false, cleanUp);
String existingJson = existingObj.marshal(false);
String newJson;
@@ -493,14 +523,14 @@ public class HttpEntry {
if (query.isDependent()) {
relatedObjects = this.getRelatedObjects(serializer, queryEngine, v, patchedObj, this.loader);
}
- LoggingContext.elapsedTime((long)serializer.getDBTimeMsecs() +
- (long)queryEngine.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
- LOGGER.info ("Completed");
+ LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs() +
+ (long) queryEngine.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
+ LOGGER.info("Completed");
LoggingContext.restoreIfPossible();
notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, patchedObj, relatedObjects, basePath);
} catch (IOException | JsonPatchException e) {
- LOGGER.info ("Caught exception: " + e.getMessage());
+ LOGGER.info("Caught exception: " + e.getMessage());
LoggingContext.restoreIfPossible();
throw new AAIException("AAI_3000", "could not perform patch operation");
}
@@ -530,7 +560,7 @@ public class HttpEntry {
Map<String, URI> uriMap = new HashMap<>();
Map<String, HashMap<String, Introspector>> deleteRelatedObjects = new HashMap<>();
- if(isDelVerticesPresent){
+ if (isDelVerticesPresent) {
deleteObjects = this.buildIntrospectorObjects(serializer, deletableVertices);
uriMap = this.buildURIMap(serializer, deleteObjects);
@@ -541,9 +571,9 @@ public class HttpEntry {
serializer.delete(v, deletableVertices, resourceVersion, enableResourceVersion);
this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth, version, loader, obj, uri, false);
- LoggingContext.elapsedTime((long)serializer.getDBTimeMsecs() +
- (long)queryEngine.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
- LOGGER.info ("Completed");
+ LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs() +
+ (long) queryEngine.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
+ LOGGER.info("Completed");
LoggingContext.restoreIfPossible();
status = Status.NO_CONTENT;
notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj, relatedObjects, basePath);
@@ -552,9 +582,9 @@ public class HttpEntry {
* Notify delete-other-v candidates
*/
- if(isDelVerticesPresent){
+ if (isDelVerticesPresent) {
this.buildNotificationEvent(sourceOfTruth, status, transactionId, notification, deleteObjects,
- uriMap, deleteRelatedObjects, basePath);
+ uriMap, deleteRelatedObjects, basePath);
}
break;
@@ -562,8 +592,8 @@ public class HttpEntry {
serializer.touchStandardVertexProperties(v, false);
serializer.deleteEdge(obj, v);
- LoggingContext.elapsedTime((long)serializer.getDBTimeMsecs(),TimeUnit.MILLISECONDS);
- LOGGER.info ("Completed");
+ LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
+ LOGGER.info("Completed");
LoggingContext.restoreIfPossible();
status = Status.NO_CONTENT;
notification.createNotificationEvent(transactionId, sourceOfTruth, Status.OK, new URI(uri.toString().replace("/relationship-list/relationship", "")), serializer.getLatestVersionView(v), relatedObjects, basePath);
@@ -576,40 +606,42 @@ public class HttpEntry {
/* temporarily adding vertex id to the headers
* to be able to use for testing the vertex id endpoint functionality
* since we presently have no other way of generating those id urls
- */
+ */
if (response == null && v != null && (
method.equals(HttpMethod.PUT)
- || method.equals(HttpMethod.GET)
- || method.equals(HttpMethod.MERGE_PATCH))
- ) {
+ || method.equals(HttpMethod.GET)
+ || method.equals(HttpMethod.MERGE_PATCH)
+ || method.equals(HttpMethod.GET_RELATIONSHIP))
+
+ ) {
String myvertid = v.id().toString();
- if(this.isPaginated()){
+ if (this.isPaginated()) {
response = Response.status(status)
- .header("vertex-id", myvertid)
- .header("total-results", this.getTotalVertices())
- .header("total-pages", this.getTotalPaginationBuckets())
- .entity(result)
- .type(outputMediaType).build();
- }else {
+ .header("vertex-id", myvertid)
+ .header("total-results", this.getTotalVertices())
+ .header("total-pages", this.getTotalPaginationBuckets())
+ .entity(result)
+ .type(outputMediaType).build();
+ } else {
response = Response.status(status)
- .header("vertex-id", myvertid)
- .entity(result)
- .type(outputMediaType).build();
+ .header("vertex-id", myvertid)
+ .entity(result)
+ .type(outputMediaType).build();
}
} else if (response == null) {
response = Response.status(status)
- .type(outputMediaType).build();
+ .type(outputMediaType).build();
} else {
//response already set to something
}
- Pair<URI,Response> pairedResp = Pair.with(request.getUri(), response);
+ Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
responses.add(pairedResp);
//break out of retry loop
break;
} catch (JanusGraphException e) {
this.dbEngine.rollback();
- LOGGER.info ("Caught exception: " + e.getMessage());
+ LOGGER.info("Caught exception: " + e.getMessage());
LoggingContext.restoreIfPossible();
AAIException ex = new AAIException("AAI_6142", e);
ErrorLogHelper.logException(ex);
@@ -630,10 +662,10 @@ public class HttpEntry {
templateVars.addAll(e.getTemplateVars());
ErrorLogHelper.logException(e);
response = Response
- .status(e.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), e, templateVars))
- .build();
- Pair<URI,Response> pairedResp = Pair.with(request.getUri(), response);
+ .status(e.getErrorObject().getHTTPResponseCode())
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), e, templateVars))
+ .build();
+ Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
responses.add(pairedResp);
continue;
} catch (Exception e) {
@@ -645,9 +677,9 @@ public class HttpEntry {
templateVars.add(request.getUri().getPath().toString());
ErrorLogHelper.logException(ex);
response = Response
- .status(ex.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), ex, templateVars))
- .build();
+ .status(ex.getErrorObject().getHTTPResponseCode())
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), ex, templateVars))
+ .build();
Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
responses.add(pairedResp);
continue;
@@ -664,7 +696,7 @@ public class HttpEntry {
* @param mediaTypeList the media type list
* @return the media type
*/
- private String getMediaType(List <MediaType> mediaTypeList) {
+ private String getMediaType(List<MediaType> mediaTypeList) {
String mediaType = MediaType.APPLICATION_JSON; // json is the default
for (MediaType mt : mediaTypeList) {
if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt)) {
@@ -709,6 +741,44 @@ public class HttpEntry {
}
/**
+ * Gets the object from db.
+ *
+ * @param serializer the serializer
+ * @param query the query
+ * @param obj the obj
+ * @param uri the uri
+ * @param depth the depth
+ * @param cleanUp the clean up
+ * @return the object from db
+ * @throws AAIException the AAI exception
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws SecurityException the security exception
+ * @throws InstantiationException the instantiation exception
+ * @throws NoSuchMethodException the no such method exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ * @throws MalformedURLException the malformed URL exception
+ * @throws AAIUnknownObjectException
+ * @throws URISyntaxException
+ */
+ private Introspector getRelationshipObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query, URI uri) throws AAIException, IllegalArgumentException, SecurityException, UnsupportedEncodingException, AAIUnknownObjectException {
+
+ //nothing found
+ if (results.isEmpty()) {
+ String msg = createNotFoundMessage(query.getResultType(), uri);
+ throw new AAIException("AAI_6114", msg);
+ }
+
+ if (results.size() > 1) {
+ throw new AAIException("AAI_6148", uri.getPath());
+ }
+
+ Vertex v = results.get(0);
+ return serializer.dbToRelationshipObject(v);
+ }
+
+ /**
* Invoke extension.
*
* @param dbEngine the db engine
@@ -748,11 +818,11 @@ public class HttpEntry {
ExtensionController ext = new ExtensionController();
ext.runExtension(aaiExtMap.getApiVersion(),
- extensionInformation.getNamespace(),
- extensionInformation.getTopObject(),
- extensionInformation.getMethodName(httpMethod, isPreprocess),
- aaiExtMap,
- isPreprocess);
+ extensionInformation.getNamespace(),
+ extensionInformation.getTopObject(),
+ extensionInformation.getMethodName(httpMethod, isPreprocess),
+ aaiExtMap,
+ isPreprocess);
if (aaiExtMap.getPrecheckAddedList().size() > 0) {
response = notifyOnSkeletonCreation(aaiExtMap, obj, request.getHeaders());
@@ -793,12 +863,12 @@ public class HttpEntry {
}
templateVars.add(StringUtils.join(keys, ", "));
exceptionList.put(new AAIException("AAI_0004", msg.getAaiResponseMessageResourceType()),
- templateVars);
+ templateVars);
}
response = Response
- .status(Status.ACCEPTED).entity(ErrorLogHelper
- .getRESTAPIInfoResponse(headers.getAcceptableMediaTypes(), exceptionList))
- .build();
+ .status(Status.ACCEPTED).entity(ErrorLogHelper
+ .getRESTAPIInfoResponse(headers.getAcceptableMediaTypes(), exceptionList))
+ .build();
return response;
}
@@ -818,6 +888,20 @@ public class HttpEntry {
}
/**
+ * Creates the not found message.
+ *
+ * @param resultType the result type
+ * @param uri the uri
+ * @return the string
+ */
+ private String createRelationshipNotFoundMessage(String resultType, URI uri) {
+
+ String msg = "No relationship found of type " + resultType + " at the given URI: " + uri.getPath() + "/relationship-list";
+
+ return msg;
+ }
+
+ /**
* Sets the depth.
*
* @param depthParam the depth param
@@ -829,18 +913,18 @@ public class HttpEntry {
String getAllRandomStr = AAIConfig.get("aai.rest.getall.depthparam", "");
if (depthParam != null && getAllRandomStr != null && !getAllRandomStr.isEmpty()
- && getAllRandomStr.equals(depthParam)) {
+ && getAllRandomStr.equals(depthParam)) {
return depth;
}
- if(depthParam == null){
- if(this.version.compareTo(schemaVersions.getDepthVersion()) >= 0){
+ if (depthParam == null) {
+ if (this.version.compareTo(schemaVersions.getDepthVersion()) >= 0) {
depth = 0;
} else {
depth = AAIProperties.MAXIMUM_DEPTH;
}
} else {
- if (!depthParam.isEmpty() && !"all".equals(depthParam)){
+ if (!depthParam.isEmpty() && !"all".equals(depthParam)) {
try {
depth = Integer.parseInt(depthParam);
} catch (Exception e) {
@@ -853,15 +937,15 @@ public class HttpEntry {
int maximumDepth = AAIProperties.MAXIMUM_DEPTH;
- if(maxDepth != null){
+ if (maxDepth != null) {
try {
maximumDepth = Integer.parseInt(maxDepth);
- } catch(Exception ex){
+ } catch (Exception ex) {
throw new AAIException("AAI_4018");
}
}
- if(depth > maximumDepth){
+ if (depth > maximumDepth) {
throw new AAIException("AAI_3303");
}
@@ -937,7 +1021,7 @@ public class HttpEntry {
while (depth >= 0 && !obj.isTopLevel()) {
template = obj.getMetadata(ObjectMetadata.URI_TEMPLATE);
- if(template == null){
+ if (template == null) {
LOGGER.warn("Unable to find the uriTemplate for the object {}", obj.getDbName());
return null;
}
@@ -945,12 +1029,12 @@ public class HttpEntry {
int templateCount = StringUtils.countMatches(template, "/");
int truncatedUriCount = StringUtils.countMatches(truncatedUri, "/");
- if(templateCount > truncatedUriCount){
+ if (templateCount > truncatedUriCount) {
LOGGER.warn("Template uri {} contains more slashes than truncatedUri {}", template, truncatedUri);
return null;
}
- int cutIndex = StringUtils.ordinalIndexOf(truncatedUri, "/", truncatedUriCount-templateCount+1);
+ int cutIndex = StringUtils.ordinalIndexOf(truncatedUri, "/", truncatedUriCount - templateCount + 1);
truncatedUri = StringUtils.substring(truncatedUri, 0, cutIndex);
uriList.add(truncatedUri);
obj = new URIToObject(loader, UriBuilder.fromPath(truncatedUri).build()).getEntity();
@@ -983,8 +1067,8 @@ public class HttpEntry {
HashMap<String, Introspector> relatedVertices = new HashMap<>();
VertexProperty aaiUriProperty = v.property(AAIProperties.AAI_URI);
- if(!aaiUriProperty.isPresent()){
- if(LOGGER.isDebugEnabled()){
+ if (!aaiUriProperty.isPresent()) {
+ if (LOGGER.isDebugEnabled()) {
LOGGER.debug("For the given vertex {}, it seems aai-uri is not present so not getting related objects", v.id().toString());
} else {
LOGGER.info("It seems aai-uri is not present in vertex, so not getting related objects, for more info enable debug log");
@@ -994,18 +1078,18 @@ public class HttpEntry {
String aaiUri = aaiUriProperty.value().toString();
- if(!obj.isTopLevel()){
+ if (!obj.isTopLevel()) {
String[] uriList = convertIntrospectorToUriList(aaiUri, obj, loader);
List<Vertex> vertexChain = null;
// If the uriList is null then there is something wrong with converting the uri
// into a list of aai-uris so falling back to the old mechanism for finding parents
- if(uriList == null){
+ if (uriList == null) {
LOGGER.info("Falling back to the old mechanism due to unable to convert aai-uri to list of uris but this is not optimal");
vertexChain = queryEngine.findParents(v);
} else {
vertexChain = queryEngine.findParents(uriList);
}
- for(Vertex vertex : vertexChain){
+ for (Vertex vertex : vertexChain) {
try {
final Introspector vertexObj = serializer.getVertexProperties(vertex);
relatedVertices.put(vertexObj.getObjectId(), vertexObj);
@@ -1050,8 +1134,9 @@ public class HttpEntry {
URI uri;
try {
uri = serializer.getURIForVertex(entry.getKey());
- if (null != entry.getValue())
+ if (null != entry.getValue()) {
uriMap.put(entry.getValue().getObjectId(), uri);
+ }
} catch (UnsupportedEncodingException e) {
LOGGER.warn("Unable to get URIs, Just continue");
continue;
@@ -1064,18 +1149,19 @@ public class HttpEntry {
}
private Map<String, HashMap<String, Introspector>> buildRelatedObjects(DBSerializer serializer,
- QueryEngine queryEngine, Map<Vertex, Introspector> introSpector) {
+ QueryEngine queryEngine, Map<Vertex, Introspector> introSpector) {
Map<String, HashMap<String, Introspector>> relatedObjectsMap = new HashMap<>();
for (Map.Entry<Vertex, Introspector> entry : introSpector.entrySet()) {
try {
HashMap<String, Introspector> relatedObjects = this.getRelatedObjects(serializer, queryEngine,
- entry.getKey(), entry.getValue(), this.loader);
- if (null != entry.getValue())
+ entry.getKey(), entry.getValue(), this.loader);
+ if (null != entry.getValue()) {
relatedObjectsMap.put(entry.getValue().getObjectId(), relatedObjects);
+ }
} catch (IllegalAccessException | IllegalArgumentException
- | InvocationTargetException | SecurityException | InstantiationException | NoSuchMethodException
- | UnsupportedEncodingException | AAIException | URISyntaxException e) {
+ | InvocationTargetException | SecurityException | InstantiationException | NoSuchMethodException
+ | UnsupportedEncodingException | AAIException | URISyntaxException e) {
LOGGER.warn("Unable to get realted Objects, Just continue");
continue;
}
@@ -1087,8 +1173,8 @@ public class HttpEntry {
}
private void buildNotificationEvent(String sourceOfTruth, Status status, String transactionId,
- UEBNotification notification, Map<Vertex, Introspector> deleteObjects, Map<String, URI> uriMap,
- Map<String, HashMap<String, Introspector>> deleteRelatedObjects, String basePath) {
+ UEBNotification notification, Map<Vertex, Introspector> deleteObjects, Map<String, URI> uriMap,
+ Map<String, HashMap<String, Introspector>> deleteRelatedObjects, String basePath) {
for (Map.Entry<Vertex, Introspector> entry : deleteObjects.entrySet()) {
try {
String vertexObjectId = "";
@@ -1096,9 +1182,10 @@ public class HttpEntry {
if (null != entry.getValue()) {
vertexObjectId = entry.getValue().getObjectId();
- if (uriMap.containsKey(vertexObjectId) && deleteRelatedObjects.containsKey(vertexObjectId))
+ if (uriMap.containsKey(vertexObjectId) && deleteRelatedObjects.containsKey(vertexObjectId)) {
notification.createNotificationEvent(transactionId, sourceOfTruth, status,
- uriMap.get(vertexObjectId), entry.getValue(), deleteRelatedObjects.get(vertexObjectId), basePath);
+ uriMap.get(vertexObjectId), entry.getValue(), deleteRelatedObjects.get(vertexObjectId), basePath);
+ }
}
} catch (UnsupportedEncodingException | AAIException e) {
@@ -1114,17 +1201,17 @@ public class HttpEntry {
}
}
- public List<Object> getPaginatedVertexList(List<Object> vertexList) throws AAIException{
+ public List<Object> getPaginatedVertexList(List<Object> vertexList) throws AAIException {
List<Object> vertices;
- if(this.isPaginated()) {
+ if (this.isPaginated()) {
this.setTotalsForPaging(vertexList.size(), this.getPaginationBucket());
int startIndex = (this.getPaginationIndex() - 1) * this.getPaginationBucket();
int endIndex = Math.min((this.getPaginationBucket() * this.getPaginationIndex()), vertexList.size());
- if(startIndex > endIndex){
- throw new AAIException("AAI_6150"," ResultIndex is not appropriate for the result set, Needs to be <= "+ endIndex);
+ if (startIndex > endIndex) {
+ throw new AAIException("AAI_6150", " ResultIndex is not appropriate for the result set, Needs to be <= " + endIndex);
}
vertices = vertexList.subList(startIndex, endIndex);
- }else{
+ } else {
vertices = vertexList;
}
return vertices;
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/HttpMethod.java b/aai-core/src/main/java/org/onap/aai/restcore/HttpMethod.java
index 85c7dfa9..54215d6a 100644
--- a/aai-core/src/main/java/org/onap/aai/restcore/HttpMethod.java
+++ b/aai-core/src/main/java/org/onap/aai/restcore/HttpMethod.java
@@ -28,5 +28,6 @@ public enum HttpMethod {
DELETE,
PUT_EDGE,
DELETE_EDGE,
- GET;
+ GET,
+ GET_RELATIONSHIP;
}
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java b/aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java
new file mode 100644
index 00000000..1d074dd4
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java
@@ -0,0 +1,58 @@
+/**
+ * ============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.restcore.search;
+
+import groovy.lang.Binding;
+import groovy.lang.Script;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+import java.util.Map;
+
+/**
+ * Creates and returns a groovy shell with the
+ * configuration to statically import graph classes
+ *
+ */
+public class GremlinGroovyShell extends AAIAbstractGroovyShell {
+
+ public GremlinGroovyShell() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GraphTraversal<?, ?> executeTraversal (String traversal, Map<String, Object> params) {
+ Binding binding = new Binding(params);
+ Script script = shell.parse(traversal);
+ script.setBinding(binding);
+ return (GraphTraversal<?, ?>) script.run();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public String executeTraversal(TransactionalGraphEngine engine, String traversal, Map<String, Object> params) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java b/aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java
new file mode 100644
index 00000000..48d4ba8c
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java
@@ -0,0 +1,74 @@
+/**
+ * ============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.restcore.search;
+
+import groovy.lang.Binding;
+import groovy.lang.Script;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.query.builder.QueryBuilder;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.setup.SchemaVersions;
+
+import java.util.Map;
+
+/**
+ * Creates and returns a groovy shell with the
+ * configuration to statically import graph classes
+ *
+ */
+public class GroovyQueryBuilder extends AAIAbstractGroovyShell {
+
+ public GroovyQueryBuilder() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String executeTraversal (TransactionalGraphEngine engine, String traversal, Map<String, Object> params) {
+ QueryBuilder<Vertex> builder = engine.getQueryBuilder(QueryStyle.GREMLIN_TRAVERSAL);
+ SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
+ Loader loader = SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
+
+ builder.changeLoader(loader);
+ Binding binding = new Binding(params);
+ binding.setVariable("builder", builder);
+ Script script = shell.parse(traversal);
+ script.setBinding(binding);
+ script.run();
+
+ return builder.getQuery();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public GraphTraversal<?, ?> executeTraversal(String traversal, Map<String, Object> params) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java b/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
index 95582b98..a23ff1f9 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
@@ -992,6 +992,11 @@ public class DBSerializer {
return simplePropsHashMap;
}
+ public Introspector dbToRelationshipObject(Vertex v) throws UnsupportedEncodingException, AAIException {
+ Introspector relationshipList = this.latestLoader.introspectorFromName("relationship-list");
+ relationshipList = createRelationshipList(v, relationshipList, "false");
+ return relationshipList;
+ }
/**
* Creates the relationship list.
*
@@ -1235,7 +1240,7 @@ public class DBSerializer {
}
public void addRelatedToProperty(Introspector relationship, Vertex cousinVertex, String cousinType) throws AAIUnknownObjectException {
- Introspector obj = loader.introspectorFromName(cousinType);
+ Introspector obj = this.latestLoader.introspectorFromName(cousinType);
String nameProps = obj.getMetadata(ObjectMetadata.NAME_PROPS);
List<Introspector> relatedToProperties = new ArrayList<>();
@@ -1734,11 +1739,11 @@ public class DBSerializer {
/**
* Verify resource version.
*
- * @param action the action
- * @param nodeType the node type
+ * @param action the action
+ * @param nodeType the node type
* @param currentResourceVersion the current resource version
- * @param resourceVersion the resource version
- * @param uri the uri
+ * @param resourceVersion the resource version
+ * @param uri the uri
* @return true, if successful
* @throws AAIException the AAI exception
*/
@@ -1746,6 +1751,7 @@ public class DBSerializer {
String enabled = "";
String errorDetail = "";
String aaiExceptionCode = "";
+ boolean isDeleteResourceVersionOk = true;
if (currentResourceVersion == null) {
currentResourceVersion = "";
}
@@ -1755,12 +1761,16 @@ public class DBSerializer {
}
try {
enabled = AAIConfig.get(AAIConstants.AAI_RESVERSION_ENABLEFLAG);
+
} catch (AAIException e) {
ErrorLogHelper.logException(e);
}
if (enabled.equals("true")) {
- if (!currentResourceVersion.equals(resourceVersion)) {
- if (action.equals("create") && !resourceVersion.equals("")) {
+ if ("delete".equals(action)) {
+ isDeleteResourceVersionOk = verifyResourceVersionForDelete(currentResourceVersion, resourceVersion);
+ }
+ if ((!isDeleteResourceVersionOk) || ((!"delete".equals(action)) && (!currentResourceVersion.equals(resourceVersion)))) {
+ if ("create".equals(action) && !resourceVersion.equals("")) {
errorDetail = "resource-version passed for " + action + " of " + uri;
aaiExceptionCode = "AAI_6135";
} else if (resourceVersion.equals("")) {
@@ -1779,12 +1789,31 @@ public class DBSerializer {
}
/**
+ * Verify resource version for delete.
+ *
+ * @param currentResourceVersion the current resource version
+ * @param resourceVersion the resource version
+ * @return true, if successful or false if there is a mismatch
+ */
+ private boolean verifyResourceVersionForDelete(String currentResourceVersion, String resourceVersion) {
+
+ boolean isDeleteResourceVersionOk = true;
+ String resourceVersionDisabledUuid = AAIConfig.get(AAIConstants.AAI_RESVERSION_DISABLED_UUID,
+ AAIConstants.AAI_RESVERSION_DISABLED_UUID_DEFAULT);
+
+ if ((!currentResourceVersion.equals(resourceVersion)) && (!resourceVersion.equals(resourceVersionDisabledUuid))) {
+ isDeleteResourceVersionOk = false;
+ }
+ return isDeleteResourceVersionOk;
+ }
+
+ /**
* Convert from camel case.
*
* @param name the name
* @return the string
*/
- private String convertFromCamelCase (String name) {
+ private String convertFromCamelCase(String name) {
String result = "";
result = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, name);
@@ -1810,7 +1839,7 @@ public class DBSerializer {
private void executePreSideEffects(Introspector obj, Vertex self) throws AAIException {
SideEffectRunner runner = new SideEffectRunner
- .Builder(this.engine, this).addSideEffect(DataCopy.class).addSideEffect(PrivateEdge.class).build();
+ .Builder(this.engine, this).addSideEffect(DataCopy.class).addSideEffect(PrivateEdge.class).build();
runner.execute(obj, self);
}
@@ -1818,15 +1847,15 @@ public class DBSerializer {
private void executePostSideEffects(Introspector obj, Vertex self) throws AAIException {
SideEffectRunner runner = new SideEffectRunner
- .Builder(this.engine, this).addSideEffect(DataLinkWriter.class).build();
+ .Builder(this.engine, this).addSideEffect(DataLinkWriter.class).build();
runner.execute(obj, self);
}
- private void enrichData(Introspector obj, Vertex self) throws AAIException {
+ private void enrichData(Introspector obj, Vertex self) throws AAIException {
SideEffectRunner runner = new SideEffectRunner
- .Builder(this.engine, this).addSideEffect(DataLinkReader.class).build();
+ .Builder(this.engine, this).addSideEffect(DataLinkReader.class).build();
runner.execute(obj, self);
}
diff --git a/aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java b/aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java
new file mode 100644
index 00000000..c7ef769b
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java
@@ -0,0 +1,56 @@
+/**
+ * ============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.service;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.onap.aai.validation.nodes.NodeValidator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+@Service
+@ConditionalOnProperty(name = "schema.translator.list", havingValue = "config", matchIfMissing = true)
+@PropertySource(value = "classpath:schema-ingest.properties", ignoreResourceNotFound = true)
+@PropertySource(value = "file:${schema.ingest.file}", ignoreResourceNotFound = true)
+public class NodeValidationService {
+
+ private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(NodeValidationService.class);
+
+ @Autowired(required=false)
+ private NodeValidator nodeValidator;
+
+ public NodeValidationService(NodeValidator nodeValidator){
+ this.nodeValidator = nodeValidator;
+ }
+
+ @PostConstruct
+ public void initialize(){
+ if(!nodeValidator.validate()){
+ LOGGER.warn(nodeValidator.getErrorMsg());
+ } else {
+ LOGGER.info("Node validation check passed");
+ }
+ }
+}
+
diff --git a/aai-core/src/main/java/org/onap/aai/util/AAIConstants.java b/aai-core/src/main/java/org/onap/aai/util/AAIConstants.java
index c7a7b4a1..b735f722 100644
--- a/aai-core/src/main/java/org/onap/aai/util/AAIConstants.java
+++ b/aai-core/src/main/java/org/onap/aai/util/AAIConstants.java
@@ -29,9 +29,9 @@ public final class AAIConstants {
public static final String AAI_FILESEP = (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator");
//
/** Default to opt aai if system property aai.home is null, using file.separator */
- public static final String AAI_HOME = (System.getProperty(AJSC_HOME) == null) ? AAI_FILESEP + "opt" + AAI_FILESEP + "app" + AAI_FILESEP +"aai" : System.getProperty(AJSC_HOME);
+ public static final String AAI_HOME = (System.getProperty(AJSC_HOME) == null) ? AAI_FILESEP + "opt" + AAI_FILESEP + "app" + AAI_FILESEP +"aai" : System.getProperty(AJSC_HOME);
public static final String AAI_BUNDLECONFIG_NAME = (System.getProperty("BUNDLECONFIG_DIR") == null) ? "bundleconfig" : System.getProperty("BUNDLECONFIG_DIR");
- public static final String AAI_HOME_BUNDLECONFIG = (System.getProperty(AJSC_HOME) == null) ? AAI_FILESEP + "opt" + AAI_FILESEP + "app" + AAI_FILESEP + "aai" + AAI_FILESEP + AAI_BUNDLECONFIG_NAME : System.getProperty(AJSC_HOME)+ AAI_FILESEP + AAI_BUNDLECONFIG_NAME;
+ public static final String AAI_HOME_BUNDLECONFIG = (System.getProperty(AJSC_HOME) == null) ? AAI_FILESEP + "opt" + AAI_FILESEP + "app" + AAI_FILESEP + "aai" + AAI_FILESEP + AAI_BUNDLECONFIG_NAME : System.getProperty(AJSC_HOME)+ AAI_FILESEP + AAI_BUNDLECONFIG_NAME;
/** etc directory, relative to AAI_HOME */
public static final String AAI_HOME_ETC = AAI_HOME_BUNDLECONFIG + AAI_FILESEP + "etc" + AAI_FILESEP;
@@ -63,10 +63,10 @@ public final class AAIConstants {
public static final int AAI_QUERY_PORT = 8446;
public static final int AAI_LEGACY_PORT = 8443;
- public static final String AAI_DEFAULT_API_VERSION = "v7";
+ public static final String AAI_DEFAULT_API_VERSION = "v10";
public static final String AAI_DEFAULT_API_VERSION_PROP = "aai.default.api.version";
public static final String AAI_NOTIFICATION_CURRENT_VERSION = "aai.notification.current.version";
-
+
public static final String AAI_NODENAME = "aai.config.nodename";
public static final String AAI_BULKCONSUMER_LIMIT = "aai.bulkconsumer.payloadlimit";
@@ -85,15 +85,12 @@ public final class AAIConstants {
public static final String AAI_CRUD_TIMEOUT_APP = "aai.crud.timeout.appspecific";
public static final String AAI_RESVERSION_ENABLEFLAG = "aai.resourceversion.enableflag";
+ public static final String AAI_RESVERSION_DISABLED_UUID = "aai.resourceversion.disabled.uuid";
+ public static final String AAI_RESVERSION_DISABLED_UUID_DEFAULT = "38cf3090-6a0c-4e9d-8142-4332a7352846";
+
- public static final int AAI_GROOMING_DEFAULT_MAX_FIX = 150;
- public static final int AAI_GROOMING_DEFAULT_SLEEP_MINUTES = 7;
-
- public static final int AAI_DUPETOOL_DEFAULT_MAX_FIX = 25;
- public static final int AAI_DUPETOOL_DEFAULT_SLEEP_MINUTES = 7;
-
public static final long HISTORY_MAX_HOURS = 192;
-
+
public static final String LOGGING_MAX_STACK_TRACE_ENTRIES = "aai.logging.maxStackTraceEntries";
/*** UEB ***/
diff --git a/aai-core/src/main/java/org/onap/aai/util/GenerateXsd.java b/aai-core/src/main/java/org/onap/aai/util/GenerateXsd.java
index 84f06064..97803653 100644
--- a/aai-core/src/main/java/org/onap/aai/util/GenerateXsd.java
+++ b/aai-core/src/main/java/org/onap/aai/util/GenerateXsd.java
@@ -42,8 +42,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GenerateXsd {
-
- private static final Logger logger = LoggerFactory.getLogger("GenerateXsd.class");
+
+ private static final Logger logger = LoggerFactory.getLogger("GenerateXsd.class");
protected static String apiVersion = null;
public static AnnotationConfigApplicationContext ctx = null;
static String apiVersionFmt = null;
@@ -76,18 +76,18 @@ public class GenerateXsd {
public static final int VALUE_DESCRIPTION = 1;
public static final int VALUE_INDEXED_PROPS = 2;
public static final int VALUE_CONTAINER = 3;
-
+
private static final String generateTypeXSD = "xsd";
private static final String generateTypeYAML = "yaml";
-
+
private final static String nodeDir = System.getProperty("nodes.configuration.location");
private final static String edgeDir = System.getProperty("edges.configuration.location");
private static final String baseRoot = "aai-schema/";
private static final String baseAutoGenRoot = "aai-schema/";
-
+
private static final String root = baseRoot + "src/main/resources";
private static final String autoGenRoot = baseAutoGenRoot + "src/main/resources";
-
+
private static final String normalStartDir = "aai-core";
private static final String xsd_dir = root + "/" + RELEASE +"/aai_schema";
@@ -97,9 +97,9 @@ public class GenerateXsd {
private static int swaggerSupportStartsVersion = 1; // minimum version to support swagger documentation
-
+
private static boolean validVersion(String versionToGen) {
-
+
if ("ALL".equalsIgnoreCase(versionToGen)) {
return true;
}
@@ -113,14 +113,14 @@ public class GenerateXsd {
return false;
}
-
+
private static boolean versionSupportsSwagger( String version) {
if (new Integer(version.substring(1)).intValue() >= swaggerSupportStartsVersion ) {
return true;
}
return false;
}
-
+
public static String getAPIVersion() {
return apiVersion;
}
@@ -146,19 +146,19 @@ public class GenerateXsd {
if ( fileTypeToGen == null ) {
fileTypeToGen = generateTypeXSD;
}
-
+
if ( !fileTypeToGen.equals( generateTypeXSD ) && !fileTypeToGen.equals( generateTypeYAML )) {
System.err.println("Invalid gen_type passed. " + fileTypeToGen);
System.exit(1);
}
-
+
String responsesLabel = System.getProperty("yamlresponses_url");
responsesUrl = responsesLabel;
-
+
List<SchemaVersion> versionsToGen = new ArrayList<>();
if ( versionToGen == null ) {
System.err.println("Version is required, ie v<n> or ALL.");
- System.exit(1);
+ System.exit(1);
}
else if (!"ALL".equalsIgnoreCase(versionToGen) && !versionToGen.matches("v\\d+") && !validVersion(versionToGen)) {
System.err.println("Invalid version passed. " + versionToGen);
@@ -171,14 +171,14 @@ public class GenerateXsd {
} else {
versionsToGen.add(new SchemaVersion(versionToGen));
}
-
+
//process file type System property
fileTypeToGen = (fileTypeToGen == null ? generateTypeXSD : fileTypeToGen.toLowerCase());
if ( !fileTypeToGen.equals( generateTypeXSD ) && !fileTypeToGen.equals( generateTypeYAML )) {
System.err.println("Invalid gen_type passed. " + fileTypeToGen);
System.exit(1);
} else if ( fileTypeToGen.equals(generateTypeYAML) ) {
- if ( responsesUrl == null || responsesUrl.length() < 1
+ if ( responsesUrl == null || responsesUrl.length() < 1
|| responsesLabel == null || responsesLabel.length() < 1 ) {
System.err.println("generating swagger yaml file requires yamlresponses_url and yamlresponses_label properties" );
System.exit(1);
@@ -217,11 +217,11 @@ public class GenerateXsd {
logger.debug("user.dir = "+System.getProperty("user.dir"));
if(System.getProperty("user.dir") != null && !System.getProperty("user.dir").contains(normalStartDir)) {
fileName = baseAutoGenRoot + fileName;
-
+
}
else {
fileName = baseRoot + fileName;
-
+
}
edgeRuleFile = new File( fileName);
// Document doc = ni.getSchema(translateVersion(v));
@@ -232,6 +232,9 @@ public class GenerateXsd {
HTMLfromOXM swagger = ctx.getBean(HTMLfromOXM.class);
swagger.setVersion(v);
fileContent = swagger.process();
+ if ( fileContent.startsWith("Schema format issue")) {
+ throw new Exception(fileContent);
+ }
} catch(Exception e) {
logger.error( "Exception creating output file " + outfileName);
logger.error( e.getMessage());
@@ -241,7 +244,7 @@ public class GenerateXsd {
} else if ( versionSupportsSwagger(apiVersion )) {
outfileName = yaml_dir + "/aai_swagger_" + apiVersion + "." + generateTypeYAML;
nodesfileName = yaml_dir + "/aai_swagger_" + apiVersion + "." + "nodes"+"."+generateTypeYAML;
- try {
+ try {
YAMLfromOXM swagger = (YAMLfromOXM) ctx.getBean(YAMLfromOXM.class);
swagger.setVersion(v);
fileContent = swagger.process();
@@ -259,13 +262,13 @@ public class GenerateXsd {
}
outfile = new File(outfileName);
File parentDir = outfile.getParentFile();
- if(! parentDir.exists())
+ if(! parentDir.exists())
parentDir.mkdirs();
if(nodesfileName != null) {
BufferedWriter nodesBW = null;
nodesfile = new File(nodesfileName);
parentDir = nodesfile.getParentFile();
- if(! parentDir.exists())
+ if(! parentDir.exists())
parentDir.mkdirs();
try {
nodesfile.createNewFile();
@@ -287,7 +290,7 @@ public class GenerateXsd {
}
}
}
-
+
try {
outfile.createNewFile();
} catch (IOException e) {
@@ -310,9 +313,8 @@ public class GenerateXsd {
}
logger.debug( "GeneratedXSD successful, saved in " + outfileName);
}
-
+
}
}
- \ No newline at end of file
diff --git a/aai-core/src/main/java/org/onap/aai/util/genxsd/NodesYAMLfromOXM.java b/aai-core/src/main/java/org/onap/aai/util/genxsd/NodesYAMLfromOXM.java
index 0b89ce10..5abd8f48 100644
--- a/aai-core/src/main/java/org/onap/aai/util/genxsd/NodesYAMLfromOXM.java
+++ b/aai-core/src/main/java/org/onap/aai/util/genxsd/NodesYAMLfromOXM.java
@@ -131,8 +131,7 @@ public class NodesYAMLfromOXM extends OxmFileProcessor {
}
XSDElement javaTypeElement = new XSDElement(elem);
-
-
+
logger.debug("External: "+javaTypeElement.getAttribute("name")+"/"+getXmlRootElementName(javaTypeName));
if ( javaTypeName == null ) {
String msg = "Invalid OXM file: <java-type> has no name attribute in " + oxmFile;
@@ -140,7 +139,6 @@ public class NodesYAMLfromOXM extends OxmFileProcessor {
throw new AAIException(msg);
}
namespaceFilter.add(getXmlRootElementName(javaTypeName));
-
processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
definitionsSb, null, null, null, null, null, null);
}
@@ -274,7 +272,11 @@ public class NodesYAMLfromOXM extends OxmFileProcessor {
}
if ( indexedProps != null
&& indexedProps.contains(xmlElementElement.getAttribute("name") ) ) {
- containerProps.add(xmlElementElement.getQueryParamYAML());
+ containerProps.add(xmlElementElement.getQueryParamYAML(elementDescription));
+ NodeGetOperation.addContainerProps(container, containerProps);
+ } else if ( indexedProps == null || indexedProps.isEmpty() && "true".equals(xmlElementElement.getAttribute("required")) ){
+ // no indexedProps and element is required, also considered using xml-key in this case
+ containerProps.add(xmlElementElement.getPathParamYAMLRqd(elementDescription, false));
NodeGetOperation.addContainerProps(container, containerProps);
}
if ( xmlElementElement.isStandardType()) {
@@ -500,8 +502,7 @@ public class NodesYAMLfromOXM extends OxmFileProcessor {
}
Path path = Paths.get(outfileName);
Charset charset = Charset.forName("UTF-8");
- try {
- BufferedWriter bw = Files.newBufferedWriter(path, charset);
+ try(BufferedWriter bw = Files.newBufferedWriter(path, charset);) {
bw.write(fileContent);
if ( bw != null ) {
bw.close();
diff --git a/aai-core/src/main/java/org/onap/aai/util/genxsd/OxmFileProcessor.java b/aai-core/src/main/java/org/onap/aai/util/genxsd/OxmFileProcessor.java
index a758be50..8edab757 100644
--- a/aai-core/src/main/java/org/onap/aai/util/genxsd/OxmFileProcessor.java
+++ b/aai-core/src/main/java/org/onap/aai/util/genxsd/OxmFileProcessor.java
@@ -43,7 +43,6 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-
import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
import org.onap.aai.exceptions.AAIException;
@@ -65,7 +64,7 @@ public abstract class OxmFileProcessor {
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static final String DOUBLE_LINE_SEPARATOR = System.getProperty("line.separator") + System.getProperty("line.separator");
-
+
EdgeIngestor ei;
NodeIngestor ni;
protected Set<String> namespaceFilter;
@@ -75,17 +74,17 @@ public abstract class OxmFileProcessor {
protected Document doc = null;
protected String apiVersion = null;
protected SchemaVersions schemaVersions;
-
- protected Map combinedJavaTypes;
-
-
+
+
protected static int annotationsStartVersion = 9; // minimum version to support annotations in xsd
protected static int annotationsMinVersion = 6; // lower versions support annotations in xsd
protected static int swaggerSupportStartsVersion = 1; // minimum version to support swagger documentation
protected static int swaggerDiffStartVersion = 1; // minimum version to support difference
protected static int swaggerMinBasepath = 6; // minimum version to support difference
-
-
+
+ protected Map combinedJavaTypes;
+
+
protected String apiVersionFmt = null;
protected HashMap<String, String> generatedJavaType = new HashMap<String, String>();
protected HashMap<String, String> appliedPaths = new HashMap<String, String>();
@@ -125,8 +124,8 @@ public abstract class OxmFileProcessor {
this.ni = ni;
this.ei = ei;
}
-
-
+
+
public void setOxmVersion(File oxmFile, SchemaVersion v) {
this.oxmFile = oxmFile;
@@ -137,16 +136,16 @@ public abstract class OxmFileProcessor {
this.xml = xml;
this.v = v;
}
-
+
public void setVersion(SchemaVersion v) {
this.oxmFile = null;
this.v = v;
}
-
+
public void setNodeIngestor(NodeIngestor ni) {
this.ni = ni;
}
-
+
public void setEdgeIngestor(EdgeIngestor ei) {
this.ei = ei;
}
@@ -158,25 +157,25 @@ public abstract class OxmFileProcessor {
public void setSchemaVersions(SchemaVersions schemaVersions) {
this.schemaVersions = schemaVersions;
}
-
+
protected void init() throws ParserConfigurationException, SAXException, IOException, AAIException, EdgeRuleNotFoundException {
- if(this.xml != null || this.oxmFile != null ) {
+ if(this.xml != null || this.oxmFile != null ) {
createDocument();
}
if(this.doc == null) {
this.doc = ni.getSchema(v);
}
namespaceFilter = new HashSet<>();
-
+
NodeList bindingsNodes = doc.getElementsByTagName("xml-bindings");
Element bindingElement;
NodeList javaTypesNodes;
Element javaTypesElement;
-
+
if ( bindingsNodes == null || bindingsNodes.getLength() == 0 ) {
throw new AAIException("OXM file error: missing <binding-nodes> in " + oxmFile);
- }
-
+ }
+
bindingElement = (Element) bindingsNodes.item(0);
javaTypesNodes = bindingElement.getElementsByTagName("java-types");
if ( javaTypesNodes.getLength() < 1 ) {
@@ -192,14 +191,14 @@ public abstract class OxmFileProcessor {
private void createDocument() throws ParserConfigurationException, SAXException, IOException, AAIException {
DocumentBuilder dBuilder = null;
- try {
+ try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
dBuilder = dbFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw e;
}
- try {
+ try {
if ( xml == null ) {
doc = dBuilder.parse(oxmFile);
} else {
@@ -215,11 +214,11 @@ public abstract class OxmFileProcessor {
}
public abstract String getDocumentHeader();
public abstract String process() throws ParserConfigurationException, SAXException, IOException, AAIException, FileNotFoundException, EdgeRuleNotFoundException ;
-
+
public String getXMLRootElementName(Element javaTypeElement) {
String xmlRootElementName=null;
NamedNodeMap attributes;
-
+
NodeList valNodes = javaTypeElement.getElementsByTagName("xml-root-element");
Element valElement = (Element) valNodes.item(0);
attributes = valElement.getAttributes();
@@ -233,7 +232,7 @@ public abstract class OxmFileProcessor {
}
return xmlRootElementName;
}
-
+
public String getXmlRootElementName( String javaTypeName )
{
String attrName, attrValue;
@@ -263,22 +262,22 @@ public abstract class OxmFileProcessor {
}
return null;
}
-
+
public Map getCombinedJavaTypes() {
return combinedJavaTypes;
}
-
+
public void setCombinedJavaTypes(Map combinedJavaTypes) {
this.combinedJavaTypes = combinedJavaTypes;
}
-
+
public Element getJavaTypeElementSwagger( String javaTypeName )
{
-
+
String attrName, attrValue;
Attr attr;
Element javaTypeElement;
-
+
List<Element> combineElementList = new ArrayList<Element>();
for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
javaTypeElement = (Element) javaTypeNodes.item(i);
@@ -295,12 +294,11 @@ public abstract class OxmFileProcessor {
if ( combineElementList.size() == 0 ) {
return (Element) null;
} else if ( combineElementList.size() > 1 ) {
- // need to combine java-attributes
return combineElements( javaTypeName, combineElementList);
}
return combineElementList.get(0);
}
-
+
public boolean versionSupportsSwaggerDiff( String version) {
int ver = new Integer(version.substring(1)).intValue();
if ( ver >= HTMLfromOXM.swaggerDiffStartVersion ) {
@@ -308,7 +306,7 @@ public abstract class OxmFileProcessor {
}
return false;
}
-
+
public boolean versionSupportsBasePathProperty( String version) {
int ver = new Integer(version.substring(1)).intValue();
if ( ver <= HTMLfromOXM.swaggerMinBasepath ) {
@@ -340,11 +338,11 @@ public abstract class OxmFileProcessor {
for ( int i = 0; i < moreXmlElementNodes.getLength(); ++i ) {
xmlElement = (Element)moreXmlElementNodes.item(i);
- childNode = xmlElement.cloneNode(true);
+ childNode = xmlElement.cloneNode(true);
parentElement.insertBefore(childNode, refChild);
}
}
-
+
protected Node getXmlPropertiesNode(Element javaTypeElement ) {
NodeList nl = javaTypeElement.getChildNodes();
Node child;
@@ -356,7 +354,7 @@ public abstract class OxmFileProcessor {
}
return null;
}
-
+
protected Node merge( NodeList nl, Node mergeNode ) {
NamedNodeMap nnm = mergeNode.getAttributes();
Node childNode;
@@ -390,7 +388,7 @@ public abstract class OxmFileProcessor {
childNode = mergeNode.cloneNode(true);
return childNode;
}
-
+
protected void mergeXmlProperties(Node useChildProperties, NodeList propertiesToMerge ) {
NodeList nl = useChildProperties.getChildNodes();
Node childNode;
@@ -403,10 +401,10 @@ public abstract class OxmFileProcessor {
useChildProperties.appendChild(newNode);
}
}
-
+
}
}
-
+
protected void combineXmlProperties(int useElement, List<Element> combineElementList) {
// add or update xml-properties to the referenced element from the combined list
Element javaTypeElement = combineElementList.get(useElement);
@@ -443,7 +441,7 @@ public abstract class OxmFileProcessor {
}
}
-
+
protected Element combineElements( String javaTypeName, List<Element> combineElementList ) {
Element javaTypeElement;
NodeList parentNodes;
@@ -486,7 +484,7 @@ public abstract class OxmFileProcessor {
parentNodes = javaTypeElement.getElementsByTagName("java-attributes");
if ( parentNodes.getLength() == 0 ) {
continue;
- }
+ }
otherParentElement = (Element)parentNodes.item(0);
xmlElementNodes = otherParentElement.getElementsByTagName("xml-element");
if ( xmlElementNodes.getLength() <= 0 ) {
@@ -494,7 +492,7 @@ public abstract class OxmFileProcessor {
}
// xml-element that are not present
updateParentXmlElements( parentElement, xmlElementNodes);
-
+
}
}
// need to combine xml-properties
@@ -502,7 +500,7 @@ public abstract class OxmFileProcessor {
combinedJavaTypes.put( javaTypeName, useElement);
return combineElementList.get(useElement);
}
-
+
private static void prettyPrint(Node node, String tab)
{
diff --git a/aai-core/src/main/java/org/onap/aai/util/genxsd/PutOperation.java b/aai-core/src/main/java/org/onap/aai/util/genxsd/PutOperation.java
index cb5e779e..6597d034 100644
--- a/aai-core/src/main/java/org/onap/aai/util/genxsd/PutOperation.java
+++ b/aai-core/src/main/java/org/onap/aai/util/genxsd/PutOperation.java
@@ -84,14 +84,14 @@ public class PutOperation {
pathSb.append(" operationId: createOrUpdate" + useOpId + "\n");
pathSb.append(" consumes:\n");
pathSb.append(" - application/json\n");
- pathSb.append(" - application/xml\n");
+ pathSb.append(" - application/xml\n");
pathSb.append(" produces:\n");
pathSb.append(" - application/json\n");
pathSb.append(" - application/xml\n");
pathSb.append(" responses:\n");
pathSb.append(" \"default\":\n");
pathSb.append(" " + GenerateXsd.getResponsesUrl());
-
+
pathSb.append(" parameters:\n");
pathSb.append(pathParams); // for nesting
pathSb.append(" - name: body\n");
@@ -99,7 +99,11 @@ public class PutOperation {
pathSb.append(" description: " + xmlRootElementName + " object that needs to be created or updated. "+relationshipExamplesSb.toString()+"\n");
pathSb.append(" required: true\n");
pathSb.append(" schema:\n");
- pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
+ String useElement = xmlRootElementName;
+ if ( xmlRootElementName.equals("relationship")) {
+ useElement += "-dict";
+ }
+ pathSb.append(" $ref: \"#/definitions/" + useElement + "\"\n");
this.tagRelationshipPathMapEntry();
return pathSb.toString();
}
@@ -110,5 +114,5 @@ public class PutOperation {
}
return "";
}
-
- } \ No newline at end of file
+
+ }
diff --git a/aai-core/src/main/java/org/onap/aai/util/genxsd/XSDElement.java b/aai-core/src/main/java/org/onap/aai/util/genxsd/XSDElement.java
index 9de7967e..db7c54c3 100644
--- a/aai-core/src/main/java/org/onap/aai/util/genxsd/XSDElement.java
+++ b/aai-core/src/main/java/org/onap/aai/util/genxsd/XSDElement.java
@@ -52,13 +52,13 @@ public class XSDElement implements Element {
this.xmlElementElement = xmlElementElement;
this.maxOccurs = maxOccurs;
}
-
+
public XSDElement(Element xmlElementElement) {
super();
this.xmlElementElement = xmlElementElement;
this.maxOccurs = null;
}
-
+
public String name() {
return this.getAttribute("name");
}
@@ -235,13 +235,23 @@ public class XSDElement implements Element {
}
public String getQueryParamYAML() {
+ return getQueryParamYAML(null);
+ }
+
+ public String getQueryParamYAML(String elementDescription ) {
+ // when elementDescription is not null, return parameters with description and example
StringBuffer sbParameter = new StringBuffer();
sbParameter.append((" - name: " + this.getAttribute("name") + "\n"));
sbParameter.append((" in: query\n"));
- if ( this.getAttribute("description") != null && this.getAttribute("description").length() > 0 )
- sbParameter.append((" description: " + this.getAttribute("description") + "\n"));
- else
+ String useDescription = elementDescription;
+ if ( elementDescription == null ) {
+ useDescription = this.getAttribute("description");
+ }
+ if ( useDescription != null && useDescription.length() > 0 ) {
+ sbParameter.append((" description: " + useDescription + "\n"));
+ } else {
sbParameter.append((" description:\n"));
+ }
sbParameter.append((" required: false\n"));
if ( ("java.lang.String").equals(this.getAttribute("type")))
sbParameter.append(" type: string\n");
@@ -256,16 +266,28 @@ public class XSDElement implements Element {
if ( ("java.lang.Boolean").equals(this.getAttribute("type"))) {
sbParameter.append(" type: boolean\n");
}
+ if ( elementDescription != null && StringUtils.isNotBlank(this.getAttribute("name"))) {
+ sbParameter.append(" example: "+"__"+this.getAttribute("name").toUpperCase()+"__"+"\n");
+ }
return sbParameter.toString();
}
public String getPathParamYAML(String elementDescription) {
+ return getPathParamYAMLRqd( elementDescription, true);
+ }
+
+ public String getPathParamYAMLRqd(String elementDescription, boolean isRqd) {
StringBuffer sbParameter = new StringBuffer();
sbParameter.append((" - name: " + this.getAttribute("name") + "\n"));
sbParameter.append((" in: path\n"));
if ( elementDescription != null && elementDescription.length() > 0 )
sbParameter.append((" description: " + elementDescription + "\n"));
- sbParameter.append((" required: true\n"));
+ if ( isRqd ) {
+ sbParameter.append((" required: true\n"));
+ } else {
+ // used by Nodes API for query params
+ sbParameter.append((" required: false\n"));
+ }
if ( ("java.lang.String").equals(this.getAttribute("type")))
sbParameter.append(" type: string\n");
if ( ("java.lang.Long").equals(this.getAttribute("type"))) {
@@ -306,7 +328,7 @@ public class XSDElement implements Element {
sbElement.append(" type=\"xs:int\"");
if ( elementType.equals("java.lang.Boolean"))
sbElement.append(" type=\"xs:boolean\"");
- if ( addType != null || elementType.startsWith("java.lang.") ) {
+ if ( addType != null || elementType.startsWith("java.lang.") ) {
sbElement.append(" minOccurs=\"0\"");
}
if ( elementContainerType != null && elementContainerType.equals("java.util.ArrayList")) {
diff --git a/aai-core/src/main/java/org/onap/aai/util/genxsd/YAMLfromOXM.java b/aai-core/src/main/java/org/onap/aai/util/genxsd/YAMLfromOXM.java
index a14a6977..f807bcb1 100644
--- a/aai-core/src/main/java/org/onap/aai/util/genxsd/YAMLfromOXM.java
+++ b/aai-core/src/main/java/org/onap/aai/util/genxsd/YAMLfromOXM.java
@@ -112,7 +112,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
try {
init();
} catch(Exception e) {
- logger.error( "Error initializing " + this.getClass());
+ logger.error( "Error initializing " + this.getClass(),e);
throw e;
}
pathSb.append(getDocumentHeader());
@@ -138,7 +138,6 @@ public class YAMLfromOXM extends OxmFileProcessor {
throw new AAIException(msg);
}
namespaceFilter.add(getXmlRootElementName(javaTypeName));
-
processJavaTypeElementSwagger( javaTypeName, javaTypeElement, pathSb,
definitionsSb, null, null, null, null, null, null);
}
@@ -235,7 +234,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
private String processJavaTypeElementSwagger( String javaTypeName, Element javaTypeElement,
StringBuffer pathSb, StringBuffer definitionsSb, String path, String tag, String opId,
String getItemName, StringBuffer pathParams, String validEdges) {
-
+
String xmlRootElementName = getXMLRootElementName(javaTypeElement);
StringBuilder definitionsLocalSb = new StringBuilder(256);
@@ -468,7 +467,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
results.get(key).stream().filter((i) -> (i.getFrom().equals(xmlRootElementName) && (! i.isPrivateEdge() && i.getPreventDelete().equals("OUT")))).forEach((i) ->{ preventDelete.add(i.getTo().toUpperCase());} );
}
} catch(Exception e) {
- logger.debug("xmlRootElementName: "+xmlRootElementName+"\n"+e);
+ logger.debug("xmlRootElementName: "+xmlRootElementName+" from edge exception\n", e);
}
try {
EdgeRuleQuery q1 = new EdgeRuleQuery.Builder(xmlRootElementName).version(v).toOnly().build();
@@ -481,7 +480,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
results.get(key).stream().filter((i) -> (i.getTo().equals(xmlRootElementName) && (! i.isPrivateEdge() && i.getPreventDelete().equals("IN")))).forEach((i) ->{ preventDelete.add(i.getFrom().toUpperCase());} );
}
} catch(Exception e) {
- logger.debug("xmlRootElementName: "+xmlRootElementName+"\n"+e);
+ logger.debug("xmlRootElementName: "+xmlRootElementName+" to edge exception\n", e);
}
if(preventDelete.size() > 0) {
prevent = xmlRootElementName.toUpperCase()+" cannot be deleted if related to "+String.join(",",preventDelete);
@@ -536,6 +535,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
}
} catch (Exception e) {
e.printStackTrace();
+ logger.error("Exception adding in javaTypeDefinitions",e);
}
if ( xmlRootElementName.equals("inventory") ) {
logger.trace("skip xmlRootElementName(2)="+xmlRootElementName);
@@ -568,15 +568,10 @@ public class YAMLfromOXM extends OxmFileProcessor {
logger.error( "Exception creating output file " + outfileName);
e.printStackTrace();
}
- BufferedWriter bw = null;
Charset charset = Charset.forName("UTF-8");
Path path = Paths.get(outfileName);
- try {
- bw = Files.newBufferedWriter(path, charset);
+ try(BufferedWriter bw = Files.newBufferedWriter(path, charset)){
bw.write(fileContent);
- if ( bw != null ) {
- bw.close();
- }
} catch ( IOException e) {
logger.error( "Exception writing output file " + outfileName);
e.printStackTrace();
@@ -600,4 +595,4 @@ public class YAMLfromOXM extends OxmFileProcessor {
return false;
}
-} \ No newline at end of file
+}
diff --git a/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java b/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java
index ac897273..94d8f4cd 100644
--- a/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java
+++ b/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java
@@ -37,7 +37,7 @@ public class EventClientPublisher {
private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(EventClientPublisher.class);
- @Value("${dmaap.ribbon.listOfServers}")
+ @Value("${dmaap.ribbon.listOfServers:}")
private String hosts;
@Value("${dmaap.ribbon.username:}")
diff --git a/aai-core/src/main/resources/schema-ingest.properties b/aai-core/src/main/resources/schema-ingest.properties
new file mode 100644
index 00000000..4bae01db
--- /dev/null
+++ b/aai-core/src/main/resources/schema-ingest.properties
@@ -0,0 +1 @@
+schema.translator.list=config