blob: 1187c88f442e38be08fe402f1d1b0ed37a4a26f4 [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 Koide4ea84192014-07-31 12:10:12 -070021import net.onrc.onos.api.flowmanager.FlowBatchOperation;
Toshio Koide84648822014-08-21 02:07:56 -070022import net.onrc.onos.api.flowmanager.FlowBatchOperation.Operator;
Toshio Koide025a9152014-07-21 11:00:34 -070023import net.onrc.onos.api.flowmanager.FlowId;
Toshio Koide079d57c2014-08-21 18:03:58 -070024import net.onrc.onos.api.flowmanager.FlowIdGenerator;
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 Koide03eba332014-08-26 10:46:55 -070027import net.onrc.onos.core.datagrid.IDatagridService;
Toshio Koide84648822014-08-21 02:07:56 -070028import net.onrc.onos.core.matchaction.MatchActionIdGeneratorWithIdBlockAllocator;
29import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
30import net.onrc.onos.core.matchaction.MatchActionOperations;
31import net.onrc.onos.core.matchaction.MatchActionOperationsIdGeneratorWithIdBlockAllocator;
Toshio Koide03eba332014-08-26 10:46:55 -070032import net.onrc.onos.core.registry.IControllerRegistryService;
Toshio Koide84648822014-08-21 02:07:56 -070033import net.onrc.onos.core.util.IdBlockAllocator;
Toshio Koidea03915e2014-07-01 18:39:52 -070034
35/**
Toshio Koide7894ca02014-08-15 14:30:13 -070036 * Manages a set of Flow objects, computes and maintains a set of Match-Action
37 * entries based on the Flow objects, and executes Match-Action plans.
Toshio Koidea03915e2014-07-01 18:39:52 -070038 * <p>
39 * TODO: Make all methods thread-safe
40 */
Toshio Koide03eba332014-08-26 10:46:55 -070041public class FlowManagerModule implements FlowManagerFloodlightService, IFloodlightModule {
Toshio Koided46b66d2014-07-21 10:27:27 -070042 private ConflictDetectionPolicy conflictDetectionPolicy;
Toshio Koidefc5acc72014-08-12 18:45:46 -070043 private FlowOperationMap flowOperationMap;
Toshio Koide079d57c2014-08-21 18:03:58 -070044 private MatchActionIdGeneratorWithIdBlockAllocator maIdGenerator;
45 private MatchActionOperationsIdGeneratorWithIdBlockAllocator maoIdGenerator;
46 private FlowIdGeneratorWithIdBlockAllocator flowIdGenerator;
Toshio Koide03eba332014-08-26 10:46:55 -070047 private IControllerRegistryService registryService;
Toshio Koided46b66d2014-07-21 10:27:27 -070048
Toshio Koide03eba332014-08-26 10:46:55 -070049 @Override
50 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
51 List<Class<? extends IFloodlightService>> services =
52 new ArrayList<Class<? extends IFloodlightService>>();
53 services.add(FlowManagerFloodlightService.class);
54 return services;
55 }
56
57 @Override
58 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
59 Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
60 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
61 impls.put(FlowManagerFloodlightService.class, this);
62 return impls;
63 }
64
65 @Override
66 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
67 return Arrays.asList(
68 IDatagridService.class,
69 IControllerRegistryService.class);
70 }
71
72 @Override
73 public void init(FloodlightModuleContext context) throws FloodlightModuleException {
74 registryService = context.getServiceImpl(IControllerRegistryService.class);
75 }
76
77 @Override
78 public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
79
80 IdBlockAllocator idBlockAllocator = registryService;
Toshio Koide079d57c2014-08-21 18:03:58 -070081 this.flowIdGenerator =
82 new FlowIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide079d57c2014-08-21 18:03:58 -070083
Toshio Koide03eba332014-08-26 10:46:55 -070084 // TODO: MatchActionOperationsIdGenerator should be retrieved from
85 // MatchAction Module.
Toshio Koide079d57c2014-08-21 18:03:58 -070086 this.maIdGenerator =
87 new MatchActionIdGeneratorWithIdBlockAllocator(idBlockAllocator);
88 this.maoIdGenerator =
89 new MatchActionOperationsIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koide03eba332014-08-26 10:46:55 -070090
91 // TODO: datagridService =
92 // context.getServiceImpl(IDatagridService.class);
93 this.flowOperationMap = new FlowOperationMap(idBlockAllocator);
94 }
95
96 /**
97 * Constructs FlowManagerModule.
98 */
99 public FlowManagerModule() {
100 this.conflictDetectionPolicy = ConflictDetectionPolicy.FREE;
Toshio Koided46b66d2014-07-21 10:27:27 -0700101 }
102
Toshio Koidea03915e2014-07-01 18:39:52 -0700103 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700104 public FlowBatchHandle addFlow(Flow flow) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700105 FlowBatchOperation ops = new FlowBatchOperation();
106 ops.addAddFlowOperation(flow);
Toshio Koidea03915e2014-07-01 18:39:52 -0700107 return executeBatch(ops);
108 }
109
110 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700111 public FlowBatchHandle removeFlow(FlowId id) {
Toshio Koide4ea84192014-07-31 12:10:12 -0700112 FlowBatchOperation ops = new FlowBatchOperation();
113 ops.addRemoveFlowOperation(id);
Toshio Koidea03915e2014-07-01 18:39:52 -0700114 return executeBatch(ops);
115 }
116
117 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700118 public Flow getFlow(FlowId id) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700119 // TODO Auto-generated method stub
120 return null;
121 }
122
123 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -0700124 public Collection<Flow> getFlows() {
Toshio Koidea03915e2014-07-01 18:39:52 -0700125 // TODO Auto-generated method stub
126 return null;
127 }
128
Toshio Koide84648822014-08-21 02:07:56 -0700129 /**
130 * Executes batch operation of Flow object asynchronously.
131 * <p>
132 * To track the execution result, use the returned FlowBatchHandle object.
133 * <p>
134 * This method just put the batch-operation object to the global flow
135 * operation map with unique ID. The worker process for execution and
136 * installation will get the appended operation when it gets events from the
137 * map. This method returns a handler for obtaining the result of this
138 * operation, control the executing process, etc.
139 *
140 * @param ops flow operations to be executed
141 * @return FlowBatchHandle object if succeeded, null otherwise
142 */
Toshio Koidea03915e2014-07-01 18:39:52 -0700143 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -0700144 public FlowBatchHandle executeBatch(FlowBatchOperation ops) {
Toshio Koide3c846312014-08-21 19:47:15 -0700145 return flowOperationMap.putBatchOperation(ops);
Toshio Koidea03915e2014-07-01 18:39:52 -0700146 }
147
148 @Override
Toshio Koide079d57c2014-08-21 18:03:58 -0700149 public FlowIdGenerator getFlowIdGenerator() {
150 return flowIdGenerator;
151 }
152
153 @Override
Toshio Koidea03915e2014-07-01 18:39:52 -0700154 public void setConflictDetectionPolicy(ConflictDetectionPolicy policy) {
Toshio Koided46b66d2014-07-21 10:27:27 -0700155 if (policy == ConflictDetectionPolicy.FREE) {
156 conflictDetectionPolicy = policy;
157 } else {
158 throw new UnsupportedOperationException(
159 policy.toString() + " is not supported.");
160 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700161 }
162
163 @Override
164 public ConflictDetectionPolicy getConflictDetectionPolicy() {
Toshio Koided46b66d2014-07-21 10:27:27 -0700165 return conflictDetectionPolicy;
Toshio Koidea03915e2014-07-01 18:39:52 -0700166 }
167
168 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700169 public void addListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700170 // TODO Auto-generated method stub
171
172 }
173
174 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700175 public void removeListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700176 // TODO Auto-generated method stub
177
178 }
Toshio Koide84648822014-08-21 02:07:56 -0700179
180 private MatchActionOperations createNewMatchActionOperations() {
Toshio Koide079d57c2014-08-21 18:03:58 -0700181 return new MatchActionOperations(maoIdGenerator.getNewId());
Toshio Koide84648822014-08-21 02:07:56 -0700182 }
183
184 /**
185 * Generates the series of MatchActionOperations from the
186 * {@link FlowBatchOperation}.
187 * <p>
188 * Note: Currently supporting ADD operations only.
189 * <p>
190 * Note: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
191 *
192 * @param op the {@link FlowBatchOperation} object
193 * @return the list of {@link MatchActionOperations} objects
194 */
195 private List<MatchActionOperations>
196 generateMatchActionOperationsList(FlowBatchOperation op) {
197 MatchActionOperations firstOps = createNewMatchActionOperations();
198 MatchActionOperations secondOps = createNewMatchActionOperations();
199
200 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
201 if (e.getOperator() != FlowBatchOperation.Operator.ADD) {
202 throw new UnsupportedOperationException(
203 "FlowManager supports ADD operations only.");
204 }
205 if (!(e.getTarget() instanceof Flow)) {
206 throw new IllegalStateException(
207 "The target is not Flow object: " + e.getTarget());
208 }
209
210 Flow flow = (Flow) e.getTarget();
211 List<MatchActionOperations> maOps = flow.compile(
Toshio Koide079d57c2014-08-21 18:03:58 -0700212 e.getOperator(), maIdGenerator, maoIdGenerator);
Toshio Koide84648822014-08-21 02:07:56 -0700213 checkNotNull(maOps, "Could not compile the flow: " + flow);
214 checkState(maOps.size() == 2,
215 "The flow generates unspported match-action operations.");
216
217 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
218 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
219 firstOps.addOperation(mae);
220 }
221
222 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
223 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
224 secondOps.addOperation(mae);
225 }
226 }
227
228 return Arrays.asList(firstOps, secondOps);
229 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700230}