blob: d4d3254e69569f0da67820d6e7067125b4cf76c8 [file] [log] [blame]
Yuta HIGUCHI8810aa42017-08-02 15:05:37 -07001/*
2 * Copyright 2017-present Open Networking Foundation
3 *
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.d.config.sync.operation;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19
20import java.util.ArrayList;
21import java.util.Collection;
22import java.util.Collections;
23import java.util.List;
24import java.util.NoSuchElementException;
25import java.util.Objects;
26import java.util.Optional;
27
28import org.apache.commons.lang3.tuple.Pair;
29import org.onosproject.d.config.sync.operation.SetRequest.Change.Operation;
30import org.onosproject.yang.model.DataNode;
31import org.onosproject.yang.model.ResourceId;
32
33import com.google.common.annotations.Beta;
34import com.google.common.base.MoreObjects;
35import com.google.common.collect.ImmutableList;
36
37// One SetRequest is expected to be a transaction, all-or-nothing
38/**
39 * Collection of changes about a single Device,
40 * intended to be applied to the Device transactionally.
41 */
42@Beta
43public final class SetRequest {
44
45 private final Collection<Change> changes;
46
47 SetRequest(Collection<Change> changes) {
48 this.changes = ImmutableList.copyOf(changes);
49 }
50
51 public Collection<Change> changes() {
52 return changes;
53 }
54
55 public Collection<Pair<Operation, ResourceId>> subjects() {
56 return changes.stream()
57 .map(c -> Pair.of(c.op(), c.path()))
58 .collect(ImmutableList.toImmutableList());
59 }
60
61 @Override
62 public boolean equals(Object obj) {
63 if (this == obj) {
64 return true;
65 }
66 if (obj instanceof SetRequest) {
67 SetRequest that = (SetRequest) obj;
68 return Objects.equals(this.changes, that.changes);
69 }
70 return false;
71 }
72
73 @Override
74 public int hashCode() {
75 return Objects.hash(changes);
76 }
77
78 @Override
79 public String toString() {
80 return MoreObjects.toStringHelper(getClass())
81 .add("changes", changes)
82 .toString();
83 }
84 public static SetRequest.Builder builder() {
85 return new Builder();
86 }
87
88 public static class Builder {
89 private final List<Change> changes = new ArrayList<>();
90
91 /**
92 * Returns changes contained in this builder.
93 *
94 * @return unmodifiable list view of Changes
95 */
96 public List<Change> changes() {
97 return Collections.unmodifiableList(changes);
98 }
99
100 /**
101 * Adds request to remove specified {@code path}.
102 *
103 * @param path resource path relative to device root node
104 * @return self
105 */
106 public SetRequest.Builder delete(ResourceId path) {
107 changes.add(Change.delete(path));
108 return this;
109 }
110
111 /**
112 * Adds request to replace specified {@code path} with specified {@code val}.
113 *
114 * @param path resource path relative to device root node
115 * @param val resource value
116 * @return self
117 */
118 public SetRequest.Builder replace(ResourceId path, DataNode val) {
119 changes.add(Change.replace(path, val));
120 return this;
121 }
122
123 /**
124 * Adds request to update/merge specified {@code val} to the {@code path}.
125 *
126 * @param path resource path relative to device root node
127 * @param val resource value
128 * @return self
129 */
130 public SetRequest.Builder update(ResourceId path, DataNode val) {
131 changes.add(Change.update(path, val));
132 return this;
133 }
134
135 public SetRequest build() {
136 return new SetRequest(changes);
137 }
138 }
139
140 public static final class Change {
141
142 public enum Operation {
143
144 // Note: equivalent to remove in netconf
145 /**
146 * Request to delete specified {@code path}.
147 * If path does not exist, it is silently ignored.
148 */
149 DELETE,
150 // Note: equivalent to replace in netconf
151 /**
152 * Request to replace specified {@code path} with specified {@code val}.
153 */
154 REPLACE,
155 // Note: equivalent to merge in netconf
156 /**
157 * Request to update/merge specified {@code val} to the {@code path}.
158 */
159 UPDATE
160 }
161
162 private final Operation op;
163 private final ResourceId path;
164 private final Optional<DataNode> val;
165
166 public static Change delete(ResourceId path) {
167 return new Change(Operation.DELETE, path, Optional.empty());
168 }
169
170 public static Change replace(ResourceId path, DataNode val) {
171 return new Change(Operation.REPLACE, path, Optional.of(val));
172 }
173
174 public static Change update(ResourceId path, DataNode val) {
175 return new Change(Operation.UPDATE, path, Optional.of(val));
176 }
177
178 Change(Operation op, ResourceId path, Optional<DataNode> val) {
179 this.op = checkNotNull(op);
180 this.path = checkNotNull(path);
181 this.val = checkNotNull(val);
182 }
183
184 /**
185 * Returns type of change operation.
186 *
187 * @return Operation
188 */
189 public Operation op() {
190 return op;
191 }
192
193 /**
194 * Returns resource path to be changed.
195 *
196 * @return resource path relative to device root node
197 */
198 public ResourceId path() {
199 return path;
200 }
201
202 /**
203 * Returns the {@code val} specified.
204 *
205 * @return {@code val}
206 * @throws NoSuchElementException if this object represent {@code DELETE} op.
207 */
208 public DataNode val() {
209 return val.get();
210 }
211
212 @Override
213 public boolean equals(Object obj) {
214 if (this == obj) {
215 return true;
216 }
217 if (obj instanceof Change) {
218 Change that = (Change) obj;
219 return Objects.equals(this.op, that.op) &&
220 Objects.equals(this.path, that.path) &&
221 Objects.equals(this.val, that.val);
222 }
223 return false;
224 }
225
226 @Override
227 public int hashCode() {
228 return Objects.hash(op, path, val);
229 }
230
231 @Override
232 public String toString() {
233 return MoreObjects.toStringHelper(getClass())
234 .add("op", op)
235 .add("path", path)
236 .add("val", val)
237 .toString();
238 }
239 }
240}