2 * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.impl.services.sal;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.ArgumentMatchers.any;
14 import static org.mockito.Mockito.inOrder;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.times;
17 import static org.mockito.Mockito.verify;
18 import static org.mockito.Mockito.verifyNoMoreInteractions;
19 import static org.mockito.Mockito.when;
21 import com.google.common.collect.Lists;
22 import com.google.common.util.concurrent.AsyncFunction;
23 import com.google.common.util.concurrent.ListenableFuture;
24 import java.util.Iterator;
25 import java.util.LinkedHashMap;
26 import java.util.List;
28 import org.junit.After;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.ArgumentCaptor;
33 import org.mockito.Captor;
34 import org.mockito.Mock;
35 import org.mockito.junit.MockitoJUnitRunner;
36 import org.opendaylight.openflowplugin.impl.services.batch.BatchPlanStep;
37 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepJob;
38 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepType;
39 import org.opendaylight.openflowplugin.impl.util.FlatBatchUtil;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.failure.ids.aug.FlatBatchFailureFlowIdCase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.failure.ids.aug.FlatBatchFailureFlowIdCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchAddFlowCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchRemoveFlowCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchUpdateFlowCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlow;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlowBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlowBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchAddGroupCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchRemoveGroupCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchUpdateGroupCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroupBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroupBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroupBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchAddMeterCaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchRemoveMeterCaseBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchUpdateMeterCaseBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeterBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeterBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeterBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatch;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatch;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatch;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchOutputBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatch;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchOutputBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatch;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchOutputBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatch;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchOutputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.OriginalBatchedGroupBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.UpdatedBatchedGroupBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatch;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchOutputBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatch;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchOutputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatch;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchOutputBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.OriginalBatchedMeterBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.UpdatedBatchedMeterBuilder;
105 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
106 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
107 import org.opendaylight.yangtools.yang.common.ErrorType;
108 import org.opendaylight.yangtools.yang.common.RpcResult;
109 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
110 import org.opendaylight.yangtools.yang.common.Uint16;
111 import org.opendaylight.yangtools.yang.common.Uint32;
114 * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
116 @RunWith(MockitoJUnitRunner.class)
117 public class ProcessFlatBatchImplTest {
118 private static final NodeId NODE_ID = new NodeId("ut-node-id");
119 private static final InstanceIdentifier<Node> NODE_II = InstanceIdentifier.create(Nodes.class)
120 .child(Node.class, new NodeKey(NODE_ID));
121 private static final NodeRef NODE_REF = new NodeRef(NODE_II);
124 private AddFlowsBatch addFlowsBatch;
126 private RemoveFlowsBatch removeFlowsBatch;
128 private UpdateFlowsBatch updateFlowsBatch;
130 private AddGroupsBatch addGroupsBatch;
132 private RemoveGroupsBatch removeGroupsBatch;
134 private UpdateGroupsBatch updateGroupsBatch;
136 private AddMetersBatch addMetersBatch;
138 private RemoveMetersBatch removeMetersBatch;
140 private UpdateMetersBatch updateMetersBatch;
142 private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
144 private ProcessFlatBatchImpl processFlatBatch;
147 public void setUp() {
148 processFlatBatch = new ProcessFlatBatchImpl(addFlowsBatch, removeFlowsBatch, updateFlowsBatch, addGroupsBatch,
149 removeGroupsBatch, updateGroupsBatch, addMetersBatch, removeMetersBatch, updateMetersBatch);
153 public void tearDown() {
154 verifyNoMoreInteractions(addFlowsBatch, removeFlowsBatch, updateFlowsBatch, addGroupsBatch,
155 removeGroupsBatch, updateGroupsBatch, addMetersBatch, removeMetersBatch, updateMetersBatch);
159 public void testProcessFlatBatch_allSuccessFinished() throws Exception {
160 when(addFlowsBatch.invoke(any()))
161 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
162 when(removeFlowsBatch.invoke(any()))
163 .thenReturn(RpcResultBuilder.success(new RemoveFlowsBatchOutputBuilder().build()).buildFuture());
164 when(updateFlowsBatch.invoke(any()))
165 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
167 when(addGroupsBatch.invoke(any()))
168 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
169 when(removeGroupsBatch.invoke(any()))
170 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
171 when(updateGroupsBatch.invoke(any()))
172 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
174 when(addMetersBatch.invoke(any()))
175 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
176 when(removeMetersBatch.invoke(any()))
177 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
178 when(updateMetersBatch.invoke(any()))
179 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
182 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
184 .setBatch(BindingMap.ordered(
185 createFlowAddBatch(0, "f1"),
186 createFlowRemoveBatch(1, "f2"),
187 createFlowUpdateBatch(2, "f3"),
189 createGroupAddBatch(3, 1L),
190 createGroupRemoveBatch(4, 2L),
191 createGroupUpdateBatch(5, 3L),
193 createMeterAddBatch(6, 1L),
194 createMeterRemoveBatch(7, 2L),
195 createMeterUpdateBatch(8, 3L)
197 .setExitOnFirstError(true)
200 final var rpcResultFuture = processFlatBatch.invoke(batchInput);
201 assertTrue(rpcResultFuture.isDone());
202 final var rpcResult = rpcResultFuture.get();
203 assertTrue(rpcResult.isSuccessful());
204 assertTrue(rpcResult.getErrors().isEmpty());
205 assertTrue(rpcResult.getResult().nonnullBatchFailure().isEmpty());
207 final var inOrder = inOrder(addFlowsBatch, removeFlowsBatch, updateFlowsBatch, addGroupsBatch,
208 removeGroupsBatch, updateGroupsBatch, addMetersBatch, removeMetersBatch, updateMetersBatch);
209 inOrder.verify(addFlowsBatch).invoke(any());
210 inOrder.verify(removeFlowsBatch).invoke(any());
211 inOrder.verify(updateFlowsBatch).invoke(any());
213 inOrder.verify(addGroupsBatch).invoke(any());
214 inOrder.verify(removeGroupsBatch).invoke(any());
215 inOrder.verify(updateGroupsBatch).invoke(any());
217 inOrder.verify(addMetersBatch).invoke(any());
218 inOrder.verify(removeMetersBatch).invoke(any());
219 inOrder.verify(updateMetersBatch).invoke(any());
223 public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
224 prepareFirstFailingMockService();
227 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
229 .setBatch(BindingMap.ordered(
230 createFlowAddBatch(idx++, "f1", 2),
231 createFlowRemoveBatch(idx++, "f2"),
232 createFlowUpdateBatch(idx++, "f3"),
234 createGroupAddBatch(idx++, 1L),
235 createGroupRemoveBatch(idx++, 2L),
236 createGroupUpdateBatch(idx++, 3L),
238 createMeterAddBatch(idx++, 1L),
239 createMeterRemoveBatch(idx++, 2L),
240 createMeterUpdateBatch(idx++, 3L)
242 .setExitOnFirstError(true)
245 final var rpcResultFuture = processFlatBatch.invoke(batchInput);
246 assertTrue(rpcResultFuture.isDone());
247 final var rpcResult = rpcResultFuture.get();
248 assertFalse(rpcResult.isSuccessful());
249 assertEquals(1, rpcResult.getErrors().size());
250 assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
251 assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
252 .getBatchOrder().intValue());
254 final var inOrder = inOrder(addFlowsBatch, removeFlowsBatch, updateFlowsBatch, addGroupsBatch);
255 inOrder.verify(addFlowsBatch).invoke(any());
256 inOrder.verify(removeFlowsBatch).invoke(any());
257 inOrder.verify(updateFlowsBatch).invoke(any());
258 inOrder.verify(addGroupsBatch).invoke(any());
262 public void testProcessFlatBatch_firstFailedContinue() throws Exception {
263 prepareFirstFailingMockService();
266 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
268 .setBatch(BindingMap.ordered(
269 createFlowAddBatch(idx++, "f1", 2),
270 createFlowRemoveBatch(idx++, "f2"),
271 createFlowUpdateBatch(idx++, "f3"),
273 createGroupAddBatch(idx++, 1L),
274 createGroupRemoveBatch(idx++, 2L),
275 createGroupUpdateBatch(idx++, 3L),
277 createMeterAddBatch(idx++, 1L),
278 createMeterRemoveBatch(idx++, 2L),
279 createMeterUpdateBatch(idx++, 3L)
281 .setExitOnFirstError(false)
284 final var rpcResultFuture = processFlatBatch.invoke(batchInput);
285 assertTrue(rpcResultFuture.isDone());
286 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
287 assertFalse(rpcResult.isSuccessful());
288 assertEquals(1, rpcResult.getErrors().size());
289 assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
290 assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
291 .getBatchOrder().intValue());
293 final var inOrder = inOrder(addFlowsBatch, removeFlowsBatch, updateFlowsBatch, addGroupsBatch,
294 removeGroupsBatch, updateGroupsBatch, addMetersBatch, removeMetersBatch, updateMetersBatch);
295 inOrder.verify(addFlowsBatch).invoke(any());
296 inOrder.verify(removeFlowsBatch).invoke(any());
297 inOrder.verify(updateFlowsBatch).invoke(any());
299 inOrder.verify(addGroupsBatch).invoke(any());
300 inOrder.verify(removeGroupsBatch).invoke(any());
301 inOrder.verify(updateGroupsBatch).invoke(any());
303 inOrder.verify(addMetersBatch).invoke(any());
304 inOrder.verify(removeMetersBatch).invoke(any());
305 inOrder.verify(updateMetersBatch).invoke(any());
308 private void prepareFirstFailingMockService() {
309 when(addFlowsBatch.invoke(any()))
310 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
311 when(removeFlowsBatch.invoke(any()))
312 .thenReturn(RpcResultBuilder.<RemoveFlowsBatchOutput>failed()
313 .withResult(new RemoveFlowsBatchOutputBuilder()
314 .setBatchFailedFlowsOutput(BindingMap.ordered(
315 new BatchFailedFlowsOutputBuilder()
316 .setBatchOrder(Uint16.ONE)
317 .setFlowId(new FlowId("123"))
320 .withError(ErrorType.APPLICATION, "ut-firstFlowAddError")
322 when(updateFlowsBatch.invoke(any()))
323 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
325 when(addGroupsBatch.invoke(any()))
326 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
327 when(removeGroupsBatch.invoke(any()))
328 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
329 when(updateGroupsBatch.invoke(any()))
330 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
332 when(addMetersBatch.invoke(any()))
333 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
334 when(removeMetersBatch.invoke(any()))
335 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
336 when(updateMetersBatch.invoke(any()))
337 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
340 private static Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
341 return createFlowAddBatch(batchOrder, flowIdValue, 1);
344 private static Batch createFlowAddBatch(final int batchOrder, final String flowIdValue, final int amount) {
345 return new BatchBuilder()
346 .setBatchOrder(Uint16.valueOf(batchOrder))
347 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
348 .setFlatBatchAddFlow(repeatFlatBatchAddFlowInList(flowIdValue, amount))
353 private static Map<FlatBatchAddFlowKey, FlatBatchAddFlow> repeatFlatBatchAddFlowInList(final String flowIdValue,
355 final Map<FlatBatchAddFlowKey, FlatBatchAddFlow> map = new LinkedHashMap<>();
356 for (int i = 0; i < amount; i++) {
357 final FlatBatchAddFlowKey key = new FlatBatchAddFlowKey(Uint16.valueOf(i));
358 map.put(key, new FlatBatchAddFlowBuilder().withKey(key).setFlowId(new FlowId(flowIdValue + i)).build());
363 private static Batch createFlowRemoveBatch(final int batchOrder, final String flowIdValue) {
364 return new BatchBuilder()
365 .setBatchOrder(Uint16.valueOf(batchOrder))
366 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
367 .setFlatBatchRemoveFlow(BindingMap.of(new FlatBatchRemoveFlowBuilder()
368 .setFlowId(new FlowId(flowIdValue))
369 .setBatchOrder(Uint16.valueOf(batchOrder))
375 private static Batch createFlowUpdateBatch(final int batchOrder, final String flowIdValue) {
376 final Uint16 uint = Uint16.valueOf(batchOrder);
377 return new BatchBuilder()
379 .withKey(new BatchKey(uint))
380 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
381 .setFlatBatchUpdateFlow(BindingMap.of(new FlatBatchUpdateFlowBuilder()
382 .setFlowId(new FlowId(flowIdValue))
383 .setBatchOrder(Uint16.valueOf(batchOrder))
389 private static Batch createGroupAddBatch(final int batchOrder, final long groupIdValue) {
390 return new BatchBuilder()
391 .setBatchOrder(Uint16.valueOf(batchOrder))
392 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
393 .setFlatBatchAddGroup(BindingMap.of(new FlatBatchAddGroupBuilder()
394 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
395 .setBatchOrder(Uint16.valueOf(batchOrder))
401 private static Batch createGroupRemoveBatch(final int batchOrder, final long groupIdValue) {
402 return new BatchBuilder()
403 .setBatchOrder(Uint16.valueOf(batchOrder))
404 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
405 .setFlatBatchRemoveGroup(BindingMap.of(new FlatBatchRemoveGroupBuilder()
406 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
407 .setBatchOrder(Uint16.valueOf(batchOrder))
413 private static Batch createGroupUpdateBatch(final int batchOrder, final long groupIdValue) {
414 return new BatchBuilder()
415 .setBatchOrder(Uint16.valueOf(batchOrder))
416 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
417 .setFlatBatchUpdateGroup(BindingMap.of(new FlatBatchUpdateGroupBuilder()
418 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder()
419 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
421 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
422 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
424 .setBatchOrder(Uint16.valueOf(batchOrder))
430 private static Batch createMeterAddBatch(final int batchOrder, final long groupIdValue) {
431 return new BatchBuilder()
432 .setBatchOrder(Uint16.valueOf(batchOrder))
433 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
434 .setFlatBatchAddMeter(BindingMap.of(new FlatBatchAddMeterBuilder()
435 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
436 .setBatchOrder(Uint16.valueOf(batchOrder))
442 private static Batch createMeterRemoveBatch(final int batchOrder, final long groupIdValue) {
443 return new BatchBuilder()
444 .setBatchOrder(Uint16.valueOf(batchOrder))
445 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
446 .setFlatBatchRemoveMeter(BindingMap.of(new FlatBatchRemoveMeterBuilder()
447 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
448 .setBatchOrder(Uint16.valueOf(batchOrder))
454 private static Batch createMeterUpdateBatch(final int batchOrder, final long groupIdValue) {
455 return new BatchBuilder()
456 .setBatchOrder(Uint16.valueOf(batchOrder))
457 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
458 .setFlatBatchUpdateMeter(BindingMap.of(new FlatBatchUpdateMeterBuilder()
459 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder()
460 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
462 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
463 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
465 .setBatchOrder(Uint16.valueOf(batchOrder))
472 public void testExecuteBatchPlan() throws Exception {
473 BatchStepJob batchStepJob1 = mock(BatchStepJob.class);
474 BatchStepJob batchStepJob2 = mock(BatchStepJob.class);
475 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function1 =
476 mock(AsyncFunction.class);
477 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function2 =
478 mock(AsyncFunction.class);
479 when(batchStepJob1.getStepFunction()).thenReturn(function1);
480 when(batchStepJob2.getStepFunction()).thenReturn(function2);
481 BatchPlanStep batchPlanStep1 = new BatchPlanStep(BatchStepType.GROUP_ADD);
482 batchPlanStep1.setBarrierAfter(true);
483 BatchPlanStep batchPlanStep2 = new BatchPlanStep(BatchStepType.FLOW_ADD);
484 batchPlanStep1.setBarrierAfter(false);
485 when(batchStepJob1.getPlanStep()).thenReturn(batchPlanStep1);
486 when(batchStepJob2.getPlanStep()).thenReturn(batchPlanStep2);
488 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> succeededChainOutput =
489 FlatBatchUtil.createEmptyRpcBatchResultFuture(true);
490 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> failedChainOutput =
491 RpcResultBuilder.<ProcessFlatBatchOutput>failed()
492 .withError(ErrorType.APPLICATION, "ut-chainError")
493 .withResult(createFlatBatchOutput(createFlowBatchFailure(Uint16.ZERO, "f1"),
494 createFlowBatchFailure(Uint16.ONE, "f2")))
497 when(batchStepJob1.getStepFunction().apply(any())).thenReturn(succeededChainOutput);
498 when(batchStepJob2.getStepFunction().apply(any())).thenReturn(failedChainOutput);
500 final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
501 final var rpcResultFuture = processFlatBatch.executeBatchPlan(batchChainElements);
503 assertTrue(rpcResultFuture.isDone());
504 final var rpcResult = rpcResultFuture.get();
505 assertFalse(rpcResult.isSuccessful());
506 assertEquals(1, rpcResult.getErrors().size());
507 assertEquals(2, rpcResult.getResult().nonnullBatchFailure().size());
508 Iterator<BatchFailure> iterator = rpcResult.getResult().nonnullBatchFailure().values().iterator();
509 //Moving iterator two get second element
512 ((FlatBatchFailureFlowIdCase) iterator.next().getBatchItemIdChoice())
513 .getFlowId().getValue());
516 private static BatchFailure createFlowBatchFailure(final Uint16 batchOrder, final String flowIdValue) {
517 return new BatchFailureBuilder()
518 .setBatchOrder(batchOrder)
519 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
520 .setFlowId(new FlowId(flowIdValue))
525 private static ProcessFlatBatchOutput createFlatBatchOutput(final BatchFailure... batchFailures) {
526 return new ProcessFlatBatchOutputBuilder()
527 .setBatchFailure(BindingMap.ordered(batchFailures))
532 public void testPrepareBatchPlan_success() throws Exception {
533 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
534 .setFlowId(new FlowId("f1"))
535 .setBatchOrder(Uint16.ONE)
537 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
538 .setFlowId(new FlowId("f2"))
539 .setBatchOrder(Uint16.TWO)
541 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
542 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
543 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep);
545 final List<BatchStepJob> batchChain = processFlatBatch.prepareBatchChain(batchPlan, NODE_REF, true);
547 assertEquals(1, batchChain.size());
549 when(addFlowsBatch.invoke(any()))
550 .thenReturn(RpcResultBuilder
551 .success(new AddFlowsBatchOutputBuilder().build())
554 final var rpcResultFuture = processFlatBatch.executeBatchPlan(batchChain);
555 assertTrue(rpcResultFuture.isDone());
556 final var rpcResult = rpcResultFuture.get();
557 assertTrue(rpcResult.isSuccessful());
558 assertEquals(0, rpcResult.getErrors().size());
559 assertEquals(0, rpcResult.getResult().nonnullBatchFailure().size());
561 verify(addFlowsBatch).invoke(any());
565 public void testPrepareBatchPlan_failure() throws Exception {
566 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
567 .setFlowId(new FlowId("f1"))
568 .setBatchOrder(Uint16.ONE)
570 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
571 .setFlowId(new FlowId("f2"))
572 .setBatchOrder(Uint16.TWO)
574 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
575 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
577 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
579 final List<BatchStepJob> batchChain = processFlatBatch.prepareBatchChain(batchPlan, NODE_REF, true);
581 assertEquals(2, batchChain.size());
583 when(addFlowsBatch.invoke(any()))
584 .thenReturn(RpcResultBuilder
585 .<AddFlowsBatchOutput>failed()
586 .withResult(new AddFlowsBatchOutputBuilder()
587 .setBatchFailedFlowsOutput(BindingMap.ordered(
588 new BatchFailedFlowsOutputBuilder()
589 .setBatchOrder(Uint16.ZERO)
590 .setFlowId(new FlowId("f1"))
592 new BatchFailedFlowsOutputBuilder()
593 .setBatchOrder(Uint16.ONE)
594 .setFlowId(new FlowId("f2"))
597 .withError(ErrorType.APPLICATION, "ut-addFlowBatchError")
600 final var rpcResultFuture = processFlatBatch.executeBatchPlan(batchChain);
601 assertTrue(rpcResultFuture.isDone());
602 final var rpcResult = rpcResultFuture.get();
603 assertFalse(rpcResult.isSuccessful());
604 assertEquals(2, rpcResult.getErrors().size());
605 assertEquals(4, rpcResult.getResult().getBatchFailure().size());
607 verify(addFlowsBatch, times(2)).invoke(addFlowsBatchInputCpt.capture());
608 assertEquals(2, addFlowsBatchInputCpt.getValue().nonnullBatchAddFlows().size());