blob: c027998f0554860ece21d7edeb3d0e6136c31b79 [file] [log] [blame]
Pavlin Radoslavove1b37bc2013-10-16 03:57:06 -07001package net.onrc.onos.ofcontroller.topology;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -08002
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -07003import java.util.ArrayList;
4import java.util.Collection;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -07005import java.util.Collections;
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -08006import java.util.HashMap;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -07007import java.util.HashSet;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -07008import java.util.LinkedList;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -08009import java.util.List;
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080010import java.util.Map;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -070011import java.util.Queue;
12import java.util.Set;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080013
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070014import net.floodlightcontroller.core.IFloodlightProviderService;
15import net.floodlightcontroller.core.module.FloodlightModuleContext;
16import net.floodlightcontroller.core.module.FloodlightModuleException;
17import net.floodlightcontroller.core.module.IFloodlightModule;
18import net.floodlightcontroller.core.module.IFloodlightService;
19
20import net.onrc.onos.datagrid.IDatagridService;
Pankaj Berde38646d62013-06-21 11:34:04 -070021import net.onrc.onos.graph.GraphDBOperation;
HIGUCHI Yuta20514902013-06-12 11:24:16 -070022import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
HIGUCHI Yuta20514902013-06-12 11:24:16 -070023import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070024import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
HIGUCHI Yuta356086e2013-06-12 15:21:19 -070025import net.onrc.onos.ofcontroller.util.DataPath;
26import net.onrc.onos.ofcontroller.util.Dpid;
27import net.onrc.onos.ofcontroller.util.FlowEntry;
28import net.onrc.onos.ofcontroller.util.Port;
29import net.onrc.onos.ofcontroller.util.SwitchPort;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080030
31import org.openflow.util.HexString;
Pankaj Berde15193092013-03-21 17:30:14 -070032import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080034
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -070035import com.tinkerpop.blueprints.Direction;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080036import com.tinkerpop.blueprints.Vertex;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080037
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -070038
39/**
Pavlin Radoslavov1278ac72013-10-16 04:43:49 -070040 * A class for implementing Topology Network Service.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070041 */
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070042public class TopologyManager implements IFloodlightModule,
43 ITopologyNetService {
Pavlin Radoslavove1b37bc2013-10-16 03:57:06 -070044 private static Logger log = LoggerFactory.getLogger(TopologyManager.class);
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070045 protected IFloodlightProviderService floodlightProvider;
46
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070047 protected GraphDBOperation dbHandler;
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080048
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070049
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070050 /**
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070051 * Default constructor.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070052 */
Pavlin Radoslavove1b37bc2013-10-16 03:57:06 -070053 public TopologyManager() {
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080054 }
55
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070056 /**
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070057 * Constructor for given database configuration file.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070058 *
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070059 * @param config the database configuration file to use for
60 * the initialization.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070061 */
Pavlin Radoslavove1b37bc2013-10-16 03:57:06 -070062 public TopologyManager(String config) {
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070063 this.init(config);
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080064 }
65
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070066 /**
Pavlin Radoslavov0367d352013-10-19 11:04:43 -070067 * Constructor for a given database operation handler.
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070068 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070069 * @param dbHandler the database operation handler to use for the
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070070 * initialization.
71 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070072 public TopologyManager(GraphDBOperation dbHandler) {
73 this.dbHandler = dbHandler;
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070074 }
75
76 /**
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070077 * Init the module.
78 *
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070079 * @param config the database configuration file to use for
80 * the initialization.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070081 */
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070082 public void init(String config) {
83 try {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070084 dbHandler = new GraphDBOperation(config);
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070085 } catch (Exception e) {
86 log.error(e.getMessage());
87 }
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080088 }
89
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070090 /**
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070091 * Shutdown the Topology Manager operation.
92 */
93 public void finalize() {
94 close();
95 }
96
97 /**
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070098 * Close the service. It will close the corresponding database connection.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070099 */
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -0700100 public void close() {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700101 dbHandler.close();
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -0800102 }
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -0800103
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -0700104 /**
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -0700105 * Get the collection of offered module services.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -0700106 *
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -0700107 * @return the collection of offered module services.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -0700108 */
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -0700109 @Override
110 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
111 Collection<Class<? extends IFloodlightService>> l =
112 new ArrayList<Class<? extends IFloodlightService>>();
113 l.add(ITopologyNetService.class);
114 return l;
115 }
116
117 /**
118 * Get the collection of implemented services.
119 *
120 * @return the collection of implemented services.
121 */
122 @Override
123 public Map<Class<? extends IFloodlightService>, IFloodlightService>
124 getServiceImpls() {
125 Map<Class<? extends IFloodlightService>,
126 IFloodlightService> m =
127 new HashMap<Class<? extends IFloodlightService>,
128 IFloodlightService>();
129 m.put(ITopologyNetService.class, this);
130 return m;
131 }
132
133 /**
134 * Get the collection of modules this module depends on.
135 *
136 * @return the collection of modules this module depends on.
137 */
138 @Override
139 public Collection<Class<? extends IFloodlightService>>
140 getModuleDependencies() {
141 Collection<Class<? extends IFloodlightService>> l =
142 new ArrayList<Class<? extends IFloodlightService>>();
143 l.add(IFloodlightProviderService.class);
144 l.add(INetworkGraphService.class);
145 l.add(IDatagridService.class);
146 return l;
147 }
148
149 /**
150 * Initialize the module.
151 *
152 * @param context the module context to use for the initialization.
153 */
154 @Override
155 public void init(FloodlightModuleContext context)
156 throws FloodlightModuleException {
157 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
158
159 String conf = "";
160 this.init(conf);
161 }
162
163 /**
164 * Startup module operation.
165 *
166 * @param context the module context to use for the startup.
167 */
168 @Override
169 public void startUp(FloodlightModuleContext context) {
170
Pavlin Radoslavovcec899a2013-06-27 15:47:50 -0700171 }
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -0800172
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700173 /**
174 * Fetch the Switch and Ports info from the Titan Graph
Pavlin Radoslavov9556b142013-05-20 21:49:04 +0000175 * and return it for fast access during the shortest path
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700176 * computation.
177 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700178 * After fetching the state, method @ref getTopologyShortestPath()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700179 * can be used for fast shortest path computation.
180 *
181 * Note: There is certain cost to fetch the state, hence it should
182 * be used only when there is a large number of shortest path
183 * computations that need to be done on the same topology.
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700184 * Typically, a single call to @ref newDatabaseTopology()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700185 * should be followed by a large number of calls to
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700186 * method @ref getTopologyShortestPath().
187 * After the last @ref getTopologyShortestPath() call,
188 * method @ref dropTopology() should be used to release
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700189 * the internal state that is not needed anymore:
190 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700191 * Topology topology = topologyManager.newDatabaseTopology();
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700192 * for (int i = 0; i < 10000; i++) {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700193 * dataPath = topologyManager.getTopologyShortestPath(topology, ...);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700194 * ...
195 * }
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700196 * topologyManager.dropTopology(shortestPathTopo);
Pavlin Radoslavov9556b142013-05-20 21:49:04 +0000197 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700198 * @return the allocated topology handler.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700199 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700200 public Topology newDatabaseTopology() {
201 Topology topology = new Topology();
202 topology.readFromDatabase(dbHandler);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700203
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700204 return topology;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700205 }
206
207 /**
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700208 * Release the topology that was populated by
209 * method @ref newDatabaseTopology().
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700210 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700211 * See the documentation for method @ref newDatabaseTopology()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700212 * for additional information and usage.
Pavlin Radoslavov9556b142013-05-20 21:49:04 +0000213 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700214 * @param topology the topology to release.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700215 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700216 public void dropTopology(Topology topology) {
217 topology = null;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700218 }
219
220 /**
221 * Get the shortest path from a source to a destination by
222 * using the pre-populated local topology state prepared
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700223 * by method @ref newDatabaseTopology().
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700224 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700225 * See the documentation for method @ref newDatabaseTopology()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700226 * for additional information and usage.
227 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700228 * @param topology the topology handler to use.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700229 * @param src the source in the shortest path computation.
230 * @param dest the destination in the shortest path computation.
231 * @return the data path with the computed shortest path if
232 * found, otherwise null.
233 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700234 public DataPath getTopologyShortestPath(Topology topology,
235 SwitchPort src, SwitchPort dest) {
236 return ShortestPath.getTopologyShortestPath(topology, src, dest);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700237 }
238
239 /**
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700240 * Get the shortest path from a source to a destination by using
241 * the underlying database.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700242 *
243 * @param src the source in the shortest path computation.
244 * @param dest the destination in the shortest path computation.
245 * @return the data path with the computed shortest path if
246 * found, otherwise null.
247 */
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800248 @Override
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700249 public DataPath getDatabaseShortestPath(SwitchPort src, SwitchPort dest) {
250 return ShortestPath.getDatabaseShortestPath(dbHandler, src, dest);
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800251 }
252
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700253 /**
254 * Test whether a route exists from a source to a destination.
255 *
256 * @param src the source node for the test.
257 * @param dest the destination node for the test.
258 * @return true if a route exists, otherwise false.
259 */
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800260 @Override
Pavlin Radoslavovf83aa442013-02-26 14:09:01 -0800261 public Boolean routeExists(SwitchPort src, SwitchPort dest) {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700262 DataPath dataPath = getDatabaseShortestPath(src, dest);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700263 return (dataPath != null);
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800264 }
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -0800265}