2 * Copyright (c) 2019 Orange. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.graph.impl;
10 import static com.google.common.base.Preconditions.checkArgument;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.graph.ConnectedEdge;
17 import org.opendaylight.graph.ConnectedGraph;
18 import org.opendaylight.graph.ConnectedVertex;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.Graph;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Edge;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Vertex;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * This Class implements the Connected Graph for path computation algorithms.
35 * @author Olivier Dugeon
36 * @author Philippe Niger
38 public class ConnectedGraphImpl implements ConnectedGraph {
39 private static final Logger LOG = LoggerFactory.getLogger(ConnectedGraphImpl.class);
41 /* List of Connected Vertics that composed this Connected Graph */
42 private final HashMap<Long, ConnectedVertexImpl> vertices = new HashMap<>();
44 /* List of Connected Edges that composed this Connected Graph */
45 private final HashMap<Long, ConnectedEdgeImpl> edges = new HashMap<>();
47 /* List of IP prefix attached to Vertices */
48 private final HashMap<IpPrefix, Prefix> prefixes = new HashMap<>();
50 /* Reference to the non connected Graph stored in DataStore */
53 /* Reference to Graph Model Server to store corresponding graph in DataStore */
54 private final ConnectedGraphServer connectedGraphServer;
56 public ConnectedGraphImpl(final Graph newGraph, final ConnectedGraphServer server) {
57 this.graph = newGraph;
58 createConnectedGraph();
59 this.connectedGraphServer = server;
63 * Transform the associated Graph in a Connected Graph. This method will automatically create associated Connected
64 * Vertices, from the Graph Vertices, Connected Edges, from the Graph Edges and Prefix from the Graph Prefix.
67 private void createConnectedGraph() {
68 if (this.graph == null) {
71 /* Add all vertices */
72 for (Vertex vertex : this.graph.nonnullVertex().values()) {
73 ConnectedVertexImpl cvertex = new ConnectedVertexImpl(vertex);
74 vertices.put(cvertex.getKey(), cvertex);
77 for (Edge edge : this.graph.nonnullEdge().values()) {
78 ConnectedEdgeImpl cedge = new ConnectedEdgeImpl(edge);
79 edges.put(cedge.getKey(), cedge);
81 /* Add all prefixes */
82 for (Prefix prefix : this.graph.nonnullPrefix().values()) {
83 ConnectedVertexImpl cvertex = vertices.get(prefix.getVertexId().longValue());
84 if (cvertex != null) {
85 cvertex.addPrefix(prefix);
87 prefixes.putIfAbsent(prefix.getPrefix(), prefix);
92 * Return Connected Vertex if it exists or create a new one.
94 * @param key Unique Vertex Key identifier
95 * @return new or existing Connected Vertex
97 private ConnectedVertexImpl updateConnectedVertex(final @NonNull Long key) {
98 checkArgument(key != 0, "Provided Vertex Key must not be equal to 0");
99 ConnectedVertexImpl vertex = vertices.get(key);
100 if (vertex == null) {
101 vertex = new ConnectedVertexImpl(key);
102 vertices.put(key, vertex);
108 * Return Connected Edge if it exist or create a new one.
110 * @param key Unique Edge Key identifier
111 * @return new or existing Connected Edge
113 private ConnectedEdgeImpl updateConnectedEdge(final @NonNull Long key) {
114 checkArgument(key != 0, "Provided Edge Key must not be equal to 0");
115 ConnectedEdgeImpl edge = edges.get(key);
117 edge = new ConnectedEdgeImpl(key);
118 edges.put(edge.getKey(), edge);
124 * Connect source and destination Connected Vertices with the given Connected Edge.
126 * @param srcVertex Source Connected Vertex
127 * @param dstVertex Destination Connected Vertex
128 * @param edge Connected Edge
130 private static void connectVertices(final ConnectedVertexImpl srcVertex, final ConnectedVertexImpl dstVertex,
131 final ConnectedEdgeImpl edge) {
133 edge.setSource(srcVertex);
134 edge.setDestination(dstVertex);
136 if (srcVertex != null) {
137 srcVertex.addOutput(edge);
139 if (dstVertex != null) {
140 dstVertex.addInput(edge);
145 public Graph getGraph() {
150 public List<ConnectedVertex> getVertices() {
151 return new ArrayList<>(this.vertices.values());
155 public ConnectedVertex getConnectedVertex(final Long key) {
156 return vertices.get(key);
160 public ConnectedVertex getConnectedVertex(final IpAddress address) {
161 IpPrefix prefix = null;
162 if (address.getIpv4Address() != null) {
163 prefix = new IpPrefix(new Ipv4Prefix(address.getIpv4Address().getValue() + "/32"));
165 if (address.getIpv6Address() != null) {
166 prefix = new IpPrefix(new Ipv6Prefix(address.getIpv6Address().getValue() + "/128"));
168 if (prefix != null && prefixes.containsKey(prefix)) {
169 long key = prefixes.get(prefix).getVertexId().longValue();
170 return vertices.get(key);
177 public int getVerticesSize() {
178 return vertices.size();
182 public List<ConnectedEdge> getEdges() {
183 return new ArrayList<>(this.edges.values());
187 public ConnectedEdge getConnectedEdge(final Long key) {
188 return edges.get(key);
192 public ConnectedEdge getConnectedEdge(final IpAddress address) {
193 for (ConnectedEdge cedge : edges.values()) {
194 if (cedge.getEdge() == null) {
197 if (cedge.getEdge().getEdgeAttributes().getLocalAddress().equals(address)) {
205 public int getEdgesSize() {
210 public List<Prefix> getPrefixes() {
211 return new ArrayList<>(this.prefixes.values());
215 public Prefix getPrefix(final IpPrefix prefix) {
216 return this.prefixes.get(prefix);
220 public ConnectedVertex addVertex(final Vertex vertex) {
221 checkArgument(vertex != null, "Provided Vertex is a null object");
222 ConnectedVertexImpl cvertex = updateConnectedVertex(vertex.getVertexId().longValue());
223 Vertex old = cvertex.getVertex();
224 this.connectedGraphServer.addVertex(this.graph, vertex, old);
225 cvertex.setVertex(vertex);
230 public void deleteVertex(final VertexKey key) {
231 checkArgument(key != null, "Provided Vertex Key is a null object");
232 ConnectedVertexImpl cvertex = vertices.get(key.getVertexId().longValue());
233 if (cvertex != null) {
234 cvertex.disconnect();
235 vertices.remove(cvertex.getKey());
236 this.connectedGraphServer.deleteVertex(this.graph, cvertex.getVertex());
237 cvertex.setVertex(null);
242 public ConnectedEdge addEdge(final Edge edge) {
243 checkArgument(edge != null, "Provided Edge is a null object");
244 ConnectedEdgeImpl cedge = updateConnectedEdge(edge.getEdgeId().longValue());
245 Edge old = cedge.getEdge();
247 ConnectedVertexImpl source = null;
248 ConnectedVertexImpl destination = null;
249 if (edge.getLocalVertexId() != null) {
250 source = updateConnectedVertex(edge.getLocalVertexId().longValue());
252 if (edge.getRemoteVertexId() != null) {
253 destination = updateConnectedVertex(edge.getRemoteVertexId().longValue());
255 connectVertices(source, destination, cedge);
257 this.connectedGraphServer.addEdge(this.graph, edge, old);
263 public void deleteEdge(final EdgeKey key) {
264 checkArgument(key != null, "Provided Edge Key is a null object");
265 ConnectedEdgeImpl cedge = edges.get(key.getEdgeId().longValue());
267 this.connectedGraphServer.deleteEdge(this.graph, cedge.getEdge());
269 edges.remove(cedge.getKey());
275 public void addPrefix(final Prefix prefix) {
276 checkArgument(prefix != null, "Provided Prefix is a null object");
277 ConnectedVertexImpl cvertex = updateConnectedVertex(prefix.getVertexId().longValue());
278 cvertex.addPrefix(prefix);
279 prefixes.putIfAbsent(prefix.getPrefix(), prefix);
280 this.connectedGraphServer.addPrefix(this.graph, prefix);
284 public void deletePrefix(final IpPrefix ippfx) {
285 checkArgument(ippfx != null, "Provided Prefix is a null object");
286 Prefix prefix = prefixes.get(ippfx);
287 if (prefix != null) {
288 ConnectedVertexImpl cvertex = vertices.get(prefix.getVertexId().longValue());
289 if (cvertex != null) {
290 cvertex.removePrefix(prefix);
292 prefixes.remove(prefix.getPrefix());
293 this.connectedGraphServer.deletePrefix(this.graph, prefix);
298 public void clear() {
299 LOG.info("Reset Connected Graph({})", graph.getName());
300 this.vertices.clear();
302 this.prefixes.clear();
303 this.connectedGraphServer.clearGraph(this.graph);
308 public String getSummary() {
309 return vertices.size() + "/" + edges.size() + "/" + prefixes.size();
313 * Returns the name of the associated Graph.
318 public String toString() {
319 return this.graph.getName();