blob: 6422666c0c8ecefaa2d4646dff7d6b5c78b4a757 [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 Shiota11516712013-06-05 22:36:01 -070031 /**
32 * Update a record in the LinkStorage in a way provided by op.
33 * @param link Record of a link to be updated.
34 * @param op Operation to be done.
35 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080036 @Override
37 public void update(Link link, DM_OPERATION op) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080038 update(link, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080039 }
40
Naoki Shiota11516712013-06-05 22:36:01 -070041 /**
42 * Update multiple records in the LinkStorage in a way provided by op.
43 * @param links List of records to be updated.
44 * @param op Operation to be done.
45 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080046 @Override
47 public void update(List<Link> links, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080048 for (Link lt: links) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080049 update(lt, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080050 }
51 }
52
Naoki Shiota11516712013-06-05 22:36:01 -070053 /**
54 * Update a record of link with meta-information in the LinkStorage in a way provided by op.
55 * @param link Record of a link to update.
56 * @param linkinfo Meta-information of a link to be updated.
57 * @param op Operation to be done.
58 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080059 @Override
60 public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080061 switch (op) {
62 case UPDATE:
63 case CREATE:
64 case INSERT:
Pankaj Berde254abb42013-06-10 21:21:49 -070065 updateLink(link, linkinfo, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080066 break;
67 case DELETE:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080068 deleteLink(link);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080069 break;
70 }
71 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080072
Naoki Shiota11516712013-06-05 22:36:01 -070073 /**
74 * Perform INSERT/CREATE/UPDATE operation to update the LinkStorage.
75 * @param lt Record of a link to be updated.
76 * @param linkinfo Meta-information of a link to be updated.
77 * @param op Operation to be done. (only INSERT/CREATE/UPDATE is acceptable)
78 */
Pankaj Berde254abb42013-06-10 21:21:49 -070079 public void updateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
Pankaj Berde5fb27632013-04-05 08:56:12 -070080 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
81 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080082
Pankaj Berde254abb42013-06-10 21:21:49 -070083 log.trace("updateLink(): op {} {} {}", new Object[]{op, lt, linkinfo});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080084
85 try {
86 // get source port vertex
87 String dpid = HexString.toHexString(lt.getSrc());
88 short port = lt.getSrcPort();
Pankaj Berde5fb27632013-04-05 08:56:12 -070089 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080090
91 // get dest port vertex
92 dpid = HexString.toHexString(lt.getDst());
93 port = lt.getDstPort();
Pankaj Berde5fb27632013-04-05 08:56:12 -070094 vportDst = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080095
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080096 if (vportSrc != null && vportDst != null) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080097 // check if the link exists
Pankaj Berde77b58512013-04-05 12:06:37 -070098
Pankaj Berde62016142013-04-09 15:35:50 -070099 Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
100 List<IPortObject> currLinks = new ArrayList<IPortObject>();
Pankaj Berde77b58512013-04-05 12:06:37 -0700101 for (IPortObject V : currPorts) {
Pankaj Berde6debb042013-01-16 18:04:32 -0800102 currLinks.add(V);
103 }
Naoki Shiotacae568a2013-06-05 17:53:41 -0700104
Pankaj Berde6debb042013-01-16 18:04:32 -0800105 if (currLinks.contains(vportDst)) {
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700106 // TODO: update linkinfo
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800107 if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800108 log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800109 new Object[]{op, lt, vportSrc, vportDst});
110 }
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800111 } else {
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700112 vportSrc.setLinkPort(vportDst);
Pankaj Berde62016142013-04-09 15:35:50 -0700113
Pankaj Berde86a0d412013-04-05 15:06:26 -0700114 conn.endTx(Transaction.COMMIT);
Pankaj Berde254abb42013-06-10 21:21:49 -0700115 log.debug("updateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800116 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800117 } else {
Pankaj Berde254abb42013-06-10 21:21:49 -0700118 log.error("updateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
119 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800120 }
121 } catch (TitanException e) {
122 /*
123 * retry till we succeed?
124 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800125 e.printStackTrace();
Pankaj Berde254abb42013-06-10 21:21:49 -0700126 log.error("updateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800127 }
128 }
129
Naoki Shiota11516712013-06-05 22:36:01 -0700130 /**
131 * Delete multiple records in the LinkStorage.
132 * @param links List of records to be deleted.
133 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800134 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800135 public void deleteLinks(List<Link> links) {
136
137 for (Link lt : links) {
138 deleteLink(lt);
139 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800140 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800141
Naoki Shiota11516712013-06-05 22:36:01 -0700142 /**
143 * Delete a record in the LinkStorage.
144 * @param link Record to be deleted.
145 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800146 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800147 public void deleteLink(Link lt) {
Pankaj Berde5fb27632013-04-05 08:56:12 -0700148 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700149 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800150 int count = 0;
151
152 log.debug("deleteLink(): {}", lt);
153
154 try {
155 // get source port vertex
156 String dpid = HexString.toHexString(lt.getSrc());
157 short port = lt.getSrcPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700158 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800159
160 // get dst port vertex
161 dpid = HexString.toHexString(lt.getDst());
162 port = lt.getDstPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700163 vportDst = conn.utils().searchPort(conn, dpid, port);
164 // FIXME: This needs to remove all edges
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800165
166 if (vportSrc != null && vportDst != null) {
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700167
168 /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800169 log.debug("deleteLink(): {} in {} out {}",
170 new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
171 if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800172 graph.removeEdge(e);
173 count++;
174 }
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700175 }*/
176 vportSrc.removeLink(vportDst);
Naoki Shiotacae568a2013-06-05 17:53:41 -0700177
Pankaj Berde5fb27632013-04-05 08:56:12 -0700178 conn.endTx(Transaction.COMMIT);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700179 log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
180 lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800181
182 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800183 log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
Pankaj Berde254abb42013-06-10 21:21:49 -0700184 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800185 }
186
187 } catch (TitanException e) {
188 /*
189 * retry till we succeed?
190 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800191 log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
Pankaj Berde254abb42013-06-10 21:21:49 -0700192 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800193 e.printStackTrace();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800194 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800195 }
196
Naoki Shiota11516712013-06-05 22:36:01 -0700197 /**
198 * Get list of all links connected to the port specified by given DPID and port number.
199 * @param dpid DPID of desired port.
200 * @param port Port number of desired port.
201 * @return List of links. Empty list if no port was found.
202 */
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700203 // TODO: Fix me
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800204 @Override
205 public List<Link> getLinks(Long dpid, short port) {
Pankaj Berde62016142013-04-09 15:35:50 -0700206 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
mininet403d5892013-06-05 03:48:17 -0700207 IPortObject vportSrc;
208
209 List<Link> links = new ArrayList<Link>();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800210
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700211 // BEGIN: Trial code
212 // author: Naoki Shiota
Pankaj Berde62016142013-04-09 15:35:50 -0700213 vportSrc = conn.utils().searchPort(conn, HexString.toHexString(dpid), port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800214 if (vportSrc != null) {
mininet403d5892013-06-05 03:48:17 -0700215
216 for (Edge e : vportSrc.asVertex().getEdges(Direction.IN)) {
217 if(e.getLabel().equals("link")) {
218 Vertex v = e.getVertex(Direction.OUT);
219 short dst_port = v.getProperty("number");
220 for(Edge e2 : v.getEdges(Direction.IN)) {
221 if(e2.getLabel().equals("on")) {
222 Vertex v2 = e2.getVertex(Direction.OUT);
223 long dst_dpid = HexString.toLong((String) v2.getProperty("dpid"));
224
225 Link lt = new Link(dpid, port, dst_dpid, dst_port);
226 links.add(lt);
227 }
228 }
229 }
230 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800231 }
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700232 // END: Trial code
mininet403d5892013-06-05 03:48:17 -0700233
234 return links;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800235 }
236
Naoki Shiota11516712013-06-05 22:36:01 -0700237 /**
238 * Initialize the object. Open LinkStorage using given configuration file.
239 * @param conf Path (absolute path for now) to configuration file.
240 */
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800241 @Override
242 public void init(String conf) {
Pankaj Berde1f10be02013-02-01 14:06:02 -0800243 //TODO extract the DB location from properties
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800244
Pankaj Berde5fb27632013-04-05 08:56:12 -0700245 this.conf = conf;
Pankaj Berde62016142013-04-09 15:35:50 -0700246
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800247 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800248
Naoki Shiota11516712013-06-05 22:36:01 -0700249 /**
250 * Delete records of the links connected to the port specified by given DPID and port number.
251 * @param dpid DPID of desired port.
252 * @param port Port number of desired port.
253 */
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700254 // TODO: Fix me
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800255 @Override
256 public void deleteLinksOnPort(Long dpid, short port) {
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700257 // BEGIN: Trial code
258 // author: Naoki Shiota
mininet403d5892013-06-05 03:48:17 -0700259 List<Link> linksToDelete = getLinks(dpid,port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800260
mininet403d5892013-06-05 03:48:17 -0700261 for(Link l : linksToDelete) {
262 deleteLink(l);
263 }
Naoki Shiotab0d0c002013-06-05 20:21:20 -0700264 // END: Trial code
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800265 }
266
Naoki Shiota11516712013-06-05 22:36:01 -0700267 /**
268 * Get list of all links connected to the switch specified by given DPID.
269 * @param dpid DPID of desired switch.
270 * @return List of links. Empty list if no port was found.
271 */
Naoki Shiota1b972862013-06-05 19:49:09 -0700272 // TODO: Fix me
Pankaj Berdeff421802013-01-29 20:28:52 -0800273 @Override
274 public List<Link> getLinks(String dpid) {
mininet403d5892013-06-05 03:48:17 -0700275 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
276 ISwitchObject vswitch;
277 List<Link> links = new ArrayList<Link>();
278
Naoki Shiota1b972862013-06-05 19:49:09 -0700279 // BEGIN: Trial code
280 // author: Naoki Shiota
mininet403d5892013-06-05 03:48:17 -0700281 vswitch = conn.utils().searchSwitch(conn, dpid);
282
283 for(IPortObject vportSrc : vswitch.getPorts()) {
Naoki Shiota1b972862013-06-05 19:49:09 -0700284 // array concatenation may be heavy...
mininet403d5892013-06-05 03:48:17 -0700285 List<Link> sublinks = getLinks(HexString.toLong(dpid), vportSrc.getNumber());
286 links.addAll(sublinks);
287 }
Naoki Shiota1b972862013-06-05 19:49:09 -0700288 // END: Trial code
mininet403d5892013-06-05 03:48:17 -0700289
290 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800291 }
292
Naoki Shiota11516712013-06-05 22:36:01 -0700293 /**
294 * Get list of all links whose state is ACTIVE.
295 * @return List of active links. Empty list if no port was found.
296 */
Pankaj Berdeff421802013-01-29 20:28:52 -0800297 public List<Link> getActiveLinks() {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800298
Pankaj Berde62016142013-04-09 15:35:50 -0700299 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
Pankaj Berdeff421802013-01-29 20:28:52 -0800300
Pankaj Berde62016142013-04-09 15:35:50 -0700301 Iterable<ISwitchObject> switches = conn.utils().getActiveSwitches(conn);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800302
303 List<Link> links = new ArrayList<Link>();
304 for (ISwitchObject sw : switches) {
305 GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
306 ExtractLink extractor = new ExtractLink();
307
308 pipe.start(sw.asVertex());
309 pipe.enablePath(true);
Pankaj Berde1f10be02013-02-01 14:06:02 -0800310 pipe.out("on").out("link").in("on").path().step(extractor);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800311
Pankaj Berde1f10be02013-02-01 14:06:02 -0800312 while (pipe.hasNext() ) {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800313 Link l = pipe.next();
314 links.add(l);
315 }
316
317 }
318 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800319 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800320
Naoki Shiota11516712013-06-05 22:36:01 -0700321 /**
322 * PipeFunction object to extract link from given "switch-port-port-switch" Path.
323 */
Pankaj Berde5024ec12013-01-31 17:07:29 -0800324 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
325
Pankaj Berde5024ec12013-01-31 17:07:29 -0800326 @Override
327 public Link compute(PathPipe<Vertex> pipe ) {
Pankaj Berded18c7622013-02-04 10:28:35 -0800328 // TODO Auto-generated method stub
Pankaj Berde5024ec12013-01-31 17:07:29 -0800329 long s_dpid = 0;
330 long d_dpid = 0;
331 short s_port = 0;
332 short d_port = 0;
333 List<Vertex> V = new ArrayList<Vertex>();
334 V = pipe.next();
335 Vertex src_sw = V.get(0);
336 Vertex dest_sw = V.get(3);
337 Vertex src_port = V.get(1);
338 Vertex dest_port = V.get(2);
339 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
340 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
341 s_port = (Short) src_port.getProperty("number");
342 d_port = (Short) dest_port.getProperty("number");
343
344 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
345
346 return l;
347 }
348 }
Pankaj Berded18c7622013-02-04 10:28:35 -0800349
Naoki Shiota11516712013-06-05 22:36:01 -0700350 /**
351 * Finalize the object.
352 */
Pankaj Berded18c7622013-02-04 10:28:35 -0800353 public void finalize() {
354 close();
355 }
356
Naoki Shiota11516712013-06-05 22:36:01 -0700357 /**
358 * Close LinkStorage.
359 */
Pankaj Berded18c7622013-02-04 10:28:35 -0800360 @Override
361 public void close() {
362 // TODO Auto-generated method stub
Pankaj Berde62016142013-04-09 15:35:50 -0700363// graph.shutdown();
Pankaj Berded18c7622013-02-04 10:28:35 -0800364 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800365
Pankaj Berdeff421802013-01-29 20:28:52 -0800366
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800367}