blob: 1a3523b3cd9ff70cd39a71b72f72031fea6281aa [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 Koide84648822014-08-21 02:07:56 -070029import net.onrc.onos.core.matchaction.MatchActionIdGeneratorWithIdBlockAllocator;
30import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
31import net.onrc.onos.core.matchaction.MatchActionOperations;
32import net.onrc.onos.core.matchaction.MatchActionOperationsIdGeneratorWithIdBlockAllocator;
Toshio Koide03eba332014-08-26 10:46:55 -070033import net.onrc.onos.core.registry.IControllerRegistryService;
Toshio Koide84648822014-08-21 02:07:56 -070034import net.onrc.onos.core.util.IdBlockAllocator;
Toshio Koidea03915e2014-07-01 18:39:52 -070035
36/**
Toshio Koide7894ca02014-08-15 14:30:13 -070037 * Manages a set of Flow objects, computes and maintains a set of Match-Action
38 * entries based on the Flow objects, and executes Match-Action plans.
Toshio Koidea03915e2014-07-01 18:39:52 -070039 * <p>
40 * TODO: Make all methods thread-safe
41 */
Toshio Koide03eba332014-08-26 10:46:55 -070042public class FlowManagerModule implements FlowManagerFloodlightService, IFloodlightModule {
Toshio Koided46b66d2014-07-21 10:27:27 -070043 private ConflictDetectionPolicy conflictDetectionPolicy;
Toshio Koide7db3ce92014-08-27 16:57:43 -070044 private FlowIdGeneratorWithIdBlockAllocator flowIdGenerator;
45 private FlowBatchIdGeneratorWithIdBlockAllocator flowBatchIdGenerator;
Toshio Koide079d57c2014-08-21 18:03:58 -070046 private MatchActionIdGeneratorWithIdBlockAllocator maIdGenerator;
47 private MatchActionOperationsIdGeneratorWithIdBlockAllocator maoIdGenerator;
Toshio Koide03eba332014-08-26 10:46:55 -070048 private IControllerRegistryService registryService;
Toshio Koide7db3ce92014-08-27 16:57:43 -070049 private ISharedCollectionsService sharedCollectionService;
50 private FlowMap flowMap;
51 private FlowBatchMap flowBatchMap;
Toshio Koided46b66d2014-07-21 10:27:27 -070052
Toshio Koide03eba332014-08-26 10:46:55 -070053 @Override
54 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
55 List<Class<? extends IFloodlightService>> services =
56 new ArrayList<Class<? extends IFloodlightService>>();
57 services.add(FlowManagerFloodlightService.class);
58 return services;
59 }
60
61 @Override
62 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
63 Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
64 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
65 impls.put(FlowManagerFloodlightService.class, this);
66 return impls;
67 }
68
69 @Override
70 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
71 return Arrays.asList(
Toshio Koide7db3ce92014-08-27 16:57:43 -070072 // TODO: Add MatchActionService.class.
73 // The class has to be an instance of IFloodlightService.
74 ISharedCollectionsService.class,
Toshio Koide03eba332014-08-26 10:46:55 -070075 IControllerRegistryService.class);
76 }
77
78 @Override
79 public void init(FloodlightModuleContext context) throws FloodlightModuleException {
80 registryService = context.getServiceImpl(IControllerRegistryService.class);
Toshio Koide7db3ce92014-08-27 16:57:43 -070081 sharedCollectionService = context.getServiceImpl(ISharedCollectionsService.class);
Toshio Koide03eba332014-08-26 10:46:55 -070082 }
83
84 @Override
85 public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
86
87 IdBlockAllocator idBlockAllocator = registryService;
Toshio Koide7db3ce92014-08-27 16:57:43 -070088 flowIdGenerator =
Toshio Koide079d57c2014-08-21 18:03:58 -070089 new FlowIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide7db3ce92014-08-27 16:57:43 -070090 flowBatchIdGenerator =
91 new FlowBatchIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide079d57c2014-08-21 18:03:58 -070092
Toshio Koide7db3ce92014-08-27 16:57:43 -070093 // TODO: MatchAction related ID generator should be retrieved from
Toshio Koide03eba332014-08-26 10:46:55 -070094 // MatchAction Module.
Toshio Koide7db3ce92014-08-27 16:57:43 -070095 maIdGenerator =
Toshio Koide079d57c2014-08-21 18:03:58 -070096 new MatchActionIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide7db3ce92014-08-27 16:57:43 -070097 maoIdGenerator =
Toshio Koide079d57c2014-08-21 18:03:58 -070098 new MatchActionOperationsIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide03eba332014-08-26 10:46:55 -070099
Toshio Koide7db3ce92014-08-27 16:57:43 -0700100 flowMap = new SharedFlowMap(sharedCollectionService);
101 flowBatchMap = new SharedFlowBatchMap(sharedCollectionService);
Toshio Koide03eba332014-08-26 10:46:55 -0700102 }
103
104 /**
105 * Constructs FlowManagerModule.
106 */
107 public FlowManagerModule() {
108 this.conflictDetectionPolicy = ConflictDetectionPolicy.FREE;
Toshio Koided46b66d2014-07-21 10:27:27 -0700109 }
110
Toshio Koidea03915e2014-07-01 18:39:52 -0700111 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700112 public FlowBatchHandle addFlow(Flow flow) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700113 FlowBatchOperation ops = new FlowBatchOperation();
114 ops.addAddFlowOperation(flow);
Toshio Koidea03915e2014-07-01 18:39:52 -0700115 return executeBatch(ops);
116 }
117
118 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700119 public FlowBatchHandle removeFlow(FlowId id) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700120 FlowBatchOperation ops = new FlowBatchOperation();
121 ops.addRemoveFlowOperation(id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700122 return executeBatch(ops);
123 }
124
125 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700126 public Flow getFlow(FlowId id) {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700127 return flowMap.get(id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700128 }
129
130 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700131 public Collection<Flow> getFlows() {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700132 return flowMap.getAll();
Toshio Koidea03915e2014-07-01 18:39:52 -0700133 }
134
Toshio Koide84648822014-08-21 02:07:56 -0700135 /**
136 * Executes batch operation of Flow object asynchronously.
137 * <p>
138 * To track the execution result, use the returned FlowBatchHandle object.
139 * <p>
Toshio Koide7db3ce92014-08-27 16:57:43 -0700140 * This method just put the batch-operation object to the global flow batch
Toshio Koide84648822014-08-21 02:07:56 -0700141 * operation map with unique ID. The worker process for execution and
142 * installation will get the appended operation when it gets events from the
143 * map. This method returns a handler for obtaining the result of this
144 * operation, control the executing process, etc.
145 *
146 * @param ops flow operations to be executed
Toshio Koide7db3ce92014-08-27 16:57:43 -0700147 * @return {@link FlowBatchHandle} object if succeeded, null otherwise
Toshio Koide84648822014-08-21 02:07:56 -0700148 */
Toshio Koidea03915e2014-07-01 18:39:52 -0700149 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700150 public FlowBatchHandle executeBatch(FlowBatchOperation ops) {
Toshio Koide7db3ce92014-08-27 16:57:43 -0700151 FlowBatchId id = flowBatchIdGenerator.getNewId();
152 flowBatchMap.put(id, ops);
153 return new FlowBatchHandleImpl(flowBatchMap, id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700154 }
155
156 @Override
Toshio Koide079d57c2014-08-21 18:03:58 -0700157 public FlowIdGenerator getFlowIdGenerator() {
158 return flowIdGenerator;
159 }
160
161 @Override
Toshio Koidea03915e2014-07-01 18:39:52 -0700162 public void setConflictDetectionPolicy(ConflictDetectionPolicy policy) {
Toshio Koided46b66d2014-07-21 10:27:27 -0700163 if (policy == ConflictDetectionPolicy.FREE) {
164 conflictDetectionPolicy = policy;
165 } else {
166 throw new UnsupportedOperationException(
167 policy.toString() + " is not supported.");
168 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700169 }
170
171 @Override
172 public ConflictDetectionPolicy getConflictDetectionPolicy() {
Toshio Koided46b66d2014-07-21 10:27:27 -0700173 return conflictDetectionPolicy;
Toshio Koidea03915e2014-07-01 18:39:52 -0700174 }
175
176 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700177 public void addListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700178 // TODO Auto-generated method stub
179
180 }
181
182 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700183 public void removeListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700184 // TODO Auto-generated method stub
185
186 }
Toshio Koide84648822014-08-21 02:07:56 -0700187
188 private MatchActionOperations createNewMatchActionOperations() {
Toshio Koide079d57c2014-08-21 18:03:58 -0700189 return new MatchActionOperations(maoIdGenerator.getNewId());
Toshio Koide84648822014-08-21 02:07:56 -0700190 }
191
192 /**
193 * Generates the series of MatchActionOperations from the
194 * {@link FlowBatchOperation}.
195 * <p>
196 * Note: Currently supporting ADD operations only.
197 * <p>
198 * Note: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
199 *
200 * @param op the {@link FlowBatchOperation} object
201 * @return the list of {@link MatchActionOperations} objects
202 */
203 private List<MatchActionOperations>
204 generateMatchActionOperationsList(FlowBatchOperation op) {
205 MatchActionOperations firstOps = createNewMatchActionOperations();
206 MatchActionOperations secondOps = createNewMatchActionOperations();
207
208 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
209 if (e.getOperator() != FlowBatchOperation.Operator.ADD) {
210 throw new UnsupportedOperationException(
211 "FlowManager supports ADD operations only.");
212 }
213 if (!(e.getTarget() instanceof Flow)) {
214 throw new IllegalStateException(
215 "The target is not Flow object: " + e.getTarget());
216 }
217
218 Flow flow = (Flow) e.getTarget();
219 List<MatchActionOperations> maOps = flow.compile(
Toshio Koide079d57c2014-08-21 18:03:58 -0700220 e.getOperator(), maIdGenerator, maoIdGenerator);
Toshio Koide84648822014-08-21 02:07:56 -0700221 checkNotNull(maOps, "Could not compile the flow: " + flow);
222 checkState(maOps.size() == 2,
223 "The flow generates unspported match-action operations.");
224
225 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
226 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
227 firstOps.addOperation(mae);
228 }
229
230 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
231 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
232 secondOps.addOperation(mae);
233 }
234 }
235
236 return Arrays.asList(firstOps, secondOps);
237 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700238}