blob: 176a1a034600b4b3ee7e9ae8cf888d5a842b5372 [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 Berde1e2f7312013-02-15 08:25:31 -08008import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
Pankaj Berde5024ec12013-01-31 17:07:29 -08009import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
Pankaj Berde5024ec12013-01-31 17:07:29 -080010import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080011import net.floodlightcontroller.linkdiscovery.ILinkStorage;
12import net.floodlightcontroller.linkdiscovery.LinkInfo;
13import net.floodlightcontroller.routing.Link;
14
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080015import org.openflow.util.HexString;
16import org.slf4j.Logger;
17import org.slf4j.LoggerFactory;
18
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080019import com.thinkaurelius.titan.core.TitanException;
20import com.thinkaurelius.titan.core.TitanFactory;
21import com.thinkaurelius.titan.core.TitanGraph;
22import com.tinkerpop.blueprints.Direction;
23import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
24import com.tinkerpop.blueprints.Vertex;
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080025import com.tinkerpop.blueprints.Edge;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080026import com.tinkerpop.gremlin.java.GremlinPipeline;
Pankaj Berde5024ec12013-01-31 17:07:29 -080027import com.tinkerpop.pipes.PipeFunction;
28import com.tinkerpop.pipes.transform.PathPipe;
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080029
30public class LinkStorageImpl implements ILinkStorage {
31 public TitanGraph graph;
32 protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080033
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080034 @Override
35 public void update(Link link, DM_OPERATION op) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080036 update(link, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080037 }
38
39 @Override
40 public void update(List<Link> links, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080041 for (Link lt: links) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080042 update(lt, (LinkInfo)null, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080043 }
44 }
45
46 @Override
47 public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080048 switch (op) {
49 case UPDATE:
50 case CREATE:
51 case INSERT:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080052 addOrUpdateLink(link, linkinfo, op);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080053 break;
54 case DELETE:
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080055 deleteLink(link);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080056 break;
57 }
58 }
59
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080060 private Vertex getPortVertex(String dpid, short port) {
61 Vertex vsw, vport = null;
62 if ((vsw = graph.getVertices("dpid", dpid).iterator().next()) != null) {
63 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
64 pipe.start(vsw).out("on").has("number", port);
65 if (pipe.hasNext()) {
66 vport = pipe.next();
67 }
68 }
69 return vport;
70 }
71
72 public void addOrUpdateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080073 Vertex vportSrc = null, vportDst = null;
74
Umesh Krishnaswamy0ef75ee2013-03-25 17:50:27 -070075 log.trace("addOrUpdateLink(): op {} {} {}", new Object[]{op, lt, linkinfo});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080076
77 try {
78 // get source port vertex
79 String dpid = HexString.toHexString(lt.getSrc());
80 short port = lt.getSrcPort();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080081 vportSrc = getPortVertex(dpid, port);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080082
83 // get dest port vertex
84 dpid = HexString.toHexString(lt.getDst());
85 port = lt.getDstPort();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080086 vportDst = getPortVertex(dpid, port);
87
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -080088 if (vportSrc != null && vportDst != null) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080089
90 // check if the link exists
Pankaj Berde6debb042013-01-16 18:04:32 -080091 List<Vertex> currLinks = new ArrayList<Vertex>();
92 for (Vertex V : vportSrc.query().direction(Direction.OUT).labels("link").vertices()) {
93 currLinks.add(V);
94 }
95
96 if (currLinks.contains(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -080097 // TODO: update linkinfo
98 if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -080099 log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800100 new Object[]{op, lt, vportSrc, vportDst});
101 }
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800102 } else {
103 graph.addEdge(null, vportSrc, vportDst, "link");
104 graph.stopTransaction(Conclusion.SUCCESS);
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800105 log.debug("addOrUpdateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Pankaj Berde0fc4e432013-01-12 09:47:22 -0800106 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800107 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800108 log.error("addOrUpdateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800109 graph.stopTransaction(Conclusion.FAILURE);
110 }
111 } catch (TitanException e) {
112 /*
113 * retry till we succeed?
114 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800115 log.error("addOrUpdateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
116 e.printStackTrace();
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800117 }
118 }
119
120 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800121 public void deleteLinks(List<Link> links) {
122
123 for (Link lt : links) {
124 deleteLink(lt);
125 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800126 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800127
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800128
129 @Override
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800130 public void deleteLink(Link lt) {
131 Vertex vportSrc = null, vportDst = null;
132 int count = 0;
133
134 log.debug("deleteLink(): {}", lt);
135
136 try {
137 // get source port vertex
138 String dpid = HexString.toHexString(lt.getSrc());
139 short port = lt.getSrcPort();
140 vportSrc = getPortVertex(dpid, port);
141
142 // get dst port vertex
143 dpid = HexString.toHexString(lt.getDst());
144 port = lt.getDstPort();
145 vportDst = getPortVertex(dpid, port);
146
147 if (vportSrc != null && vportDst != null) {
148 for (Edge e : vportSrc.getEdges(Direction.OUT)) {
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800149 log.debug("deleteLink(): {} in {} out {}",
150 new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
151 if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800152 graph.removeEdge(e);
153 count++;
154 }
155 }
156 graph.stopTransaction(Conclusion.SUCCESS);
Umesh Krishnaswamy11060ed2013-01-23 19:24:36 -0800157 log.debug("deleteLink(): deleted {} edges {} src {} dst {}", new Object[]{
158 count, lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800159
160 } else {
Umesh Krishnaswamy9306f952013-01-24 20:42:59 -0800161 log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800162 graph.stopTransaction(Conclusion.FAILURE);
163 }
164
165 } catch (TitanException e) {
166 /*
167 * retry till we succeed?
168 */
Umesh Krishnaswamyc56a8cc2013-01-24 21:47:51 -0800169 log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
170 e.printStackTrace();
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800171 }
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800172 }
173
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800174 // TODO: Fix me
175 @Override
176 public List<Link> getLinks(Long dpid, short port) {
177 Vertex vportSrc, vportDst;
178 List<Link> links = null;
179 Link lt;
180
181 vportSrc = getPortVertex(HexString.toHexString(dpid), port);
182 if (vportSrc != null) {
183 for (Edge e : vportSrc.getEdges(Direction.OUT)) {
184 if (e.getLabel().equals("link")) {
185 break;
186 }
187 }
188 }
189 return null;
190 }
191
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800192 @Override
193 public void init(String conf) {
Pankaj Berde1f10be02013-02-01 14:06:02 -0800194 //TODO extract the DB location from properties
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800195
196 graph = TitanFactory.open(conf);
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800197
Pankaj Berde67f88fb2013-01-15 17:16:01 -0800198 // 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 -0800199 Set<String> s = graph.getIndexedKeys(Vertex.class);
200 if (!s.contains("dpid")) {
201 graph.createKeyIndex("dpid", Vertex.class);
202 graph.stopTransaction(Conclusion.SUCCESS);
203 }
204 if (!s.contains("type")) {
205 graph.createKeyIndex("type", Vertex.class);
206 graph.stopTransaction(Conclusion.SUCCESS);
207 }
208 }
Umesh Krishnaswamyf962d642013-01-23 19:04:23 -0800209
210 @Override
211 public void deleteLinksOnPort(Long dpid, short port) {
212 // TODO Auto-generated method stub
213
214 }
215
Pankaj Berdeff421802013-01-29 20:28:52 -0800216 @Override
217 public List<Link> getLinks(String dpid) {
218 // TODO Auto-generated method stub
219 return null;
220 }
221
222 public List<Link> getActiveLinks() {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800223
224 ITopoSwitchService swService = new TopoSwitchServiceImpl();
Pankaj Berdeff421802013-01-29 20:28:52 -0800225
Pankaj Berde1cde50b2013-02-19 20:16:06 -0800226 Iterable<ISwitchObject> switches = swService.getActiveSwitches();
Pankaj Berde5024ec12013-01-31 17:07:29 -0800227
228 List<Link> links = new ArrayList<Link>();
229 for (ISwitchObject sw : switches) {
230 GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
231 ExtractLink extractor = new ExtractLink();
232
233 pipe.start(sw.asVertex());
234 pipe.enablePath(true);
Pankaj Berde1f10be02013-02-01 14:06:02 -0800235 pipe.out("on").out("link").in("on").path().step(extractor);
Pankaj Berde5024ec12013-01-31 17:07:29 -0800236
Pankaj Berde1f10be02013-02-01 14:06:02 -0800237 while (pipe.hasNext() ) {
Pankaj Berde5024ec12013-01-31 17:07:29 -0800238 Link l = pipe.next();
239 links.add(l);
240 }
241
242 }
243 return links;
Pankaj Berdeff421802013-01-29 20:28:52 -0800244 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800245
246 static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
247
Pankaj Berde5024ec12013-01-31 17:07:29 -0800248 @Override
249 public Link compute(PathPipe<Vertex> pipe ) {
Pankaj Berded18c7622013-02-04 10:28:35 -0800250 // TODO Auto-generated method stub
Pankaj Berde5024ec12013-01-31 17:07:29 -0800251 long s_dpid = 0;
252 long d_dpid = 0;
253 short s_port = 0;
254 short d_port = 0;
255 List<Vertex> V = new ArrayList<Vertex>();
256 V = pipe.next();
257 Vertex src_sw = V.get(0);
258 Vertex dest_sw = V.get(3);
259 Vertex src_port = V.get(1);
260 Vertex dest_port = V.get(2);
261 s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
262 d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
263 s_port = (Short) src_port.getProperty("number");
264 d_port = (Short) dest_port.getProperty("number");
265
266 Link l = new Link(s_dpid,s_port,d_dpid,d_port);
267
268 return l;
269 }
270 }
Pankaj Berded18c7622013-02-04 10:28:35 -0800271
272 public void finalize() {
273 close();
274 }
275
276 @Override
277 public void close() {
278 // TODO Auto-generated method stub
279 graph.shutdown();
280 }
Pankaj Berde5024ec12013-01-31 17:07:29 -0800281
Pankaj Berdeff421802013-01-29 20:28:52 -0800282
Umesh Krishnaswamyb676ca22013-01-11 12:39:25 -0800283}