blob: ccb64f82e067e1a41713afcdadae35dfe6287016 [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 Radoslavovd7d8b792013-02-22 10:24:38 -08005import java.util.HashMap;
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -08006import java.util.Map;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -08007
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -07008import net.floodlightcontroller.core.IFloodlightProviderService;
9import net.floodlightcontroller.core.module.FloodlightModuleContext;
10import net.floodlightcontroller.core.module.FloodlightModuleException;
11import net.floodlightcontroller.core.module.IFloodlightModule;
12import net.floodlightcontroller.core.module.IFloodlightService;
13
14import net.onrc.onos.datagrid.IDatagridService;
Pankaj Berde38646d62013-06-21 11:34:04 -070015import net.onrc.onos.graph.GraphDBOperation;
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070016import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
HIGUCHI Yuta356086e2013-06-12 15:21:19 -070017import net.onrc.onos.ofcontroller.util.DataPath;
HIGUCHI Yuta356086e2013-06-12 15:21:19 -070018import net.onrc.onos.ofcontroller.util.SwitchPort;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080019
Pankaj Berde15193092013-03-21 17:30:14 -070020import org.slf4j.Logger;
21import org.slf4j.LoggerFactory;
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080022
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -070023/**
Pavlin Radoslavov1278ac72013-10-16 04:43:49 -070024 * A class for implementing Topology Network Service.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070025 */
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070026public class TopologyManager implements IFloodlightModule,
27 ITopologyNetService {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070028 private final static Logger log = LoggerFactory.getLogger(TopologyManager.class);
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070029 protected IFloodlightProviderService floodlightProvider;
30
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070031 protected GraphDBOperation dbHandler;
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080032
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070033
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070034 /**
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070035 * Default constructor.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070036 */
Pavlin Radoslavove1b37bc2013-10-16 03:57:06 -070037 public TopologyManager() {
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080038 }
39
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070040 /**
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070041 * Constructor for given database configuration file.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070042 *
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070043 * @param config the database configuration file to use for
44 * the initialization.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070045 */
Pavlin Radoslavove1b37bc2013-10-16 03:57:06 -070046 public TopologyManager(String config) {
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070047 this.init(config);
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080048 }
49
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070050 /**
Pavlin Radoslavov0367d352013-10-19 11:04:43 -070051 * Constructor for a given database operation handler.
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070052 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070053 * @param dbHandler the database operation handler to use for the
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070054 * initialization.
55 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070056 public TopologyManager(GraphDBOperation dbHandler) {
57 this.dbHandler = dbHandler;
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070058 }
59
60 /**
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070061 * Init the module.
62 *
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070063 * @param config the database configuration file to use for
64 * the initialization.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070065 */
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070066 public void init(String config) {
67 try {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070068 dbHandler = new GraphDBOperation(config);
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070069 } catch (Exception e) {
70 log.error(e.getMessage());
71 }
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080072 }
73
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070074 /**
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070075 * Shutdown the Topology Manager operation.
76 */
77 public void finalize() {
78 close();
79 }
80
81 /**
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070082 * Close the service. It will close the corresponding database connection.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070083 */
Pavlin Radoslavovddd01ba2013-07-03 15:40:44 -070084 public void close() {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -070085 dbHandler.close();
Pavlin Radoslavovd7d8b792013-02-22 10:24:38 -080086 }
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -080087
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070088 /**
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070089 * Get the collection of offered module services.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070090 *
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070091 * @return the collection of offered module services.
Pavlin Radoslavovc5d2fbc2013-06-27 18:15:56 -070092 */
Pavlin Radoslavov5d8d77e2013-10-18 18:49:25 -070093 @Override
94 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
95 Collection<Class<? extends IFloodlightService>> l =
96 new ArrayList<Class<? extends IFloodlightService>>();
97 l.add(ITopologyNetService.class);
98 return l;
99 }
100
101 /**
102 * Get the collection of implemented services.
103 *
104 * @return the collection of implemented services.
105 */
106 @Override
107 public Map<Class<? extends IFloodlightService>, IFloodlightService>
108 getServiceImpls() {
109 Map<Class<? extends IFloodlightService>,
110 IFloodlightService> m =
111 new HashMap<Class<? extends IFloodlightService>,
112 IFloodlightService>();
113 m.put(ITopologyNetService.class, this);
114 return m;
115 }
116
117 /**
118 * Get the collection of modules this module depends on.
119 *
120 * @return the collection of modules this module depends on.
121 */
122 @Override
123 public Collection<Class<? extends IFloodlightService>>
124 getModuleDependencies() {
125 Collection<Class<? extends IFloodlightService>> l =
126 new ArrayList<Class<? extends IFloodlightService>>();
127 l.add(IFloodlightProviderService.class);
128 l.add(INetworkGraphService.class);
129 l.add(IDatagridService.class);
130 return l;
131 }
132
133 /**
134 * Initialize the module.
135 *
136 * @param context the module context to use for the initialization.
137 */
138 @Override
139 public void init(FloodlightModuleContext context)
140 throws FloodlightModuleException {
141 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
142
143 String conf = "";
144 this.init(conf);
145 }
146
147 /**
148 * Startup module operation.
149 *
150 * @param context the module context to use for the startup.
151 */
152 @Override
153 public void startUp(FloodlightModuleContext context) {
154
Pavlin Radoslavovcec899a2013-06-27 15:47:50 -0700155 }
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -0800156
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700157 /**
158 * Fetch the Switch and Ports info from the Titan Graph
Pavlin Radoslavov9556b142013-05-20 21:49:04 +0000159 * and return it for fast access during the shortest path
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700160 * computation.
161 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700162 * After fetching the state, method @ref getTopologyShortestPath()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700163 * can be used for fast shortest path computation.
164 *
165 * Note: There is certain cost to fetch the state, hence it should
166 * be used only when there is a large number of shortest path
167 * computations that need to be done on the same topology.
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700168 * Typically, a single call to @ref newDatabaseTopology()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700169 * should be followed by a large number of calls to
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700170 * method @ref getTopologyShortestPath().
171 * After the last @ref getTopologyShortestPath() call,
172 * method @ref dropTopology() should be used to release
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700173 * the internal state that is not needed anymore:
174 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700175 * Topology topology = topologyManager.newDatabaseTopology();
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700176 * for (int i = 0; i < 10000; i++) {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700177 * dataPath = topologyManager.getTopologyShortestPath(topology, ...);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700178 * ...
179 * }
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700180 * topologyManager.dropTopology(shortestPathTopo);
Pavlin Radoslavov9556b142013-05-20 21:49:04 +0000181 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700182 * @return the allocated topology handler.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700183 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700184 public Topology newDatabaseTopology() {
185 Topology topology = new Topology();
186 topology.readFromDatabase(dbHandler);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700187
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700188 return topology;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700189 }
190
191 /**
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700192 * Release the topology that was populated by
193 * method @ref newDatabaseTopology().
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700194 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700195 * See the documentation for method @ref newDatabaseTopology()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700196 * for additional information and usage.
Pavlin Radoslavov9556b142013-05-20 21:49:04 +0000197 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700198 * @param topology the topology to release.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700199 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700200 public void dropTopology(Topology topology) {
201 topology = null;
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700202 }
203
204 /**
205 * Get the shortest path from a source to a destination by
206 * using the pre-populated local topology state prepared
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700207 * by method @ref newDatabaseTopology().
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700208 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700209 * See the documentation for method @ref newDatabaseTopology()
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700210 * for additional information and usage.
211 *
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700212 * @param topology the topology handler to use.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700213 * @param src the source in the shortest path computation.
214 * @param dest the destination in the shortest path computation.
215 * @return the data path with the computed shortest path if
216 * found, otherwise null.
217 */
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700218 public DataPath getTopologyShortestPath(Topology topology,
219 SwitchPort src, SwitchPort dest) {
220 return ShortestPath.getTopologyShortestPath(topology, src, dest);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700221 }
222
223 /**
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700224 * Get the shortest path from a source to a destination by using
225 * the underlying database.
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700226 *
227 * @param src the source in the shortest path computation.
228 * @param dest the destination in the shortest path computation.
229 * @return the data path with the computed shortest path if
230 * found, otherwise null.
231 */
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800232 @Override
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700233 public DataPath getDatabaseShortestPath(SwitchPort src, SwitchPort dest) {
234 return ShortestPath.getDatabaseShortestPath(dbHandler, src, dest);
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800235 }
236
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700237 /**
238 * Test whether a route exists from a source to a destination.
239 *
240 * @param src the source node for the test.
241 * @param dest the destination node for the test.
242 * @return true if a route exists, otherwise false.
243 */
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800244 @Override
Pavlin Radoslavovf83aa442013-02-26 14:09:01 -0800245 public Boolean routeExists(SwitchPort src, SwitchPort dest) {
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700246 DataPath dataPath = getDatabaseShortestPath(src, dest);
Pavlin Radoslavova5f167b2013-03-21 11:39:27 -0700247 return (dataPath != null);
Pavlin Radoslavovf34c2902013-02-22 10:33:34 -0800248 }
Pavlin Radoslavov382b22a2013-01-28 09:24:04 -0800249}