blob: 33ae22acb3496b368b5d801694005e2fc97f856f [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);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080039
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080040 @Override
41 public void update(Link link, DM_OPERATION op) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080042 update(link, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080043 }
44
45 @Override
46 public void update(List<Link> links, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080047 for (Link lt: links) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080048 update(lt, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080049 }
50 }
51
52 @Override
53 public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080054 switch (op) {
55 case UPDATE:
56 case CREATE:
57 case INSERT:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080058 addOrUpdateLink(link, linkinfo, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080059 break;
60 case DELETE:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080061 deleteLink(link);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080062 break;
63 }
64 }
65
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080066 private Vertex getPortVertex(String dpid, short port) {
67 Vertex vsw, vport = null;
68 if ((vsw = graph.getVertices("dpid", dpid).iterator().next()) != null) {
69 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
70 pipe.start(vsw).out("on").has("number", port);
71 if (pipe.hasNext()) {
72 vport = pipe.next();
73 }
74 }
75 return vport;
76 }
77
78 public void addOrUpdateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080079 Vertex vportSrc = null, vportDst = null;
80
Umesh Krishnaswamy0ef75ee2013-03-25 17:50:27 -070081 log.trace("addOrUpdateLink(): op {} {} {}", new Object[]{op, lt, linkinfo});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080082
83 try {
84 // get source port vertex
85 String dpid = HexString.toHexString(lt.getSrc());
86 short port = lt.getSrcPort();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080087 vportSrc = getPortVertex(dpid, port);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080088
89 // get dest port vertex
90 dpid = HexString.toHexString(lt.getDst());
91 port = lt.getDstPort();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080092 vportDst = getPortVertex(dpid, port);
93
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080094 if (vportSrc != null && vportDst != null) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080095
96 // check if the link exists
Pankaj Berde6debb042013-01-16 18:04:32 -080097 List<Vertex> currLinks = new ArrayList<Vertex>();
98 for (Vertex V : vportSrc.query().direction(Direction.OUT).labels("link").vertices()) {
99 currLinks.add(V);
100 }
101
102 if (currLinks.contains(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800103 // TODO: update linkinfo
104 if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800105 log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800106 new Object[]{op, lt, vportSrc, vportDst});
107 }
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800108 } else {
109 graph.addEdge(null, vportSrc, vportDst, "link");
110 graph.stopTransaction(Conclusion.SUCCESS);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800111 log.debug("addOrUpdateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800112 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800113 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800114 log.error("addOrUpdateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800115 graph.stopTransaction(Conclusion.FAILURE);
116 }
117 } catch (TitanException e) {
118 /*
119 * retry till we succeed?
120 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800121 log.error("addOrUpdateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
122 e.printStackTrace();
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800123 }
124 }
125
126 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800127 public void deleteLinks(List<Link> links) {
128
129 for (Link lt : links) {
130 deleteLink(lt);
131 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800132 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800133
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800134
135 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800136 public void deleteLink(Link lt) {
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700137 GraphDBConnection conn = GraphDBConnection.getInstance("");
138 IPortObject vportSrc = null, vportDst = null;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800139 int count = 0;
140
141 log.debug("deleteLink(): {}", lt);
142
143 try {
144 // get source port vertex
145 String dpid = HexString.toHexString(lt.getSrc());
146 short port = lt.getSrcPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700147 vportSrc = conn.utils().searchPort(conn, dpid, port);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800148
149 // get dst port vertex
150 dpid = HexString.toHexString(lt.getDst());
151 port = lt.getDstPort();
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700152 vportDst = conn.utils().searchPort(conn, dpid, port);
153 // FIXME: This needs to remove all edges
154 // FIXME: Events will only be generated on singleton graph object (GraphDBConnection)
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800155
156 if (vportSrc != null && vportDst != null) {
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700157
158 /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800159 log.debug("deleteLink(): {} in {} out {}",
160 new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
161 if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800162 graph.removeEdge(e);
163 count++;
164 }
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700165 }*/
166 vportSrc.removeLink(vportDst);
167 conn.endTx(Transaction.COMMIT, GenerateEvent.TRUE);
168 log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
169 lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800170
171 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800172 log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
Pankaj Berde2239f0d2013-04-04 09:42:43 -0700173 conn.endTx(Transaction.ROLLBACK);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800174 }
175
176 } catch (TitanException e) {
177 /*
178 * retry till we succeed?
179 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800180 log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
181 e.printStackTrace();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800182 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800183 }
184
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800185 // TODO: Fix me
186 @Override
187 public List<Link> getLinks(Long dpid, short port) {
188 Vertex vportSrc, vportDst;
189 List<Link> links = null;
190 Link lt;
191
192 vportSrc = getPortVertex(HexString.toHexString(dpid), port);
193 if (vportSrc != null) {
194 for (Edge e : vportSrc.getEdges(Direction.OUT)) {
195 if (e.getLabel().equals("link")) {
196 break;
197 }
198 }
199 }
200 return null;
201 }
202
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800203 @Override
204 public void init(String conf) {
Pankaj Berde1f10be02013-02-01 14:06:02 -0800205 //TODO extract the DB location from properties
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800206
207 graph = TitanFactory.open(conf);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800208
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800209 // 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 -0800210 Set<String> s = graph.getIndexedKeys(Vertex.class);
211 if (!s.contains("dpid")) {
212 graph.createKeyIndex("dpid", Vertex.class);
213 graph.stopTransaction(Conclusion.SUCCESS);
214 }
215 if (!s.contains("type")) {
216 graph.createKeyIndex("type", Vertex.class);
217 graph.stopTransaction(Conclusion.SUCCESS);
218 }
219 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800220
221 @Override
222 public void deleteLinksOnPort(Long dpid, short port) {
223 // TODO Auto-generated method stub
224
225 }
226
Pankaj Berdeff421802013-01-29 20:28:52 -0800227 @Override
228 public List<Link> getLinks(String dpid) {
229 // TODO Auto-generated method stub
230 return null;
231 }
232
233 public List<Link> getActiveLinks() {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800234
235 ITopoSwitchService swService = new TopoSwitchServiceImpl();
Pankaj Berdeff421802013-01-29 20:28:52 -0800236
Pankaj Berde1cde50b2013-02-19 20:16:06 -0800237 Iterable<ISwitchObject> switches = swService.getActiveSwitches();
Pankaj Berde5024ec12013-01-31 17:07:29 -0800238
239 List<Link> links = new ArrayList<Link>();
240 for (ISwitchObject sw : switches) {
241 GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
242 ExtractLink extractor = new ExtractLink();
243
244 pipe.start(sw.asVertex());
245 pipe.enablePath(true);
Pankaj Berde1f10be02013-02-01 14:06:02 -0800246 pipe.out("on").out("link").in("on").path().step(extractor);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800247
Pankaj Berde1f10be02013-02-01 14:06:02 -0800248 while (pipe.hasNext() ) {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800249 Link l = pipe.next();
250 links.add(l);
251 }
252
253 }
254 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800255 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800256
257 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
258
Pankaj Berde5024ec12013-01-31 17:07:29 -0800259 @Override
260 public Link compute(PathPipe<Vertex> pipe ) {
Pankaj Berded18c7622013-02-04 10:28:35 -0800261 // TODO Auto-generated method stub
Pankaj Berde5024ec12013-01-31 17:07:29 -0800262 long s_dpid = 0;
263 long d_dpid = 0;
264 short s_port = 0;
265 short d_port = 0;
266 List<Vertex> V = new ArrayList<Vertex>();
267 V = pipe.next();
268 Vertex src_sw = V.get(0);
269 Vertex dest_sw = V.get(3);
270 Vertex src_port = V.get(1);
271 Vertex dest_port = V.get(2);
272 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
273 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
274 s_port = (Short) src_port.getProperty("number");
275 d_port = (Short) dest_port.getProperty("number");
276
277 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
278
279 return l;
280 }
281 }
Pankaj Berded18c7622013-02-04 10:28:35 -0800282
283 public void finalize() {
284 close();
285 }
286
287 @Override
288 public void close() {
289 // TODO Auto-generated method stub
290 graph.shutdown();
291 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800292
Pankaj Berdeff421802013-01-29 20:28:52 -0800293
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800294}