Update MRI projects for Aluminium
[bgpcep.git] / graph / graph-impl / src / main / java / org / opendaylight / graph / impl / ConnectedGraphImpl.java
1 /*
2  * Copyright (c) 2019 Orange. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.graph.impl;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11
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;
31
32 /**
33  * This Class implements the Connected Graph for path computation algorithms.
34  *
35  * @author Olivier Dugeon
36  * @author Philippe Niger
37  */
38 public class ConnectedGraphImpl implements ConnectedGraph {
39     private static final Logger LOG = LoggerFactory.getLogger(ConnectedGraphImpl.class);
40
41     /* List of Connected Vertics that composed this Connected Graph */
42     private final HashMap<Long, ConnectedVertexImpl> vertices = new HashMap<>();
43
44     /* List of Connected Edges that composed this Connected Graph */
45     private final HashMap<Long, ConnectedEdgeImpl> edges = new HashMap<>();
46
47     /* List of IP prefix attached to Vertices */
48     private final HashMap<IpPrefix, Prefix> prefixes = new HashMap<>();
49
50     /* Reference to the non connected Graph stored in DataStore */
51     private Graph graph;
52
53     /* Reference to Graph Model Server to store corresponding graph in DataStore */
54     private final ConnectedGraphServer connectedGraphServer;
55
56     public ConnectedGraphImpl(final Graph newGraph, final ConnectedGraphServer server) {
57         this.graph = newGraph;
58         createConnectedGraph();
59         this.connectedGraphServer = server;
60     }
61
62     /**
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.
65      *
66      */
67     private void createConnectedGraph() {
68         if (this.graph == null) {
69             return;
70         }
71         /* Add all vertices */
72         for (Vertex vertex : this.graph.nonnullVertex().values()) {
73             ConnectedVertexImpl cvertex = new ConnectedVertexImpl(vertex);
74             vertices.put(cvertex.getKey(), cvertex);
75         }
76         /* Add all edges */
77         for (Edge edge : this.graph.nonnullEdge().values()) {
78             ConnectedEdgeImpl cedge = new ConnectedEdgeImpl(edge);
79             edges.put(cedge.getKey(), cedge);
80         }
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);
86             }
87             prefixes.putIfAbsent(prefix.getPrefix(), prefix);
88         }
89     }
90
91     /**
92      * Return Connected Vertex if it exists or create a new one.
93      *
94      * @param  key   Unique Vertex Key identifier
95      * @return new or existing Connected Vertex
96      */
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);
103         }
104         return vertex;
105     }
106
107     /**
108      * Return Connected Edge if it exist or create a new one.
109      *
110      * @param key   Unique Edge Key identifier
111      * @return new or existing Connected Edge
112      */
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);
116         if (edge == null) {
117             edge = new ConnectedEdgeImpl(key);
118             edges.put(edge.getKey(), edge);
119         }
120         return edge;
121     }
122
123     /**
124      * Connect source and destination Connected Vertices with the given Connected Edge.
125      *
126      * @param srcVertex Source Connected Vertex
127      * @param dstVertex Destination Connected Vertex
128      * @param edge      Connected Edge
129      */
130     private static void connectVertices(final ConnectedVertexImpl srcVertex, final ConnectedVertexImpl dstVertex,
131             final ConnectedEdgeImpl edge) {
132         if (edge != null) {
133             edge.setSource(srcVertex);
134             edge.setDestination(dstVertex);
135         }
136         if (srcVertex != null) {
137             srcVertex.addOutput(edge);
138         }
139         if (dstVertex != null) {
140             dstVertex.addInput(edge);
141         }
142     }
143
144     @Override
145     public Graph getGraph() {
146         return this.graph;
147     }
148
149     @Override
150     public List<ConnectedVertex> getVertices() {
151         return new ArrayList<>(this.vertices.values());
152     }
153
154     @Override
155     public ConnectedVertex getConnectedVertex(final Long key) {
156         return vertices.get(key);
157     }
158
159     @Override
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"));
164         }
165         if (address.getIpv6Address() != null) {
166             prefix = new IpPrefix(new Ipv6Prefix(address.getIpv6Address().getValue() + "/128"));
167         }
168         if (prefix != null && prefixes.containsKey(prefix)) {
169             long key = prefixes.get(prefix).getVertexId().longValue();
170             return vertices.get(key);
171         } else {
172             return null;
173         }
174     }
175
176     @Override
177     public int getVerticesSize() {
178         return vertices.size();
179     }
180
181     @Override
182     public List<ConnectedEdge> getEdges() {
183         return new ArrayList<>(this.edges.values());
184     }
185
186     @Override
187     public ConnectedEdge getConnectedEdge(final Long key) {
188         return edges.get(key);
189     }
190
191     @Override
192     public ConnectedEdge getConnectedEdge(final IpAddress address) {
193         for (ConnectedEdge cedge : edges.values()) {
194             if (cedge.getEdge() == null) {
195                 continue;
196             }
197             if (cedge.getEdge().getEdgeAttributes().getLocalAddress().equals(address)) {
198                 return cedge;
199             }
200         }
201         return null;
202     }
203
204     @Override
205     public int getEdgesSize() {
206         return edges.size();
207     }
208
209     @Override
210     public List<Prefix> getPrefixes() {
211         return new ArrayList<>(this.prefixes.values());
212     }
213
214     @Override
215     public Prefix getPrefix(final IpPrefix prefix) {
216         return this.prefixes.get(prefix);
217     }
218
219     @Override
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);
226         return cvertex;
227     }
228
229     @Override
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);
238         }
239     }
240
241     @Override
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();
246         if (old == null) {
247             ConnectedVertexImpl source = null;
248             ConnectedVertexImpl destination = null;
249             if (edge.getLocalVertexId() != null) {
250                 source = updateConnectedVertex(edge.getLocalVertexId().longValue());
251             }
252             if (edge.getRemoteVertexId() != null) {
253                 destination = updateConnectedVertex(edge.getRemoteVertexId().longValue());
254             }
255             connectVertices(source, destination, cedge);
256         }
257         this.connectedGraphServer.addEdge(this.graph, edge, old);
258         cedge.setEdge(edge);
259         return cedge;
260     }
261
262     @Override
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());
266         if (cedge != null) {
267             this.connectedGraphServer.deleteEdge(this.graph, cedge.getEdge());
268             cedge.disconnect();
269             edges.remove(cedge.getKey());
270             cedge.setEdge(null);
271         }
272     }
273
274     @Override
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);
281     }
282
283     @Override
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);
291             }
292             prefixes.remove(prefix.getPrefix());
293             this.connectedGraphServer.deletePrefix(this.graph, prefix);
294         }
295     }
296
297     @Override
298     public void clear() {
299         LOG.info("Reset Connected Graph({})", graph.getName());
300         this.vertices.clear();
301         this.edges.clear();
302         this.prefixes.clear();
303         this.connectedGraphServer.clearGraph(this.graph);
304         this.graph = null;
305     }
306
307     @Override
308     public String getSummary() {
309         return vertices.size() + "/" + edges.size() + "/" + prefixes.size();
310     }
311
312     /**
313      * Returns the name of the associated Graph.
314      *
315      * @return Graph name
316      */
317     @Override
318     public String toString() {
319         return this.graph.getName();
320     }
321 }