blob: 4185f70c38aac3c2848300294e1d0bdcbdc47028 [file] [log] [blame]
Carmelo Cascone4c289b72019-01-22 15:30:45 -08001/*
2 * Copyright 2019-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 */
16
17package org.onosproject.p4runtime.api;
18
19import org.onosproject.net.pi.model.PiPipeconf;
20import org.onosproject.net.pi.runtime.PiEntity;
21import org.onosproject.net.pi.runtime.PiEntityType;
22import org.onosproject.net.pi.runtime.PiHandle;
23
24import java.util.Collection;
25import java.util.concurrent.CompletableFuture;
26
27/**
28 * P4Runtime client interface for the Write RPC that allows inserting, modifying
29 * and deleting PI entities. Allows batching of write requests and it returns a
30 * detailed response for each PI entity in the request.
31 */
32public interface P4RuntimeWriteClient {
33
34 /**
35 * Returns a new {@link WriteRequest} instance that can be used to build a
Carmelo Casconec2be50a2019-04-10 00:15:39 -070036 * batched write request, for the given P4Runtime-internal device ID and
37 * pipeconf.
Carmelo Cascone4c289b72019-01-22 15:30:45 -080038 *
Carmelo Casconec2be50a2019-04-10 00:15:39 -070039 * @param p4DeviceId P4Runtime-internal device ID
40 * @param pipeconf pipeconf
Carmelo Cascone4c289b72019-01-22 15:30:45 -080041 * @return new write request
42 */
Carmelo Casconec2be50a2019-04-10 00:15:39 -070043 WriteRequest write(long p4DeviceId, PiPipeconf pipeconf);
Carmelo Cascone4c289b72019-01-22 15:30:45 -080044
45 /**
46 * Signals the type of write operation for a given PI entity.
47 */
48 enum UpdateType {
49 /**
50 * Inserts an entity.
51 */
52 INSERT,
53 /**
54 * Modifies an existing entity.
55 */
56 MODIFY,
57 /**
58 * Deletes an existing entity.
59 */
60 DELETE
61 }
62
63 /**
64 * Signals if the entity was written successfully or not.
65 */
Carmelo Cascone61469462019-03-05 23:59:11 -080066 enum EntityUpdateStatus {
Carmelo Cascone4c289b72019-01-22 15:30:45 -080067 /**
68 * The entity was written successfully, no errors occurred.
69 */
70 OK,
71 /**
72 * The server didn't return any status for the entity.
73 */
74 PENDING,
75 /**
76 * The entity was not added to the write request because it was not
77 * possible to encode/decode it.
78 */
79 CODEC_ERROR,
80 /**
81 * Server responded that it was not possible to insert the entity as
82 * another one with the same handle already exists.
83 */
84 ALREADY_EXIST,
85 /**
86 * Server responded that it was not possible to modify or delete the
87 * entity as the same cannot be found on the server.
88 */
89 NOT_FOUND,
90 /**
Carmelo Cascone61469462019-03-05 23:59:11 -080091 * Other error. See {@link EntityUpdateResponse#explanation()} or {@link
92 * EntityUpdateResponse#throwable()} for more details.
Carmelo Cascone4c289b72019-01-22 15:30:45 -080093 */
94 OTHER_ERROR,
95 }
96
97 /**
98 * Signals the atomicity mode that the server should follow when executing a
99 * write request. For more information on each atomicity mode please see the
100 * P4Runtime spec.
101 */
102 enum Atomicity {
103 /**
104 * Continue on error. Default value for all write requests.
105 */
106 CONTINUE_ON_ERROR,
107 /**
108 * Rollback on error.
109 */
110 ROLLBACK_ON_ERROR,
111 /**
112 * Dataplane atomic.
113 */
114 DATAPLANE_ATOMIC,
115 }
116
117 /**
Carmelo Cascone61469462019-03-05 23:59:11 -0800118 * Abstraction of a batched P4Runtime write request. Multiple entities can
119 * be added to the same request before submitting it. The implementation
120 * should guarantee that entities are added in the final P4Runtime protobuf
121 * message in the same order as added in this write request.
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800122 */
123 interface WriteRequest {
124
125 /**
126 * Sets the atomicity mode of this write request. Default value is
127 * {@link Atomicity#CONTINUE_ON_ERROR}.
128 *
129 * @param atomicity atomicity mode
130 * @return this
131 */
132 WriteRequest withAtomicity(Atomicity atomicity);
133
134 /**
135 * Requests to insert one PI entity.
136 *
137 * @param entity PI entity
138 * @return this
139 */
140 WriteRequest insert(PiEntity entity);
141
142 /**
143 * Requests to insert multiple PI entities.
144 *
145 * @param entities iterable of PI entities
146 * @return this
147 */
148 WriteRequest insert(Iterable<? extends PiEntity> entities);
149
150 /**
151 * Requests to modify one PI entity.
152 *
153 * @param entity PI entity
154 * @return this
155 */
156 WriteRequest modify(PiEntity entity);
157
158 /**
159 * Requests to modify multiple PI entities.
160 *
161 * @param entities iterable of PI entities
162 * @return this
163 */
164 WriteRequest modify(Iterable<? extends PiEntity> entities);
165
166 /**
167 * Requests to delete one PI entity identified by the given handle.
168 *
169 * @param handle PI handle
170 * @return this
171 */
172 WriteRequest delete(PiHandle handle);
173
174 /**
175 * Requests to delete multiple PI entities identified by the given
176 * handles.
177 *
178 * @param handles iterable of handles
179 * @return this
180 */
181 WriteRequest delete(Iterable<? extends PiHandle> handles);
182
183 /**
184 * Requests to write the given PI entity with the given update type. If
185 * {@code updateType} is {@link UpdateType#DELETE}, then only the handle
186 * will be considered by the request.
187 *
188 * @param entity PI entity
189 * @param updateType update type
190 * @return this
191 */
192 WriteRequest entity(PiEntity entity, UpdateType updateType);
193
194 /**
195 * Requests to write the given PI entities with the given update type.
196 * If {@code updateType} is {@link UpdateType#DELETE}, then only the
197 * handles will be considered by the request.
198 *
199 * @param entities iterable of PI entity
200 * @param updateType update type
201 * @return this
202 */
203 WriteRequest entities(Iterable<? extends PiEntity> entities, UpdateType updateType);
204
205 /**
206 * Submits this write request to the server and returns a completable
207 * future holding the response. The future is completed only after the
208 * server signals that all entities are written.
209 *
210 * @return completable future of the write response
211 */
212 CompletableFuture<WriteResponse> submit();
213
214 /**
215 * Similar to {@link #submit()}, but blocks until the operation is
216 * completed, after which, it returns a read response.
217 *
218 * @return read response
219 */
220 P4RuntimeWriteClient.WriteResponse submitSync();
Carmelo Cascone61469462019-03-05 23:59:11 -0800221
222 /**
223 * Returns all entity update requests for which we are expecting a
224 * responce from the device, in the same order they were added to this
225 * batch.
226 *
Carmelo Cascone61469462019-03-05 23:59:11 -0800227 * @return entity update requests
228 */
229 Collection<EntityUpdateRequest> pendingUpdates();
230 }
231
232 /**
233 * Represents the update request for a specific entity.
234 */
235 interface EntityUpdateRequest {
236 /**
237 * Returns the handle of the PI entity subject of this update.
238 *
239 * @return handle
240 */
241 PiHandle handle();
242
243 /**
244 * Returns the PI entity subject of this update. Returns {@code null} if
245 * the update type is {@link UpdateType#DELETE}, in which case only the
246 * handle is used in the request.
247 *
248 * @return PI entity or null
249 */
250 PiEntity entity();
251
252 /**
253 * Returns the type of update requested for this entity.
254 *
255 * @return update type
256 */
257 UpdateType updateType();
258
259 /**
260 * Returns the type of entity subject of this update.
261 *
262 * @return PI entity type
263 */
264 PiEntityType entityType();
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800265 }
266
267 /**
268 * Abstraction of a response obtained from a P4Runtime server after a write
269 * request is submitted. It allows returning a detailed response ({@link
Carmelo Cascone61469462019-03-05 23:59:11 -0800270 * EntityUpdateResponse}) for each PI entity in the batched request. Entity
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800271 * responses are guaranteed to be returned in the same order as the
272 * corresponding PI entity in the request.
273 */
274 interface WriteResponse {
275
276 /**
277 * Returns true if all entities in the request were successfully
278 * written. In other words, if no errors occurred. False otherwise.
279 *
280 * @return true if all entities were written successfully, false
281 * otherwise
282 */
283 boolean isSuccess();
284
285 /**
286 * Returns a detailed response for each PI entity in the request. The
287 * implementation of this method should guarantee that the returned
288 * collection has size equal to the number of PI entities in the
289 * original write request.
290 *
Carmelo Cascone61469462019-03-05 23:59:11 -0800291 * @return collection of {@link EntityUpdateResponse}
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800292 */
Carmelo Cascone61469462019-03-05 23:59:11 -0800293 Collection<EntityUpdateResponse> all();
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800294
295 /**
296 * Returns a detailed response for each PI entity that was successfully
297 * written. If {@link #isSuccess()} is {@code true}, then this method is
298 * expected to return the same values as {@link #all()}.
299 *
Carmelo Cascone61469462019-03-05 23:59:11 -0800300 * @return collection of {@link EntityUpdateResponse}
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800301 */
Carmelo Cascone61469462019-03-05 23:59:11 -0800302 Collection<EntityUpdateResponse> success();
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800303
304 /**
305 * Returns a detailed response for each PI entity for which the server
306 * returned an error. If {@link #isSuccess()} is {@code true}, then this
307 * method is expected to return an empty collection.
308 *
Carmelo Cascone61469462019-03-05 23:59:11 -0800309 * @return collection of {@link EntityUpdateResponse}
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800310 */
Carmelo Cascone61469462019-03-05 23:59:11 -0800311 Collection<EntityUpdateResponse> failed();
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800312
313 /**
314 * Returns a detailed response for each PI entity for which the server
315 * returned the given status.
316 *
317 * @param status status
Carmelo Cascone61469462019-03-05 23:59:11 -0800318 * @return collection of {@link EntityUpdateResponse}
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800319 */
Carmelo Cascone61469462019-03-05 23:59:11 -0800320 Collection<EntityUpdateResponse> status(EntityUpdateStatus status);
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800321 }
322
323 /**
Carmelo Cascone61469462019-03-05 23:59:11 -0800324 * Represents the response to an update request request for a specific PI
325 * entity.
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800326 */
Carmelo Cascone61469462019-03-05 23:59:11 -0800327 interface EntityUpdateResponse extends EntityUpdateRequest {
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800328
329 /**
330 * Returns true if this PI entity was written successfully, false
331 * otherwise.
332 *
333 * @return true if this PI entity was written successfully, false
334 * otherwise
335 */
336 boolean isSuccess();
337
338 /**
339 * Returns the status for this PI entity. If {@link #isSuccess()}
340 * returns {@code true}, then this method is expected to return {@link
Carmelo Casconec2be50a2019-04-10 00:15:39 -0700341 * EntityUpdateStatus#OK}. If {@link EntityUpdateStatus#OTHER_ERROR} is
342 * returned, further details might be provided in {@link #explanation()}
343 * and {@link #throwable()}.
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800344 *
345 * @return status
346 */
Carmelo Cascone61469462019-03-05 23:59:11 -0800347 EntityUpdateStatus status();
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800348
349 /**
350 * If the PI entity was NOT written successfully, this method returns a
351 * message explaining the error occurred. Returns an empty string if
352 * such message is not available, or {@code null} if no errors
353 * occurred.
354 *
355 * @return error explanation or empty string or null
356 */
357 String explanation();
358
359 /**
360 * If the PI entity was NOT written successfully, this method returns
361 * the internal throwable instance associated with the error (e.g. a
362 * {@link io.grpc.StatusRuntimeException} instance). Returns null if
363 * such throwable instance is not available or if no errors occurred.
364 *
365 * @return throwable instance associated with this PI entity
366 */
367 Throwable throwable();
368 }
369}