blob: 14af90d543bcec347b877579b7e95ed26e00245c [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;
24import java.util.Set;
25
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -070026import static com.google.common.base.Preconditions.checkNotNull;
pierventre07af21d2022-03-18 10:31:04 +010027import static org.onosproject.net.flow.FlowRuleOperation.Type.ADD;
28import static org.onosproject.net.flow.FlowRuleOperation.Type.REMOVE;
29import static org.onosproject.net.flow.FlowRuleOperation.Type.MODIFY;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080030
31/**
32 * A batch of flow rule operations that are broken into stages.
33 * TODO move this up to parent's package
34 */
35public class FlowRuleOperations {
36
37 private final List<Set<FlowRuleOperation>> stages;
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -070038 private final FlowRuleOperationsContext callback;
pierventre07af21d2022-03-18 10:31:04 +010039 private final Integer stripeKey;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080040
41 private FlowRuleOperations(List<Set<FlowRuleOperation>> stages,
pierventre07af21d2022-03-18 10:31:04 +010042 FlowRuleOperationsContext cb,
43 Integer stripeKey) {
Brian O'Connor72cb19a2015-01-16 16:14:41 -080044 this.stages = stages;
45 this.callback = cb;
pierventre07af21d2022-03-18 10:31:04 +010046 this.stripeKey = stripeKey;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080047 }
48
49 // kryo-constructor
50 protected FlowRuleOperations() {
51 this.stages = Lists.newArrayList();
52 this.callback = null;
pierventre07af21d2022-03-18 10:31:04 +010053 this.stripeKey = null;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080054 }
55
56 /**
57 * Returns the flow rule operations as sets of stages that should be
58 * executed sequentially.
59 *
60 * @return flow rule stages
61 */
62 public List<Set<FlowRuleOperation>> stages() {
63 return stages;
64 }
65
66 /**
67 * Returns the callback for this batch of operations.
68 *
69 * @return callback
70 */
71 public FlowRuleOperationsContext callback() {
72 return callback;
73 }
74
75 /**
pierventre07af21d2022-03-18 10:31:04 +010076 * Returns the stripe key. Expectation is that FlowRuleOperations with the
77 * same key will be executed sequentially in the same order as they are
78 * submitted to the FlowRuleService. Operations without a key or with
79 * different keys might be executed in parallel.
80 *
81 * @return the stripe key associated to this or null if not present
82 */
83 public Integer stripeKey() {
84 return stripeKey;
85 }
86
87 /**
Brian O'Connor72cb19a2015-01-16 16:14:41 -080088 * Returns a new builder.
89 *
90 * @return new builder
91 */
92 public static Builder builder() {
93 return new Builder();
94 }
95
96 @Override
97 public String toString() {
98 return MoreObjects.toStringHelper(this)
99 .add("stages", stages)
100 .toString();
101 }
102
103 /**
104 * A builder for constructing flow rule operations.
105 */
106 public static final class Builder {
107
108 private final ImmutableList.Builder<Set<FlowRuleOperation>> listBuilder = ImmutableList.builder();
109 private ImmutableSet.Builder<FlowRuleOperation> currentStage = ImmutableSet.builder();
pierventre07af21d2022-03-18 10:31:04 +0100110 private Integer stripeKey = null;
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800111
112 // prevent use of the default constructor outside of this file; use the above method
113 private Builder() {}
114
115 /**
116 * Appends a flow rule add to the current stage.
117 *
118 * @param flowRule flow rule
119 * @return this
120 */
121 public Builder add(FlowRule flowRule) {
122 currentStage.add(new FlowRuleOperation(flowRule, ADD));
123 return this;
124 }
125
126 /**
Ray Milkey71ade562015-02-18 15:08:07 -0800127 * Appends an existing flow rule to the current stage.
128 *
129 * @param flowRuleOperation flow rule operation
130 * @return this
131 */
132 public Builder operation(FlowRuleOperation flowRuleOperation) {
133 currentStage.add(flowRuleOperation);
134 return this;
135 }
136
137 /**
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800138 * Appends a flow rule modify to the current stage.
139 *
140 * @param flowRule flow rule
141 * @return this
142 */
143 public Builder modify(FlowRule flowRule) {
144 currentStage.add(new FlowRuleOperation(flowRule, MODIFY));
145 return this;
146 }
147
148 /**
149 * Appends a flow rule remove to the current stage.
150 *
151 * @param flowRule flow rule
152 * @return this
153 */
154 // FIXME this is confusing, consider renaming
155 public Builder remove(FlowRule flowRule) {
156 currentStage.add(new FlowRuleOperation(flowRule, REMOVE));
157 return this;
158 }
159
160 /**
161 * Closes the current stage.
162 */
163 private void closeStage() {
164 ImmutableSet<FlowRuleOperation> stage = currentStage.build();
165 if (!stage.isEmpty()) {
166 listBuilder.add(stage);
167 }
168 }
169
170 /**
171 * Closes the current stage and starts a new one.
172 *
173 * @return this
174 */
175 public Builder newStage() {
176 closeStage();
177 currentStage = ImmutableSet.builder();
178 return this;
179 }
180
181 /**
pierventre07af21d2022-03-18 10:31:04 +0100182 * Provides semantics similar to lock striping. FlowRuleOperations
183 * with the same key will be executed sequentially. Operations without
184 * a key or with different keys might be executed in parallel.
185 * <p>
186 * This parameter is useful to correlate different operations with
187 * potentially conflicting writes, to guarantee that operations are
188 * executed in-order. For example, to handle the case where one operation
189 * that removes a flow rule is followed by one that adds the same flow rule.
190 * </p>
191 *
192 * @param stripeKey an integer key
193 * @return this
194 */
195 public Builder striped(int stripeKey) {
196 this.stripeKey = stripeKey;
197 return this;
198 }
199
200 /**
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800201 * Builds the immutable flow rule operations.
202 *
203 * @return flow rule operations
204 */
205 public FlowRuleOperations build() {
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -0700206 return build(NullFlowRuleOperationsContext.getInstance());
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800207 }
208
209 /**
210 * Builds the immutable flow rule operations.
211 *
212 * @param cb the callback to call when this operation completes
213 * @return flow rule operations
214 */
215 public FlowRuleOperations build(FlowRuleOperationsContext cb) {
Sho SHIMIZUad4f2cd2016-09-01 13:05:56 -0700216 checkNotNull(cb);
217
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800218 closeStage();
pierventre07af21d2022-03-18 10:31:04 +0100219 return new FlowRuleOperations(listBuilder.build(), cb, stripeKey);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800220 }
221 }
222}