blob: 5c01af61d8d1488f5fc406315f74f358c28183ac [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 Berde77b58512013-04-05 12:06:37 -0700100 List<IPortObject> currLinks = new ArrayList<IPortObject>();
101 Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
102
103 for (IPortObject V : currPorts) {
Pankaj Berde6debb042013-01-16 18:04:32 -0800104 currLinks.add(V);
105 }
106
107 if (currLinks.contains(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800108 // TODO: update linkinfo
109 if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800110 log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800111 new Object[]{op, lt, vportSrc, vportDst});
112 }
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800113 } else {
Pankaj Berde5fb27632013-04-05 08:56:12 -0700114 graph.addEdge(null, vportSrc.asVertex(), vportDst.asVertex(), "link");
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800115 graph.stopTransaction(Conclusion.SUCCESS);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800116 log.debug("addOrUpdateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800117 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800118 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800119 log.error("addOrUpdateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800120 graph.stopTransaction(Conclusion.FAILURE);
121 }
122 } catch (TitanException e) {
123 /*
124 * retry till we succeed?
125 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800126 log.error("addOrUpdateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
127 e.printStackTrace();
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800128 }
129 }
130
131 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800132 public void deleteLinks(List<Link> links) {
133
134 for (Link lt : links) {
135 deleteLink(lt);
136 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800137 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800138
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800139
140 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800141 public void deleteLink(Link lt) {
Pankaj Berde5fb27632013-04-05 08:56:12 -0700142 GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700143 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800144 int count = 0;
145
146 log.debug("deleteLink(): {}", lt);
147
148 try {
149 // get source port vertex
150 String dpid = HexString.toHexString(lt.getSrc());
151 short port = lt.getSrcPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700152 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800153
154 // get dst port vertex
155 dpid = HexString.toHexString(lt.getDst());
156 port = lt.getDstPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700157 vportDst = conn.utils().searchPort(conn, dpid, port);
158 // FIXME: This needs to remove all edges
159 // FIXME: Events will only be generated on singleton graph object (GraphDBConnection)
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800160
161 if (vportSrc != null && vportDst != null) {
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700162
163 /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800164 log.debug("deleteLink(): {} in {} out {}",
165 new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
166 if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800167 graph.removeEdge(e);
168 count++;
169 }
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700170 }*/
171 vportSrc.removeLink(vportDst);
Pankaj Berde5fb27632013-04-05 08:56:12 -0700172 conn.endTx(Transaction.COMMIT);
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700173 log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
174 lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800175
176 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800177 log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700178 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800179 }
180
181 } catch (TitanException e) {
182 /*
183 * retry till we succeed?
184 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800185 log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
186 e.printStackTrace();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800187 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800188 }
189
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800190 // TODO: Fix me
191 @Override
192 public List<Link> getLinks(Long dpid, short port) {
193 Vertex vportSrc, vportDst;
194 List<Link> links = null;
195 Link lt;
196
197 vportSrc = getPortVertex(HexString.toHexString(dpid), port);
198 if (vportSrc != null) {
199 for (Edge e : vportSrc.getEdges(Direction.OUT)) {
200 if (e.getLabel().equals("link")) {
201 break;
202 }
203 }
204 }
205 return null;
206 }
207
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800208 @Override
209 public void init(String conf) {
Pankaj Berde1f10be02013-02-01 14:06:02 -0800210 //TODO extract the DB location from properties
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800211
Pankaj Berde5fb27632013-04-05 08:56:12 -0700212 this.conf = conf;
213 graph = TitanFactory.open(this.conf);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800214
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800215 // 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 -0800216 Set<String> s = graph.getIndexedKeys(Vertex.class);
217 if (!s.contains("dpid")) {
218 graph.createKeyIndex("dpid", Vertex.class);
219 graph.stopTransaction(Conclusion.SUCCESS);
220 }
221 if (!s.contains("type")) {
222 graph.createKeyIndex("type", Vertex.class);
223 graph.stopTransaction(Conclusion.SUCCESS);
224 }
225 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800226
227 @Override
228 public void deleteLinksOnPort(Long dpid, short port) {
229 // TODO Auto-generated method stub
230
231 }
232
Pankaj Berdeff421802013-01-29 20:28:52 -0800233 @Override
234 public List<Link> getLinks(String dpid) {
235 // TODO Auto-generated method stub
236 return null;
237 }
238
239 public List<Link> getActiveLinks() {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800240
241 ITopoSwitchService swService = new TopoSwitchServiceImpl();
Pankaj Berdeff421802013-01-29 20:28:52 -0800242
Pankaj Berde1cde50b2013-02-19 20:16:06 -0800243 Iterable<ISwitchObject> switches = swService.getActiveSwitches();
Pankaj Berde5024ec12013-01-31 17:07:29 -0800244
245 List<Link> links = new ArrayList<Link>();
246 for (ISwitchObject sw : switches) {
247 GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
248 ExtractLink extractor = new ExtractLink();
249
250 pipe.start(sw.asVertex());
251 pipe.enablePath(true);
Pankaj Berde1f10be02013-02-01 14:06:02 -0800252 pipe.out("on").out("link").in("on").path().step(extractor);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800253
Pankaj Berde1f10be02013-02-01 14:06:02 -0800254 while (pipe.hasNext() ) {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800255 Link l = pipe.next();
256 links.add(l);
257 }
258
259 }
260 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800261 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800262
263 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
264
Pankaj Berde5024ec12013-01-31 17:07:29 -0800265 @Override
266 public Link compute(PathPipe<Vertex> pipe ) {
Pankaj Berded18c7622013-02-04 10:28:35 -0800267 // TODO Auto-generated method stub
Pankaj Berde5024ec12013-01-31 17:07:29 -0800268 long s_dpid = 0;
269 long d_dpid = 0;
270 short s_port = 0;
271 short d_port = 0;
272 List<Vertex> V = new ArrayList<Vertex>();
273 V = pipe.next();
274 Vertex src_sw = V.get(0);
275 Vertex dest_sw = V.get(3);
276 Vertex src_port = V.get(1);
277 Vertex dest_port = V.get(2);
278 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
279 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
280 s_port = (Short) src_port.getProperty("number");
281 d_port = (Short) dest_port.getProperty("number");
282
283 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
284
285 return l;
286 }
287 }
Pankaj Berded18c7622013-02-04 10:28:35 -0800288
289 public void finalize() {
290 close();
291 }
292
293 @Override
294 public void close() {
295 // TODO Auto-generated method stub
296 graph.shutdown();
297 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800298
Pankaj Berdeff421802013-01-29 20:28:52 -0800299
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800300}