blob: cd8f9ad31436b2568648d8d512f82267103cf17f [file] [log] [blame]
HIGUCHI Yuta2d011582013-06-15 01:47:11 -07001package net.onrc.onos.ofcontroller.core.internal;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -08002
Pankaj Berde6debb042013-01-16 18:04:32 -08003import java.util.ArrayList;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -08004import java.util.List;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -08005
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -08006import net.floodlightcontroller.routing.Link;
Pankaj Berde38646d62013-06-21 11:34:04 -07007import net.onrc.onos.graph.GraphDBOperation;
HIGUCHI Yuta2d011582013-06-15 01:47:11 -07008import net.onrc.onos.ofcontroller.core.ILinkStorage;
HIGUCHI Yuta20514902013-06-12 11:24:16 -07009import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
10import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
HIGUCHI Yutaa56fbde2013-06-17 14:26:05 -070011import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080012
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080013import org.openflow.util.HexString;
14import org.slf4j.Logger;
15import org.slf4j.LoggerFactory;
16
Naoki Shiotac57efb82013-06-18 13:40:28 -070017import com.tinkerpop.blueprints.Vertex;
Naoki Shiotac57efb82013-06-18 13:40:28 -070018import com.tinkerpop.pipes.PipeFunction;
19import com.tinkerpop.pipes.transform.PathPipe;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080020
Naoki Shiota1c393ce2013-06-28 22:55:14 -070021/**
Naoki Shiotab2d17e82013-10-18 18:08:16 -070022 * This is the class for storing the information of links into GraphDB
Naoki Shiota1c393ce2013-06-28 22:55:14 -070023 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080024public class LinkStorageImpl implements ILinkStorage {
Pankaj Berde62016142013-04-09 15:35:50 -070025
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070026 protected final static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
Naoki Shiota987a5722013-10-23 11:59:36 -070027 protected GraphDBOperation op;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080028
Naoki Shiotab2d17e82013-10-18 18:08:16 -070029
30 /**
31 * Initialize the object. Open LinkStorage using given configuration file.
32 * @param conf Path (absolute path for now) to configuration file.
33 */
34 @Override
35 public void init(String conf) {
Naoki Shiota987a5722013-10-23 11:59:36 -070036 this.op = new GraphDBOperation(conf);
Naoki Shiotab2d17e82013-10-18 18:08:16 -070037 }
38
Naoki Shiota987a5722013-10-23 11:59:36 -070039 // Method designing policy:
40 // op.commit() and op.rollback() MUST called in public (first-class) methods.
41 // A first-class method MUST NOT call other first-class method.
42 // Routine process should be implemented in private method.
43 // A private method MUST NOT call commit or rollback.
44
45
Naoki Shiota11516712013-06-05 22:36:01 -070046 /**
Naoki Shiota987a5722013-10-23 11:59:36 -070047 * Update a record in the LinkStorage in a way provided by dmop.
Naoki Shiota11516712013-06-05 22:36:01 -070048 * @param link Record of a link to be updated.
Naoki Shiota987a5722013-10-23 11:59:36 -070049 * @param linkinfo Meta-information of a link to be updated.
50 * @param dmop Operation to be done.
Naoki Shiota11516712013-06-05 22:36:01 -070051 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080052 @Override
Naoki Shiota987a5722013-10-23 11:59:36 -070053 public boolean update(Link link, LinkInfo linkinfo, DM_OPERATION dmop) {
54 boolean success = false;
55
56 switch (dmop) {
Naoki Shiotab2d17e82013-10-18 18:08:16 -070057 case CREATE:
58 case INSERT:
Naoki Shiota987a5722013-10-23 11:59:36 -070059 if (link != null) {
60 try {
61 if (addLinkImpl(link)) {
62 op.commit();
63 success = true;
64 }
65 } catch (Exception e) {
66 op.rollback();
67 e.printStackTrace();
68 log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
69 }
70 }
Naoki Shiotab2d17e82013-10-18 18:08:16 -070071 break;
72 case UPDATE:
Naoki Shiota987a5722013-10-23 11:59:36 -070073 if (link != null && linkinfo != null) {
74 try {
75 if (setLinkInfoImpl(link, linkinfo)) {
76 op.commit();
77 success = true;
78 }
79 } catch (Exception e) {
80 op.rollback();
81 e.printStackTrace();
82 log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
83 }
Naoki Shiotab2d17e82013-10-18 18:08:16 -070084 }
85 break;
86 case DELETE:
Naoki Shiota987a5722013-10-23 11:59:36 -070087 if (link != null) {
88 try {
89 if (deleteLinkImpl(link)) {
90 op.commit();
91 success = true;
92 log.debug("LinkStorageImpl:update {} link:{} succeeded", dmop, link);
93 } else {
94 op.rollback();
95 log.debug("LinkStorageImpl:update {} link:{} failed", dmop, link);
96 }
97 } catch (Exception e) {
98 op.rollback();
99 e.printStackTrace();
100 log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
101 }
102 }
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700103 break;
104 }
Naoki Shiota987a5722013-10-23 11:59:36 -0700105
106 return success;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800107 }
108
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700109 @Override
Naoki Shiota987a5722013-10-23 11:59:36 -0700110 public boolean addLink(Link link) {
111 return addLink(link, null);
112 }
113
114 @Override
115 public boolean addLink(Link link, LinkInfo linfo) {
116 boolean success = false;
117
118 try {
119 if (addLinkImpl(link)) {
120 // Set LinkInfo only if linfo is non-null.
121 if (linfo != null && (! setLinkInfoImpl(link, linfo))) {
Jonathan Hart13ccdca2013-10-30 15:23:28 -0700122 log.debug("Adding linkinfo failed: {}", link);
Naoki Shiota987a5722013-10-23 11:59:36 -0700123 op.rollback();
124 }
125 op.commit();
126 success = true;
127 } else {
Jonathan Hart13ccdca2013-10-30 15:23:28 -0700128 // If we fail here that's because the ports aren't added
129 // before we try to add the link
130 log.debug("Adding link failed: {}", link);
Naoki Shiota987a5722013-10-23 11:59:36 -0700131 op.rollback();
132 }
133 } catch (Exception e) {
134 e.printStackTrace();
135 log.error("LinkStorageImpl:addLink link:{} linfo:{} failed", link, linfo);
136 }
137
138 return success;
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700139 }
140
Naoki Shiota11516712013-06-05 22:36:01 -0700141 /**
142 * Update multiple records in the LinkStorage in a way provided by op.
143 * @param links List of records to be updated.
144 * @param op Operation to be done.
145 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800146 @Override
Naoki Shiota987a5722013-10-23 11:59:36 -0700147 public boolean addLinks(List<Link> links) {
148 boolean success = false;
149
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800150 for (Link lt: links) {
Naoki Shiota987a5722013-10-23 11:59:36 -0700151 if (! addLinkImpl(lt)) {
152 return false;
153 }
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700154 }
Naoki Shiota987a5722013-10-23 11:59:36 -0700155
156 try {
157 op.commit();
158 success = true;
159 } catch (Exception e) {
160 e.printStackTrace();
161 log.error("LinkStorageImpl:addLinks link:s{} failed", links);
162 }
163
164 return success;
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700165 }
166
167 /**
Naoki Shiota987a5722013-10-23 11:59:36 -0700168 * Delete a record in the LinkStorage.
169 * @param lt Record to be deleted.
170 */
171 @Override
172 public boolean deleteLink(Link lt) {
173 boolean success = false;
174
175 log.debug("LinkStorageImpl:deleteLink(): {}", lt);
176
177 try {
178 if (deleteLinkImpl(lt)) {
179 op.commit();
180 success = true;
181 log.debug("LinkStorageImpl:deleteLink(): deleted edges {}", lt);
182 } else {
183 op.rollback();
184 log.error("LinkStorageImpl:deleteLink(): failed invalid vertices {}", lt);
185 }
186 } catch (Exception e) {
187 op.rollback();
188 log.error("LinkStorageImpl:deleteLink(): failed {} {}",
189 new Object[]{lt, e.toString()});
190 e.printStackTrace();
191 }
192
193 return success;
194 }
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700195
196 /**
197 * Delete multiple records in LinkStorage.
198 * @param links List of records to be deleted.
199 */
200 @Override
Naoki Shiota987a5722013-10-23 11:59:36 -0700201 public boolean deleteLinks(List<Link> links) {
202 boolean success = false;
203
204 try {
205 for (Link lt : links) {
206 if (! deleteLinkImpl(lt)) {
207 op.rollback();
208 return false;
209 }
210 }
211 op.commit();
212 success = true;
213 } catch (Exception e) {
214 op.rollback();
215 e.printStackTrace();
216 log.error("LinkStorageImpl:deleteLinks failed invalid vertices {}", links);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800217 }
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700218
Naoki Shiota987a5722013-10-23 11:59:36 -0700219 return success;
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700220 }
221
Naoki Shiota11516712013-06-05 22:36:01 -0700222 /**
Naoki Shiota11516712013-06-05 22:36:01 -0700223 * Get list of all links connected to the port specified by given DPID and port number.
224 * @param dpid DPID of desired port.
225 * @param port Port number of desired port.
226 * @return List of links. Empty list if no port was found.
227 */
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800228 @Override
229 public List<Link> getLinks(Long dpid, short port) {
Naoki Shiota93ec1712013-06-13 15:49:36 -0700230 List<Link> links = new ArrayList<Link>();
231
Naoki Shiota987a5722013-10-23 11:59:36 -0700232 IPortObject srcPort = op.searchPort(HexString.toHexString(dpid), port);
Naoki Shiota93ec1712013-06-13 15:49:36 -0700233 ISwitchObject srcSw = srcPort.getSwitch();
234
Pankaj Berdee7c21522013-08-01 16:52:29 -0700235 if(srcSw != null && srcPort != null) {
Naoki Shiota93ec1712013-06-13 15:49:36 -0700236 for(IPortObject dstPort : srcPort.getLinkedPorts()) {
237 ISwitchObject dstSw = dstPort.getSwitch();
Pavlin Radoslavov43781cd2013-11-04 18:19:10 -0800238 if (dstSw != null) {
239 Link link = new Link(HexString.toLong(srcSw.getDPID()),
240 srcPort.getNumber(),
241 HexString.toLong(dstSw.getDPID()),
242 dstPort.getNumber());
243 links.add(link);
244 }
245 }
246 }
247
248 return links;
249 }
250
251 /**
252 * Get list of all reverse links connected to the port specified by given DPID and port number.
253 * @param dpid DPID of desired port.
254 * @param port Port number of desired port.
255 * @return List of reverse links. Empty list if no port was found.
256 */
257 @Override
258 public List<Link> getReverseLinks(Long dpid, short port) {
259 List<Link> links = new ArrayList<Link>();
260
261 IPortObject srcPort = op.searchPort(HexString.toHexString(dpid), port);
262 ISwitchObject srcSw = srcPort.getSwitch();
263
264 if(srcSw != null && srcPort != null) {
265 for(IPortObject dstPort : srcPort.getReverseLinkedPorts()) {
266 ISwitchObject dstSw = dstPort.getSwitch();
267 if (dstSw != null) {
268 Link link = new Link(HexString.toLong(dstSw.getDPID()),
269 dstPort.getNumber(),
270 HexString.toLong(srcSw.getDPID()),
271 srcPort.getNumber());
272 links.add(link);
273 }
Naoki Shiota93ec1712013-06-13 15:49:36 -0700274 }
275 }
276
mininet403d5892013-06-05 03:48:17 -0700277 return links;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800278 }
279
Naoki Shiota11516712013-06-05 22:36:01 -0700280 /**
Naoki Shiota11516712013-06-05 22:36:01 -0700281 * Delete records of the links connected to the port specified by given DPID and port number.
282 * @param dpid DPID of desired port.
283 * @param port Port number of desired port.
284 */
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800285 @Override
Naoki Shiota987a5722013-10-23 11:59:36 -0700286 public boolean deleteLinksOnPort(Long dpid, short port) {
287 boolean success = false;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800288
Naoki Shiota987a5722013-10-23 11:59:36 -0700289 List<Link> linksToDelete = getLinks(dpid, port);
290 try {
291 for(Link l : linksToDelete) {
292 if (! deleteLinkImpl(l)) {
293 op.rollback();
294 log.error("LinkStorageImpl:deleteLinksOnPort dpid:{} port:{} failed", dpid, port);
295 return false;
296 }
297 }
298 op.commit();
299 success = true;
300 } catch (Exception e) {
301 op.rollback();
302 e.printStackTrace();
303 log.error("LinkStorageImpl:deleteLinksOnPort dpid:{} port:{} failed", dpid, port);
mininet403d5892013-06-05 03:48:17 -0700304 }
Naoki Shiota987a5722013-10-23 11:59:36 -0700305
306 return success;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800307 }
308
Naoki Shiota11516712013-06-05 22:36:01 -0700309 /**
310 * Get list of all links connected to the switch specified by given DPID.
311 * @param dpid DPID of desired switch.
312 * @return List of links. Empty list if no port was found.
313 */
Pankaj Berdeff421802013-01-29 20:28:52 -0800314 @Override
315 public List<Link> getLinks(String dpid) {
mininet403d5892013-06-05 03:48:17 -0700316 List<Link> links = new ArrayList<Link>();
317
Naoki Shiota987a5722013-10-23 11:59:36 -0700318 ISwitchObject srcSw = op.searchSwitch(dpid);
Naoki Shiota93ec1712013-06-13 15:49:36 -0700319
320 if(srcSw != null) {
321 for(IPortObject srcPort : srcSw.getPorts()) {
322 for(IPortObject dstPort : srcPort.getLinkedPorts()) {
323 ISwitchObject dstSw = dstPort.getSwitch();
324 if(dstSw != null) {
325 Link link = new Link(HexString.toLong(srcSw.getDPID()),
326 srcPort.getNumber(),
327 HexString.toLong(dstSw.getDPID()),
328 dstPort.getNumber());
329 links.add(link);
330 }
331 }
332 }
333 }
334
mininet403d5892013-06-05 03:48:17 -0700335 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800336 }
337
Naoki Shiota11516712013-06-05 22:36:01 -0700338 /**
Pavlin Radoslavovc934b4a2013-11-02 14:53:52 -0700339 * Get list of all reverse links connected to the switch specified by
340 * given DPID.
341 * @param dpid DPID of desired switch.
342 * @return List of reverse links. Empty list if no port was found.
343 */
344 @Override
345 public List<Link> getReverseLinks(String dpid) {
346 List<Link> links = new ArrayList<Link>();
347
348 ISwitchObject srcSw = op.searchSwitch(dpid);
349
350 if(srcSw != null) {
351 for(IPortObject srcPort : srcSw.getPorts()) {
352 for(IPortObject dstPort : srcPort.getReverseLinkedPorts()) {
353 ISwitchObject dstSw = dstPort.getSwitch();
354 if(dstSw != null) {
355 Link link = new Link(
356 HexString.toLong(dstSw.getDPID()),
357 dstPort.getNumber(),
358
359 HexString.toLong(srcSw.getDPID()),
360 srcPort.getNumber());
361 links.add(link);
362 }
363 }
364 }
365 }
366
367 return links;
368 }
369
370 /**
Naoki Shiota11516712013-06-05 22:36:01 -0700371 * Get list of all links whose state is ACTIVE.
372 * @return List of active links. Empty list if no port was found.
373 */
Pankaj Berdeff421802013-01-29 20:28:52 -0800374 public List<Link> getActiveLinks() {
Naoki Shiota987a5722013-10-23 11:59:36 -0700375 Iterable<ISwitchObject> switches = op.getActiveSwitches();
Pankaj Berde5024ec12013-01-31 17:07:29 -0800376
377 List<Link> links = new ArrayList<Link>();
Naoki Shiota826e84a2013-06-18 13:13:25 -0700378
379 for (ISwitchObject srcSw : switches) {
380 for(IPortObject srcPort : srcSw.getPorts()) {
381 for(IPortObject dstPort : srcPort.getLinkedPorts()) {
382 ISwitchObject dstSw = dstPort.getSwitch();
Pankaj Berde5024ec12013-01-31 17:07:29 -0800383
Naoki Shiota826e84a2013-06-18 13:13:25 -0700384 if(dstSw != null && dstSw.getState().equals("ACTIVE")) {
385 links.add(new Link(HexString.toLong(srcSw.getDPID()),
386 srcPort.getNumber(),
387 HexString.toLong(dstSw.getDPID()),
388 dstPort.getNumber()));
389 }
390 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800391 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800392 }
Naoki Shiota826e84a2013-06-18 13:13:25 -0700393
Pankaj Berde5024ec12013-01-31 17:07:29 -0800394 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800395 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800396
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700397 @Override
398 public LinkInfo getLinkInfo(Link link) {
399 // TODO implement this
400 return null;
401 }
402
403 /**
404 * Finalize the object.
405 */
406 public void finalize() {
407 close();
408 }
409
410 /**
411 * Close LinkStorage.
412 */
413 @Override
414 public void close() {
415 // TODO Auto-generated method stub
416// graph.shutdown();
417 }
418
Naoki Shiota987a5722013-10-23 11:59:36 -0700419 /**
420 * Update a record of link with meta-information in the LinkStorage.
421 * @param link Record of a link to update.
422 * @param linkinfo Meta-information of a link to be updated.
423 */
424 private boolean setLinkInfoImpl(Link link, LinkInfo linkinfo) {
425 // TODO implement this
426
427 return false;
428 }
429
430 private boolean addLinkImpl(Link lt) {
431 boolean success = false;
432
433 IPortObject vportSrc = null, vportDst = null;
434
435 // get source port vertex
436 String dpid = HexString.toHexString(lt.getSrc());
437 short port = lt.getSrcPort();
438 vportSrc = op.searchPort(dpid, port);
439
440 // get dest port vertex
441 dpid = HexString.toHexString(lt.getDst());
442 port = lt.getDstPort();
443 vportDst = op.searchPort(dpid, port);
444
445 if (vportSrc != null && vportDst != null) {
446 IPortObject portExist = null;
447 // check if the link exists
448 for (IPortObject V : vportSrc.getLinkedPorts()) {
449 if (V.equals(vportDst)) {
450 portExist = V;
451 break;
452 }
453 }
454
455 if (portExist == null) {
456 vportSrc.setLinkPort(vportDst);
457 success = true;
458 } else {
459 log.debug("LinkStorageImpl:addLinkImpl failed link exists {} {} src {} dst {}",
460 new Object[]{op, lt, vportSrc, vportDst});
461 }
462 }
463
464 return success;
465 }
466
467 private boolean deleteLinkImpl(Link lt) {
468 boolean success = false;
469 IPortObject vportSrc = null, vportDst = null;
470
471 // get source port vertex
472 String dpid = HexString.toHexString(lt.getSrc());
473 short port = lt.getSrcPort();
474 vportSrc = op.searchPort(dpid, port);
475
476 // get dst port vertex
477 dpid = HexString.toHexString(lt.getDst());
478 port = lt.getDstPort();
479 vportDst = op.searchPort(dpid, port);
480
481 // FIXME: This needs to remove all edges
482 if (vportSrc != null && vportDst != null) {
483 vportSrc.removeLink(vportDst);
484 log.debug("deleteLinkImpl(): deleted edges src {} dst {}", new Object[]{
485 lt, vportSrc, vportDst});
486 success = true;
487 }
488
489 return success;
490 }
491
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700492 // TODO should be moved to TopoLinkServiceImpl (never used in this class)
HIGUCHI Yutaf05c4802013-06-17 11:15:50 -0700493 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
Naoki Shiotac57efb82013-06-18 13:40:28 -0700494
Yuta HIGUCHI57e67f22013-10-14 10:21:05 -0700495 @SuppressWarnings("unchecked")
Naoki Shiotac57efb82013-06-18 13:40:28 -0700496 @Override
497 public Link compute(PathPipe<Vertex> pipe ) {
Naoki Shiotac57efb82013-06-18 13:40:28 -0700498 long s_dpid = 0;
499 long d_dpid = 0;
500 short s_port = 0;
501 short d_port = 0;
502 List<Vertex> V = new ArrayList<Vertex>();
Yuta HIGUCHI57e67f22013-10-14 10:21:05 -0700503 V = (List<Vertex>)pipe.next();
Naoki Shiotac57efb82013-06-18 13:40:28 -0700504 Vertex src_sw = V.get(0);
505 Vertex dest_sw = V.get(3);
506 Vertex src_port = V.get(1);
507 Vertex dest_port = V.get(2);
508 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
509 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
510 s_port = (Short) src_port.getProperty("number");
511 d_port = (Short) dest_port.getProperty("number");
512
513 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
514
515 return l;
516 }
517 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800518
Pankaj Berdeff421802013-01-29 20:28:52 -0800519
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800520}