blob: d76401490c474f9bae3d865291fe51e57081f9f5 [file] [log] [blame]
Toshio Koideb0d86242014-08-28 16:05:30 -07001package net.onrc.onos.core.flowmanager;
2
3import static com.google.common.base.Verify.verify;
4import static com.google.common.base.Verify.verifyNotNull;
5
6import java.util.Arrays;
7import java.util.List;
8
9import net.onrc.onos.api.batchoperation.BatchOperationEntry;
10import net.onrc.onos.api.flowmanager.Flow;
11import net.onrc.onos.api.flowmanager.FlowBatchId;
12import net.onrc.onos.api.flowmanager.FlowBatchOperation;
13import net.onrc.onos.api.flowmanager.FlowBatchOperation.Operator;
14import net.onrc.onos.api.flowmanager.FlowBatchState;
15import net.onrc.onos.core.matchaction.MatchActionId;
16import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
17import net.onrc.onos.core.matchaction.MatchActionOperations;
18import net.onrc.onos.core.matchaction.MatchActionOperationsId;
19import net.onrc.onos.core.matchaction.MatchActionService;
20import net.onrc.onos.core.util.IdGenerator;
21
22/**
23 * Executes {@link FlowBatchOperation}.
24 * <p>
25 * This class compiles pairs of {@link Flow} and ADD/REMOVE operation to a list
26 * of a set of match-action operations.
27 */
28class FlowBatchOperationExecutor implements FlowBatchMapEventListener {
29 private final FlowBatchMap flowBatchMap;
30 // TODO: ADD later: private final FlowMap flowMap;
31 private final MatchActionService matchActionService;
32 private IdGenerator<MatchActionId> maIdGenerator;
33 private IdGenerator<MatchActionOperationsId> maoIdGenerator;
34
35 /**
36 * Creates {@link FlowBatchOperationExecutor} instance.
37 */
38 public FlowBatchOperationExecutor(MatchActionService matchActionService,
39 FlowMap flowMap, FlowBatchMap flowBatchMap) {
40 this.flowBatchMap = flowBatchMap;
41 // TODO: Add later: this.flowMap = flowMap;
42 this.matchActionService = matchActionService;
43 this.maIdGenerator = matchActionService.getMatchActionIdGenerator();
44 this.maoIdGenerator = matchActionService.getMatchActionOperationsIdGenerator();
45 }
46
47 /**
48 * Generates the series of MatchActionOperations from the
49 * {@link FlowBatchOperation}.
50 * <p>
51 * FIXME: Currently supporting ADD operations only.
52 * <p>
53 * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
54 * <p>
55 * FIXME: MatchActionOperations should have dependency field to the other
56 * match action operations, and this method should use this.
57 *
58 * @param op the {@link FlowBatchOperation} object
59 * @return the list of {@link MatchActionOperations} objects
60 */
61 private List<MatchActionOperations>
62 generateMatchActionOperationsList(FlowBatchOperation op) {
63
64 // MatchAction operations at head (ingress) switches.
65 MatchActionOperations headOps =
66 new MatchActionOperations(maoIdGenerator.getNewId());
67
68 // MatchAction operations at rest of the switches.
69 MatchActionOperations tailOps =
70 new MatchActionOperations(maoIdGenerator.getNewId());
71
72 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
73
74 // Check if it includes unsupported operations
75 if (e.getOperator() != FlowBatchOperation.Operator.ADD) {
76 throw new UnsupportedOperationException(
77 "FlowManager supports ADD operations only.");
78 }
79 if (!(e.getTarget() instanceof Flow)) {
80 throw new IllegalStateException(
81 "The target is not Flow object: " + e.getTarget());
82 }
83
84 // Compile flows to match-actions
85 Flow flow = (Flow) e.getTarget();
86 List<MatchActionOperations> maOps = flow.compile(
87 e.getOperator(), maIdGenerator, maoIdGenerator);
88 verifyNotNull(maOps, "Could not compile the flow: " + flow);
89 verify(maOps.size() == 2,
90 "The flow generates unspported match-action operations.");
91
92 // Merge match-action operations
93 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
94 verify(mae.getOperator() == MatchActionOperations.Operator.ADD);
95 tailOps.addOperation(mae);
96 }
97 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
98 verify(mae.getOperator() == MatchActionOperations.Operator.ADD);
99 headOps.addOperation(mae);
100 }
101 }
102
103 return Arrays.asList(tailOps, headOps);
104 }
105
106 @Override
107 public void flowBatchOperationAdded(FlowBatchId id, FlowBatchOperation flowOp) {
108
109 if (flowBatchMap.isLocal(id)) {
110 // TODO: update flowMap based on flowOp.
111
112 List<MatchActionOperations> maOps = generateMatchActionOperationsList(flowOp);
113 for (MatchActionOperations maOp : maOps) {
114 matchActionService.executeOperations(maOp);
115 }
116 }
117 }
118
119 @Override
120 public void flowBatchOperationRemoved(FlowBatchId id) {
121 // not used.
122 }
123
124 @Override
125 public void flowBatchOperationStateChanged(FlowBatchId id, FlowBatchState oldState,
126 FlowBatchState currentState) {
127 // TODO: update flow states in flowMap.
128 // TODO: update flow batch operation states in flowBatchMap.
129 }
130
131 /**
132 * Starts executor.
133 */
134 public void start() {
135 flowBatchMap.addListener(this);
136 }
137
138 /**
139 * Stops executor.
140 */
141 public void stop() {
142 flowBatchMap.removeListener(this);
143 }
144}