blob: 14c63df66a467f96d3752e892a45e558e201c58f [file] [log] [blame]
Toshio Koidea03915e2014-07-01 18:39:52 -07001package net.onrc.onos.core.flowmanager;
2
Toshio Koide84648822014-08-21 02:07:56 -07003import static com.google.common.base.Preconditions.checkNotNull;
4import static com.google.common.base.Preconditions.checkState;
Toshio Koidea03915e2014-07-01 18:39:52 -07005
Toshio Koide03eba332014-08-26 10:46:55 -07006import java.util.ArrayList;
Toshio Koide84648822014-08-21 02:07:56 -07007import java.util.Arrays;
8import java.util.Collection;
Toshio Koide03eba332014-08-26 10:46:55 -07009import java.util.HashMap;
Toshio Koide84648822014-08-21 02:07:56 -070010import java.util.List;
Toshio Koide03eba332014-08-26 10:46:55 -070011import java.util.Map;
Toshio Koide84648822014-08-21 02:07:56 -070012
Toshio Koide03eba332014-08-26 10:46:55 -070013import net.floodlightcontroller.core.module.FloodlightModuleContext;
14import net.floodlightcontroller.core.module.FloodlightModuleException;
15import net.floodlightcontroller.core.module.IFloodlightModule;
16import net.floodlightcontroller.core.module.IFloodlightService;
Toshio Koide84648822014-08-21 02:07:56 -070017import net.onrc.onos.api.batchoperation.BatchOperationEntry;
Toshio Koidea03915e2014-07-01 18:39:52 -070018import net.onrc.onos.api.flowmanager.ConflictDetectionPolicy;
Toshio Koideb8cea262014-08-12 18:45:46 -070019import net.onrc.onos.api.flowmanager.Flow;
Toshio Koidefc5acc72014-08-12 18:45:46 -070020import net.onrc.onos.api.flowmanager.FlowBatchHandle;
Toshio Koide7db3ce92014-08-27 16:57:43 -070021import net.onrc.onos.api.flowmanager.FlowBatchId;
Toshio Koide4ea84192014-07-31 12:10:12 -070022import net.onrc.onos.api.flowmanager.FlowBatchOperation;
Toshio Koide84648822014-08-21 02:07:56 -070023import net.onrc.onos.api.flowmanager.FlowBatchOperation.Operator;
Toshio Koide025a9152014-07-21 11:00:34 -070024import net.onrc.onos.api.flowmanager.FlowId;
Toshio Koide03eba332014-08-26 10:46:55 -070025import net.onrc.onos.api.flowmanager.FlowManagerFloodlightService;
Toshio Koideb8cea262014-08-12 18:45:46 -070026import net.onrc.onos.api.flowmanager.FlowManagerListener;
Toshio Koide7db3ce92014-08-27 16:57:43 -070027import net.onrc.onos.core.datagrid.ISharedCollectionsService;
Toshio Koide77ec9982014-08-27 16:57:43 -070028import net.onrc.onos.core.matchaction.MatchActionFloodlightService;
Sho SHIMIZU7cd8a422014-08-27 16:05:21 -070029import net.onrc.onos.core.matchaction.MatchActionId;
Toshio Koide84648822014-08-21 02:07:56 -070030import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
31import net.onrc.onos.core.matchaction.MatchActionOperations;
Sho SHIMIZU7cd8a422014-08-27 16:05:21 -070032import net.onrc.onos.core.matchaction.MatchActionOperationsId;
Toshio Koide77ec9982014-08-27 16:57:43 -070033import net.onrc.onos.core.matchaction.MatchActionService;
Toshio Koide03eba332014-08-26 10:46:55 -070034import net.onrc.onos.core.registry.IControllerRegistryService;
Toshio Koide84648822014-08-21 02:07:56 -070035import net.onrc.onos.core.util.IdBlockAllocator;
Sho SHIMIZU7cd8a422014-08-27 16:05:21 -070036import net.onrc.onos.core.util.IdGenerator;
Toshio Koidea03915e2014-07-01 18:39:52 -070037
38/**
Toshio Koide7894ca02014-08-15 14:30:13 -070039 * Manages a set of Flow objects, computes and maintains a set of Match-Action
40 * entries based on the Flow objects, and executes Match-Action plans.
Toshio Koidea03915e2014-07-01 18:39:52 -070041 * <p>
42 * TODO: Make all methods thread-safe
43 */
Toshio Koide03eba332014-08-26 10:46:55 -070044public class FlowManagerModule implements FlowManagerFloodlightService, IFloodlightModule {
Toshio Koided46b66d2014-07-21 10:27:27 -070045 private ConflictDetectionPolicy conflictDetectionPolicy;
Toshio Koide7db3ce92014-08-27 16:57:43 -070046 private FlowIdGeneratorWithIdBlockAllocator flowIdGenerator;
47 private FlowBatchIdGeneratorWithIdBlockAllocator flowBatchIdGenerator;
Sho SHIMIZU7cd8a422014-08-27 16:05:21 -070048 private IdGenerator<MatchActionId> maIdGenerator;
49 private IdGenerator<MatchActionOperationsId> maoIdGenerator;
Toshio Koide77ec9982014-08-27 16:57:43 -070050 private MatchActionService matchActionService;
Toshio Koide03eba332014-08-26 10:46:55 -070051 private IControllerRegistryService registryService;
Toshio Koide7db3ce92014-08-27 16:57:43 -070052 private ISharedCollectionsService sharedCollectionService;
53 private FlowMap flowMap;
54 private FlowBatchMap flowBatchMap;
Toshio Koided6dbb952014-08-22 14:29:04 -070055 private FlowEventDispatcher flowEventDispatcher;
Toshio Koided46b66d2014-07-21 10:27:27 -070056
Toshio Koide03eba332014-08-26 10:46:55 -070057 @Override
58 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
59 List<Class<? extends IFloodlightService>> services =
60 new ArrayList<Class<? extends IFloodlightService>>();
61 services.add(FlowManagerFloodlightService.class);
62 return services;
63 }
64
65 @Override
66 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
67 Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
68 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
69 impls.put(FlowManagerFloodlightService.class, this);
70 return impls;
71 }
72
73 @Override
74 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
75 return Arrays.asList(
Toshio Koide77ec9982014-08-27 16:57:43 -070076 MatchActionFloodlightService.class,
Toshio Koide7db3ce92014-08-27 16:57:43 -070077 ISharedCollectionsService.class,
Toshio Koide03eba332014-08-26 10:46:55 -070078 IControllerRegistryService.class);
79 }
80
81 @Override
82 public void init(FloodlightModuleContext context) throws FloodlightModuleException {
Toshio Koide77ec9982014-08-27 16:57:43 -070083 matchActionService = context.getServiceImpl(MatchActionFloodlightService.class);
Toshio Koide03eba332014-08-26 10:46:55 -070084 registryService = context.getServiceImpl(IControllerRegistryService.class);
Toshio Koide7db3ce92014-08-27 16:57:43 -070085 sharedCollectionService = context.getServiceImpl(ISharedCollectionsService.class);
Toshio Koide03eba332014-08-26 10:46:55 -070086 }
87
88 @Override
89 public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
Toshio Koide03eba332014-08-26 10:46:55 -070090 IdBlockAllocator idBlockAllocator = registryService;
Toshio Koide7db3ce92014-08-27 16:57:43 -070091 flowIdGenerator =
Toshio Koide079d57c2014-08-21 18:03:58 -070092 new FlowIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide7db3ce92014-08-27 16:57:43 -070093 flowBatchIdGenerator =
94 new FlowBatchIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide77ec9982014-08-27 16:57:43 -070095 maIdGenerator = matchActionService.getMatchActionIdGenerator();
96 maoIdGenerator = matchActionService.getMatchActionOperationsIdGenerator();
Toshio Koide03eba332014-08-26 10:46:55 -070097
Toshio Koide7db3ce92014-08-27 16:57:43 -070098 flowMap = new SharedFlowMap(sharedCollectionService);
99 flowBatchMap = new SharedFlowBatchMap(sharedCollectionService);
Toshio Koided6dbb952014-08-22 14:29:04 -0700100 flowEventDispatcher =
101 new FlowEventDispatcher(flowMap, flowBatchMap, matchActionService);
102 flowEventDispatcher.start();
Toshio Koide03eba332014-08-26 10:46:55 -0700103 }
104
105 /**
106 * Constructs FlowManagerModule.
107 */
108 public FlowManagerModule() {
109 this.conflictDetectionPolicy = ConflictDetectionPolicy.FREE;
Toshio Koided46b66d2014-07-21 10:27:27 -0700110 }
111
Toshio Koidea03915e2014-07-01 18:39:52 -0700112 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700113 public FlowBatchHandle addFlow(Flow flow) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700114 FlowBatchOperation ops = new FlowBatchOperation();
115 ops.addAddFlowOperation(flow);
Toshio Koidea03915e2014-07-01 18:39:52 -0700116 return executeBatch(ops);
117 }
118
119 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700120 public FlowBatchHandle removeFlow(FlowId id) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700121 FlowBatchOperation ops = new FlowBatchOperation();
122 ops.addRemoveFlowOperation(id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700123 return executeBatch(ops);
124 }
125
126 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700127 public Flow getFlow(FlowId id) {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700128 return flowMap.get(id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700129 }
130
131 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700132 public Collection<Flow> getFlows() {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700133 return flowMap.getAll();
Toshio Koidea03915e2014-07-01 18:39:52 -0700134 }
135
Toshio Koide84648822014-08-21 02:07:56 -0700136 /**
137 * Executes batch operation of Flow object asynchronously.
138 * <p>
139 * To track the execution result, use the returned FlowBatchHandle object.
140 * <p>
Toshio Koide7db3ce92014-08-27 16:57:43 -0700141 * This method just put the batch-operation object to the global flow batch
Toshio Koide84648822014-08-21 02:07:56 -0700142 * operation map with unique ID. The worker process for execution and
143 * installation will get the appended operation when it gets events from the
144 * map. This method returns a handler for obtaining the result of this
145 * operation, control the executing process, etc.
146 *
147 * @param ops flow operations to be executed
Toshio Koide7db3ce92014-08-27 16:57:43 -0700148 * @return {@link FlowBatchHandle} object if succeeded, null otherwise
Toshio Koide84648822014-08-21 02:07:56 -0700149 */
Toshio Koidea03915e2014-07-01 18:39:52 -0700150 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700151 public FlowBatchHandle executeBatch(FlowBatchOperation ops) {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700152 FlowBatchId id = flowBatchIdGenerator.getNewId();
153 flowBatchMap.put(id, ops);
154 return new FlowBatchHandleImpl(flowBatchMap, id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700155 }
156
157 @Override
Sho SHIMIZU7cd8a422014-08-27 16:05:21 -0700158 public IdGenerator<FlowId> getFlowIdGenerator() {
Toshio Koide079d57c2014-08-21 18:03:58 -0700159 return flowIdGenerator;
160 }
161
162 @Override
Toshio Koidea03915e2014-07-01 18:39:52 -0700163 public void setConflictDetectionPolicy(ConflictDetectionPolicy policy) {
Toshio Koided46b66d2014-07-21 10:27:27 -0700164 if (policy == ConflictDetectionPolicy.FREE) {
165 conflictDetectionPolicy = policy;
166 } else {
167 throw new UnsupportedOperationException(
168 policy.toString() + " is not supported.");
169 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700170 }
171
172 @Override
173 public ConflictDetectionPolicy getConflictDetectionPolicy() {
Toshio Koided46b66d2014-07-21 10:27:27 -0700174 return conflictDetectionPolicy;
Toshio Koidea03915e2014-07-01 18:39:52 -0700175 }
176
177 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700178 public void addListener(FlowManagerListener listener) {
Toshio Koided6dbb952014-08-22 14:29:04 -0700179 flowEventDispatcher.addListener(listener);
Toshio Koidea03915e2014-07-01 18:39:52 -0700180 }
181
182 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700183 public void removeListener(FlowManagerListener listener) {
Toshio Koided6dbb952014-08-22 14:29:04 -0700184 flowEventDispatcher.removeListener(listener);
Toshio Koidea03915e2014-07-01 18:39:52 -0700185 }
Toshio Koide84648822014-08-21 02:07:56 -0700186
187 private MatchActionOperations createNewMatchActionOperations() {
Toshio Koide079d57c2014-08-21 18:03:58 -0700188 return new MatchActionOperations(maoIdGenerator.getNewId());
Toshio Koide84648822014-08-21 02:07:56 -0700189 }
190
191 /**
192 * Generates the series of MatchActionOperations from the
193 * {@link FlowBatchOperation}.
194 * <p>
195 * Note: Currently supporting ADD operations only.
196 * <p>
197 * Note: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
198 *
199 * @param op the {@link FlowBatchOperation} object
200 * @return the list of {@link MatchActionOperations} objects
201 */
202 private List<MatchActionOperations>
203 generateMatchActionOperationsList(FlowBatchOperation op) {
204 MatchActionOperations firstOps = createNewMatchActionOperations();
205 MatchActionOperations secondOps = createNewMatchActionOperations();
206
207 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
208 if (e.getOperator() != FlowBatchOperation.Operator.ADD) {
209 throw new UnsupportedOperationException(
210 "FlowManager supports ADD operations only.");
211 }
212 if (!(e.getTarget() instanceof Flow)) {
213 throw new IllegalStateException(
214 "The target is not Flow object: " + e.getTarget());
215 }
216
217 Flow flow = (Flow) e.getTarget();
218 List<MatchActionOperations> maOps = flow.compile(
Toshio Koide079d57c2014-08-21 18:03:58 -0700219 e.getOperator(), maIdGenerator, maoIdGenerator);
Toshio Koide84648822014-08-21 02:07:56 -0700220 checkNotNull(maOps, "Could not compile the flow: " + flow);
221 checkState(maOps.size() == 2,
222 "The flow generates unspported match-action operations.");
223
224 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
225 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
226 firstOps.addOperation(mae);
227 }
228
229 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
230 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
231 secondOps.addOperation(mae);
232 }
233 }
234
235 return Arrays.asList(firstOps, secondOps);
236 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700237}