blob: e67ecac31173b089b69cc744c2682ca33132fd00 [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;
Pankaj Berde5024ec12013-01-31 17:07:29 -08004import java.util.Collection;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -08005import java.util.List;
6import java.util.Set;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -08007
Pankaj Berde2239f0d2013-04-04 09:42:43 -07008import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
Pankaj Berde1e2f7312013-02-15 08:25:31 -08009import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
Pankaj Berde5024ec12013-01-31 17:07:29 -080010import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
Pankaj Berde5024ec12013-01-31 17:07:29 -080011import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080012import net.floodlightcontroller.linkdiscovery.ILinkStorage;
13import net.floodlightcontroller.linkdiscovery.LinkInfo;
14import net.floodlightcontroller.routing.Link;
Pankaj Berde2239f0d2013-04-04 09:42:43 -070015import net.onrc.onos.util.GraphDBConnection;
16import net.onrc.onos.util.GraphDBConnection.GenerateEvent;
17import net.onrc.onos.util.GraphDBConnection.Transaction;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080018
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080019import org.openflow.util.HexString;
20import org.slf4j.Logger;
21import org.slf4j.LoggerFactory;
22
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080023import com.thinkaurelius.titan.core.TitanException;
24import com.thinkaurelius.titan.core.TitanFactory;
25import com.thinkaurelius.titan.core.TitanGraph;
26import com.tinkerpop.blueprints.Direction;
27import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
28import com.tinkerpop.blueprints.Vertex;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080029import com.tinkerpop.blueprints.Edge;
Pankaj Berde2239f0d2013-04-04 09:42:43 -070030import com.tinkerpop.blueprints.util.wrappers.event.EventGraph;
31import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080032import com.tinkerpop.gremlin.java.GremlinPipeline;
Pankaj Berde5024ec12013-01-31 17:07:29 -080033import com.tinkerpop.pipes.PipeFunction;
34import com.tinkerpop.pipes.transform.PathPipe;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080035
36public class LinkStorageImpl implements ILinkStorage {
37 public TitanGraph graph;
38 protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
Pankaj Berde5fb27632013-04-05 08:56:12 -070039 protected String conf;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080040
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080041 @Override
42 public void update(Link link, DM_OPERATION op) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080043 update(link, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080044 }
45
46 @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
53 @Override
54 public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080055 switch (op) {
56 case UPDATE:
57 case CREATE:
58 case INSERT:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080059 addOrUpdateLink(link, linkinfo, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080060 break;
61 case DELETE:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080062 deleteLink(link);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080063 break;
64 }
65 }
66
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080067 private Vertex getPortVertex(String dpid, short port) {
68 Vertex vsw, vport = null;
69 if ((vsw = graph.getVertices("dpid", dpid).iterator().next()) != null) {
70 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
71 pipe.start(vsw).out("on").has("number", port);
72 if (pipe.hasNext()) {
73 vport = pipe.next();
74 }
75 }
76 return vport;
77 }
78
79 public void addOrUpdateLink(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
Umesh Krishnaswamy0ef75ee2013-03-25 17:50:27 -070083 log.trace("addOrUpdateLink(): 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) {
Pankaj Berde5fb27632013-04-05 08:56:12 -070097
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080098
99 // check if the link exists
Pankaj Berde6debb042013-01-16 18:04:32 -0800100 List<Vertex> currLinks = new ArrayList<Vertex>();
Pankaj Berde5fb27632013-04-05 08:56:12 -0700101 for (Vertex V : vportSrc.asVertex().query().direction(Direction.OUT).labels("link").vertices()) {
Pankaj Berde6debb042013-01-16 18:04:32 -0800102 currLinks.add(V);
103 }
104
105 if (currLinks.contains(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800106 // TODO: update linkinfo
107 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 {
Pankaj Berde5fb27632013-04-05 08:56:12 -0700112 graph.addEdge(null, vportSrc.asVertex(), vportDst.asVertex(), "link");
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800113 graph.stopTransaction(Conclusion.SUCCESS);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800114 log.debug("addOrUpdateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800115 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800116 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800117 log.error("addOrUpdateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800118 graph.stopTransaction(Conclusion.FAILURE);
119 }
120 } catch (TitanException e) {
121 /*
122 * retry till we succeed?
123 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800124 log.error("addOrUpdateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
125 e.printStackTrace();
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800126 }
127 }
128
129 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800130 public void deleteLinks(List<Link> links) {
131
132 for (Link lt : links) {
133 deleteLink(lt);
134 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800135 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800136
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800137
138 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800139 public void deleteLink(Link lt) {
Pankaj Berde5fb27632013-04-05 08:56:12 -0700140 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700141 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800142 int count = 0;
143
144 log.debug("deleteLink(): {}", lt);
145
146 try {
147 // get source port vertex
148 String dpid = HexString.toHexString(lt.getSrc());
149 short port = lt.getSrcPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700150 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800151
152 // get dst port vertex
153 dpid = HexString.toHexString(lt.getDst());
154 port = lt.getDstPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700155 vportDst = conn.utils().searchPort(conn, dpid, port);
156 // FIXME: This needs to remove all edges
157 // FIXME: Events will only be generated on singleton graph object (GraphDBConnection)
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800158
159 if (vportSrc != null && vportDst != null) {
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700160
161 /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800162 log.debug("deleteLink(): {} in {} out {}",
163 new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
164 if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800165 graph.removeEdge(e);
166 count++;
167 }
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700168 }*/
169 vportSrc.removeLink(vportDst);
Pankaj Berde5fb27632013-04-05 08:56:12 -0700170 conn.endTx(Transaction.COMMIT);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700171 log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
172 lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800173
174 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800175 log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700176 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800177 }
178
179 } catch (TitanException e) {
180 /*
181 * retry till we succeed?
182 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800183 log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
184 e.printStackTrace();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800185 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800186 }
187
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800188 // TODO: Fix me
189 @Override
190 public List<Link> getLinks(Long dpid, short port) {
191 Vertex vportSrc, vportDst;
192 List<Link> links = null;
193 Link lt;
194
195 vportSrc = getPortVertex(HexString.toHexString(dpid), port);
196 if (vportSrc != null) {
197 for (Edge e : vportSrc.getEdges(Direction.OUT)) {
198 if (e.getLabel().equals("link")) {
199 break;
200 }
201 }
202 }
203 return null;
204 }
205
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800206 @Override
207 public void init(String conf) {
Pankaj Berde1f10be02013-02-01 14:06:02 -0800208 //TODO extract the DB location from properties
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800209
Pankaj Berde5fb27632013-04-05 08:56:12 -0700210 this.conf = conf;
211 graph = TitanFactory.open(this.conf);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800212
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800213 // FIXME: These keys are not needed for Links but we better create it before using it as per titan
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800214 Set<String> s = graph.getIndexedKeys(Vertex.class);
215 if (!s.contains("dpid")) {
216 graph.createKeyIndex("dpid", Vertex.class);
217 graph.stopTransaction(Conclusion.SUCCESS);
218 }
219 if (!s.contains("type")) {
220 graph.createKeyIndex("type", Vertex.class);
221 graph.stopTransaction(Conclusion.SUCCESS);
222 }
223 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800224
225 @Override
226 public void deleteLinksOnPort(Long dpid, short port) {
227 // TODO Auto-generated method stub
228
229 }
230
Pankaj Berdeff421802013-01-29 20:28:52 -0800231 @Override
232 public List<Link> getLinks(String dpid) {
233 // TODO Auto-generated method stub
234 return null;
235 }
236
237 public List<Link> getActiveLinks() {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800238
239 ITopoSwitchService swService = new TopoSwitchServiceImpl();
Pankaj Berdeff421802013-01-29 20:28:52 -0800240
Pankaj Berde1cde50b2013-02-19 20:16:06 -0800241 Iterable<ISwitchObject> switches = swService.getActiveSwitches();
Pankaj Berde5024ec12013-01-31 17:07:29 -0800242
243 List<Link> links = new ArrayList<Link>();
244 for (ISwitchObject sw : switches) {
245 GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
246 ExtractLink extractor = new ExtractLink();
247
248 pipe.start(sw.asVertex());
249 pipe.enablePath(true);
Pankaj Berde1f10be02013-02-01 14:06:02 -0800250 pipe.out("on").out("link").in("on").path().step(extractor);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800251
Pankaj Berde1f10be02013-02-01 14:06:02 -0800252 while (pipe.hasNext() ) {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800253 Link l = pipe.next();
254 links.add(l);
255 }
256
257 }
258 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800259 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800260
261 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
262
Pankaj Berde5024ec12013-01-31 17:07:29 -0800263 @Override
264 public Link compute(PathPipe<Vertex> pipe ) {
Pankaj Berded18c7622013-02-04 10:28:35 -0800265 // TODO Auto-generated method stub
Pankaj Berde5024ec12013-01-31 17:07:29 -0800266 long s_dpid = 0;
267 long d_dpid = 0;
268 short s_port = 0;
269 short d_port = 0;
270 List<Vertex> V = new ArrayList<Vertex>();
271 V = pipe.next();
272 Vertex src_sw = V.get(0);
273 Vertex dest_sw = V.get(3);
274 Vertex src_port = V.get(1);
275 Vertex dest_port = V.get(2);
276 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
277 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
278 s_port = (Short) src_port.getProperty("number");
279 d_port = (Short) dest_port.getProperty("number");
280
281 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
282
283 return l;
284 }
285 }
Pankaj Berded18c7622013-02-04 10:28:35 -0800286
287 public void finalize() {
288 close();
289 }
290
291 @Override
292 public void close() {
293 // TODO Auto-generated method stub
294 graph.shutdown();
295 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800296
Pankaj Berdeff421802013-01-29 20:28:52 -0800297
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800298}