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
9 package org.opendaylight.openflowplugin.impl.services.sal;
11 import com.google.common.collect.Lists;
12 import com.google.common.util.concurrent.AsyncFunction;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.concurrent.Future;
19 import org.junit.After;
20 import org.junit.Assert;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.ArgumentCaptor;
25 import org.mockito.ArgumentMatchers;
26 import org.mockito.Captor;
27 import org.mockito.InOrder;
28 import org.mockito.Mock;
29 import org.mockito.Mockito;
30 import org.mockito.junit.MockitoJUnitRunner;
31 import org.opendaylight.openflowplugin.impl.services.batch.BatchPlanStep;
32 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepJob;
33 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepType;
34 import org.opendaylight.openflowplugin.impl.util.FlatBatchUtil;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.flow._case.FlatBatchAddFlow;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.flow._case.FlatBatchAddFlowBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.flow._case.FlatBatchAddFlowKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.group._case.FlatBatchAddGroupBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.meter._case.FlatBatchAddMeterBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.flow._case.FlatBatchRemoveFlowBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.group._case.FlatBatchRemoveGroupBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.meter._case.FlatBatchRemoveMeterBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.flow._case.FlatBatchUpdateFlowBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.group._case.FlatBatchUpdateGroupBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.meter._case.FlatBatchUpdateMeterBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.SalFlowsBatchService;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchOutputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchOutputBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.SalGroupsBatchService;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchOutputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.OriginalBatchedGroupBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.UpdatedBatchedGroupBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchOutputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchOutputBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.SalMetersBatchService;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchOutputBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.OriginalBatchedMeterBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.UpdatedBatchedMeterBuilder;
94 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
95 import org.opendaylight.yangtools.yang.common.RpcError;
96 import org.opendaylight.yangtools.yang.common.RpcResult;
97 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
100 * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
102 @RunWith(MockitoJUnitRunner.class)
103 public class SalFlatBatchServiceImplTest {
105 private static final NodeId NODE_ID = new NodeId("ut-node-id");
106 private static final InstanceIdentifier<Node> NODE_II = InstanceIdentifier.create(Nodes.class)
107 .child(Node.class, new NodeKey(NODE_ID));
108 private static final NodeRef NODE_REF = new NodeRef(NODE_II);
111 private SalFlowsBatchService salFlowsBatchService;
113 private SalGroupsBatchService salGroupsBatchService;
115 private SalMetersBatchService salMetersBatchService;
117 private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
119 private SalFlatBatchServiceImpl salFlatBatchService;
122 public void setUp() {
123 salFlatBatchService =
124 new SalFlatBatchServiceImpl(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
129 public void tearDown() {
130 Mockito.verifyNoMoreInteractions(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
134 public void testProcessFlatBatch_allSuccessFinished() throws Exception {
135 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
136 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
137 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
138 .thenReturn(RpcResultBuilder.success(new RemoveFlowsBatchOutputBuilder().build()).buildFuture());
139 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
140 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
142 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
143 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
144 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
145 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
146 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
147 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
149 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
150 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
151 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
152 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
153 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
154 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
157 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
159 .setBatch(Lists.newArrayList(
160 createFlowAddBatch(0, "f1"),
161 createFlowRemoveBatch(1, "f2"),
162 createFlowUpdateBatch(2, "f3"),
164 createGroupAddBatch(3, 1L),
165 createGroupRemoveBatch(4, 2L),
166 createGroupUpdateBatch(5, 3L),
168 createMeterAddBatch(6, 1L),
169 createMeterRemoveBatch(7, 2L),
170 createMeterUpdateBatch(8, 3L)
172 .setExitOnFirstError(true)
175 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
176 salFlatBatchService.processFlatBatch(batchInput);
177 Assert.assertTrue(rpcResultFuture.isDone());
178 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
179 Assert.assertTrue(rpcResult.isSuccessful());
180 Assert.assertTrue(rpcResult.getErrors().isEmpty());
181 Assert.assertTrue(rpcResult.getResult().nonnullBatchFailure().isEmpty());
183 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
184 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
185 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
186 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
188 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
189 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
190 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
192 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
193 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
194 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
198 public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
199 prepareFirstFailingMockService();
202 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
204 .setBatch(Lists.newArrayList(
205 createFlowAddBatch(idx++, "f1", 2),
206 createFlowRemoveBatch(idx++, "f2"),
207 createFlowUpdateBatch(idx++, "f3"),
209 createGroupAddBatch(idx++, 1L),
210 createGroupRemoveBatch(idx++, 2L),
211 createGroupUpdateBatch(idx++, 3L),
213 createMeterAddBatch(idx++, 1L),
214 createMeterRemoveBatch(idx++, 2L),
215 createMeterUpdateBatch(idx++, 3L)
217 .setExitOnFirstError(true)
220 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
221 salFlatBatchService.processFlatBatch(batchInput);
222 Assert.assertTrue(rpcResultFuture.isDone());
223 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
224 Assert.assertFalse(rpcResult.isSuccessful());
225 Assert.assertEquals(1, rpcResult.getErrors().size());
226 Assert.assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
227 Assert.assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
228 .getBatchOrder().intValue());
230 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
231 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
232 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
233 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
234 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
238 public void testProcessFlatBatch_firstFailedContinue() throws Exception {
239 prepareFirstFailingMockService();
242 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
244 .setBatch(Lists.newArrayList(
245 createFlowAddBatch(idx++, "f1", 2),
246 createFlowRemoveBatch(idx++, "f2"),
247 createFlowUpdateBatch(idx++, "f3"),
249 createGroupAddBatch(idx++, 1L),
250 createGroupRemoveBatch(idx++, 2L),
251 createGroupUpdateBatch(idx++, 3L),
253 createMeterAddBatch(idx++, 1L),
254 createMeterRemoveBatch(idx++, 2L),
255 createMeterUpdateBatch(idx++, 3L)
257 .setExitOnFirstError(false)
260 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
261 salFlatBatchService.processFlatBatch(batchInput);
262 Assert.assertTrue(rpcResultFuture.isDone());
263 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
264 Assert.assertFalse(rpcResult.isSuccessful());
265 Assert.assertEquals(1, rpcResult.getErrors().size());
266 Assert.assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
267 Assert.assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
268 .getBatchOrder().intValue());
270 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
271 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
272 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
273 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
275 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
276 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
277 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
279 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
280 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
281 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
284 private void prepareFirstFailingMockService() {
285 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
286 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
287 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
288 .thenReturn(RpcResultBuilder.<RemoveFlowsBatchOutput>failed()
289 .withResult(new RemoveFlowsBatchOutputBuilder()
290 .setBatchFailedFlowsOutput(Lists.newArrayList(
291 new BatchFailedFlowsOutputBuilder()
293 .setFlowId(new FlowId("123"))
296 .withError(RpcError.ErrorType.APPLICATION, "ut-firstFlowAddError")
298 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
299 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
301 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
302 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
303 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
304 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
305 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
306 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
308 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
309 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
310 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
311 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
312 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
313 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
316 private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
317 return createFlowAddBatch(batchOrder, flowIdValue, 1);
320 private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue, final int amount) {
321 return new BatchBuilder()
322 .setBatchOrder(batchOrder)
323 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
324 .setFlatBatchAddFlow(repeatFlatBatchAddFlowInList(flowIdValue, amount))
329 private List<FlatBatchAddFlow> repeatFlatBatchAddFlowInList(final String flowIdValue, final int amount) {
330 final List<FlatBatchAddFlow> list = new ArrayList<>();
331 for (int i = 0; i < amount; i++) {
332 list.add(new FlatBatchAddFlowBuilder()
333 .setFlowId(new FlowId(flowIdValue + i))
334 .withKey(new FlatBatchAddFlowKey(i))
340 private <T> List<T> repeatInList(final T item, final int amount) {
341 final List<T> list = new ArrayList<>();
342 for (int i = 0; i < amount; i++) {
348 private Batch createFlowRemoveBatch(final int batchOrder, final String flowIdValue) {
349 return new BatchBuilder()
350 .setBatchOrder(batchOrder)
351 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
352 .setFlatBatchRemoveFlow(Collections.singletonList(new FlatBatchRemoveFlowBuilder()
353 .setFlowId(new FlowId(flowIdValue))
359 private Batch createFlowUpdateBatch(final int batchOrder, final String flowIdValue) {
360 return new BatchBuilder()
361 .setBatchOrder(batchOrder)
362 .withKey(new BatchKey(batchOrder))
363 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
364 .setFlatBatchUpdateFlow(Collections.singletonList(new FlatBatchUpdateFlowBuilder()
365 .setFlowId(new FlowId(flowIdValue))
371 private Batch createGroupAddBatch(final int batchOrder, final long groupIdValue) {
372 return new BatchBuilder()
373 .setBatchOrder(batchOrder)
374 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
375 .setFlatBatchAddGroup(Collections.singletonList(new FlatBatchAddGroupBuilder()
376 .setGroupId(new GroupId(groupIdValue))
382 private Batch createGroupRemoveBatch(final int batchOrder, final long groupIdValue) {
383 return new BatchBuilder()
384 .setBatchOrder(batchOrder)
385 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
386 .setFlatBatchRemoveGroup(Collections.singletonList(new FlatBatchRemoveGroupBuilder()
387 .setGroupId(new GroupId(groupIdValue))
393 private Batch createGroupUpdateBatch(final int batchOrder, final long groupIdValue) {
394 return new BatchBuilder()
395 .setBatchOrder(batchOrder)
396 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
397 .setFlatBatchUpdateGroup(Collections.singletonList(new FlatBatchUpdateGroupBuilder()
398 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder()
399 .setGroupId(new GroupId(groupIdValue))
401 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
402 .setGroupId(new GroupId(groupIdValue))
409 private Batch createMeterAddBatch(final int batchOrder, final long groupIdValue) {
410 return new BatchBuilder()
411 .setBatchOrder(batchOrder)
412 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
413 .setFlatBatchAddMeter(Collections.singletonList(new FlatBatchAddMeterBuilder()
414 .setMeterId(new MeterId(groupIdValue))
420 private Batch createMeterRemoveBatch(final int batchOrder, final long groupIdValue) {
421 return new BatchBuilder()
422 .setBatchOrder(batchOrder)
423 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
424 .setFlatBatchRemoveMeter(Collections.singletonList(new FlatBatchRemoveMeterBuilder()
425 .setMeterId(new MeterId(groupIdValue))
431 private Batch createMeterUpdateBatch(final int batchOrder, final long groupIdValue) {
432 return new BatchBuilder()
433 .setBatchOrder(batchOrder)
434 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
435 .setFlatBatchUpdateMeter(Collections.singletonList(new FlatBatchUpdateMeterBuilder()
436 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder()
437 .setMeterId(new MeterId(groupIdValue))
439 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
440 .setMeterId(new MeterId(groupIdValue))
448 public void testExecuteBatchPlan() throws Exception {
449 BatchStepJob batchStepJob1 = Mockito.mock(BatchStepJob.class);
450 BatchStepJob batchStepJob2 = Mockito.mock(BatchStepJob.class);
451 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function1 =
452 Mockito.mock(AsyncFunction.class);
453 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function2 =
454 Mockito.mock(AsyncFunction.class);
455 Mockito.when(batchStepJob1.getStepFunction()).thenReturn(function1);
456 Mockito.when(batchStepJob2.getStepFunction()).thenReturn(function2);
457 BatchPlanStep batchPlanStep1 = new BatchPlanStep(BatchStepType.GROUP_ADD);
458 batchPlanStep1.setBarrierAfter(true);
459 BatchPlanStep batchPlanStep2 = new BatchPlanStep(BatchStepType.FLOW_ADD);
460 batchPlanStep1.setBarrierAfter(false);
461 Mockito.when(batchStepJob1.getPlanStep()).thenReturn(batchPlanStep1);
462 Mockito.when(batchStepJob2.getPlanStep()).thenReturn(batchPlanStep2);
464 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> succeededChainOutput =
465 FlatBatchUtil.createEmptyRpcBatchResultFuture(true);
466 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> failedChainOutput =
467 RpcResultBuilder.<ProcessFlatBatchOutput>failed()
468 .withError(RpcError.ErrorType.APPLICATION, "ut-chainError")
469 .withResult(createFlatBatchOutput(createFlowBatchFailure(0, "f1"),
470 createFlowBatchFailure(1, "f2")))
473 Mockito.when(batchStepJob1.getStepFunction().apply(ArgumentMatchers.any()))
474 .thenReturn(succeededChainOutput);
475 Mockito.when(batchStepJob2.getStepFunction().apply(ArgumentMatchers.any()))
476 .thenReturn(failedChainOutput);
478 final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
479 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
480 salFlatBatchService.executeBatchPlan(batchChainElements);
482 Assert.assertTrue(rpcResultFuture.isDone());
483 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
484 Assert.assertFalse(rpcResult.isSuccessful());
485 Assert.assertEquals(1, rpcResult.getErrors().size());
486 Assert.assertEquals(2, rpcResult.getResult().nonnullBatchFailure().size());
487 Iterator<BatchFailure> iterator = rpcResult.getResult().nonnullBatchFailure().values().iterator();
488 //Moving iterator two get second element
490 Assert.assertEquals("f2",
491 ((FlatBatchFailureFlowIdCase) iterator.next().getBatchItemIdChoice())
492 .getFlowId().getValue());
495 private BatchFailure createFlowBatchFailure(final int batchOrder, final String flowIdValue) {
496 return new BatchFailureBuilder()
497 .setBatchOrder(batchOrder)
498 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
499 .setFlowId(new FlowId(flowIdValue))
504 private ProcessFlatBatchOutput createFlatBatchOutput(final BatchFailure... batchFailures) {
505 return new ProcessFlatBatchOutputBuilder()
506 .setBatchFailure(Lists.newArrayList(batchFailures))
511 public void testPrepareBatchPlan_success() throws Exception {
512 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
513 .setFlowId(new FlowId("f1"))
515 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
516 .setFlowId(new FlowId("f2"))
518 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
519 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
520 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep);
522 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
524 Assert.assertEquals(1, batchChain.size());
526 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
527 .thenReturn(RpcResultBuilder
528 .success(new AddFlowsBatchOutputBuilder().build())
531 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
532 salFlatBatchService.executeBatchPlan(batchChain);
533 Assert.assertTrue(rpcResultFuture.isDone());
534 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
535 Assert.assertTrue(rpcResult.isSuccessful());
536 Assert.assertEquals(0, rpcResult.getErrors().size());
537 Assert.assertEquals(0, rpcResult.getResult().nonnullBatchFailure().size());
539 Mockito.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
543 public void testPrepareBatchPlan_failure() throws Exception {
544 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
545 .setFlowId(new FlowId("f1"))
547 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
548 .setFlowId(new FlowId("f2"))
550 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
551 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
553 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
555 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
557 Assert.assertEquals(2, batchChain.size());
559 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
560 .thenReturn(RpcResultBuilder
561 .<AddFlowsBatchOutput>failed()
562 .withResult(new AddFlowsBatchOutputBuilder()
563 .setBatchFailedFlowsOutput(Lists.newArrayList(
564 new BatchFailedFlowsOutputBuilder()
566 .setFlowId(new FlowId("f1"))
568 new BatchFailedFlowsOutputBuilder()
570 .setFlowId(new FlowId("f2"))
573 .withError(RpcError.ErrorType.APPLICATION, "ut-addFlowBatchError")
576 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
577 salFlatBatchService.executeBatchPlan(batchChain);
578 Assert.assertTrue(rpcResultFuture.isDone());
579 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
580 Assert.assertFalse(rpcResult.isSuccessful());
581 Assert.assertEquals(2, rpcResult.getErrors().size());
582 Assert.assertEquals(4, rpcResult.getResult().getBatchFailure().size());
584 Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
585 Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());