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
9 package org.opendaylight.graph.impl;
11 import static com.google.common.base.Preconditions.checkArgument;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.graph.ConnectedEdge;
18 import org.opendaylight.graph.ConnectedGraph;
19 import org.opendaylight.graph.ConnectedVertex;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.Graph;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Edge;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Vertex;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * This Class implements the Connected Graph for path computation algorithms.
36 * @author Olivier Dugeon
37 * @author Philippe Niger
41 public class ConnectedGraphImpl implements ConnectedGraph {
43 private static final Logger LOG = LoggerFactory.getLogger(ConnectedGraphImpl.class);
45 /* List of Connected Vertics that composed this Connected Graph */
46 private final HashMap<Long, ConnectedVertexImpl> vertices = new HashMap<>();
48 /* List of Connected Edges that composed this Connected Graph */
49 private final HashMap<Long, ConnectedEdgeImpl> edges = new HashMap<>();
51 /* List of IP prefix attached to Vertices */
52 private final HashMap<IpPrefix, Prefix> prefixes = new HashMap<>();
54 /* Reference to the non connected Graph stored in DataStore */
57 /* Reference to Graph Model Server to store corresponding graph in DataStore */
58 private final ConnectedGraphServer connectedGraphServer;
60 public ConnectedGraphImpl(Graph newGraph, ConnectedGraphServer server) {
61 this.graph = newGraph;
62 createConnectedGraph();
63 this.connectedGraphServer = server;
67 * Transform the associated Graph in a Connected Graph. This method will automatically create associated Connected
68 * Vertices, from the Graph Vertices, Connected Edges, from the Graph Edges and Prefix from the Graph Prefix.
71 private void createConnectedGraph() {
72 if (this.graph == null) {
75 /* Add all vertices */
76 if (this.graph.getVertex() != null) {
77 for (Vertex vertex : this.graph.getVertex()) {
78 ConnectedVertexImpl cvertex = new ConnectedVertexImpl(vertex);
79 vertices.put(cvertex.getKey(), cvertex);
83 if (this.graph.getEdge() != null) {
84 for (Edge edge : this.graph.getEdge()) {
85 ConnectedEdgeImpl cedge = new ConnectedEdgeImpl(edge);
86 edges.put(cedge.getKey(), cedge);
89 /* Add all prefixes */
90 if (this.graph.getPrefix() != null) {
91 for (Prefix prefix : this.graph.getPrefix()) {
92 ConnectedVertexImpl cvertex = vertices.get(prefix.getVertexId().longValue());
93 if (cvertex != null) {
94 cvertex.addPrefix(prefix);
96 prefixes.putIfAbsent(prefix.getPrefix(), prefix);
102 * Return Connected Vertex if it exists or create a new one.
104 * @param key Unique Vertex Key identifier
105 * @return new or existing Connected Vertex
107 private ConnectedVertexImpl updateConnectedVertex(@NonNull Long key) {
108 checkArgument(key != 0, "Provided Vertex Key must not be equal to 0");
109 ConnectedVertexImpl vertex = vertices.get(key);
110 if (vertex == null) {
111 vertex = new ConnectedVertexImpl(key);
112 vertices.put(key, vertex);
118 * Return Connected Edge if it exist or create a new one.
120 * @param key Unique Edge Key identifier
121 * @return new or existing Connected Edge
123 private ConnectedEdgeImpl updateConnectedEdge(@NonNull Long key) {
124 checkArgument(key != 0, "Provided Edge Key must not be equal to 0");
125 ConnectedEdgeImpl edge = edges.get(key);
127 edge = new ConnectedEdgeImpl(key);
128 edges.put(edge.getKey(), edge);
134 * Connect source and destination Connected Vertices with the given Connected Edge.
136 * @param srcVertex Source Connected Vertex
137 * @param dstVertex Destination Connected Vertex
138 * @param edge Connected Edge
140 private void connectVertices(ConnectedVertexImpl srcVertex, ConnectedVertexImpl dstVertex, ConnectedEdgeImpl edge) {
142 edge.setSource(srcVertex);
143 edge.setDestination(dstVertex);
145 if (srcVertex != null) {
146 srcVertex.addOutput(edge);
148 if (dstVertex != null) {
149 dstVertex.addInput(edge);
154 public Graph getGraph() {
159 public List<ConnectedVertex> getVertices() {
160 return new ArrayList<ConnectedVertex>(this.vertices.values());
164 public ConnectedVertex getConnectedVertex(@NonNull Long key) {
165 return vertices.get(key);
169 public ConnectedVertex getConnectedVertex(IpAddress address) {
170 IpPrefix prefix = null;
171 if (address.getIpv4Address() != null) {
172 prefix = new IpPrefix(new Ipv4Prefix(address.getIpv4Address().getValue() + "/32"));
174 if (address.getIpv6Address() != null) {
175 prefix = new IpPrefix(new Ipv6Prefix(address.getIpv6Address().getValue() + "/128"));
177 if (prefix != null && prefixes.containsKey(prefix)) {
178 long key = prefixes.get(prefix).getVertexId().longValue();
179 return vertices.get(key);
186 public int getVerticesSize() {
187 return vertices.size();
191 public List<ConnectedEdge> getEdges() {
192 return new ArrayList<ConnectedEdge>(this.edges.values());
196 public ConnectedEdge getConnectedEdge(@NonNull Long key) {
197 return edges.get(key);
201 public ConnectedEdge getConnectedEdge(IpAddress address) {
202 for (ConnectedEdge cedge : edges.values()) {
203 if (cedge.getEdge() == null) {
206 if (cedge.getEdge().getEdgeAttributes().getLocalAddress().equals(address)) {
214 public int getEdgesSize() {
219 public List<Prefix> getPrefixes() {
220 return new ArrayList<Prefix>(this.prefixes.values());
224 public Prefix getPrefix(IpPrefix prefix) {
225 return this.prefixes.get(prefix);
229 public ConnectedVertex addVertex(Vertex vertex) {
230 checkArgument(vertex != null, "Provided Vertex is a null object");
231 ConnectedVertexImpl cvertex = updateConnectedVertex(vertex.getVertexId().longValue());
232 Vertex old = cvertex.getVertex();
233 this.connectedGraphServer.addVertex(this.graph, vertex, old);
234 cvertex.setVertex(vertex);
239 public void deleteVertex(VertexKey key) {
240 checkArgument(key != null, "Provided Vertex Key is a null object");
241 ConnectedVertexImpl cvertex = vertices.get(key.getVertexId().longValue());
242 if (cvertex != null) {
243 cvertex.disconnect();
244 vertices.remove(cvertex.getKey());
245 this.connectedGraphServer.deleteVertex(this.graph, cvertex.getVertex());
246 cvertex.setVertex(null);
251 public ConnectedEdge addEdge(Edge edge) {
252 checkArgument(edge != null, "Provided Edge is a null object");
253 ConnectedEdgeImpl cedge = updateConnectedEdge(edge.getEdgeId().longValue());
254 Edge old = cedge.getEdge();
256 ConnectedVertexImpl source = null;
257 ConnectedVertexImpl destination = null;
258 if (edge.getLocalVertexId() != null) {
259 source = updateConnectedVertex(edge.getLocalVertexId().longValue());
261 if (edge.getRemoteVertexId() != null) {
262 destination = updateConnectedVertex(edge.getRemoteVertexId().longValue());
264 connectVertices(source, destination, cedge);
266 this.connectedGraphServer.addEdge(this.graph, edge, old);
272 public void deleteEdge(EdgeKey key) {
273 checkArgument(key != null, "Provided Edge Key is a null object");
274 ConnectedEdgeImpl cedge = edges.get(key.getEdgeId().longValue());
276 this.connectedGraphServer.deleteEdge(this.graph, cedge.getEdge());
278 edges.remove(cedge.getKey());
284 public void addPrefix(Prefix prefix) {
285 checkArgument(prefix != null, "Provided Prefix is a null object");
286 ConnectedVertexImpl cvertex = updateConnectedVertex(prefix.getVertexId().longValue());
287 cvertex.addPrefix(prefix);
288 prefixes.putIfAbsent(prefix.getPrefix(), prefix);
289 this.connectedGraphServer.addPrefix(this.graph, prefix);
293 public void deletePrefix(IpPrefix ippfx) {
294 checkArgument(ippfx != null, "Provided Prefix is a null object");
295 Prefix prefix = prefixes.get(ippfx);
296 if (prefix != null) {
297 ConnectedVertexImpl cvertex = vertices.get(prefix.getVertexId().longValue());
298 if (cvertex != null) {
299 cvertex.removePrefix(prefix);
301 prefixes.remove(prefix.getPrefix());
302 this.connectedGraphServer.deletePrefix(this.graph, prefix);
307 public void clear() {
308 LOG.info("Reset Connected Graph({})", graph.getName());
309 this.vertices.clear();
311 this.prefixes.clear();
312 this.connectedGraphServer.clearGraph(this.graph);
317 public String getSummary() {
318 return vertices.size() + "/" + edges.size() + "/" + prefixes.size();
322 * Returns the name of the associated Graph.
327 public String toString() {
328 return this.graph.getName();