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 com.google.common.collect.Lists;
11 import com.google.common.util.concurrent.AsyncFunction;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.concurrent.Future;
18 import org.junit.After;
19 import org.junit.Assert;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.ArgumentCaptor;
24 import org.mockito.ArgumentMatchers;
25 import org.mockito.Captor;
26 import org.mockito.InOrder;
27 import org.mockito.Mock;
28 import org.mockito.Mockito;
29 import org.mockito.junit.MockitoJUnitRunner;
30 import org.opendaylight.openflowplugin.impl.services.batch.BatchPlanStep;
31 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepJob;
32 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepType;
33 import org.opendaylight.openflowplugin.impl.util.FlatBatchUtil;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
50 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;
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.FlatBatchAddFlowBuilder;
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.FlatBatchAddFlowKey;
53 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;
54 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;
55 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;
56 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;
57 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;
58 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;
59 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;
60 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;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCaseBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutputBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.SalFlowsBatchService;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.SalGroupsBatchService;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.OriginalBatchedGroupBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.UpdatedBatchedGroupBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchOutputBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchOutputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.SalMetersBatchService;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchOutputBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.OriginalBatchedMeterBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.UpdatedBatchedMeterBuilder;
93 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
94 import org.opendaylight.yangtools.yang.common.RpcError;
95 import org.opendaylight.yangtools.yang.common.RpcResult;
96 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
99 * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
101 @RunWith(MockitoJUnitRunner.class)
102 public class SalFlatBatchServiceImplTest {
104 private static final NodeId NODE_ID = new NodeId("ut-node-id");
105 private static final InstanceIdentifier<Node> NODE_II = InstanceIdentifier.create(Nodes.class)
106 .child(Node.class, new NodeKey(NODE_ID));
107 private static final NodeRef NODE_REF = new NodeRef(NODE_II);
110 private SalFlowsBatchService salFlowsBatchService;
112 private SalGroupsBatchService salGroupsBatchService;
114 private SalMetersBatchService salMetersBatchService;
116 private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
118 private SalFlatBatchServiceImpl salFlatBatchService;
121 public void setUp() {
122 salFlatBatchService =
123 new SalFlatBatchServiceImpl(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
128 public void tearDown() {
129 Mockito.verifyNoMoreInteractions(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
133 public void testProcessFlatBatch_allSuccessFinished() throws Exception {
134 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
135 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
136 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
137 .thenReturn(RpcResultBuilder.success(new RemoveFlowsBatchOutputBuilder().build()).buildFuture());
138 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
139 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
141 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
142 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
143 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
144 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
145 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
146 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
148 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
149 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
150 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
151 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
152 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
153 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
156 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
158 .setBatch(Lists.newArrayList(
159 createFlowAddBatch(0, "f1"),
160 createFlowRemoveBatch(1, "f2"),
161 createFlowUpdateBatch(2, "f3"),
163 createGroupAddBatch(3, 1L),
164 createGroupRemoveBatch(4, 2L),
165 createGroupUpdateBatch(5, 3L),
167 createMeterAddBatch(6, 1L),
168 createMeterRemoveBatch(7, 2L),
169 createMeterUpdateBatch(8, 3L)
171 .setExitOnFirstError(true)
174 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
175 salFlatBatchService.processFlatBatch(batchInput);
176 Assert.assertTrue(rpcResultFuture.isDone());
177 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
178 Assert.assertTrue(rpcResult.isSuccessful());
179 Assert.assertTrue(rpcResult.getErrors().isEmpty());
180 Assert.assertTrue(rpcResult.getResult().nonnullBatchFailure().isEmpty());
182 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
183 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
184 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
185 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
187 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
188 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
189 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
191 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
192 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
193 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
197 public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
198 prepareFirstFailingMockService();
201 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
203 .setBatch(Lists.newArrayList(
204 createFlowAddBatch(idx++, "f1", 2),
205 createFlowRemoveBatch(idx++, "f2"),
206 createFlowUpdateBatch(idx++, "f3"),
208 createGroupAddBatch(idx++, 1L),
209 createGroupRemoveBatch(idx++, 2L),
210 createGroupUpdateBatch(idx++, 3L),
212 createMeterAddBatch(idx++, 1L),
213 createMeterRemoveBatch(idx++, 2L),
214 createMeterUpdateBatch(idx++, 3L)
216 .setExitOnFirstError(true)
219 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
220 salFlatBatchService.processFlatBatch(batchInput);
221 Assert.assertTrue(rpcResultFuture.isDone());
222 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
223 Assert.assertFalse(rpcResult.isSuccessful());
224 Assert.assertEquals(1, rpcResult.getErrors().size());
225 Assert.assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
226 Assert.assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
227 .getBatchOrder().intValue());
229 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
230 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
231 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
232 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
233 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
237 public void testProcessFlatBatch_firstFailedContinue() throws Exception {
238 prepareFirstFailingMockService();
241 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
243 .setBatch(Lists.newArrayList(
244 createFlowAddBatch(idx++, "f1", 2),
245 createFlowRemoveBatch(idx++, "f2"),
246 createFlowUpdateBatch(idx++, "f3"),
248 createGroupAddBatch(idx++, 1L),
249 createGroupRemoveBatch(idx++, 2L),
250 createGroupUpdateBatch(idx++, 3L),
252 createMeterAddBatch(idx++, 1L),
253 createMeterRemoveBatch(idx++, 2L),
254 createMeterUpdateBatch(idx++, 3L)
256 .setExitOnFirstError(false)
259 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
260 salFlatBatchService.processFlatBatch(batchInput);
261 Assert.assertTrue(rpcResultFuture.isDone());
262 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
263 Assert.assertFalse(rpcResult.isSuccessful());
264 Assert.assertEquals(1, rpcResult.getErrors().size());
265 Assert.assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
266 Assert.assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
267 .getBatchOrder().intValue());
269 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
270 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
271 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
272 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
274 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
275 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
276 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
278 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
279 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
280 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
283 private void prepareFirstFailingMockService() {
284 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
285 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
286 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
287 .thenReturn(RpcResultBuilder.<RemoveFlowsBatchOutput>failed()
288 .withResult(new RemoveFlowsBatchOutputBuilder()
289 .setBatchFailedFlowsOutput(Lists.newArrayList(
290 new BatchFailedFlowsOutputBuilder()
292 .setFlowId(new FlowId("123"))
295 .withError(RpcError.ErrorType.APPLICATION, "ut-firstFlowAddError")
297 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
298 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
300 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
301 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
302 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
303 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
304 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
305 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
307 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
308 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
309 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
310 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
311 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
312 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
315 private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
316 return createFlowAddBatch(batchOrder, flowIdValue, 1);
319 private static Batch createFlowAddBatch(final int batchOrder, final String flowIdValue, final int amount) {
320 return new BatchBuilder()
321 .setBatchOrder(batchOrder)
322 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
323 .setFlatBatchAddFlow(repeatFlatBatchAddFlowInList(flowIdValue, amount))
328 private static List<FlatBatchAddFlow> repeatFlatBatchAddFlowInList(final String flowIdValue, final int amount) {
329 final List<FlatBatchAddFlow> list = new ArrayList<>();
330 for (int i = 0; i < amount; i++) {
331 list.add(new FlatBatchAddFlowBuilder()
332 .setFlowId(new FlowId(flowIdValue + i))
333 .withKey(new FlatBatchAddFlowKey(i))
339 private static <T> List<T> repeatInList(final T item, final int amount) {
340 final List<T> list = new ArrayList<>();
341 for (int i = 0; i < amount; i++) {
347 private static Batch createFlowRemoveBatch(final int batchOrder, final String flowIdValue) {
348 return new BatchBuilder()
349 .setBatchOrder(batchOrder)
350 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
351 .setFlatBatchRemoveFlow(Collections.singletonList(new FlatBatchRemoveFlowBuilder()
352 .setFlowId(new FlowId(flowIdValue))
358 private static Batch createFlowUpdateBatch(final int batchOrder, final String flowIdValue) {
359 return new BatchBuilder()
360 .setBatchOrder(batchOrder)
361 .withKey(new BatchKey(batchOrder))
362 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
363 .setFlatBatchUpdateFlow(Collections.singletonList(new FlatBatchUpdateFlowBuilder()
364 .setFlowId(new FlowId(flowIdValue))
370 private static Batch createGroupAddBatch(final int batchOrder, final long groupIdValue) {
371 return new BatchBuilder()
372 .setBatchOrder(batchOrder)
373 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
374 .setFlatBatchAddGroup(Collections.singletonList(new FlatBatchAddGroupBuilder()
375 .setGroupId(new GroupId(groupIdValue))
381 private static Batch createGroupRemoveBatch(final int batchOrder, final long groupIdValue) {
382 return new BatchBuilder()
383 .setBatchOrder(batchOrder)
384 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
385 .setFlatBatchRemoveGroup(Collections.singletonList(new FlatBatchRemoveGroupBuilder()
386 .setGroupId(new GroupId(groupIdValue))
392 private static Batch createGroupUpdateBatch(final int batchOrder, final long groupIdValue) {
393 return new BatchBuilder()
394 .setBatchOrder(batchOrder)
395 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
396 .setFlatBatchUpdateGroup(Collections.singletonList(new FlatBatchUpdateGroupBuilder()
397 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder()
398 .setGroupId(new GroupId(groupIdValue))
400 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
401 .setGroupId(new GroupId(groupIdValue))
408 private static Batch createMeterAddBatch(final int batchOrder, final long groupIdValue) {
409 return new BatchBuilder()
410 .setBatchOrder(batchOrder)
411 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
412 .setFlatBatchAddMeter(Collections.singletonList(new FlatBatchAddMeterBuilder()
413 .setMeterId(new MeterId(groupIdValue))
419 private static Batch createMeterRemoveBatch(final int batchOrder, final long groupIdValue) {
420 return new BatchBuilder()
421 .setBatchOrder(batchOrder)
422 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
423 .setFlatBatchRemoveMeter(Collections.singletonList(new FlatBatchRemoveMeterBuilder()
424 .setMeterId(new MeterId(groupIdValue))
430 private static Batch createMeterUpdateBatch(final int batchOrder, final long groupIdValue) {
431 return new BatchBuilder()
432 .setBatchOrder(batchOrder)
433 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
434 .setFlatBatchUpdateMeter(Collections.singletonList(new FlatBatchUpdateMeterBuilder()
435 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder()
436 .setMeterId(new MeterId(groupIdValue))
438 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
439 .setMeterId(new MeterId(groupIdValue))
447 public void testExecuteBatchPlan() throws Exception {
448 BatchStepJob batchStepJob1 = Mockito.mock(BatchStepJob.class);
449 BatchStepJob batchStepJob2 = Mockito.mock(BatchStepJob.class);
450 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function1 =
451 Mockito.mock(AsyncFunction.class);
452 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function2 =
453 Mockito.mock(AsyncFunction.class);
454 Mockito.when(batchStepJob1.getStepFunction()).thenReturn(function1);
455 Mockito.when(batchStepJob2.getStepFunction()).thenReturn(function2);
456 BatchPlanStep batchPlanStep1 = new BatchPlanStep(BatchStepType.GROUP_ADD);
457 batchPlanStep1.setBarrierAfter(true);
458 BatchPlanStep batchPlanStep2 = new BatchPlanStep(BatchStepType.FLOW_ADD);
459 batchPlanStep1.setBarrierAfter(false);
460 Mockito.when(batchStepJob1.getPlanStep()).thenReturn(batchPlanStep1);
461 Mockito.when(batchStepJob2.getPlanStep()).thenReturn(batchPlanStep2);
463 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> succeededChainOutput =
464 FlatBatchUtil.createEmptyRpcBatchResultFuture(true);
465 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> failedChainOutput =
466 RpcResultBuilder.<ProcessFlatBatchOutput>failed()
467 .withError(RpcError.ErrorType.APPLICATION, "ut-chainError")
468 .withResult(createFlatBatchOutput(createFlowBatchFailure(0, "f1"),
469 createFlowBatchFailure(1, "f2")))
472 Mockito.when(batchStepJob1.getStepFunction().apply(ArgumentMatchers.any()))
473 .thenReturn(succeededChainOutput);
474 Mockito.when(batchStepJob2.getStepFunction().apply(ArgumentMatchers.any()))
475 .thenReturn(failedChainOutput);
477 final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
478 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
479 salFlatBatchService.executeBatchPlan(batchChainElements);
481 Assert.assertTrue(rpcResultFuture.isDone());
482 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
483 Assert.assertFalse(rpcResult.isSuccessful());
484 Assert.assertEquals(1, rpcResult.getErrors().size());
485 Assert.assertEquals(2, rpcResult.getResult().nonnullBatchFailure().size());
486 Iterator<BatchFailure> iterator = rpcResult.getResult().nonnullBatchFailure().values().iterator();
487 //Moving iterator two get second element
489 Assert.assertEquals("f2",
490 ((FlatBatchFailureFlowIdCase) iterator.next().getBatchItemIdChoice())
491 .getFlowId().getValue());
494 private static BatchFailure createFlowBatchFailure(final int batchOrder, final String flowIdValue) {
495 return new BatchFailureBuilder()
496 .setBatchOrder(batchOrder)
497 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
498 .setFlowId(new FlowId(flowIdValue))
503 private static ProcessFlatBatchOutput createFlatBatchOutput(final BatchFailure... batchFailures) {
504 return new ProcessFlatBatchOutputBuilder()
505 .setBatchFailure(Lists.newArrayList(batchFailures))
510 public void testPrepareBatchPlan_success() throws Exception {
511 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
512 .setFlowId(new FlowId("f1"))
514 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
515 .setFlowId(new FlowId("f2"))
517 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
518 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
519 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep);
521 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
523 Assert.assertEquals(1, batchChain.size());
525 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
526 .thenReturn(RpcResultBuilder
527 .success(new AddFlowsBatchOutputBuilder().build())
530 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
531 salFlatBatchService.executeBatchPlan(batchChain);
532 Assert.assertTrue(rpcResultFuture.isDone());
533 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
534 Assert.assertTrue(rpcResult.isSuccessful());
535 Assert.assertEquals(0, rpcResult.getErrors().size());
536 Assert.assertEquals(0, rpcResult.getResult().nonnullBatchFailure().size());
538 Mockito.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
542 public void testPrepareBatchPlan_failure() throws Exception {
543 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
544 .setFlowId(new FlowId("f1"))
546 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
547 .setFlowId(new FlowId("f2"))
549 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
550 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
552 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
554 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
556 Assert.assertEquals(2, batchChain.size());
558 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
559 .thenReturn(RpcResultBuilder
560 .<AddFlowsBatchOutput>failed()
561 .withResult(new AddFlowsBatchOutputBuilder()
562 .setBatchFailedFlowsOutput(Lists.newArrayList(
563 new BatchFailedFlowsOutputBuilder()
565 .setFlowId(new FlowId("f1"))
567 new BatchFailedFlowsOutputBuilder()
569 .setFlowId(new FlowId("f2"))
572 .withError(RpcError.ErrorType.APPLICATION, "ut-addFlowBatchError")
575 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
576 salFlatBatchService.executeBatchPlan(batchChain);
577 Assert.assertTrue(rpcResultFuture.isDone());
578 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
579 Assert.assertFalse(rpcResult.isSuccessful());
580 Assert.assertEquals(2, rpcResult.getErrors().size());
581 Assert.assertEquals(4, rpcResult.getResult().getBatchFailure().size());
583 Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
584 Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());