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.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.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
49 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;
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.FlatBatchAddFlowBuilder;
51 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;
52 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;
53 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;
54 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;
55 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;
56 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;
57 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;
58 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;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCaseBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.SalFlowsBatchService;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchOutputBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchOutputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchOutputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.SalGroupsBatchService;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.OriginalBatchedGroupBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.UpdatedBatchedGroupBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchOutputBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchOutputBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.SalMetersBatchService;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchOutputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.OriginalBatchedMeterBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.UpdatedBatchedMeterBuilder;
91 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
92 import org.opendaylight.yangtools.yang.common.RpcError;
93 import org.opendaylight.yangtools.yang.common.RpcResult;
94 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
97 * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
99 @RunWith(MockitoJUnitRunner.class)
100 public class SalFlatBatchServiceImplTest {
102 private static final NodeId NODE_ID = new NodeId("ut-node-id");
103 private static final InstanceIdentifier<Node> NODE_II = InstanceIdentifier.create(Nodes.class)
104 .child(Node.class, new NodeKey(NODE_ID));
105 private static final NodeRef NODE_REF = new NodeRef(NODE_II);
108 private SalFlowsBatchService salFlowsBatchService;
110 private SalGroupsBatchService salGroupsBatchService;
112 private SalMetersBatchService salMetersBatchService;
114 private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
116 private SalFlatBatchServiceImpl salFlatBatchService;
119 public void setUp() {
120 salFlatBatchService =
121 new SalFlatBatchServiceImpl(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
126 public void tearDown() {
127 Mockito.verifyNoMoreInteractions(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
131 public void testProcessFlatBatch_allSuccessFinished() throws Exception {
132 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
133 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
134 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
135 .thenReturn(RpcResultBuilder.success(new RemoveFlowsBatchOutputBuilder().build()).buildFuture());
136 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
137 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
139 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
140 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
141 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
142 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
143 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
144 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
146 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
147 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
148 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
149 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
150 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
151 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
154 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
156 .setBatch(Lists.newArrayList(
157 createFlowAddBatch(0, "f1"),
158 createFlowRemoveBatch(1, "f2"),
159 createFlowUpdateBatch(2, "f3"),
161 createGroupAddBatch(3, 1L),
162 createGroupRemoveBatch(4, 2L),
163 createGroupUpdateBatch(5, 3L),
165 createMeterAddBatch(3, 1L),
166 createMeterRemoveBatch(4, 2L),
167 createMeterUpdateBatch(5, 3L)
169 .setExitOnFirstError(true)
172 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
173 salFlatBatchService.processFlatBatch(batchInput);
174 Assert.assertTrue(rpcResultFuture.isDone());
175 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
176 Assert.assertTrue(rpcResult.isSuccessful());
177 Assert.assertTrue(rpcResult.getErrors().isEmpty());
178 Assert.assertTrue(rpcResult.getResult().getBatchFailure().isEmpty());
180 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
181 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
182 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
183 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
185 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
186 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
187 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
189 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
190 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
191 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
195 public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
196 prepareFirstFailingMockService();
199 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
201 .setBatch(Lists.newArrayList(
202 createFlowAddBatch(idx++, "f1", 2),
203 createFlowRemoveBatch(idx++, "f2"),
204 createFlowUpdateBatch(idx++, "f3"),
206 createGroupAddBatch(idx++, 1L),
207 createGroupRemoveBatch(idx++, 2L),
208 createGroupUpdateBatch(idx++, 3L),
210 createMeterAddBatch(idx++, 1L),
211 createMeterRemoveBatch(idx++, 2L),
212 createMeterUpdateBatch(idx++, 3L)
214 .setExitOnFirstError(true)
217 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
218 salFlatBatchService.processFlatBatch(batchInput);
219 Assert.assertTrue(rpcResultFuture.isDone());
220 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
221 Assert.assertFalse(rpcResult.isSuccessful());
222 Assert.assertEquals(1, rpcResult.getErrors().size());
223 Assert.assertEquals(1, rpcResult.getResult().getBatchFailure().size());
224 Assert.assertEquals(3, rpcResult.getResult().getBatchFailure().get(0).getBatchOrder().intValue());
226 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
227 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
228 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
229 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
230 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
234 public void testProcessFlatBatch_firstFailedContinue() throws Exception {
235 prepareFirstFailingMockService();
238 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
240 .setBatch(Lists.newArrayList(
241 createFlowAddBatch(idx++, "f1", 2),
242 createFlowRemoveBatch(idx++, "f2"),
243 createFlowUpdateBatch(idx++, "f3"),
245 createGroupAddBatch(idx++, 1L),
246 createGroupRemoveBatch(idx++, 2L),
247 createGroupUpdateBatch(idx++, 3L),
249 createMeterAddBatch(idx++, 1L),
250 createMeterRemoveBatch(idx++, 2L),
251 createMeterUpdateBatch(idx++, 3L)
253 .setExitOnFirstError(false)
256 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
257 salFlatBatchService.processFlatBatch(batchInput);
258 Assert.assertTrue(rpcResultFuture.isDone());
259 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
260 Assert.assertFalse(rpcResult.isSuccessful());
261 Assert.assertEquals(1, rpcResult.getErrors().size());
262 Assert.assertEquals(1, rpcResult.getResult().getBatchFailure().size());
263 Assert.assertEquals(3, rpcResult.getResult().getBatchFailure().get(0).getBatchOrder().intValue());
265 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
266 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
267 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
268 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
270 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
271 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
272 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
274 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
275 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
276 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
279 private void prepareFirstFailingMockService() {
280 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
281 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
282 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
283 .thenReturn(RpcResultBuilder.<RemoveFlowsBatchOutput>failed()
284 .withResult(new RemoveFlowsBatchOutputBuilder()
285 .setBatchFailedFlowsOutput(Lists.newArrayList(
286 new BatchFailedFlowsOutputBuilder()
288 .setFlowId(new FlowId("123"))
291 .withError(RpcError.ErrorType.APPLICATION, "ut-firstFlowAddError")
293 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
294 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
296 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
297 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
298 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
299 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
300 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
301 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
303 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
304 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
305 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
306 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
307 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
308 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
311 private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
312 return createFlowAddBatch(batchOrder, flowIdValue, 1);
315 private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue, int amount) {
316 return new BatchBuilder()
317 .setBatchOrder(batchOrder)
318 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
319 .setFlatBatchAddFlow(repeatInList(new FlatBatchAddFlowBuilder()
320 .setFlowId(new FlowId(flowIdValue))
326 private <T> List<T> repeatInList(final T item, final int amount) {
327 final List<T> list = new ArrayList<>();
328 for (int i = 0; i < amount; i++) {
334 private Batch createFlowRemoveBatch(final int batchOrder, final String flowIdValue) {
335 return new BatchBuilder()
336 .setBatchOrder(batchOrder)
337 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
338 .setFlatBatchRemoveFlow(Collections.singletonList(new FlatBatchRemoveFlowBuilder()
339 .setFlowId(new FlowId(flowIdValue))
345 private Batch createFlowUpdateBatch(final int batchOrder, final String flowIdValue) {
346 return new BatchBuilder()
347 .setBatchOrder(batchOrder)
348 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
349 .setFlatBatchUpdateFlow(Collections.singletonList(new FlatBatchUpdateFlowBuilder()
350 .setFlowId(new FlowId(flowIdValue))
356 private Batch createGroupAddBatch(final int batchOrder, final long groupIdValue) {
357 return new BatchBuilder()
358 .setBatchOrder(batchOrder)
359 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
360 .setFlatBatchAddGroup(Collections.singletonList(new FlatBatchAddGroupBuilder()
361 .setGroupId(new GroupId(groupIdValue))
367 private Batch createGroupRemoveBatch(final int batchOrder, final long groupIdValue) {
368 return new BatchBuilder()
369 .setBatchOrder(batchOrder)
370 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
371 .setFlatBatchRemoveGroup(Collections.singletonList(new FlatBatchRemoveGroupBuilder()
372 .setGroupId(new GroupId(groupIdValue))
378 private Batch createGroupUpdateBatch(final int batchOrder, final long groupIdValue) {
379 return new BatchBuilder()
380 .setBatchOrder(batchOrder)
381 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
382 .setFlatBatchUpdateGroup(Collections.singletonList(new FlatBatchUpdateGroupBuilder()
383 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder()
384 .setGroupId(new GroupId(groupIdValue))
386 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
387 .setGroupId(new GroupId(groupIdValue))
394 private Batch createMeterAddBatch(final int batchOrder, final long groupIdValue) {
395 return new BatchBuilder()
396 .setBatchOrder(batchOrder)
397 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
398 .setFlatBatchAddMeter(Collections.singletonList(new FlatBatchAddMeterBuilder()
399 .setMeterId(new MeterId(groupIdValue))
405 private Batch createMeterRemoveBatch(final int batchOrder, final long groupIdValue) {
406 return new BatchBuilder()
407 .setBatchOrder(batchOrder)
408 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
409 .setFlatBatchRemoveMeter(Collections.singletonList(new FlatBatchRemoveMeterBuilder()
410 .setMeterId(new MeterId(groupIdValue))
416 private Batch createMeterUpdateBatch(final int batchOrder, final long groupIdValue) {
417 return new BatchBuilder()
418 .setBatchOrder(batchOrder)
419 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
420 .setFlatBatchUpdateMeter(Collections.singletonList(new FlatBatchUpdateMeterBuilder()
421 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder()
422 .setMeterId(new MeterId(groupIdValue))
424 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
425 .setMeterId(new MeterId(groupIdValue))
433 public void testExecuteBatchPlan() throws Exception {
434 BatchStepJob batchStepJob1 = Mockito.mock(BatchStepJob.class);
435 BatchStepJob batchStepJob2 = Mockito.mock(BatchStepJob.class);
436 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function1 =
437 Mockito.mock(AsyncFunction.class);
438 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function2 =
439 Mockito.mock(AsyncFunction.class);
440 Mockito.when(batchStepJob1.getStepFunction()).thenReturn(function1);
441 Mockito.when(batchStepJob2.getStepFunction()).thenReturn(function2);
442 BatchPlanStep batchPlanStep1 = new BatchPlanStep(BatchStepType.GROUP_ADD);
443 batchPlanStep1.setBarrierAfter(true);
444 BatchPlanStep batchPlanStep2 = new BatchPlanStep(BatchStepType.FLOW_ADD);
445 batchPlanStep1.setBarrierAfter(false);
446 Mockito.when(batchStepJob1.getPlanStep()).thenReturn(batchPlanStep1);
447 Mockito.when(batchStepJob2.getPlanStep()).thenReturn(batchPlanStep2);
449 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> succeededChainOutput =
450 FlatBatchUtil.createEmptyRpcBatchResultFuture(true);
451 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> failedChainOutput =
452 RpcResultBuilder.<ProcessFlatBatchOutput>failed()
453 .withError(RpcError.ErrorType.APPLICATION, "ut-chainError")
454 .withResult(createFlatBatchOutput(createFlowBatchFailure(0, "f1"),
455 createFlowBatchFailure(1, "f2")))
458 Mockito.when(batchStepJob1.getStepFunction().apply(ArgumentMatchers.any()))
459 .thenReturn(succeededChainOutput);
460 Mockito.when(batchStepJob2.getStepFunction().apply(ArgumentMatchers.any()))
461 .thenReturn(failedChainOutput);
463 final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
464 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
465 salFlatBatchService.executeBatchPlan(batchChainElements);
467 Assert.assertTrue(rpcResultFuture.isDone());
468 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
469 Assert.assertFalse(rpcResult.isSuccessful());
470 Assert.assertEquals(1, rpcResult.getErrors().size());
471 Assert.assertEquals(2, rpcResult.getResult().getBatchFailure().size());
472 Assert.assertEquals("f2",
473 ((FlatBatchFailureFlowIdCase) rpcResult.getResult().getBatchFailure().get(1).getBatchItemIdChoice())
474 .getFlowId().getValue());
477 private BatchFailure createFlowBatchFailure(final int batchOrder, final String flowIdValue) {
478 return new BatchFailureBuilder()
479 .setBatchOrder(batchOrder)
480 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
481 .setFlowId(new FlowId(flowIdValue))
486 private ProcessFlatBatchOutput createFlatBatchOutput(BatchFailure... batchFailures) {
487 return new ProcessFlatBatchOutputBuilder()
488 .setBatchFailure(Lists.newArrayList(batchFailures))
493 public void testPrepareBatchPlan_success() throws Exception {
494 final FlatBatchAddFlow flatBatchAddFlow = new FlatBatchAddFlowBuilder()
495 .setFlowId(new FlowId("f1"))
497 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
498 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow, flatBatchAddFlow));
499 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep);
501 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
503 Assert.assertEquals(1, batchChain.size());
505 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
506 .thenReturn(RpcResultBuilder
507 .success(new AddFlowsBatchOutputBuilder().build())
510 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
511 salFlatBatchService.executeBatchPlan(batchChain);
512 Assert.assertTrue(rpcResultFuture.isDone());
513 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
514 Assert.assertTrue(rpcResult.isSuccessful());
515 Assert.assertEquals(0, rpcResult.getErrors().size());
516 Assert.assertEquals(0, rpcResult.getResult().getBatchFailure().size());
518 Mockito.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
522 public void testPrepareBatchPlan_failure() throws Exception {
523 final FlatBatchAddFlow flatBatchAddFlow = new FlatBatchAddFlowBuilder()
524 .setFlowId(new FlowId("f1"))
526 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
527 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow, flatBatchAddFlow));
529 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
531 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
533 Assert.assertEquals(2, batchChain.size());
535 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
536 .thenReturn(RpcResultBuilder
537 .<AddFlowsBatchOutput>failed()
538 .withResult(new AddFlowsBatchOutputBuilder()
539 .setBatchFailedFlowsOutput(Lists.newArrayList(
540 new BatchFailedFlowsOutputBuilder()
542 .setFlowId(new FlowId("f1"))
544 new BatchFailedFlowsOutputBuilder()
546 .setFlowId(new FlowId("f2"))
549 .withError(RpcError.ErrorType.APPLICATION, "ut-addFlowBatchError")
552 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
553 salFlatBatchService.executeBatchPlan(batchChain);
554 Assert.assertTrue(rpcResultFuture.isDone());
555 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
556 Assert.assertFalse(rpcResult.isSuccessful());
557 Assert.assertEquals(2, rpcResult.getErrors().size());
558 Assert.assertEquals(4, rpcResult.getResult().getBatchFailure().size());
560 Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
561 Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());