blob: ccf60815bdd9c6d43e878317784d2e987b31cbae [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 Koide079d57c2014-08-21 18:03:58 -070025import net.onrc.onos.api.flowmanager.FlowIdGenerator;
Toshio Koide03eba332014-08-26 10:46:55 -070026import net.onrc.onos.api.flowmanager.FlowManagerFloodlightService;
Toshio Koideb8cea262014-08-12 18:45:46 -070027import net.onrc.onos.api.flowmanager.FlowManagerListener;
Toshio Koide7db3ce92014-08-27 16:57:43 -070028import net.onrc.onos.core.datagrid.ISharedCollectionsService;
Toshio Koide77ec9982014-08-27 16:57:43 -070029import net.onrc.onos.core.matchaction.MatchActionFloodlightService;
30import net.onrc.onos.core.matchaction.MatchActionIdGenerator;
Toshio Koide84648822014-08-21 02:07:56 -070031import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
32import net.onrc.onos.core.matchaction.MatchActionOperations;
Toshio Koide77ec9982014-08-27 16:57:43 -070033import net.onrc.onos.core.matchaction.MatchActionOperationsIdGenerator;
34import net.onrc.onos.core.matchaction.MatchActionService;
Toshio Koide03eba332014-08-26 10:46:55 -070035import net.onrc.onos.core.registry.IControllerRegistryService;
Toshio Koide84648822014-08-21 02:07:56 -070036import net.onrc.onos.core.util.IdBlockAllocator;
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;
Toshio Koide77ec9982014-08-27 16:57:43 -070048 private MatchActionIdGenerator maIdGenerator;
49 private MatchActionOperationsIdGenerator maoIdGenerator;
50 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 Koided46b66d2014-07-21 10:27:27 -070055
Toshio Koide03eba332014-08-26 10:46:55 -070056 @Override
57 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
58 List<Class<? extends IFloodlightService>> services =
59 new ArrayList<Class<? extends IFloodlightService>>();
60 services.add(FlowManagerFloodlightService.class);
61 return services;
62 }
63
64 @Override
65 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
66 Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
67 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
68 impls.put(FlowManagerFloodlightService.class, this);
69 return impls;
70 }
71
72 @Override
73 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
74 return Arrays.asList(
Toshio Koide77ec9982014-08-27 16:57:43 -070075 MatchActionFloodlightService.class,
Toshio Koide7db3ce92014-08-27 16:57:43 -070076 ISharedCollectionsService.class,
Toshio Koide03eba332014-08-26 10:46:55 -070077 IControllerRegistryService.class);
78 }
79
80 @Override
81 public void init(FloodlightModuleContext context) throws FloodlightModuleException {
Toshio Koide77ec9982014-08-27 16:57:43 -070082 matchActionService = context.getServiceImpl(MatchActionFloodlightService.class);
Toshio Koide03eba332014-08-26 10:46:55 -070083 registryService = context.getServiceImpl(IControllerRegistryService.class);
Toshio Koide7db3ce92014-08-27 16:57:43 -070084 sharedCollectionService = context.getServiceImpl(ISharedCollectionsService.class);
Toshio Koide03eba332014-08-26 10:46:55 -070085 }
86
87 @Override
88 public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
Toshio Koide03eba332014-08-26 10:46:55 -070089 IdBlockAllocator idBlockAllocator = registryService;
Toshio Koide7db3ce92014-08-27 16:57:43 -070090 flowIdGenerator =
Toshio Koide079d57c2014-08-21 18:03:58 -070091 new FlowIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide7db3ce92014-08-27 16:57:43 -070092 flowBatchIdGenerator =
93 new FlowBatchIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide77ec9982014-08-27 16:57:43 -070094 maIdGenerator = matchActionService.getMatchActionIdGenerator();
95 maoIdGenerator = matchActionService.getMatchActionOperationsIdGenerator();
Toshio Koide03eba332014-08-26 10:46:55 -070096
Toshio Koide7db3ce92014-08-27 16:57:43 -070097 flowMap = new SharedFlowMap(sharedCollectionService);
98 flowBatchMap = new SharedFlowBatchMap(sharedCollectionService);
Toshio Koide03eba332014-08-26 10:46:55 -070099 }
100
101 /**
102 * Constructs FlowManagerModule.
103 */
104 public FlowManagerModule() {
105 this.conflictDetectionPolicy = ConflictDetectionPolicy.FREE;
Toshio Koided46b66d2014-07-21 10:27:27 -0700106 }
107
Toshio Koidea03915e2014-07-01 18:39:52 -0700108 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700109 public FlowBatchHandle addFlow(Flow flow) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700110 FlowBatchOperation ops = new FlowBatchOperation();
111 ops.addAddFlowOperation(flow);
Toshio Koidea03915e2014-07-01 18:39:52 -0700112 return executeBatch(ops);
113 }
114
115 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700116 public FlowBatchHandle removeFlow(FlowId id) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700117 FlowBatchOperation ops = new FlowBatchOperation();
118 ops.addRemoveFlowOperation(id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700119 return executeBatch(ops);
120 }
121
122 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700123 public Flow getFlow(FlowId id) {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700124 return flowMap.get(id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700125 }
126
127 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700128 public Collection<Flow> getFlows() {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700129 return flowMap.getAll();
Toshio Koidea03915e2014-07-01 18:39:52 -0700130 }
131
Toshio Koide84648822014-08-21 02:07:56 -0700132 /**
133 * Executes batch operation of Flow object asynchronously.
134 * <p>
135 * To track the execution result, use the returned FlowBatchHandle object.
136 * <p>
Toshio Koide7db3ce92014-08-27 16:57:43 -0700137 * This method just put the batch-operation object to the global flow batch
Toshio Koide84648822014-08-21 02:07:56 -0700138 * operation map with unique ID. The worker process for execution and
139 * installation will get the appended operation when it gets events from the
140 * map. This method returns a handler for obtaining the result of this
141 * operation, control the executing process, etc.
142 *
143 * @param ops flow operations to be executed
Toshio Koide7db3ce92014-08-27 16:57:43 -0700144 * @return {@link FlowBatchHandle} object if succeeded, null otherwise
Toshio Koide84648822014-08-21 02:07:56 -0700145 */
Toshio Koidea03915e2014-07-01 18:39:52 -0700146 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700147 public FlowBatchHandle executeBatch(FlowBatchOperation ops) {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700148 FlowBatchId id = flowBatchIdGenerator.getNewId();
149 flowBatchMap.put(id, ops);
150 return new FlowBatchHandleImpl(flowBatchMap, id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700151 }
152
153 @Override
Toshio Koide079d57c2014-08-21 18:03:58 -0700154 public FlowIdGenerator getFlowIdGenerator() {
155 return flowIdGenerator;
156 }
157
158 @Override
Toshio Koidea03915e2014-07-01 18:39:52 -0700159 public void setConflictDetectionPolicy(ConflictDetectionPolicy policy) {
Toshio Koided46b66d2014-07-21 10:27:27 -0700160 if (policy == ConflictDetectionPolicy.FREE) {
161 conflictDetectionPolicy = policy;
162 } else {
163 throw new UnsupportedOperationException(
164 policy.toString() + " is not supported.");
165 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700166 }
167
168 @Override
169 public ConflictDetectionPolicy getConflictDetectionPolicy() {
Toshio Koided46b66d2014-07-21 10:27:27 -0700170 return conflictDetectionPolicy;
Toshio Koidea03915e2014-07-01 18:39:52 -0700171 }
172
173 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700174 public void addListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700175 // TODO Auto-generated method stub
176
177 }
178
179 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700180 public void removeListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700181 // TODO Auto-generated method stub
182
183 }
Toshio Koide84648822014-08-21 02:07:56 -0700184
185 private MatchActionOperations createNewMatchActionOperations() {
Toshio Koide079d57c2014-08-21 18:03:58 -0700186 return new MatchActionOperations(maoIdGenerator.getNewId());
Toshio Koide84648822014-08-21 02:07:56 -0700187 }
188
189 /**
190 * Generates the series of MatchActionOperations from the
191 * {@link FlowBatchOperation}.
192 * <p>
193 * Note: Currently supporting ADD operations only.
194 * <p>
195 * Note: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
196 *
197 * @param op the {@link FlowBatchOperation} object
198 * @return the list of {@link MatchActionOperations} objects
199 */
200 private List<MatchActionOperations>
201 generateMatchActionOperationsList(FlowBatchOperation op) {
202 MatchActionOperations firstOps = createNewMatchActionOperations();
203 MatchActionOperations secondOps = createNewMatchActionOperations();
204
205 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
206 if (e.getOperator() != FlowBatchOperation.Operator.ADD) {
207 throw new UnsupportedOperationException(
208 "FlowManager supports ADD operations only.");
209 }
210 if (!(e.getTarget() instanceof Flow)) {
211 throw new IllegalStateException(
212 "The target is not Flow object: " + e.getTarget());
213 }
214
215 Flow flow = (Flow) e.getTarget();
216 List<MatchActionOperations> maOps = flow.compile(
Toshio Koide079d57c2014-08-21 18:03:58 -0700217 e.getOperator(), maIdGenerator, maoIdGenerator);
Toshio Koide84648822014-08-21 02:07:56 -0700218 checkNotNull(maOps, "Could not compile the flow: " + flow);
219 checkState(maOps.size() == 2,
220 "The flow generates unspported match-action operations.");
221
222 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
223 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
224 firstOps.addOperation(mae);
225 }
226
227 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
228 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
229 secondOps.addOperation(mae);
230 }
231 }
232
233 return Arrays.asList(firstOps, secondOps);
234 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700235}