Update MRI projects for Aluminium
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / services / sal / SalFlatBatchServiceImplTest.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.openflowplugin.impl.services.sal;
10
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;
98
99 /**
100  * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
101  */
102 @RunWith(MockitoJUnitRunner.class)
103 public class SalFlatBatchServiceImplTest {
104
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);
109
110     @Mock
111     private SalFlowsBatchService salFlowsBatchService;
112     @Mock
113     private SalGroupsBatchService salGroupsBatchService;
114     @Mock
115     private SalMetersBatchService salMetersBatchService;
116     @Captor
117     private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
118
119     private SalFlatBatchServiceImpl salFlatBatchService;
120
121     @Before
122     public void setUp() {
123         salFlatBatchService =
124                 new SalFlatBatchServiceImpl(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
125
126     }
127
128     @After
129     public void tearDown() {
130         Mockito.verifyNoMoreInteractions(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
131     }
132
133     @Test
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());
141
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());
148
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());
155
156
157         ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
158                 .setNode(NODE_REF)
159                 .setBatch(Lists.newArrayList(
160                         createFlowAddBatch(0, "f1"),
161                         createFlowRemoveBatch(1, "f2"),
162                         createFlowUpdateBatch(2, "f3"),
163
164                         createGroupAddBatch(3, 1L),
165                         createGroupRemoveBatch(4, 2L),
166                         createGroupUpdateBatch(5, 3L),
167
168                         createMeterAddBatch(6, 1L),
169                         createMeterRemoveBatch(7, 2L),
170                         createMeterUpdateBatch(8, 3L)
171                 ))
172                 .setExitOnFirstError(true)
173                 .build();
174
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());
182
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());
187
188         inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
189         inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
190         inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
191
192         inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
193         inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
194         inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
195     }
196
197     @Test
198     public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
199         prepareFirstFailingMockService();
200
201         int idx = 0;
202         ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
203                 .setNode(NODE_REF)
204                 .setBatch(Lists.newArrayList(
205                         createFlowAddBatch(idx++, "f1", 2),
206                         createFlowRemoveBatch(idx++, "f2"),
207                         createFlowUpdateBatch(idx++, "f3"),
208
209                         createGroupAddBatch(idx++, 1L),
210                         createGroupRemoveBatch(idx++, 2L),
211                         createGroupUpdateBatch(idx++, 3L),
212
213                         createMeterAddBatch(idx++, 1L),
214                         createMeterRemoveBatch(idx++, 2L),
215                         createMeterUpdateBatch(idx++, 3L)
216                 ))
217                 .setExitOnFirstError(true)
218                 .build();
219
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());
229
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());
235     }
236
237     @Test
238     public void testProcessFlatBatch_firstFailedContinue() throws Exception {
239         prepareFirstFailingMockService();
240
241         int idx = 0;
242         ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
243                 .setNode(NODE_REF)
244                 .setBatch(Lists.newArrayList(
245                         createFlowAddBatch(idx++, "f1", 2),
246                         createFlowRemoveBatch(idx++, "f2"),
247                         createFlowUpdateBatch(idx++, "f3"),
248
249                         createGroupAddBatch(idx++, 1L),
250                         createGroupRemoveBatch(idx++, 2L),
251                         createGroupUpdateBatch(idx++, 3L),
252
253                         createMeterAddBatch(idx++, 1L),
254                         createMeterRemoveBatch(idx++, 2L),
255                         createMeterUpdateBatch(idx++, 3L)
256                 ))
257                 .setExitOnFirstError(false)
258                 .build();
259
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());
269
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());
274
275         inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
276         inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
277         inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
278
279         inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
280         inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
281         inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
282     }
283
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()
292                                                 .setBatchOrder(1)
293                                                 .setFlowId(new FlowId("123"))
294                                                 .build()))
295                                 .build())
296                         .withError(RpcError.ErrorType.APPLICATION, "ut-firstFlowAddError")
297                         .buildFuture());
298         Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
299                 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
300
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());
307
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());
314     }
315
316     private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
317         return createFlowAddBatch(batchOrder, flowIdValue, 1);
318     }
319
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))
325                         .build())
326                 .build();
327     }
328
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))
335                     .build());
336         }
337         return list;
338     }
339
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++) {
343             list.add(item);
344         }
345         return list;
346     }
347
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))
354                                 .build()))
355                         .build())
356                 .build();
357     }
358
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))
366                                 .build()))
367                         .build())
368                 .build();
369     }
370
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))
377                                 .build()))
378                         .build())
379                 .build();
380     }
381
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))
388                                 .build()))
389                         .build())
390                 .build();
391     }
392
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))
400                                         .build())
401                                 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
402                                         .setGroupId(new GroupId(groupIdValue))
403                                         .build())
404                                 .build()))
405                         .build())
406                 .build();
407     }
408
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))
415                                 .build()))
416                         .build())
417                 .build();
418     }
419
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))
426                                 .build()))
427                         .build())
428                 .build();
429     }
430
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))
438                                         .build())
439                                 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
440                                         .setMeterId(new MeterId(groupIdValue))
441                                         .build())
442                                 .build()))
443                         .build())
444                 .build();
445     }
446
447     @Test
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);
463
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")))
471                         .buildFuture();
472
473         Mockito.when(batchStepJob1.getStepFunction().apply(ArgumentMatchers.any()))
474                 .thenReturn(succeededChainOutput);
475         Mockito.when(batchStepJob2.getStepFunction().apply(ArgumentMatchers.any()))
476                 .thenReturn(failedChainOutput);
477
478         final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
479         final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
480                 salFlatBatchService.executeBatchPlan(batchChainElements);
481
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
489         iterator.next();
490         Assert.assertEquals("f2",
491                 ((FlatBatchFailureFlowIdCase) iterator.next().getBatchItemIdChoice())
492                         .getFlowId().getValue());
493     }
494
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))
500                         .build())
501                 .build();
502     }
503
504     private ProcessFlatBatchOutput createFlatBatchOutput(final BatchFailure... batchFailures) {
505         return new ProcessFlatBatchOutputBuilder()
506                 .setBatchFailure(Lists.newArrayList(batchFailures))
507                 .build();
508     }
509
510     @Test
511     public void testPrepareBatchPlan_success() throws Exception {
512         final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
513                 .setFlowId(new FlowId("f1"))
514                 .build();
515         final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
516                 .setFlowId(new FlowId("f2"))
517                 .build();
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);
521
522         final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
523
524         Assert.assertEquals(1, batchChain.size());
525
526         Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
527                 .thenReturn(RpcResultBuilder
528                         .success(new AddFlowsBatchOutputBuilder().build())
529                         .buildFuture());
530
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());
538
539         Mockito.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
540     }
541
542     @Test
543     public void testPrepareBatchPlan_failure() throws Exception {
544         final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
545                 .setFlowId(new FlowId("f1"))
546                 .build();
547         final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
548                 .setFlowId(new FlowId("f2"))
549                 .build();
550         final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
551         batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
552
553         final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
554
555         final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
556
557         Assert.assertEquals(2, batchChain.size());
558
559         Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
560                 .thenReturn(RpcResultBuilder
561                         .<AddFlowsBatchOutput>failed()
562                         .withResult(new AddFlowsBatchOutputBuilder()
563                                 .setBatchFailedFlowsOutput(Lists.newArrayList(
564                                         new BatchFailedFlowsOutputBuilder()
565                                                 .setBatchOrder(0)
566                                                 .setFlowId(new FlowId("f1"))
567                                                 .build(),
568                                         new BatchFailedFlowsOutputBuilder()
569                                                 .setBatchOrder(1)
570                                                 .setFlowId(new FlowId("f2"))
571                                                 .build()))
572                                 .build())
573                         .withError(RpcError.ErrorType.APPLICATION, "ut-addFlowBatchError")
574                         .buildFuture());
575
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());
583
584         Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
585         Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());
586     }
587 }