blob: ef41ca7358bce6ea9aaf6cca28430c29f6a71872 [file] [log] [blame]
Brian O'Connor72cb19a2015-01-16 16:14:41 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Brian O'Connor72cb19a2015-01-16 16:14:41 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.flow;
17
18import com.google.common.base.MoreObjects;
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableSet;
21import com.google.common.collect.Lists;
22
23import java.util.List;
pierventre55c6f332022-03-29 15:10:39 +020024import java.util.Optional;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080025import java.util.Set;
26
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -070027import static com.google.common.base.Preconditions.checkNotNull;
pierventre07af21d2022-03-18 10:31:04 +010028import static org.onosproject.net.flow.FlowRuleOperation.Type.ADD;
29import static org.onosproject.net.flow.FlowRuleOperation.Type.REMOVE;
30import static org.onosproject.net.flow.FlowRuleOperation.Type.MODIFY;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080031
32/**
33 * A batch of flow rule operations that are broken into stages.
34 * TODO move this up to parent's package
35 */
36public class FlowRuleOperations {
37
38 private final List<Set<FlowRuleOperation>> stages;
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -070039 private final FlowRuleOperationsContext callback;
pierventre07af21d2022-03-18 10:31:04 +010040 private final Integer stripeKey;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080041
42 private FlowRuleOperations(List<Set<FlowRuleOperation>> stages,
pierventre07af21d2022-03-18 10:31:04 +010043 FlowRuleOperationsContext cb,
44 Integer stripeKey) {
Brian O'Connor72cb19a2015-01-16 16:14:41 -080045 this.stages = stages;
46 this.callback = cb;
pierventre07af21d2022-03-18 10:31:04 +010047 this.stripeKey = stripeKey;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080048 }
49
50 // kryo-constructor
51 protected FlowRuleOperations() {
52 this.stages = Lists.newArrayList();
53 this.callback = null;
pierventre07af21d2022-03-18 10:31:04 +010054 this.stripeKey = null;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080055 }
56
57 /**
58 * Returns the flow rule operations as sets of stages that should be
59 * executed sequentially.
60 *
61 * @return flow rule stages
62 */
63 public List<Set<FlowRuleOperation>> stages() {
64 return stages;
65 }
66
67 /**
68 * Returns the callback for this batch of operations.
69 *
70 * @return callback
71 */
72 public FlowRuleOperationsContext callback() {
73 return callback;
74 }
75
76 /**
pierventre07af21d2022-03-18 10:31:04 +010077 * Returns the stripe key. Expectation is that FlowRuleOperations with the
78 * same key will be executed sequentially in the same order as they are
79 * submitted to the FlowRuleService. Operations without a key or with
80 * different keys might be executed in parallel.
81 *
82 * @return the stripe key associated to this or null if not present
83 */
pierventre55c6f332022-03-29 15:10:39 +020084 public Optional<Integer> stripeKey() {
85 return Optional.ofNullable(stripeKey);
pierventre07af21d2022-03-18 10:31:04 +010086 }
87
88 /**
Brian O'Connor72cb19a2015-01-16 16:14:41 -080089 * Returns a new builder.
90 *
91 * @return new builder
92 */
93 public static Builder builder() {
94 return new Builder();
95 }
96
97 @Override
98 public String toString() {
99 return MoreObjects.toStringHelper(this)
100 .add("stages", stages)
101 .toString();
102 }
103
104 /**
105 * A builder for constructing flow rule operations.
106 */
107 public static final class Builder {
108
109 private final ImmutableList.Builder<Set<FlowRuleOperation>> listBuilder = ImmutableList.builder();
110 private ImmutableSet.Builder<FlowRuleOperation> currentStage = ImmutableSet.builder();
pierventre07af21d2022-03-18 10:31:04 +0100111 private Integer stripeKey = null;
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800112
113 // prevent use of the default constructor outside of this file; use the above method
114 private Builder() {}
115
116 /**
117 * Appends a flow rule add to the current stage.
118 *
119 * @param flowRule flow rule
120 * @return this
121 */
122 public Builder add(FlowRule flowRule) {
123 currentStage.add(new FlowRuleOperation(flowRule, ADD));
124 return this;
125 }
126
127 /**
Ray Milkey71ade562015-02-18 15:08:07 -0800128 * Appends an existing flow rule to the current stage.
129 *
130 * @param flowRuleOperation flow rule operation
131 * @return this
132 */
133 public Builder operation(FlowRuleOperation flowRuleOperation) {
134 currentStage.add(flowRuleOperation);
135 return this;
136 }
137
138 /**
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800139 * Appends a flow rule modify to the current stage.
140 *
141 * @param flowRule flow rule
142 * @return this
143 */
144 public Builder modify(FlowRule flowRule) {
145 currentStage.add(new FlowRuleOperation(flowRule, MODIFY));
146 return this;
147 }
148
149 /**
150 * Appends a flow rule remove to the current stage.
151 *
152 * @param flowRule flow rule
153 * @return this
154 */
155 // FIXME this is confusing, consider renaming
156 public Builder remove(FlowRule flowRule) {
157 currentStage.add(new FlowRuleOperation(flowRule, REMOVE));
158 return this;
159 }
160
161 /**
162 * Closes the current stage.
163 */
164 private void closeStage() {
165 ImmutableSet<FlowRuleOperation> stage = currentStage.build();
166 if (!stage.isEmpty()) {
167 listBuilder.add(stage);
168 }
169 }
170
171 /**
172 * Closes the current stage and starts a new one.
173 *
174 * @return this
175 */
176 public Builder newStage() {
177 closeStage();
178 currentStage = ImmutableSet.builder();
179 return this;
180 }
181
182 /**
pierventre07af21d2022-03-18 10:31:04 +0100183 * Provides semantics similar to lock striping. FlowRuleOperations
184 * with the same key will be executed sequentially. Operations without
185 * a key or with different keys might be executed in parallel.
186 * <p>
187 * This parameter is useful to correlate different operations with
188 * potentially conflicting writes, to guarantee that operations are
189 * executed in-order. For example, to handle the case where one operation
190 * that removes a flow rule is followed by one that adds the same flow rule.
191 * </p>
192 *
193 * @param stripeKey an integer key
194 * @return this
195 */
196 public Builder striped(int stripeKey) {
197 this.stripeKey = stripeKey;
198 return this;
199 }
200
201 /**
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800202 * Builds the immutable flow rule operations.
203 *
204 * @return flow rule operations
205 */
206 public FlowRuleOperations build() {
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -0700207 return build(NullFlowRuleOperationsContext.getInstance());
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800208 }
209
210 /**
211 * Builds the immutable flow rule operations.
212 *
213 * @param cb the callback to call when this operation completes
214 * @return flow rule operations
215 */
216 public FlowRuleOperations build(FlowRuleOperationsContext cb) {
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -0700217 checkNotNull(cb);
218
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800219 closeStage();
pierventre07af21d2022-03-18 10:31:04 +0100220 return new FlowRuleOperations(listBuilder.build(), cb, stripeKey);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800221 }
222 }
223}