blob: 81e2ce877ec96d030834579518a51a375531d958 [file] [log] [blame]
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -08001package net.floodlightcontroller.linkdiscovery.internal;
2
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
Pankaj Berde2239f0d2013-04-04 09:42:43 -07006import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
Pankaj Berde1e2f7312013-02-15 08:25:31 -08007import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -08008import net.floodlightcontroller.linkdiscovery.ILinkStorage;
9import net.floodlightcontroller.linkdiscovery.LinkInfo;
10import net.floodlightcontroller.routing.Link;
Pankaj Berde2239f0d2013-04-04 09:42:43 -070011import net.onrc.onos.util.GraphDBConnection;
Pankaj Berde2239f0d2013-04-04 09:42:43 -070012import net.onrc.onos.util.GraphDBConnection.Transaction;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080013
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080014import org.openflow.util.HexString;
15import org.slf4j.Logger;
16import org.slf4j.LoggerFactory;
17
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080018import com.thinkaurelius.titan.core.TitanException;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080019import com.tinkerpop.blueprints.Direction;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080020import com.tinkerpop.blueprints.Edge;
Pankaj Berde62016142013-04-09 15:35:50 -070021import com.tinkerpop.blueprints.Vertex;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080022import com.tinkerpop.gremlin.java.GremlinPipeline;
Pankaj Berde5024ec12013-01-31 17:07:29 -080023import com.tinkerpop.pipes.PipeFunction;
24import com.tinkerpop.pipes.transform.PathPipe;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080025
26public class LinkStorageImpl implements ILinkStorage {
Pankaj Berde62016142013-04-09 15:35:50 -070027
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080028 protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
Pankaj Berde5fb27632013-04-05 08:56:12 -070029 protected String conf;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080030
Naoki Shiotacae568a2013-06-05 17:53:41 -070031 /**
32 * Update
33 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080034 @Override
35 public void update(Link link, DM_OPERATION op) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080036 update(link, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080037 }
38
39 @Override
40 public void update(List<Link> links, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080041 for (Link lt: links) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080042 update(lt, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080043 }
44 }
45
46 @Override
47 public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080048 switch (op) {
49 case UPDATE:
50 case CREATE:
51 case INSERT:
Pankaj Berde254abb42013-06-10 21:21:49 -070052 updateLink(link, linkinfo, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080053 break;
54 case DELETE:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080055 deleteLink(link);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080056 break;
57 }
58 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080059
Pankaj Berde254abb42013-06-10 21:21:49 -070060 public void updateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
Pankaj Berde5fb27632013-04-05 08:56:12 -070061 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
62 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080063
Pankaj Berde254abb42013-06-10 21:21:49 -070064 log.trace("updateLink(): op {} {} {}", new Object[]{op, lt, linkinfo});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080065
66 try {
67 // get source port vertex
68 String dpid = HexString.toHexString(lt.getSrc());
69 short port = lt.getSrcPort();
Pankaj Berde5fb27632013-04-05 08:56:12 -070070 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080071
72 // get dest port vertex
73 dpid = HexString.toHexString(lt.getDst());
74 port = lt.getDstPort();
Pankaj Berde5fb27632013-04-05 08:56:12 -070075 vportDst = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080076
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080077 if (vportSrc != null && vportDst != null) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080078 // check if the link exists
Pankaj Berde77b58512013-04-05 12:06:37 -070079
Pankaj Berde62016142013-04-09 15:35:50 -070080 Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
81 List<IPortObject> currLinks = new ArrayList<IPortObject>();
Pankaj Berde77b58512013-04-05 12:06:37 -070082 for (IPortObject V : currPorts) {
Pankaj Berde6debb042013-01-16 18:04:32 -080083 currLinks.add(V);
84 }
Naoki Shiotacae568a2013-06-05 17:53:41 -070085
Pankaj Berde6debb042013-01-16 18:04:32 -080086 if (currLinks.contains(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080087 if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -080088 log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080089 new Object[]{op, lt, vportSrc, vportDst});
mininetc7f49a82013-06-05 03:48:17 -070090 } else if (op.equals(DM_OPERATION.UPDATE)) {
91 // TODO: update linkinfo
92 // GraphDB seems to have no KeyIndex for LinkInfo data
Naoki Shiotacb05c662013-06-05 17:53:41 -070093
94 // BEGIN: trial code (update implementation)
95 if(linkinfo != null) {
96 vportSrc.setPortState(linkinfo.getSrcPortState());
97 vportDst.setPortState(linkinfo.getDstPortState());
98
99 Vertex vsrc = vportSrc.asVertex();
100 vsrc.setProperty("first_seen_time", linkinfo.getFirstSeenTime());
101 vsrc.setProperty("last_lldp_received_time", linkinfo.getUnicastValidTime());
102 vsrc.setProperty("last_bddp_received_time", linkinfo.getMulticastValidTime());
103
104// for(Edge e: vportSrc.asVertex().getEdges(Direction.OUT)) {
105// if(e.getVertex(Direction.OUT).equals(vportDst.asVertex())) {
106// e.setProperty("first_seen_time", linkinfo.getFirstSeenTime());
107// e.setProperty("last_lldp_received_time", linkinfo.getUnicastValidTime());
108// e.setProperty("last_bddp_received_time", linkinfo.getMulticastValidTime());
109// }
110// }
111
112 conn.endTx(Transaction.COMMIT);
113 log.debug("addOrUpdateLink(): link updated {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
114 }
115 // END: trial code
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800116 }
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800117 } else {
Naoki Shiotacb05c662013-06-05 17:53:41 -0700118 if (op.equals(DM_OPERATION.UPDATE)) {
119 log.debug("addOrUpdateLink(): failed link doesn't exist {} {} src {} dst {}",
120 new Object[]{op, lt, vportSrc, vportDst});
121 } else {
122 vportSrc.setLinkPort(vportDst);
123
124 // BEGIN: trial code (update implementation)
125 if(linkinfo != null) {
126 vportSrc.setPortState(linkinfo.getSrcPortState());
127 vportDst.setPortState(linkinfo.getDstPortState());
128
129 Vertex vsrc = vportSrc.asVertex();
130 vsrc.setProperty("first_seen_time", linkinfo.getFirstSeenTime());
131 vsrc.setProperty("last_lldp_received_time", linkinfo.getUnicastValidTime());
132 vsrc.setProperty("last_bddp_received_time", linkinfo.getMulticastValidTime());
133 }
134 // END: trial code
135 }
Pankaj Berde62016142013-04-09 15:35:50 -0700136
Pankaj Berde86a0d412013-04-05 15:06:26 -0700137 conn.endTx(Transaction.COMMIT);
Pankaj Berde254abb42013-06-10 21:21:49 -0700138 log.debug("updateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800139 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800140 } else {
Pankaj Berde254abb42013-06-10 21:21:49 -0700141 log.error("updateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
142 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800143 }
144 } catch (TitanException e) {
145 /*
146 * retry till we succeed?
147 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800148 e.printStackTrace();
Pankaj Berde254abb42013-06-10 21:21:49 -0700149 log.error("updateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800150 }
151 }
152
153 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800154 public void deleteLinks(List<Link> links) {
155
156 for (Link lt : links) {
157 deleteLink(lt);
158 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800159 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800160
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800161
162 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800163 public void deleteLink(Link lt) {
Pankaj Berde5fb27632013-04-05 08:56:12 -0700164 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700165 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800166 int count = 0;
167
168 log.debug("deleteLink(): {}", lt);
169
170 try {
171 // get source port vertex
172 String dpid = HexString.toHexString(lt.getSrc());
173 short port = lt.getSrcPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700174 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800175
176 // get dst port vertex
177 dpid = HexString.toHexString(lt.getDst());
178 port = lt.getDstPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700179 vportDst = conn.utils().searchPort(conn, dpid, port);
180 // FIXME: This needs to remove all edges
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800181
182 if (vportSrc != null && vportDst != null) {
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700183
184 /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800185 log.debug("deleteLink(): {} in {} out {}",
186 new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
187 if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800188 graph.removeEdge(e);
189 count++;
190 }
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700191 }*/
192 vportSrc.removeLink(vportDst);
Naoki Shiotacae568a2013-06-05 17:53:41 -0700193
Pankaj Berde5fb27632013-04-05 08:56:12 -0700194 conn.endTx(Transaction.COMMIT);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700195 log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
196 lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800197
198 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800199 log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
Pankaj Berde254abb42013-06-10 21:21:49 -0700200 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800201 }
202
203 } catch (TitanException e) {
204 /*
205 * retry till we succeed?
206 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800207 log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
Pankaj Berde254abb42013-06-10 21:21:49 -0700208 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800209 e.printStackTrace();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800210 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800211 }
212
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800213 @Override
214 public List<Link> getLinks(Long dpid, short port) {
Pankaj Berde62016142013-04-09 15:35:50 -0700215 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
mininet403d5892013-06-05 03:48:17 -0700216 IPortObject vportSrc;
217
218 List<Link> links = new ArrayList<Link>();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800219
Pankaj Berde62016142013-04-09 15:35:50 -0700220 vportSrc = conn.utils().searchPort(conn, HexString.toHexString(dpid), port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800221 if (vportSrc != null) {
mininet403d5892013-06-05 03:48:17 -0700222
223 for (Edge e : vportSrc.asVertex().getEdges(Direction.IN)) {
224 if(e.getLabel().equals("link")) {
225 Vertex v = e.getVertex(Direction.OUT);
226 short dst_port = v.getProperty("number");
227 for(Edge e2 : v.getEdges(Direction.IN)) {
228 if(e2.getLabel().equals("on")) {
229 Vertex v2 = e2.getVertex(Direction.OUT);
230 long dst_dpid = HexString.toLong((String) v2.getProperty("dpid"));
231
232 Link lt = new Link(dpid, port, dst_dpid, dst_port);
233 links.add(lt);
234 }
235 }
236 }
237 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800238 }
mininet403d5892013-06-05 03:48:17 -0700239
240 return links;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800241 }
242
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800243 @Override
244 public void init(String conf) {
Pankaj Berde1f10be02013-02-01 14:06:02 -0800245 //TODO extract the DB location from properties
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800246
Pankaj Berde5fb27632013-04-05 08:56:12 -0700247 this.conf = conf;
Pankaj Berde62016142013-04-09 15:35:50 -0700248
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800249 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800250
251 @Override
252 public void deleteLinksOnPort(Long dpid, short port) {
mininet403d5892013-06-05 03:48:17 -0700253 List<Link> linksToDelete = getLinks(dpid,port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800254
mininet403d5892013-06-05 03:48:17 -0700255 for(Link l : linksToDelete) {
256 deleteLink(l);
257 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800258 }
259
Naoki Shiota1b972862013-06-05 19:49:09 -0700260 // TODO: Fix me
Pankaj Berdeff421802013-01-29 20:28:52 -0800261 @Override
262 public List<Link> getLinks(String dpid) {
mininet403d5892013-06-05 03:48:17 -0700263 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
264 ISwitchObject vswitch;
265 List<Link> links = new ArrayList<Link>();
266
Naoki Shiota1b972862013-06-05 19:49:09 -0700267 // BEGIN: Trial code
268 // author: Naoki Shiota
mininet403d5892013-06-05 03:48:17 -0700269 vswitch = conn.utils().searchSwitch(conn, dpid);
270
271 for(IPortObject vportSrc : vswitch.getPorts()) {
Naoki Shiota1b972862013-06-05 19:49:09 -0700272 // array concatenation may be heavy...
mininet403d5892013-06-05 03:48:17 -0700273 List<Link> sublinks = getLinks(HexString.toLong(dpid), vportSrc.getNumber());
274 links.addAll(sublinks);
275 }
Naoki Shiota1b972862013-06-05 19:49:09 -0700276 // END: Trial code
mininet403d5892013-06-05 03:48:17 -0700277
278 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800279 }
280
281 public List<Link> getActiveLinks() {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800282
Pankaj Berde62016142013-04-09 15:35:50 -0700283 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
Pankaj Berdeff421802013-01-29 20:28:52 -0800284
Pankaj Berde62016142013-04-09 15:35:50 -0700285 Iterable<ISwitchObject> switches = conn.utils().getActiveSwitches(conn);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800286
287 List<Link> links = new ArrayList<Link>();
288 for (ISwitchObject sw : switches) {
289 GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
290 ExtractLink extractor = new ExtractLink();
291
292 pipe.start(sw.asVertex());
293 pipe.enablePath(true);
Pankaj Berde1f10be02013-02-01 14:06:02 -0800294 pipe.out("on").out("link").in("on").path().step(extractor);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800295
Pankaj Berde1f10be02013-02-01 14:06:02 -0800296 while (pipe.hasNext() ) {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800297 Link l = pipe.next();
298 links.add(l);
299 }
300
301 }
302 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800303 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800304
305 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
306
Pankaj Berde5024ec12013-01-31 17:07:29 -0800307 @Override
308 public Link compute(PathPipe<Vertex> pipe ) {
Pankaj Berded18c7622013-02-04 10:28:35 -0800309 // TODO Auto-generated method stub
Pankaj Berde5024ec12013-01-31 17:07:29 -0800310 long s_dpid = 0;
311 long d_dpid = 0;
312 short s_port = 0;
313 short d_port = 0;
314 List<Vertex> V = new ArrayList<Vertex>();
315 V = pipe.next();
316 Vertex src_sw = V.get(0);
317 Vertex dest_sw = V.get(3);
318 Vertex src_port = V.get(1);
319 Vertex dest_port = V.get(2);
320 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
321 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
322 s_port = (Short) src_port.getProperty("number");
323 d_port = (Short) dest_port.getProperty("number");
324
325 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
326
327 return l;
328 }
329 }
Pankaj Berded18c7622013-02-04 10:28:35 -0800330
331 public void finalize() {
332 close();
333 }
334
335 @Override
336 public void close() {
337 // TODO Auto-generated method stub
Pankaj Berde62016142013-04-09 15:35:50 -0700338// graph.shutdown();
Pankaj Berded18c7622013-02-04 10:28:35 -0800339 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800340
Pankaj Berdeff421802013-01-29 20:28:52 -0800341
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800342}