blob: 1674cf05ee03fc77b3280a206424af71d79a3c44 [file] [log] [blame]
Pavlin Radoslavov15954d42013-10-19 15:29:04 -07001package net.onrc.onos.ofcontroller.topology;
2
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -08003import java.util.ArrayList;
Yuta HIGUCHId8c37242014-01-07 11:51:29 -08004import java.util.List;
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -08005import java.util.LinkedList;
Pavlin Radoslavov15954d42013-10-19 15:29:04 -07006import java.util.Map;
Pavlin Radoslavovdf656d62013-10-31 17:24:32 -07007import java.util.TreeMap;
Pavlin Radoslavov15954d42013-10-19 15:29:04 -07008
Yuta HIGUCHId8c37242014-01-07 11:51:29 -08009import net.onrc.onos.graph.DBOperation;
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080010import net.onrc.onos.graph.IDBOperation;
11import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070012import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
13import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
14
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080015import org.apache.commons.lang.StringUtils;
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070016import org.openflow.util.HexString;
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080017import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070019
20import com.tinkerpop.blueprints.Direction;
21import com.tinkerpop.blueprints.Vertex;
22
23/**
24 * A class for storing Node and Link information for fast computation
25 * of shortest paths.
26 */
27class Node {
28 /**
29 * A class for storing Link information for fast computation of shortest
30 * paths.
31 */
32 class Link {
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080033 public Node me; // The node this link originates from
34 public Node neighbor; // The neighbor node on the other side
35 public int myPort; // Local port ID for the link
36 public int neighborPort; // Neighbor port ID for the link
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070037
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080038 /**
39 * Link constructor.
40 *
41 * @param me the node this link originates from.
42 * @param the neighbor node on the other side of the link.
43 * @param myPort local port ID for the link.
44 * @param neighborPort neighbor port ID for the link.
45 */
46 public Link(Node me, Node neighbor, int myPort, int neighborPort) {
47 this.me = me;
48 this.neighbor = neighbor;
49 this.myPort = myPort;
50 this.neighborPort = neighborPort;
51 }
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070052 };
53
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070054 public long nodeId; // The node ID
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080055 // TODO Change type of PortNumber to Short
Pavlin Radoslavovdf656d62013-10-31 17:24:32 -070056 public TreeMap<Integer, Link> links; // The links from this node:
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080057 // (src PortNumber -> Link)
Pavlin Radoslavovdf656d62013-10-31 17:24:32 -070058 private TreeMap<Integer, Link> reverseLinksMap; // The links to this node:
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080059 // (dst PortNumber -> Link)
Pavlin Radoslavovdf656d62013-10-31 17:24:32 -070060 private TreeMap<Integer, Integer> portsMap; // The ports on this node:
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080061 // (PortNumber -> PortNumber)
Pavlin Radoslavovf9161ca2013-10-31 17:08:12 -070062 // TODO: In the future will be:
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -080063 // (PortNumber -> Port)
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070064
65 /**
66 * Node constructor.
67 *
68 * @param nodeId the node ID.
69 */
70 public Node(long nodeId) {
71 this.nodeId = nodeId;
Pavlin Radoslavovdf656d62013-10-31 17:24:32 -070072 links = new TreeMap<Integer, Link>();
73 reverseLinksMap = new TreeMap<Integer, Link>();
74 portsMap = new TreeMap<Integer, Integer>();
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070075 }
76
77 /**
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070078 * Get all ports.
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070079 *
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070080 * @return all ports.
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070081 */
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070082 public Map<Integer, Integer> ports() {
83 return portsMap;
84 }
85
86 /**
87 * Get the port for a given Port ID.
88 *
89 * Note: For now the port itself is just the Port ID. In the future
90 * it might contain more information.
91 *
92 * @return the port if found, otherwise null.
93 */
94 public Integer getPort(int portId) {
Yuta HIGUCHIdbc8c442013-10-31 10:15:37 -070095 return portsMap.get(portId);
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070096 }
97
98 /**
99 * Add a port for a given Port ID.
100 *
101 * Note: For now the port itself is just the Port ID. In the future
102 * it might contain more information.
103 *
104 * @param portId the Port ID of the port to add.
105 * @return the added Port.
106 */
107 Integer addPort(int portId) {
108 Integer port = new Integer(portId);
109 portsMap.put(portId, port);
110 return port;
111 }
112
113 /**
114 * Remove a port for a given Port ID.
115 *
116 * NOTE: The outgoing and incoming links using this port are removed as
117 * well.
118 */
119 void removePort(int portId) {
120 // Remove the outgoing link
121 Link link = getLink(portId);
122 if (link != null) {
123 link.neighbor.removeReverseLink(link);
124 removeLink(portId);
125 }
126
127 // Remove the incoming link
128 Link reverseLink = reverseLinksMap.get(portId);
129 if (reverseLink != null) {
130 // NOTE: reverseLink.myPort is the neighbor's outgoing port
Pavlin Radoslavov823f3222013-11-04 21:57:31 -0800131 reverseLink.me.removeLink(reverseLink.myPort);
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700132 removeReverseLink(reverseLink);
133 }
134
135 portsMap.remove(portId);
136 }
Yuta HIGUCHI63ee5a82013-10-31 10:16:15 -0700137
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700138 /**
139 * Get a link on a port to a neighbor.
140 *
141 * @param myPortId the local port ID for the link to the neighbor.
142 * @return the link if found, otherwise null.
143 */
144 public Link getLink(int myPortId) {
145 return links.get(myPortId);
146 }
147
148 /**
149 * Add a link to a neighbor.
150 *
151 * @param myPortId the local port ID for the link to the neighbor.
152 * @param neighbor the neighbor for the link.
153 * @param neighborPortId the neighbor port ID for the link.
154 * @return the added Link.
155 */
156 public Link addLink(int myPortId, Node neighbor, int neighborPortId) {
157 Link link = new Link(this, neighbor, myPortId, neighborPortId);
158 links.put(myPortId, link);
159 neighbor.addReverseLink(link);
160 return link;
161 }
162
163 /**
164 * Add a reverse link from a neighbor.
165 *
166 * @param link the reverse link from a neighbor to add.
167 */
168 private void addReverseLink(Link link) {
169 // NOTE: link.neghborPort is my port
170 reverseLinksMap.put(link.neighborPort, link);
171 }
172
173 /**
174 * Remove a link to a neighbor.
175 *
176 * @param myPortId the local port ID for the link to the neighbor.
177 */
178 public void removeLink(int myPortId) {
179 links.remove(myPortId);
180 }
181
182 /**
183 * Remove a reverse link from a neighbor.
184 *
185 * @param link the reverse link from a neighbor to remove.
186 */
187 private void removeReverseLink(Link link) {
188 // NOTE: link.neghborPort is my port
189 reverseLinksMap.remove(link.neighborPort);
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700190 }
191};
192
193/**
194 * A class for storing topology information.
195 */
196public class Topology {
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -0800197 private final static Logger log = LoggerFactory.getLogger(Topology.class);
198
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700199 private Map<Long, Node> nodesMap; // The dpid->Node mapping
200
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700201 /**
202 * Default constructor.
203 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700204 public Topology() {
Pavlin Radoslavovdf656d62013-10-31 17:24:32 -0700205 nodesMap = new TreeMap<Long, Node>();
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700206 }
207
208 /**
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700209 * Add a topology element to the topology.
210 *
211 * @param topologyElement the topology element to add.
212 * @return true if the topology was modified, otherwise false.
213 */
214 public boolean addTopologyElement(TopologyElement topologyElement) {
215 boolean isModified = false;
216
217 switch (topologyElement.getType()) {
218 case ELEMENT_SWITCH: {
219 // Add the switch
220 Node node = getNode(topologyElement.getSwitch());
221 if (node == null) {
222 node = addNode(topologyElement.getSwitch());
223 isModified = true;
224 }
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700225 break;
226 }
227 case ELEMENT_PORT: {
228 // Add the switch
229 Node node = getNode(topologyElement.getSwitch());
230 if (node == null) {
231 node = addNode(topologyElement.getSwitch());
232 isModified = true;
233 }
234 // Add the port for the switch
235 Integer port = node.getPort(topologyElement.getSwitchPort());
236 if (port == null) {
237 node.addPort(topologyElement.getSwitchPort());
238 isModified = true;
239 }
240 break;
241 }
242 case ELEMENT_LINK: {
243 // Add the "from" switch
244 Node fromNode = getNode(topologyElement.getFromSwitch());
245 if (fromNode == null) {
246 fromNode = addNode(topologyElement.getFromSwitch());
247 isModified = true;
248 }
249 // Add the "to" switch
250 Node toNode = getNode(topologyElement.getToSwitch());
251 if (toNode == null) {
252 toNode = addNode(topologyElement.getToSwitch());
253 isModified = true;
254 }
255 // Add the "from" port
256 Integer fromPort = fromNode.getPort(topologyElement.getFromPort());
257 if (fromPort == null) {
258 fromNode.addPort(topologyElement.getFromPort());
259 isModified = true;
260 }
261 // Add the "to" port
262 Integer toPort = fromNode.getPort(topologyElement.getToPort());
263 if (toPort == null) {
264 toNode.addPort(topologyElement.getToPort());
265 isModified = true;
266 }
267 Node.Link link = fromNode.getLink(topologyElement.getFromPort());
268 if (link == null) {
269 fromNode.addLink(topologyElement.getFromPort(),
270 toNode,
271 topologyElement.getToPort());
272 isModified = true;
273 }
274
275 break;
276 }
Pavlin Radoslavov4839f6d2013-12-11 12:49:45 -0800277 case ELEMENT_UNKNOWN:
278 // TODO: Adding "assert(false);" here can be dangerous
279 break;
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700280 }
281
282 return isModified;
283 }
284
285 /**
286 * Remove a topology element from the topology.
287 *
288 * @param topologyElement the topology element to remove.
289 * @return true if the topology was modified, otherwise false.
290 */
291 public boolean removeTopologyElement(TopologyElement topologyElement) {
292 boolean isModified = false;
293
294 switch (topologyElement.getType()) {
295 case ELEMENT_SWITCH: {
296 // Remove the switch
297 Node node = getNode(topologyElement.getSwitch());
298 if (node != null) {
299 removeNode(node);
300 isModified = true;
301 }
302 break;
303 }
304 case ELEMENT_PORT: {
305 // Find the switch
306 Node node = getNode(topologyElement.getSwitch());
307 if (node == null)
308 break;
309 // Remove the port for the switch
310 Integer port = node.getPort(topologyElement.getSwitchPort());
311 if (port != null) {
312 node.removePort(topologyElement.getSwitchPort());
313 isModified = true;
314 }
315 break;
316 }
317 case ELEMENT_LINK: {
318 // Find the "from" switch
319 Node fromNode = getNode(topologyElement.getFromSwitch());
320 if (fromNode == null)
321 break;
322 // Remove the link originating from the "from" port
323 Node.Link link = fromNode.getLink(topologyElement.getFromPort());
324 if (link != null) {
325 fromNode.removeLink(topologyElement.getFromPort());
326 isModified = true;
327 }
328 break;
329 }
Pavlin Radoslavov4839f6d2013-12-11 12:49:45 -0800330 case ELEMENT_UNKNOWN:
331 // TODO: Adding "assert(false);" here can be dangerous
332 break;
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700333 }
334
335 return isModified;
336 }
337
338 /**
339 * Get a node for a given Node ID.
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700340 *
341 * @param nodeId the Node ID to use.
342 * @return the corresponding Node if found, otherwise null.
343 */
344 Node getNode(long nodeId) {
345 return nodesMap.get(nodeId);
346 }
347
348 /**
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700349 * Add a node for a given Node ID.
350 *
351 * @param nodeId the Node ID to use.
352 * @return the added Node.
353 */
354 Node addNode(long nodeId) {
355 Node node = new Node(nodeId);
356 nodesMap.put(nodeId, node);
357 return node;
358 }
359
360 /**
361 * Remove an existing node.
362 *
363 * @param node the Node to remove.
364 */
365 void removeNode(Node node) {
366 //
367 // Remove all ports one-by-one. This operation will also remove the
368 // incoming links originating from the neighbors.
369 //
Pavlin Radoslavovcfe7b402013-10-30 19:44:22 -0700370 // NOTE: We have to extract all Port IDs in advance, otherwise we
371 // cannot loop over the Ports collection and remove entries at the
372 // same time.
373 // TODO: If there is a large number of ports, the implementation
374 // below can be sub-optimal. It should be refactored as follows:
375 // 1. Modify removePort() to perform all the cleanup, except
376 // removing the Port entry from the portsMap
377 // 2. Call portsMap.clear() at the end of this method
378 // 3. In all other methods: if removePort() is called somewhere else,
379 // add an explicit removal of the Port entry from the portsMap.
380 //
381 List<Integer> allPortIdKeys = new LinkedList<Integer>();
382 allPortIdKeys.addAll(node.ports().keySet());
383 for (Integer portId : allPortIdKeys)
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700384 node.removePort(portId);
385
386 nodesMap.remove(node.nodeId);
387 }
388
389 /**
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700390 * Read topology state from the database.
391 *
392 * @param dbHandler the Graph Database handler to use.
393 */
yoshitomob292c622013-11-23 14:35:58 -0800394 public void readFromDatabase(DBOperation dbHandler) {
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -0800395 //
396 // Fetch the relevant info from the Switch and Port vertices
397 // from the Titan Graph.
398 //
399 nodesMap.clear();
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700400
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -0800401 // Load all switches into Map
402 Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
403 for (ISwitchObject switchObj : switches) {
404 // Ignore inactive ports
405 if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
406 continue;
407 }
408 Vertex nodeVertex = switchObj.asVertex();
409 //
410 // The Switch info
411 //
412 String nodeDpid = nodeVertex.getProperty("dpid").toString();
413 long nodeId = HexString.toLong(nodeDpid);
414 addNode(nodeId);
415 }
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700416
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -0800417 //
418 // Get All Ports
419 //
420 Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
421 for (IPortObject myPortObj : ports) {
422 Vertex myPortVertex = myPortObj.asVertex();
423
424 // Ignore inactive ports
425 if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
426 continue;
427 }
428
429 short myPort = 0;
430 String idStr = myPortObj.getPortId();
431 String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
432 if (splitter.length != 2) {
433 log.error("Invalid port_id : {}", idStr);
434 continue;
435 }
436 String myDpid = splitter[0];
437 myPort = Short.parseShort(splitter[1]);
438 long myId = HexString.toLong(myDpid);
439 Node me = nodesMap.get(myId);
440
441 if (me == null) {
442 // cannot proceed ports and switches are out of sync
443 //TODO: Restart the whole read
444 continue;
445 }
446
447 if (me.getPort(myPort) == null) {
448 me.addPort(myPort);
449 } else if (me.getLink(myPort) != null) {
450 // Link already added..probably by neighbor
451 continue;
452 }
453
454 //
455 // The neighbor Port info
456 //
457 for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
458// log.debug("state : {}", neighborPortVertex.getProperty("state"));
459// log.debug("port id : {}", neighborPortVertex.getProperty("port_id"));
460 // Ignore inactive ports
461 if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
462 continue;
463 }
464 int neighborPort = 0;
465 idStr = neighborPortVertex.getProperty("port_id").toString();
466 splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
467 if (splitter.length != 2) {
468 log.error("Invalid port_id : {}", idStr);
469 continue;
470 }
471 String neighborDpid = splitter[0];
472 neighborPort = Short.parseShort(splitter[1]);
473 long neighborId = HexString.toLong(neighborDpid);
474 Node neighbor = nodesMap.get(neighborId);
475// log.debug("dpid {},{} port {}", neighborDpid, neighborId, neighborPort);
476 if (neighbor == null) {
477 continue;
478 }
479 me.addLink(myPort, neighbor, neighborPort);
480 }
481 }
482 dbHandler.commit();
483 }
484
485
486 // Only for debug use
487 List<Long> logGetSw = new ArrayList<Long>(100);
488 List<Long> logGetPt = new ArrayList<Long>(100);
489 List<Long> logAddSw = new ArrayList<Long>(100);
490 List<Long> logAddPt = new ArrayList<Long>(100);
491 List<Long> logAddLk = new ArrayList<Long>(100);
492 List<Long> logCommit = new ArrayList<Long>(100);
493 List<Integer> logGetVertices = new ArrayList<Integer>(100);
494 List<Integer> logGetProperty = new ArrayList<Integer>(100);
495 public void readFromDatabaseBreakdown(DBOperation dbHandler) {
496 int getVerticesCount = 0;
497 int getPropertyCount = 0;
498 int getVCount_sw = 0;
499 int getVCount_pt = 0;
500 int getVCount_lk = 0;
501 int getPCount_sw = 0;
502 int getPCount_pt = 0;
503 int getPCount_lk = 0;
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700504
505 //
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -0800506 // Fetch the relevant info from the Switch and Port vertices
507 // from the Titan Graph.
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700508 //
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700509
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -0800510 nodesMap.clear();
511 long t1 = System.nanoTime();
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700512
Yuta HIGUCHI2cef9ba2014-01-09 19:33:22 -0800513 // Load all switches into Map
514 Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
515
516 long t2 = System.nanoTime();
517
518 long t_addSw = 0;
519 for (ISwitchObject switchObj : switches) {
520 long t3 = System.nanoTime();
521 long t4;
522
523 // Ignore inactive ports
524 ++getPropertyCount;
525 ++getPCount_sw;
526 if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
527 t4 = System.nanoTime();
528 t_addSw += t4 - t3;
529 continue;
530 }
531 Vertex nodeVertex = switchObj.asVertex();
532 //
533 // The Switch info
534 //
535 ++getPropertyCount;
536 ++getPCount_sw;
537 String nodeDpid = nodeVertex.getProperty("dpid").toString();
538 long nodeId = HexString.toLong(nodeDpid);
539 addNode(nodeId);
540 t4 = System.nanoTime();
541 t_addSw += t4 - t3;
542 }
543
544 long t5 = System.nanoTime();
545 //
546 // Get All Ports
547 //
548 Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
549
550 long t6 = System.nanoTime();
551 long t_addPort = 0;
552 long t_addLink = 0;
553
554 for (IPortObject myPortObj : ports) {
555 long t7 = System.nanoTime();
556 long t8;
557 Vertex myPortVertex = myPortObj.asVertex();
558
559 // Ignore inactive ports
560 ++getPropertyCount;
561 ++getPCount_pt;
562 if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
563 t8 = System.nanoTime();
564 t_addPort += t8 - t7;
565 continue;
566 }
567
568 short myPort = 0;
569 ++getPropertyCount;
570 ++getPCount_pt;
571 String idStr = myPortObj.getPortId();
572 String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
573 if (splitter.length != 2) {
574 log.error("Invalid port_id : {}", idStr);
575 t8 = System.nanoTime();
576 t_addPort += t8 - t7;
577 continue;
578 }
579 String myDpid = splitter[0];
580 myPort = Short.parseShort(splitter[1]);
581 long myId = HexString.toLong(myDpid);
582 Node me = nodesMap.get(myId);
583
584 if (me == null) {
585 // cannot proceed ports and switches are out of sync
586 //TODO: Restart the whole read
587 t8 = System.nanoTime();
588 t_addPort += t8 - t7;
589 continue;
590 }
591
592 if (me.getPort(myPort) == null) {
593 me.addPort(myPort);
594 } else if (me.getLink(myPort) != null) {
595 // Link already added..probably by neighbor
596 t8 = System.nanoTime();
597 t_addPort += t8 - t7;
598 continue;
599 }
600 t8 = System.nanoTime();
601 t_addPort += t8 - t7;
602
603 //
604 // The neighbor Port info
605 //
606 ++getVerticesCount;
607 ++getVCount_pt;
608 for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
609// log.debug("state : {}", neighborPortVertex.getProperty("state"));
610// log.debug("port id : {}", neighborPortVertex.getProperty("port_id"));
611
612 long t9 = System.nanoTime();
613 long t10;
614
615 // Ignore inactive ports
616 ++getPropertyCount;
617 ++getPCount_lk;
618 if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
619 t10 = System.nanoTime();
620 t_addLink += t10 - t9;
621 continue;
622 }
623 int neighborPort = 0;
624 ++getPropertyCount;
625 ++getPCount_lk;
626 idStr = neighborPortVertex.getProperty("port_id").toString();
627 splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
628 if (splitter.length != 2) {
629 log.error("Invalid port_id : {}", idStr);
630 t10 = System.nanoTime();
631 t_addLink += t10 - t9;
632 continue;
633 }
634 String neighborDpid = splitter[0];
635 neighborPort = Short.parseShort(splitter[1]);
636 long neighborId = HexString.toLong(neighborDpid);
637 Node neighbor = nodesMap.get(neighborId);
638// log.debug("dpid {},{} port {}", neighborDpid, neighborId, neighborPort);
639 if (neighbor == null) {
640 t10 = System.nanoTime();
641 t_addLink += t10 - t9;
642 continue;
643 }
644 me.addLink(myPort, neighbor, neighborPort);
645
646 t10 = System.nanoTime();
647 t_addLink += t10 - t9;
648 }
649 }
650 long t11 = System.nanoTime();
651 dbHandler.commit();
652 long t12 = System.nanoTime();
653
654 logGetSw.add((t2-t1)/1000);
655 logGetPt.add((t6-t5)/1000);
656 logAddSw.add(t_addSw/1000);
657 logAddPt.add(t_addPort/1000);
658 logAddLk.add(t_addLink/1000);
659 logCommit.add((t12-t11)/1000);
660 logGetVertices.add(getVerticesCount);
661 logGetProperty.add(getPropertyCount);
662 log.debug("getVertices[N({}),P({}),L({})] getProperty[N({}),P({}),L({})]",
663 new Object[]{getVCount_sw,getVCount_pt,getVCount_lk,
664 getPCount_sw,getPCount_pt,getPCount_lk});
665 }
666
667 public void printMeasuredLog() {
668 log.debug("getsw: {}", StringUtils.join(logGetSw, ","));
669 log.debug("getpt: {}", StringUtils.join(logGetPt, ","));
670 log.debug("addsw: {}", StringUtils.join(logAddSw, ","));
671 log.debug("addpt: {}", StringUtils.join(logAddPt, ","));
672 log.debug("addlk: {}", StringUtils.join(logAddLk, ","));
673 log.debug("commit: {}", StringUtils.join(logCommit, ","));
674 log.debug("getvertices: {}", StringUtils.join(logGetVertices, ","));
675 log.debug("getproperty: {}", StringUtils.join(logGetProperty, ","));
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700676 }
Yuta HIGUCHId8c37242014-01-07 11:51:29 -0800677
678 // Only for debug use
679 @Override
680 public String toString() {
681 long numNodes = nodesMap.size();
682 long numLinks = 0;
683 for (Map.Entry<Long, Node> entry : nodesMap.entrySet()) {
684 Node n = entry.getValue();
685 for (Map.Entry<Integer, Node.Link> linkEntry : n.links.entrySet()) {
686 if (n.nodeId > linkEntry.getValue().neighbor.nodeId) {
687 ++numLinks;
688 }
689 }
690 }
691 return "Topology has " + numNodes + " Nodes and " + numLinks + " Links.";
692 }
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700693}