diff options
author | Pavel Paroulek <pavel.paroulek@orange.com> | 2019-04-23 15:27:28 +0200 |
---|---|---|
committer | Pavel Paroulek <pavel.paroulek@orange.com> | 2019-05-08 13:30:00 +0200 |
commit | 1722ddc1b782c79d881a11eb06df66c6e2ab6029 (patch) | |
tree | db8850cd3733b6301c90ebeef64b31b3ca8a3304 /src/main/java/org/onap | |
parent | c90203a311c4c214eb0ea74bd83461ab7ee17d94 (diff) |
Adding schema ingestor and backend
Adding backend for schema visualization, bugfixes, UI changes
Change-Id: I830c4e5566806f14ff609e8784cd1ed2f54ba4ac
Issue-ID: AAI-531
Signed-off-by: Pavel Paroulek <pavel.paroulek@orange.com>
Diffstat (limited to 'src/main/java/org/onap')
15 files changed, 793 insertions, 243 deletions
diff --git a/src/main/java/org/onap/aai/graphgraph/App.java b/src/main/java/org/onap/aai/graphgraph/App.java index 35a8b86..42effa1 100644 --- a/src/main/java/org/onap/aai/graphgraph/App.java +++ b/src/main/java/org/onap/aai/graphgraph/App.java @@ -1,13 +1,54 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph; +import java.util.HashMap; +import java.util.Map; +import org.onap.aai.edges.EdgeIngestor; +import org.onap.aai.introspection.MoxyLoader; +import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; +import org.onap.aai.nodes.NodeIngestor; +import org.onap.aai.setup.SchemaVersion; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication -public class App -{ - public static void main( String[] args ) - { - SpringApplication.run(App.class, args); +public class App{ + public static EdgeIngestor edgeIngestor; + public static Map<String, MoxyLoader> moxyLoaders = new HashMap<>(); + + // TODO + // this should be used properly within Spring as this is a 'static' workaround due + // to some initialization issues. By all means feel free to improve and move it to Spring + public static void loadSchemes(ConfigurableApplicationContext context){ + String version; + for (int i = 10; i < 17; i++) { + version = "v" + i; + moxyLoaders.put(version, new MoxyLoader(new SchemaVersion(version), (NodeIngestor) context.getBean("nodeIngestor")) ); + } + } + + public static void main( String[] args ) { + ConfigurableApplicationContext context = SpringApplication.run(App.class, args); + loadSchemes(context); + edgeIngestor = (EdgeIngestor) context.getBean("edgeIngestor"); } } diff --git a/src/main/java/org/onap/aai/graphgraph/Config.java b/src/main/java/org/onap/aai/graphgraph/Config.java index ab364a5..1d4152b 100644 --- a/src/main/java/org/onap/aai/graphgraph/Config.java +++ b/src/main/java/org/onap/aai/graphgraph/Config.java @@ -1,25 +1,53 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph; - -import org.onap.aai.graphgraph.reader.DummySchemaReader; +import java.util.LinkedList; +import java.util.List; +import org.onap.aai.graphgraph.reader.BasicSchemaReader; +import org.onap.aai.graphgraph.reader.SchemaReader; import org.onap.aai.graphgraph.reader.SchemaRepository; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import java.util.Collections; - @Configuration -@ComponentScan("org.onap.aai.graphgraph") +@ComponentScan(basePackages = { + "org.onap.aai.config", + "org.onap.aai.setup", + "org.onap.aai.graphgraph" +}) public class Config { + @Value("${schema.version.list}") + String schemaVersions; + @Bean SchemaRepository createSchemaRepository(){ - DummySchemaReader dummyReader = new DummySchemaReader(); - SchemaRepository repository = new SchemaRepository(Collections.singletonList(dummyReader)); - return repository; + List<SchemaReader> readers = new LinkedList<>(); + for (String s : schemaVersions.split(",")) { + readers.add(new BasicSchemaReader(s)); + } + return new SchemaRepository(readers); } - } diff --git a/src/main/java/org/onap/aai/graphgraph/CorsFilter.java b/src/main/java/org/onap/aai/graphgraph/CorsFilter.java new file mode 100644 index 0000000..448a2ea --- /dev/null +++ b/src/main/java/org/onap/aai/graphgraph/CorsFilter.java @@ -0,0 +1,44 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph; + +import java.io.IOException; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Component +public class CorsFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, + final FilterChain filterChain) throws ServletException, IOException { + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, HEAD"); + response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); + response.addHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Credentials"); + response.addHeader("Access-Control-Allow-Credentials", "true"); + response.addIntHeader("Access-Control-Max-Age", 10); + filterChain.doFilter(request, response); + } +}
\ No newline at end of file diff --git a/src/main/java/org/onap/aai/graphgraph/SchemaResource.java b/src/main/java/org/onap/aai/graphgraph/SchemaResource.java index f6823ee..af98289 100644 --- a/src/main/java/org/onap/aai/graphgraph/SchemaResource.java +++ b/src/main/java/org/onap/aai/graphgraph/SchemaResource.java @@ -1,3 +1,22 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph; import org.onap.aai.graphgraph.dto.Graph; @@ -41,7 +60,7 @@ public class SchemaResource { @PathVariable("schema") String schemaName, @RequestParam("fromNode") String fromNodeName, @RequestParam("toNode") String toNodeName) { - return repository.getSchemaReader(schemaName).getEdgeProperties(fromNodeName, toNodeName); + return repository.getSchemaReader(schemaName).getEdgeProperties(fromNodeName, toNodeName, "edgerule"); } @@ -51,9 +70,10 @@ public class SchemaResource { @RequestParam("node") String initialNodeName, @RequestParam("parentHops") Integer parentHops, @RequestParam("cousinHops") Integer cousinHops, - @RequestParam("childHops") Integer childHops) + @RequestParam("childHops") Integer childHops, + @RequestParam("edgeFilter") String edgeFilter) { - Graph graph = repository.getSchemaReader(schemaName).getGraph(initialNodeName, parentHops, cousinHops, childHops); + Graph graph = repository.getSchemaReader(schemaName).getGraph(initialNodeName, parentHops, cousinHops, childHops, edgeFilter); graph.setPaths(Collections.emptyList()); return graph; } @@ -63,9 +83,10 @@ public class SchemaResource { public Graph loadGraphWithPaths( @PathVariable("schema") String schemaName, @RequestParam("fromNode") String fromNode, - @RequestParam("toNode") String toNode) + @RequestParam("toNode") String toNode, + @RequestParam("edgeFilter") String edgeFilter) { - return repository.getSchemaReader(schemaName).getGraph(fromNode, toNode); + return repository.getSchemaReader(schemaName).getGraph(fromNode, toNode, edgeFilter); } diff --git a/src/main/java/org/onap/aai/graphgraph/dto/Edge.java b/src/main/java/org/onap/aai/graphgraph/dto/Edge.java index e8ad9c5..402fbb5 100644 --- a/src/main/java/org/onap/aai/graphgraph/dto/Edge.java +++ b/src/main/java/org/onap/aai/graphgraph/dto/Edge.java @@ -1,8 +1,11 @@ package org.onap.aai.graphgraph.dto; +import java.util.Arrays; +import java.util.Collections; import java.util.List; public class Edge { + private String source; private String target; private String type; @@ -27,6 +30,10 @@ public class Edge { return source; } + public List<NodeName> getNodeNames() { + return Arrays.asList(new NodeName(source), new NodeName(target)); + } + public void setSource(String source) { this.source = source; } @@ -46,4 +53,33 @@ public class Edge { public void setType(String type) { this.type = type; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Edge edge = (Edge) o; + + if (!source.equals(edge.source)) { + return false; + } + if (!target.equals(edge.target)) { + return false; + } + return type.equals(edge.type); + + } + + @Override + public int hashCode() { + int result = source.hashCode(); + result = 31 * result + target.hashCode(); + result = 31 * result + type.hashCode(); + return result; + } } diff --git a/src/main/java/org/onap/aai/graphgraph/dto/Graph.java b/src/main/java/org/onap/aai/graphgraph/dto/Graph.java index ca496b6..0d08e9d 100644 --- a/src/main/java/org/onap/aai/graphgraph/dto/Graph.java +++ b/src/main/java/org/onap/aai/graphgraph/dto/Graph.java @@ -1,5 +1,6 @@ package org.onap.aai.graphgraph.dto; +import java.util.Collections; import java.util.List; public class Graph { @@ -15,6 +16,11 @@ public class Graph { this.startNodeProperties = startNodeProperties; } + public static Graph emptyGraph() { + return new Graph(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), + Collections.emptyList()); + } + public List<Property> getStartNodeProperties() { return startNodeProperties; } diff --git a/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java b/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java index 4c3051b..b003c84 100644 --- a/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java +++ b/src/main/java/org/onap/aai/graphgraph/dto/NodeName.java @@ -14,4 +14,24 @@ public class NodeName { public void setId(String id) { this.id = id; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + NodeName nodeName = (NodeName) o; + + return id.equals(nodeName.id); + + } + + @Override + public int hashCode() { + return id.hashCode(); + } } diff --git a/src/main/java/org/onap/aai/graphgraph/dto/Property.java b/src/main/java/org/onap/aai/graphgraph/dto/Property.java index 0e0d1d6..cf0774c 100644 --- a/src/main/java/org/onap/aai/graphgraph/dto/Property.java +++ b/src/main/java/org/onap/aai/graphgraph/dto/Property.java @@ -1,6 +1,6 @@ package org.onap.aai.graphgraph.dto; -public class Property { +public class Property implements Comparable<Property>{ private String propertyName; private String propertyValue; @@ -24,4 +24,39 @@ public class Property { public void setPropertyValue(String propertyValue) { this.propertyValue = propertyValue; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Property property = (Property) o; + + if (!propertyName.equals(property.propertyName)) { + return false; + } + return propertyValue.equals(property.propertyValue); + + } + + @Override + public int hashCode() { + int result = propertyName.hashCode(); + result = 31 * result + propertyValue.hashCode(); + return result; + } + + @Override + public int compareTo(Property o) { + if (o.getPropertyName().equals(getPropertyName()) && o.getPropertyValue() != null + && getPropertyValue() != null) { + return getPropertyValue().compareTo(o.getPropertyValue()); + } + + return propertyName.compareTo(o.getPropertyName()); + } } diff --git a/src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java b/src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java new file mode 100644 index 0000000..aef091c --- /dev/null +++ b/src/main/java/org/onap/aai/graphgraph/reader/BasicSchemaReader.java @@ -0,0 +1,391 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph.reader; + +import com.google.common.collect.Multimap; +import java.util.AbstractMap; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.jgrapht.Graph; +import org.jgrapht.GraphPath; +import org.jgrapht.alg.shortestpath.FloydWarshallShortestPaths; +import org.jgrapht.graph.DefaultDirectedGraph; +import org.onap.aai.edges.EdgeIngestor; +import org.onap.aai.edges.EdgeRule; +import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException; +import org.onap.aai.graphgraph.App; +import org.onap.aai.graphgraph.dto.Edge; +import org.onap.aai.graphgraph.dto.NodeName; +import org.onap.aai.graphgraph.dto.Property; +import org.onap.aai.introspection.Introspector; +import org.onap.aai.setup.SchemaVersion; + +public class BasicSchemaReader implements SchemaReader { + + private Map<String, Introspector> allEntities; + Graph<String, MetadataEdge> graph = new DefaultDirectedGraph<>(MetadataEdge.class); + private EdgeIngestor edgeIngestor; + private String version; + + public BasicSchemaReader(String version) { + this.version = version; + } + + private void init() { + if (allEntities != null) { + return; + } + allEntities = App.moxyLoaders.get(getSchemaName()).getAllObjects(); + edgeIngestor = App.edgeIngestor; + graph = createGraph(true, true); + } + + private Graph<String, MetadataEdge> createGraph(boolean withParentChild, boolean withEdgeRules) { + Graph<String, MetadataEdge> graph = new DefaultDirectedGraph<>(MetadataEdge.class); + for (Entry<String, Introspector> currentParent : allEntities.entrySet()) { + graph.addVertex(currentParent.getKey()); + currentParent.getValue().getProperties().stream() + .filter(v -> allEntities.containsKey(v)) + .filter(v -> !currentParent.getKey().equals(v)) + .forEach(v -> { + graph.addVertex(v); + if (withParentChild) { + addParentChildEdge(currentParent.getKey(), v, graph); + } + }); + } + + if (!withEdgeRules) { + return graph; + } + + Multimap<String, EdgeRule> allRules = null; + try { + allRules = edgeIngestor.getAllRules(new SchemaVersion(getSchemaName())); + } catch (EdgeRuleNotFoundException e) { + //TODO fix + } + + allRules.asMap().values().stream().flatMap(e -> e.stream()).forEach(e -> { + switch (e.getDirection()) { + case OUT: + addEdgerule(e.getFrom(), e.getTo(), e.getLabel(), graph); + break; + case IN: + addEdgerule(e.getTo(), e.getFrom(), e.getLabel(), graph); + break; + case BOTH: + addEdgerule(e.getFrom(), e.getTo(), e.getLabel(), graph); + addEdgerule(e.getTo(), e.getFrom(), e.getLabel(), graph); + break; + } + }); + + return graph; + } + + private void addEdgerule(String parent, String child, String label, + Graph<String, MetadataEdge> graph) { + //shortening labels, long edge names are unreadable in the UI + if (label.contains(".")) { + String[] split = label.split("\\."); + label = split[split.length - 1]; + } + graph.addEdge(child, parent, + new MetadataEdge(EdgeType.EDGE_RULE.getTypeName(), child, parent, label)); + } + + private void addParentChildEdge(String parent, String child, Graph<String, MetadataEdge> graph) { + graph.addEdge(parent, child, + new MetadataEdge(EdgeType.PARENT.getTypeName(), parent, child, EdgeType.PARENT.getTypeName())); + graph.addEdge(child, parent, + new MetadataEdge(EdgeType.CHILD.getTypeName(), child, parent, EdgeType.CHILD.getTypeName())); + } + + @Override + public String getSchemaName() { + return version; + } + + @Override + public List<NodeName> getAllVertexNames() { + init(); + + return allEntities.keySet().stream().sorted() + .map(NodeName::new).collect( + Collectors.toList()); + } + + @Override + public List<Property> getVertexProperties(String nodeName) { + init(); + + if (!allEntities.containsKey(nodeName)) { + return Collections.emptyList(); + } + + Stream<Map.Entry<String, String>> incoming = graph.incomingEdgesOf(nodeName).stream() + .filter(e -> e.getType().equals(EdgeType.EDGE_RULE.getTypeName())) + .map(e -> new AbstractMap.SimpleEntry<>(e.getTarget(), e.getLabel())); + Stream<Map.Entry<String, String>> outgoing = graph.outgoingEdgesOf(nodeName).stream() + .map(e -> new AbstractMap.SimpleEntry<>(e.getSource(), e.getLabel())); + + List<Property> neighbours = Stream.concat(incoming, outgoing) + .map(t -> new Property( + String.format("This node is in relationship %s to node %s", t.getValue(), t.getKey()), + String.format("%s/%s", t.getValue(), t.getKey()))) + .distinct() + .sorted() + .collect(Collectors.toList()); + + List<Property> properties = allEntities.get(nodeName).getProperties().stream() + .filter(p -> !allEntities.containsKey(p)) + .map(p -> new Property(p, "")) + .sorted() + .collect(Collectors.toList()); + + properties.addAll(neighbours); + return properties; + } + + @Override + public List<Property> getEdgeProperties(String fromNode, String toNode, String type) { + init(); + if (type.equals(EdgeType.EDGE_RULE.getTypeName())) { + try { + List<EdgeRule> rules = edgeIngestor.getAllRules(new SchemaVersion(getSchemaName())) + .asMap() + .values() + .stream() + .flatMap(Collection::stream) + .filter(identifyEdgeRule(fromNode, toNode)) + .collect(Collectors.toList()); + + Optional<List<Property>> properties = rules.stream().map(this::edgeRuleProperties) + .findFirst(); + return properties.orElse(Collections.emptyList()); + + } catch (EdgeRuleNotFoundException e) { + //TODO fix + } + } + return Collections.emptyList(); + } + + private Predicate<EdgeRule> identifyEdgeRule(String fromNode, String toNode) { + return e -> { + switch (e.getDirection()) { + case OUT: + return e.getFrom().equals(fromNode) && e.getTo().equals(toNode); + case IN: + return e.getFrom().equals(toNode) && e.getTo().equals(fromNode); + case BOTH: + return e.getFrom().equals(toNode) && e.getTo().equals(fromNode) + || e.getFrom().equals(fromNode) && e.getTo().equals(toNode); + default: + return false; + } + }; + } + + private List<Property> edgeRuleProperties(EdgeRule r) { + List<Property> ps = new LinkedList<>(); + ps.add(new Property("Multiplicity", r.getMultiplicityRule().name())); + ps.add(new Property("Is default edge", String.valueOf(r.isDefault()))); + ps.add(new Property("Description", r.getDescription())); + ps.add(new Property("Is private edge", String.valueOf(r.isPrivateEdge()))); + ps.add(new Property("Contains", r.getContains())); + ps.add(new Property("Prevent delete", r.getPreventDelete())); + ps.add(new Property("Label", r.getLabel())); + ps.add(new Property("Delete other v", r.getDeleteOtherV())); + return ps; + } + + @Override + public org.onap.aai.graphgraph.dto.Graph getGraph(String initialNode, int parentHops, + int cousinHops, int childHops, String edgeFilter) { + init(); + + Optional<String> anyVertex = graph.vertexSet().stream().findFirst(); + if (!anyVertex.isPresent()) { + return org.onap.aai.graphgraph.dto.Graph.emptyGraph(); + } + Set<Edge> edges = computeAllEdges(anyVertex.get(), isParentChildFilter(edgeFilter), + isEdgeRulesFilter(edgeFilter)); + + if (!"all".equals(initialNode)) { + Set<String> subGraphVertices = computeNodes(initialNode, parentHops, EdgeType.CHILD.getTypeName()); + subGraphVertices.addAll(computeNodes(initialNode, childHops, EdgeType.PARENT.getTypeName())); + edges = filterEdges(edges, subGraphVertices); + } + + return new org.onap.aai.graphgraph.dto.Graph(new LinkedList<>(computeNodeNames(edges)), + new LinkedList<>(edges), Collections.emptyList(), getVertexProperties(initialNode)); + } + + private boolean isParentChildFilter(String edgeFilter) { + return "Both".equals(edgeFilter) || "Parents".equals(edgeFilter); + } + + private boolean isEdgeRulesFilter(String edgeFilter) { + return "Both".equals(edgeFilter) || "Edgerules".equals(edgeFilter); + } + + private Set<Edge> filterEdgesStrict(Set<Edge> edges, Set<String> subGraphVertices) { + return edges.stream().filter( + e -> subGraphVertices.contains(e.getSource()) && subGraphVertices.contains(e.getTarget())) + .collect( + Collectors.toSet()); + } + + private Set<Edge> filterEdges(Set<Edge> edges, Set<String> subGraphVertices) { + return edges.stream().filter(e -> + subGraphVertices.contains(e.getSource()) || subGraphVertices.contains(e.getTarget())) + .filter(e -> !e.getType().equals(EdgeType.EDGE_RULE.getTypeName())) + .collect(Collectors.toSet()); + } + + private Set<NodeName> computeNodeNames(Set<Edge> edges) { + return edges.stream().flatMap(e -> e.getNodeNames().stream()).collect( + Collectors.toSet()); + } + + private Set<Edge> computeAllEdges(String initial, boolean parentChild, boolean edgeRules) { + Set<Edge> result = new HashSet<>(); + List<String> toQuery = new LinkedList<>(); + toQuery.add(initial); + final List<String> toVisit = new LinkedList<>(); + Set<String> visited = new HashSet<>(); + + while (!toQuery.isEmpty()) { + for (String v : toQuery) { + visited.add(v); + + graph.edgesOf(v).forEach(edge -> { + String neighbour = edge.getTarget(); + toVisit.add(neighbour); + + if (EdgeType.CHILD.isType(edge.getType()) && parentChild) { + result.add(new Edge(neighbour, edge.getSource(), EdgeType.PARENT.getTypeName(), + createTooltip(neighbour, edge.getSource(), EdgeType.PARENT.getTypeName(), edge.getLabel()))); + } + + if (EdgeType.EDGE_RULE.isType(edge.getType()) && edgeRules) { + result.add(new Edge(edge.getSource(), neighbour, edge.getLabel(), + createTooltip(neighbour, edge.getSource(), EdgeType.EDGE_RULE.getTypeName(), + edge.getLabel()))); + } + }); + } + toQuery.clear(); + toQuery.addAll( + toVisit.stream().filter(s -> !visited.contains(s)).collect(Collectors.toList())); + } + + return result; + + } + + private Set<String> computeNodes(String vertex, int hops, String relationshipName) { + List<String> toQuery = new LinkedList<>(); + toQuery.add(vertex); + + Set<String> visited = new HashSet<>(); + int i = 0; + + final List<String> toVisit = new LinkedList<>(); + while (!toQuery.isEmpty() && hops > i) { + i++; + toVisit.clear(); + + for (String v : toQuery) { + visited.add(v); + graph.edgesOf(v).stream().filter(e -> e.getType().equals(relationshipName)).map( + MetadataEdge::getTarget).forEach(toVisit::add); + } + + toQuery.clear(); + toQuery + .addAll(toVisit.stream().filter(v -> !visited.contains(v)).collect(Collectors.toList())); + } + + return visited; + } + + + @Override + public org.onap.aai.graphgraph.dto.Graph getGraph(String fromNode, String toNode, + String edgeFilter) { + init(); + Graph<String, MetadataEdge> tempGraph = createGraph(isParentChildFilter(edgeFilter), isEdgeRulesFilter(edgeFilter)); + List<List<NodeName>> paths = new LinkedList<>(); + FloydWarshallShortestPaths<String, MetadataEdge> shortestPaths; + + while (true) { + shortestPaths = new FloydWarshallShortestPaths<>(tempGraph); + GraphPath<String, MetadataEdge> p = shortestPaths.getPath(fromNode, toNode); + if (p == null || p.getEdgeList() == null || p.getEdgeList().isEmpty()) { + break; + } + String previous = fromNode; + List<NodeName> path = new LinkedList<>(); + for (MetadataEdge e : p.getEdgeList()) { + if (e.getTarget().equals(previous)) { + previous = e.getSource(); + path.add(new NodeName(e.getTarget())); + } else { + previous = e.getTarget(); + path.add(new NodeName(e.getSource())); + } + } + path.add(new NodeName(previous)); + paths.add(path); + tempGraph.removeEdge(p.getEdgeList().get(p.getLength() - 1)); //remove last edge from path + } + + Set<Edge> edges = computeAllEdges(fromNode, isParentChildFilter(edgeFilter), + isEdgeRulesFilter(edgeFilter)); + edges = filterEdgesStrict(edges, + paths.stream().flatMap(Collection::stream).map(NodeName::getId).collect( + Collectors.toSet())); + return new org.onap.aai.graphgraph.dto.Graph(new LinkedList<>(computeNodeNames(edges)), + new LinkedList<>(edges), paths, getVertexProperties(fromNode)); + } + + private List<Property> createTooltip(String target, String v, String type, String label) { + List<Property> properties = new LinkedList<>(); + properties.add(new Property("From", target)); + properties.add(new Property("To", v)); + properties.add(new Property("Type", type)); + properties.add(new Property("Relationship", label)); + properties.addAll(getEdgeProperties(v, target, EdgeType.EDGE_RULE.isType(type) ? EdgeType.EDGE_RULE.getTypeName() : EdgeType.PARENT.getTypeName())); + return properties; + } +} diff --git a/src/main/java/org/onap/aai/graphgraph/reader/DummySchemaReader.java b/src/main/java/org/onap/aai/graphgraph/reader/DummySchemaReader.java deleted file mode 100644 index b8bca38..0000000 --- a/src/main/java/org/onap/aai/graphgraph/reader/DummySchemaReader.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.onap.aai.graphgraph.reader; - -import org.onap.aai.graphgraph.dto.Edge; -import org.onap.aai.graphgraph.dto.Graph; -import org.onap.aai.graphgraph.dto.NodeName; -import org.onap.aai.graphgraph.dto.Property; -import org.xml.sax.SAXException; - -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.util.*; -import java.util.stream.Collectors; - -public class DummySchemaReader implements SchemaReader{ - - @Override - public String getSchemaName() { - return "dummy"; - } - - @Override - public List<NodeName> getAllVertexNames() { - try { - Parser.parse(); - } catch (IOException | ParserConfigurationException | SAXException e) { - e.printStackTrace(); - } - - List<NodeName> names = Parser.getNodes().stream() - .map(NodeName::new).sorted(Comparator.comparing(NodeName::getId)).collect(Collectors.toList()); - return names; - } - - @Override - public List<Property> getVertexProperties(String nodeName) { - return getProperties("node"); - } - - @Override - public List<Property> getEdgeProperties(String fromNode, String toNode) { - return getProperties("edge"); - } - - @Override - public Graph getGraph(String initialNode, int parentHops, int cousingHops, int childHops) { - try { - Parser.parse(); - } catch (IOException | ParserConfigurationException | SAXException e) { - e.printStackTrace(); - } - - List<Edge> edges = new LinkedList<>(); - Parser.getNodes(); - Random rand = new Random(System.currentTimeMillis()); - - for (int i = 0; i < 20; i++) { - int v1 = rand.nextInt(Parser.getNodes().size() - 1); - int v2 = rand.nextInt(Parser.getNodes().size() - 1); - - edges.add(new Edge(Parser.getNodes().get(v1), Parser.getNodes().get(v2), "parent", getProperties("edgeshort"))); - } - - return new Graph( Parser.getNodes().stream().map(NodeName::new).collect(Collectors.toList()), edges, getPaths(), getProperties("node")); - } - - @Override - public Graph getGraph(String fromNode, String toNode) { - return getGraph(fromNode,1,1,1); - } - - - public static List<Property> getProperties(String type) { - List<Property> result = new LinkedList<>(); - - Property p0 = new Property("proptype", type); - Property p1 = new Property("prop1", "test1"); - Property p2 = new Property("prop2", "test2"); - Property p3 = new Property("random", String.valueOf(new Random(System.currentTimeMillis()).nextInt(1000))); - - result.add(p1); - result.add(p2); - result.add(p3); - result.add(p0); - - return result; - } - - private List<List<NodeName>> getPaths() { - List <List<NodeName>> l = new LinkedList<>(); - List <NodeName> l1 = new LinkedList<>(); - List <NodeName> l2 = new LinkedList<>(); - - l1.add(new NodeName("action")); - l1.add(new NodeName("pserver")); - l1.add(new NodeName("vserver")); - l1.add(new NodeName("complex")); - - l2.add(new NodeName("XXaction")); - l2.add(new NodeName("XXaction2")); - l2.add(new NodeName("XXserver")); - l2.add(new NodeName("XXservers")); - - l.add(l1); - l.add(l2); - - return l; - } -} diff --git a/src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java b/src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java new file mode 100644 index 0000000..1250474 --- /dev/null +++ b/src/main/java/org/onap/aai/graphgraph/reader/EdgeType.java @@ -0,0 +1,38 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph.reader; + +public enum EdgeType { + EDGE_RULE("edgerule"), PARENT("parent"), CHILD("child"); + + private final String name; + + EdgeType(String s) { + name = s; + } + + public String getTypeName() { + return this.name; + } + + public boolean isType(String o){ + return name.equals(o); + } +} diff --git a/src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java b/src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java new file mode 100644 index 0000000..fb8e53f --- /dev/null +++ b/src/main/java/org/onap/aai/graphgraph/reader/MetadataEdge.java @@ -0,0 +1,71 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph.reader; + +import org.jgrapht.graph.DefaultEdge; + +public class MetadataEdge extends DefaultEdge { + + private final String type; + private final String target; + private final String source; + private final String label; + + MetadataEdge(String type, String source, String target) { + this.source = source; + this.target = target; + this.type = type; + this.label = ""; + } + + MetadataEdge(String type, String target, String source, String label) { + this.type = type; + this.target = target; + this.source = source; + this.label = label; + } + + public String getLabel() { + return label; + } + + @Override + public String getTarget() { + return target; + } + + @Override + public String getSource() { + return source; + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return "MetadataEdge{" + + "type='" + type + '\'' + + ", target='" + target + '\'' + + ", source='" + source + '\'' + + '}'; + } +} diff --git a/src/main/java/org/onap/aai/graphgraph/reader/Parser.java b/src/main/java/org/onap/aai/graphgraph/reader/Parser.java deleted file mode 100644 index 7db1eb6..0000000 --- a/src/main/java/org/onap/aai/graphgraph/reader/Parser.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.onap.aai.graphgraph.reader; - -import com.tinkerpop.blueprints.Graph; -import com.tinkerpop.blueprints.Vertex; -import com.tinkerpop.blueprints.impls.tg.TinkerGraphFactory; -import org.onap.aai.graphgraph.dto.Edge; -import org.springframework.core.io.ClassPathResource; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.util.*; - -import static org.onap.aai.graphgraph.reader.DummySchemaReader.getProperties; - -public class Parser { - - static Graph g = TinkerGraphFactory.createTinkerGraph(); - static int counter = 10000; - private static List<String> nodeNames = new ArrayList<>(); - static List <Edge> edges = new LinkedList<>(); - - public static List<String> getNodes(){ - Set<String> hs = new HashSet<>(); - hs.addAll(nodeNames); - nodeNames.clear(); - nodeNames.addAll(hs); - return nodeNames; - } - - - public static void parse() throws IOException, SAXException, ParserConfigurationException { - - //File fXmlFile = new File("src/main/resources/aai_schema_v11.xsd"); - File fXmlFile = new ClassPathResource("aai_schema_v11.xsd").getFile(); - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(fXmlFile); - - doc.getDocumentElement().normalize(); - - NodeList elements = doc.getElementsByTagName("xs:element"); - - for (int i = 0; i < elements.getLength(); i++) { - Node node = elements.item(i); - handleNode(node, null); - } - } - - private static boolean isType(Node c) { - String type = c.getAttributes().getNamedItem("type").getNodeValue(); - return type.equals("xs:string") - || type.equals("xs:int") - || type.equals("xs:boolean") - || type.equals("xs:unsignedInt"); - } - - static void handleNode(Node c, Node parent){ - if (c.getNodeName().equals("xs:complexType") || c.getNodeName().equals("xs:sequence")){ - for (int i = 0; i < c.getChildNodes().getLength(); i++) - handleNode(c.getChildNodes().item(i), parent); - return; - } - - if(c.getAttributes() == null) - return; - - if(c.getAttributes().getNamedItem("name") == null && c.getAttributes().getNamedItem("ref") == null) - return; - - if(c.getAttributes().getNamedItem("type") != null) - if(isType(c)) - return; - - String vertexId = determineVertexId(c); - nodeNames.add(vertexId); - - Vertex current; - - if (g.getVertex(vertexId) == null) { - current = g.addVertex(vertexId); - }else - current = g.getVertex(vertexId); - - NodeList childNodes = getChildren(c); - for (int i = 0; i < childNodes.getLength(); i++) - handleNode(childNodes.item(i), c); - - if(parent != null) { - g.addEdge(counter++, g.getVertex(determineVertexId(parent)), current, "parent"); - edges.add(new Edge(g.getVertex(determineVertexId(parent)).getId().toString(), current.getId().toString(), "parent", getProperties("edgeshort"))); - } - - } - - private static NodeList getChildren(Node n) { - NodeList childNodes = n.getChildNodes(); - return childNodes; - } - - private static String determineVertexId(Node n) { - Node nameAttrib = n.getAttributes().getNamedItem("name"); - return nameAttrib != null ? nameAttrib.getNodeValue() : n.getAttributes().getNamedItem("ref").getNodeValue().split(":")[1]; - } - -} diff --git a/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java b/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java index be01e6a..689a30d 100644 --- a/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java +++ b/src/main/java/org/onap/aai/graphgraph/reader/SchemaReader.java @@ -1,3 +1,22 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph.reader; import org.onap.aai.graphgraph.dto.Graph; @@ -10,7 +29,8 @@ public interface SchemaReader { String getSchemaName(); List<NodeName> getAllVertexNames(); List<Property> getVertexProperties(String nodeName); - List<Property> getEdgeProperties(String fromNode, String toNode); - Graph getGraph(String initialNode, int parentHops, int cousingHops, int childHops); - Graph getGraph(String fromNode, String toNode); + List<Property> getEdgeProperties(String fromNode, String toNode, String type); + Graph getGraph(String initialNode, int parentHops, int cousinHops, int childHops, + String edgeFilter); + Graph getGraph(String fromNode, String toNode, String edgeFilter); } diff --git a/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java b/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java index c7fdd33..f49a669 100644 --- a/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java +++ b/src/main/java/org/onap/aai/graphgraph/reader/SchemaRepository.java @@ -1,3 +1,22 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 Orange 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.graphgraph.reader; import java.util.List; |