blob: 7a0b2434fa659877fc5ad0b43b7e5f2ba13c0fe8 [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 Koide84648822014-08-21 02:07:56 -07006import java.util.Arrays;
7import java.util.Collection;
8import java.util.List;
9
10import net.onrc.onos.api.batchoperation.BatchOperationEntry;
Toshio Koidea03915e2014-07-01 18:39:52 -070011import net.onrc.onos.api.flowmanager.ConflictDetectionPolicy;
Toshio Koideb8cea262014-08-12 18:45:46 -070012import net.onrc.onos.api.flowmanager.Flow;
Toshio Koidefc5acc72014-08-12 18:45:46 -070013import net.onrc.onos.api.flowmanager.FlowBatchHandle;
Toshio Koide4ea84192014-07-31 12:10:12 -070014import net.onrc.onos.api.flowmanager.FlowBatchOperation;
Toshio Koide84648822014-08-21 02:07:56 -070015import net.onrc.onos.api.flowmanager.FlowBatchOperation.Operator;
Toshio Koide025a9152014-07-21 11:00:34 -070016import net.onrc.onos.api.flowmanager.FlowId;
Toshio Koide079d57c2014-08-21 18:03:58 -070017import net.onrc.onos.api.flowmanager.FlowIdGenerator;
Toshio Koideb8cea262014-08-12 18:45:46 -070018import net.onrc.onos.api.flowmanager.FlowManagerListener;
Toshio Koidefad1cd52014-08-07 17:10:07 -070019import net.onrc.onos.api.flowmanager.FlowManagerService;
Toshio Koide84648822014-08-21 02:07:56 -070020import net.onrc.onos.core.matchaction.MatchActionIdGeneratorWithIdBlockAllocator;
21import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
22import net.onrc.onos.core.matchaction.MatchActionOperations;
23import net.onrc.onos.core.matchaction.MatchActionOperationsIdGeneratorWithIdBlockAllocator;
24import net.onrc.onos.core.util.IdBlockAllocator;
Toshio Koidea03915e2014-07-01 18:39:52 -070025
26/**
Toshio Koide7894ca02014-08-15 14:30:13 -070027 * Manages a set of Flow objects, computes and maintains a set of Match-Action
28 * entries based on the Flow objects, and executes Match-Action plans.
Toshio Koidea03915e2014-07-01 18:39:52 -070029 * <p>
30 * TODO: Make all methods thread-safe
31 */
Toshio Koidefad1cd52014-08-07 17:10:07 -070032public class FlowManagerModule implements FlowManagerService {
Toshio Koided46b66d2014-07-21 10:27:27 -070033 private ConflictDetectionPolicy conflictDetectionPolicy;
Toshio Koidefc5acc72014-08-12 18:45:46 -070034 private FlowOperationMap flowOperationMap;
Toshio Koide079d57c2014-08-21 18:03:58 -070035 private MatchActionIdGeneratorWithIdBlockAllocator maIdGenerator;
36 private MatchActionOperationsIdGeneratorWithIdBlockAllocator maoIdGenerator;
37 private FlowIdGeneratorWithIdBlockAllocator flowIdGenerator;
Toshio Koided46b66d2014-07-21 10:27:27 -070038
39 /**
Toshio Koide84648822014-08-21 02:07:56 -070040 * Constructs FlowManagerModule with {@link IdBlockAllocator}.
Toshio Koided46b66d2014-07-21 10:27:27 -070041 */
Toshio Koide84648822014-08-21 02:07:56 -070042 public FlowManagerModule(IdBlockAllocator idBlockAllocator) {
Toshio Koide079d57c2014-08-21 18:03:58 -070043 this.flowIdGenerator =
44 new FlowIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koided46b66d2014-07-21 10:27:27 -070045 this.conflictDetectionPolicy = ConflictDetectionPolicy.FREE;
Toshio Koide3c846312014-08-21 19:47:15 -070046 this.flowOperationMap = new FlowOperationMap(idBlockAllocator);
Toshio Koide079d57c2014-08-21 18:03:58 -070047
48 // TODO: MatchActionOperationsIdGenerator should be retrieved from MatchAction Module.
49 this.maIdGenerator =
50 new MatchActionIdGeneratorWithIdBlockAllocator(idBlockAllocator);
51 this.maoIdGenerator =
52 new MatchActionOperationsIdGeneratorWithIdBlockAllocator(idBlockAllocator);
Toshio Koided46b66d2014-07-21 10:27:27 -070053 }
54
Toshio Koidea03915e2014-07-01 18:39:52 -070055 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -070056 public FlowBatchHandle addFlow(Flow flow) {
Toshio Koide4ea84192014-07-31 12:10:12 -070057 FlowBatchOperation ops = new FlowBatchOperation();
58 ops.addAddFlowOperation(flow);
Toshio Koidea03915e2014-07-01 18:39:52 -070059 return executeBatch(ops);
60 }
61
62 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -070063 public FlowBatchHandle removeFlow(FlowId id) {
Toshio Koide4ea84192014-07-31 12:10:12 -070064 FlowBatchOperation ops = new FlowBatchOperation();
65 ops.addRemoveFlowOperation(id);
Toshio Koidea03915e2014-07-01 18:39:52 -070066 return executeBatch(ops);
67 }
68
69 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -070070 public Flow getFlow(FlowId id) {
Toshio Koidea03915e2014-07-01 18:39:52 -070071 // TODO Auto-generated method stub
72 return null;
73 }
74
75 @Override
Toshio Koidefad1cd52014-08-07 17:10:07 -070076 public Collection<Flow> getFlows() {
Toshio Koidea03915e2014-07-01 18:39:52 -070077 // TODO Auto-generated method stub
78 return null;
79 }
80
Toshio Koide84648822014-08-21 02:07:56 -070081 /**
82 * Executes batch operation of Flow object asynchronously.
83 * <p>
84 * To track the execution result, use the returned FlowBatchHandle object.
85 * <p>
86 * This method just put the batch-operation object to the global flow
87 * operation map with unique ID. The worker process for execution and
88 * installation will get the appended operation when it gets events from the
89 * map. This method returns a handler for obtaining the result of this
90 * operation, control the executing process, etc.
91 *
92 * @param ops flow operations to be executed
93 * @return FlowBatchHandle object if succeeded, null otherwise
94 */
Toshio Koidea03915e2014-07-01 18:39:52 -070095 @Override
Toshio Koidefc5acc72014-08-12 18:45:46 -070096 public FlowBatchHandle executeBatch(FlowBatchOperation ops) {
Toshio Koide3c846312014-08-21 19:47:15 -070097 return flowOperationMap.putBatchOperation(ops);
Toshio Koidea03915e2014-07-01 18:39:52 -070098 }
99
100 @Override
Toshio Koide079d57c2014-08-21 18:03:58 -0700101 public FlowIdGenerator getFlowIdGenerator() {
102 return flowIdGenerator;
103 }
104
105 @Override
Toshio Koidea03915e2014-07-01 18:39:52 -0700106 public void setConflictDetectionPolicy(ConflictDetectionPolicy policy) {
Toshio Koided46b66d2014-07-21 10:27:27 -0700107 if (policy == ConflictDetectionPolicy.FREE) {
108 conflictDetectionPolicy = policy;
109 } else {
110 throw new UnsupportedOperationException(
111 policy.toString() + " is not supported.");
112 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700113 }
114
115 @Override
116 public ConflictDetectionPolicy getConflictDetectionPolicy() {
Toshio Koided46b66d2014-07-21 10:27:27 -0700117 return conflictDetectionPolicy;
Toshio Koidea03915e2014-07-01 18:39:52 -0700118 }
119
120 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700121 public void addListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700122 // TODO Auto-generated method stub
123
124 }
125
126 @Override
Toshio Koideb8cea262014-08-12 18:45:46 -0700127 public void removeListener(FlowManagerListener listener) {
Toshio Koidea03915e2014-07-01 18:39:52 -0700128 // TODO Auto-generated method stub
129
130 }
Toshio Koide84648822014-08-21 02:07:56 -0700131
132 private MatchActionOperations createNewMatchActionOperations() {
Toshio Koide079d57c2014-08-21 18:03:58 -0700133 return new MatchActionOperations(maoIdGenerator.getNewId());
Toshio Koide84648822014-08-21 02:07:56 -0700134 }
135
136 /**
137 * Generates the series of MatchActionOperations from the
138 * {@link FlowBatchOperation}.
139 * <p>
140 * Note: Currently supporting ADD operations only.
141 * <p>
142 * Note: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
143 *
144 * @param op the {@link FlowBatchOperation} object
145 * @return the list of {@link MatchActionOperations} objects
146 */
147 private List<MatchActionOperations>
148 generateMatchActionOperationsList(FlowBatchOperation op) {
149 MatchActionOperations firstOps = createNewMatchActionOperations();
150 MatchActionOperations secondOps = createNewMatchActionOperations();
151
152 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
153 if (e.getOperator() != FlowBatchOperation.Operator.ADD) {
154 throw new UnsupportedOperationException(
155 "FlowManager supports ADD operations only.");
156 }
157 if (!(e.getTarget() instanceof Flow)) {
158 throw new IllegalStateException(
159 "The target is not Flow object: " + e.getTarget());
160 }
161
162 Flow flow = (Flow) e.getTarget();
163 List<MatchActionOperations> maOps = flow.compile(
Toshio Koide079d57c2014-08-21 18:03:58 -0700164 e.getOperator(), maIdGenerator, maoIdGenerator);
Toshio Koide84648822014-08-21 02:07:56 -0700165 checkNotNull(maOps, "Could not compile the flow: " + flow);
166 checkState(maOps.size() == 2,
167 "The flow generates unspported match-action operations.");
168
169 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
170 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
171 firstOps.addOperation(mae);
172 }
173
174 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
175 checkState(mae.getOperator() == MatchActionOperations.Operator.ADD);
176 secondOps.addOperation(mae);
177 }
178 }
179
180 return Arrays.asList(firstOps, secondOps);
181 }
Toshio Koidea03915e2014-07-01 18:39:52 -0700182}