blob: 0ab52e289dfa77dcc333088a581f897fd2c3d1e2 [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 Berde86a0d412013-04-05 15:06:26 -070097
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080098 // check if the link exists
Pankaj Berde77b58512013-04-05 12:06:37 -070099 List<IPortObject> currLinks = new ArrayList<IPortObject>();
100 Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
101
102 for (IPortObject V : currPorts) {
Pankaj Berde6debb042013-01-16 18:04:32 -0800103 currLinks.add(V);
104 }
105
106 if (currLinks.contains(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800107 // TODO: update linkinfo
108 if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800109 log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800110 new Object[]{op, lt, vportSrc, vportDst});
111 }
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800112 } else {
Pankaj Berde86a0d412013-04-05 15:06:26 -0700113 conn.getFramedGraph().addEdge(null, vportSrc.asVertex(), vportDst.asVertex(), "link");
114 conn.endTx(Transaction.COMMIT);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800115 log.debug("addOrUpdateLink(): 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 {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800118 log.error("addOrUpdateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Pankaj Berde86a0d412013-04-05 15:06:26 -0700119 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 log.error("addOrUpdateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
126 e.printStackTrace();
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800127 }
128 }
129
130 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800131 public void deleteLinks(List<Link> links) {
132
133 for (Link lt : links) {
134 deleteLink(lt);
135 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800136 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800137
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800138
139 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800140 public void deleteLink(Link lt) {
Pankaj Berde5fb27632013-04-05 08:56:12 -0700141 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700142 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800143 int count = 0;
144
145 log.debug("deleteLink(): {}", lt);
146
147 try {
148 // get source port vertex
149 String dpid = HexString.toHexString(lt.getSrc());
150 short port = lt.getSrcPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700151 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800152
153 // get dst port vertex
154 dpid = HexString.toHexString(lt.getDst());
155 port = lt.getDstPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700156 vportDst = conn.utils().searchPort(conn, dpid, port);
157 // FIXME: This needs to remove all edges
158 // FIXME: Events will only be generated on singleton graph object (GraphDBConnection)
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800159
160 if (vportSrc != null && vportDst != null) {
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700161
162 /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800163 log.debug("deleteLink(): {} in {} out {}",
164 new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
165 if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800166 graph.removeEdge(e);
167 count++;
168 }
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700169 }*/
170 vportSrc.removeLink(vportDst);
Pankaj Berde5fb27632013-04-05 08:56:12 -0700171 conn.endTx(Transaction.COMMIT);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700172 log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
173 lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800174
175 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800176 log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700177 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800178 }
179
180 } catch (TitanException e) {
181 /*
182 * retry till we succeed?
183 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800184 log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
185 e.printStackTrace();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800186 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800187 }
188
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800189 // TODO: Fix me
190 @Override
191 public List<Link> getLinks(Long dpid, short port) {
192 Vertex vportSrc, vportDst;
193 List<Link> links = null;
194 Link lt;
195
196 vportSrc = getPortVertex(HexString.toHexString(dpid), port);
197 if (vportSrc != null) {
198 for (Edge e : vportSrc.getEdges(Direction.OUT)) {
199 if (e.getLabel().equals("link")) {
200 break;
201 }
202 }
203 }
204 return null;
205 }
206
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800207 @Override
208 public void init(String conf) {
Pankaj Berde1f10be02013-02-01 14:06:02 -0800209 //TODO extract the DB location from properties
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800210
Pankaj Berde5fb27632013-04-05 08:56:12 -0700211 this.conf = conf;
212 graph = TitanFactory.open(this.conf);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800213
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800214 // 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 -0800215 Set<String> s = graph.getIndexedKeys(Vertex.class);
216 if (!s.contains("dpid")) {
217 graph.createKeyIndex("dpid", Vertex.class);
218 graph.stopTransaction(Conclusion.SUCCESS);
219 }
220 if (!s.contains("type")) {
221 graph.createKeyIndex("type", Vertex.class);
222 graph.stopTransaction(Conclusion.SUCCESS);
223 }
224 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800225
226 @Override
227 public void deleteLinksOnPort(Long dpid, short port) {
228 // TODO Auto-generated method stub
229
230 }
231
Pankaj Berdeff421802013-01-29 20:28:52 -0800232 @Override
233 public List<Link> getLinks(String dpid) {
234 // TODO Auto-generated method stub
235 return null;
236 }
237
238 public List<Link> getActiveLinks() {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800239
240 ITopoSwitchService swService = new TopoSwitchServiceImpl();
Pankaj Berdeff421802013-01-29 20:28:52 -0800241
Pankaj Berde1cde50b2013-02-19 20:16:06 -0800242 Iterable<ISwitchObject> switches = swService.getActiveSwitches();
Pankaj Berde5024ec12013-01-31 17:07:29 -0800243
244 List<Link> links = new ArrayList<Link>();
245 for (ISwitchObject sw : switches) {
246 GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
247 ExtractLink extractor = new ExtractLink();
248
249 pipe.start(sw.asVertex());
250 pipe.enablePath(true);
Pankaj Berde1f10be02013-02-01 14:06:02 -0800251 pipe.out("on").out("link").in("on").path().step(extractor);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800252
Pankaj Berde1f10be02013-02-01 14:06:02 -0800253 while (pipe.hasNext() ) {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800254 Link l = pipe.next();
255 links.add(l);
256 }
257
258 }
259 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800260 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800261
262 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
263
Pankaj Berde5024ec12013-01-31 17:07:29 -0800264 @Override
265 public Link compute(PathPipe<Vertex> pipe ) {
Pankaj Berded18c7622013-02-04 10:28:35 -0800266 // TODO Auto-generated method stub
Pankaj Berde5024ec12013-01-31 17:07:29 -0800267 long s_dpid = 0;
268 long d_dpid = 0;
269 short s_port = 0;
270 short d_port = 0;
271 List<Vertex> V = new ArrayList<Vertex>();
272 V = pipe.next();
273 Vertex src_sw = V.get(0);
274 Vertex dest_sw = V.get(3);
275 Vertex src_port = V.get(1);
276 Vertex dest_port = V.get(2);
277 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
278 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
279 s_port = (Short) src_port.getProperty("number");
280 d_port = (Short) dest_port.getProperty("number");
281
282 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
283
284 return l;
285 }
286 }
Pankaj Berded18c7622013-02-04 10:28:35 -0800287
288 public void finalize() {
289 close();
290 }
291
292 @Override
293 public void close() {
294 // TODO Auto-generated method stub
295 graph.shutdown();
296 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800297
Pankaj Berdeff421802013-01-29 20:28:52 -0800298
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800299}