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.Iterator;
14 import java.util.LinkedHashMap;
15 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.flat.batch.failure.ids.aug.FlatBatchFailureFlowIdCase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.failure.ids.aug.FlatBatchFailureFlowIdCaseBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchAddFlowCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchRemoveFlowCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchUpdateFlowCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlow;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlowBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlowBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchAddGroupCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchRemoveGroupCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchUpdateGroupCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroupBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroupBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroupBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchAddMeterCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchRemoveMeterCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchUpdateMeterCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeterBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeterBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeterBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
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.binding.util.BindingMap;
95 import org.opendaylight.yangtools.yang.common.ErrorType;
96 import org.opendaylight.yangtools.yang.common.RpcResult;
97 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
98 import org.opendaylight.yangtools.yang.common.Uint16;
99 import org.opendaylight.yangtools.yang.common.Uint32;
102 * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
104 @RunWith(MockitoJUnitRunner.class)
105 public class SalFlatBatchServiceImplTest {
107 private static final NodeId NODE_ID = new NodeId("ut-node-id");
108 private static final InstanceIdentifier<Node> NODE_II = InstanceIdentifier.create(Nodes.class)
109 .child(Node.class, new NodeKey(NODE_ID));
110 private static final NodeRef NODE_REF = new NodeRef(NODE_II);
113 private SalFlowsBatchService salFlowsBatchService;
115 private SalGroupsBatchService salGroupsBatchService;
117 private SalMetersBatchService salMetersBatchService;
119 private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
121 private SalFlatBatchServiceImpl salFlatBatchService;
124 public void setUp() {
125 salFlatBatchService =
126 new SalFlatBatchServiceImpl(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
131 public void tearDown() {
132 Mockito.verifyNoMoreInteractions(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
136 public void testProcessFlatBatch_allSuccessFinished() throws Exception {
137 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
138 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
139 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
140 .thenReturn(RpcResultBuilder.success(new RemoveFlowsBatchOutputBuilder().build()).buildFuture());
141 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
142 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
144 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
145 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
146 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
147 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
148 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
149 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
151 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
152 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
153 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
154 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
155 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
156 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
159 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
161 .setBatch(BindingMap.ordered(
162 createFlowAddBatch(0, "f1"),
163 createFlowRemoveBatch(1, "f2"),
164 createFlowUpdateBatch(2, "f3"),
166 createGroupAddBatch(3, 1L),
167 createGroupRemoveBatch(4, 2L),
168 createGroupUpdateBatch(5, 3L),
170 createMeterAddBatch(6, 1L),
171 createMeterRemoveBatch(7, 2L),
172 createMeterUpdateBatch(8, 3L)
174 .setExitOnFirstError(true)
177 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
178 salFlatBatchService.processFlatBatch(batchInput);
179 Assert.assertTrue(rpcResultFuture.isDone());
180 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
181 Assert.assertTrue(rpcResult.isSuccessful());
182 Assert.assertTrue(rpcResult.getErrors().isEmpty());
183 Assert.assertTrue(rpcResult.getResult().nonnullBatchFailure().isEmpty());
185 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
186 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
187 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
188 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
190 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
191 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
192 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
194 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
195 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
196 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
200 public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
201 prepareFirstFailingMockService();
204 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
206 .setBatch(BindingMap.ordered(
207 createFlowAddBatch(idx++, "f1", 2),
208 createFlowRemoveBatch(idx++, "f2"),
209 createFlowUpdateBatch(idx++, "f3"),
211 createGroupAddBatch(idx++, 1L),
212 createGroupRemoveBatch(idx++, 2L),
213 createGroupUpdateBatch(idx++, 3L),
215 createMeterAddBatch(idx++, 1L),
216 createMeterRemoveBatch(idx++, 2L),
217 createMeterUpdateBatch(idx++, 3L)
219 .setExitOnFirstError(true)
222 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
223 salFlatBatchService.processFlatBatch(batchInput);
224 Assert.assertTrue(rpcResultFuture.isDone());
225 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
226 Assert.assertFalse(rpcResult.isSuccessful());
227 Assert.assertEquals(1, rpcResult.getErrors().size());
228 Assert.assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
229 Assert.assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
230 .getBatchOrder().intValue());
232 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
233 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
234 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
235 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
236 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
240 public void testProcessFlatBatch_firstFailedContinue() throws Exception {
241 prepareFirstFailingMockService();
244 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
246 .setBatch(BindingMap.ordered(
247 createFlowAddBatch(idx++, "f1", 2),
248 createFlowRemoveBatch(idx++, "f2"),
249 createFlowUpdateBatch(idx++, "f3"),
251 createGroupAddBatch(idx++, 1L),
252 createGroupRemoveBatch(idx++, 2L),
253 createGroupUpdateBatch(idx++, 3L),
255 createMeterAddBatch(idx++, 1L),
256 createMeterRemoveBatch(idx++, 2L),
257 createMeterUpdateBatch(idx++, 3L)
259 .setExitOnFirstError(false)
262 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
263 salFlatBatchService.processFlatBatch(batchInput);
264 Assert.assertTrue(rpcResultFuture.isDone());
265 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
266 Assert.assertFalse(rpcResult.isSuccessful());
267 Assert.assertEquals(1, rpcResult.getErrors().size());
268 Assert.assertEquals(1, rpcResult.getResult().nonnullBatchFailure().size());
269 Assert.assertEquals(3, rpcResult.getResult().nonnullBatchFailure().values().iterator().next()
270 .getBatchOrder().intValue());
272 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
273 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
274 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.any());
275 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.any());
277 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.any());
278 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.any());
279 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.any());
281 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.any());
282 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.any());
283 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.any());
286 private void prepareFirstFailingMockService() {
287 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
288 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
289 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.any()))
290 .thenReturn(RpcResultBuilder.<RemoveFlowsBatchOutput>failed()
291 .withResult(new RemoveFlowsBatchOutputBuilder()
292 .setBatchFailedFlowsOutput(BindingMap.ordered(
293 new BatchFailedFlowsOutputBuilder()
294 .setBatchOrder(Uint16.ONE)
295 .setFlowId(new FlowId("123"))
298 .withError(ErrorType.APPLICATION, "ut-firstFlowAddError")
300 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.any()))
301 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
303 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.any()))
304 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
305 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.any()))
306 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
307 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.any()))
308 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
310 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.any()))
311 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
312 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.any()))
313 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
314 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.any()))
315 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
318 private static Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
319 return createFlowAddBatch(batchOrder, flowIdValue, 1);
322 private static Batch createFlowAddBatch(final int batchOrder, final String flowIdValue, final int amount) {
323 return new BatchBuilder()
324 .setBatchOrder(Uint16.valueOf(batchOrder))
325 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
326 .setFlatBatchAddFlow(repeatFlatBatchAddFlowInList(flowIdValue, amount))
331 private static Map<FlatBatchAddFlowKey, FlatBatchAddFlow> repeatFlatBatchAddFlowInList(final String flowIdValue,
333 final Map<FlatBatchAddFlowKey, FlatBatchAddFlow> map = new LinkedHashMap<>();
334 for (int i = 0; i < amount; i++) {
335 final FlatBatchAddFlowKey key = new FlatBatchAddFlowKey(Uint16.valueOf(i));
336 map.put(key, new FlatBatchAddFlowBuilder().withKey(key).setFlowId(new FlowId(flowIdValue + i)).build());
341 private static Batch createFlowRemoveBatch(final int batchOrder, final String flowIdValue) {
342 return new BatchBuilder()
343 .setBatchOrder(Uint16.valueOf(batchOrder))
344 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
345 .setFlatBatchRemoveFlow(BindingMap.of(new FlatBatchRemoveFlowBuilder()
346 .setFlowId(new FlowId(flowIdValue))
347 .setBatchOrder(Uint16.valueOf(batchOrder))
353 private static Batch createFlowUpdateBatch(final int batchOrder, final String flowIdValue) {
354 final Uint16 uint = Uint16.valueOf(batchOrder);
355 return new BatchBuilder()
357 .withKey(new BatchKey(uint))
358 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
359 .setFlatBatchUpdateFlow(BindingMap.of(new FlatBatchUpdateFlowBuilder()
360 .setFlowId(new FlowId(flowIdValue))
361 .setBatchOrder(Uint16.valueOf(batchOrder))
367 private static Batch createGroupAddBatch(final int batchOrder, final long groupIdValue) {
368 return new BatchBuilder()
369 .setBatchOrder(Uint16.valueOf(batchOrder))
370 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
371 .setFlatBatchAddGroup(BindingMap.of(new FlatBatchAddGroupBuilder()
372 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
373 .setBatchOrder(Uint16.valueOf(batchOrder))
379 private static Batch createGroupRemoveBatch(final int batchOrder, final long groupIdValue) {
380 return new BatchBuilder()
381 .setBatchOrder(Uint16.valueOf(batchOrder))
382 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
383 .setFlatBatchRemoveGroup(BindingMap.of(new FlatBatchRemoveGroupBuilder()
384 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
385 .setBatchOrder(Uint16.valueOf(batchOrder))
391 private static Batch createGroupUpdateBatch(final int batchOrder, final long groupIdValue) {
392 return new BatchBuilder()
393 .setBatchOrder(Uint16.valueOf(batchOrder))
394 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
395 .setFlatBatchUpdateGroup(BindingMap.of(new FlatBatchUpdateGroupBuilder()
396 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder()
397 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
399 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
400 .setGroupId(new GroupId(Uint32.valueOf(groupIdValue)))
402 .setBatchOrder(Uint16.valueOf(batchOrder))
408 private static Batch createMeterAddBatch(final int batchOrder, final long groupIdValue) {
409 return new BatchBuilder()
410 .setBatchOrder(Uint16.valueOf(batchOrder))
411 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
412 .setFlatBatchAddMeter(BindingMap.of(new FlatBatchAddMeterBuilder()
413 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
414 .setBatchOrder(Uint16.valueOf(batchOrder))
420 private static Batch createMeterRemoveBatch(final int batchOrder, final long groupIdValue) {
421 return new BatchBuilder()
422 .setBatchOrder(Uint16.valueOf(batchOrder))
423 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
424 .setFlatBatchRemoveMeter(BindingMap.of(new FlatBatchRemoveMeterBuilder()
425 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
426 .setBatchOrder(Uint16.valueOf(batchOrder))
432 private static Batch createMeterUpdateBatch(final int batchOrder, final long groupIdValue) {
433 return new BatchBuilder()
434 .setBatchOrder(Uint16.valueOf(batchOrder))
435 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
436 .setFlatBatchUpdateMeter(BindingMap.of(new FlatBatchUpdateMeterBuilder()
437 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder()
438 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
440 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
441 .setMeterId(new MeterId(Uint32.valueOf(groupIdValue)))
443 .setBatchOrder(Uint16.valueOf(batchOrder))
450 public void testExecuteBatchPlan() throws Exception {
451 BatchStepJob batchStepJob1 = Mockito.mock(BatchStepJob.class);
452 BatchStepJob batchStepJob2 = Mockito.mock(BatchStepJob.class);
453 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function1 =
454 Mockito.mock(AsyncFunction.class);
455 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function2 =
456 Mockito.mock(AsyncFunction.class);
457 Mockito.when(batchStepJob1.getStepFunction()).thenReturn(function1);
458 Mockito.when(batchStepJob2.getStepFunction()).thenReturn(function2);
459 BatchPlanStep batchPlanStep1 = new BatchPlanStep(BatchStepType.GROUP_ADD);
460 batchPlanStep1.setBarrierAfter(true);
461 BatchPlanStep batchPlanStep2 = new BatchPlanStep(BatchStepType.FLOW_ADD);
462 batchPlanStep1.setBarrierAfter(false);
463 Mockito.when(batchStepJob1.getPlanStep()).thenReturn(batchPlanStep1);
464 Mockito.when(batchStepJob2.getPlanStep()).thenReturn(batchPlanStep2);
466 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> succeededChainOutput =
467 FlatBatchUtil.createEmptyRpcBatchResultFuture(true);
468 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> failedChainOutput =
469 RpcResultBuilder.<ProcessFlatBatchOutput>failed()
470 .withError(ErrorType.APPLICATION, "ut-chainError")
471 .withResult(createFlatBatchOutput(createFlowBatchFailure(Uint16.ZERO, "f1"),
472 createFlowBatchFailure(Uint16.ONE, "f2")))
475 Mockito.when(batchStepJob1.getStepFunction().apply(ArgumentMatchers.any()))
476 .thenReturn(succeededChainOutput);
477 Mockito.when(batchStepJob2.getStepFunction().apply(ArgumentMatchers.any()))
478 .thenReturn(failedChainOutput);
480 final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
481 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
482 salFlatBatchService.executeBatchPlan(batchChainElements);
484 Assert.assertTrue(rpcResultFuture.isDone());
485 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
486 Assert.assertFalse(rpcResult.isSuccessful());
487 Assert.assertEquals(1, rpcResult.getErrors().size());
488 Assert.assertEquals(2, rpcResult.getResult().nonnullBatchFailure().size());
489 Iterator<BatchFailure> iterator = rpcResult.getResult().nonnullBatchFailure().values().iterator();
490 //Moving iterator two get second element
492 Assert.assertEquals("f2",
493 ((FlatBatchFailureFlowIdCase) iterator.next().getBatchItemIdChoice())
494 .getFlowId().getValue());
497 private static BatchFailure createFlowBatchFailure(final Uint16 batchOrder, final String flowIdValue) {
498 return new BatchFailureBuilder()
499 .setBatchOrder(batchOrder)
500 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
501 .setFlowId(new FlowId(flowIdValue))
506 private static ProcessFlatBatchOutput createFlatBatchOutput(final BatchFailure... batchFailures) {
507 return new ProcessFlatBatchOutputBuilder()
508 .setBatchFailure(BindingMap.ordered(batchFailures))
513 public void testPrepareBatchPlan_success() throws Exception {
514 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
515 .setFlowId(new FlowId("f1"))
516 .setBatchOrder(Uint16.ONE)
518 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
519 .setFlowId(new FlowId("f2"))
520 .setBatchOrder(Uint16.TWO)
522 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
523 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
524 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep);
526 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
528 Assert.assertEquals(1, batchChain.size());
530 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
531 .thenReturn(RpcResultBuilder
532 .success(new AddFlowsBatchOutputBuilder().build())
535 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
536 salFlatBatchService.executeBatchPlan(batchChain);
537 Assert.assertTrue(rpcResultFuture.isDone());
538 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
539 Assert.assertTrue(rpcResult.isSuccessful());
540 Assert.assertEquals(0, rpcResult.getErrors().size());
541 Assert.assertEquals(0, rpcResult.getResult().nonnullBatchFailure().size());
543 Mockito.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.any());
547 public void testPrepareBatchPlan_failure() throws Exception {
548 final FlatBatchAddFlow flatBatchAddFlow_1 = new FlatBatchAddFlowBuilder()
549 .setFlowId(new FlowId("f1"))
550 .setBatchOrder(Uint16.ONE)
552 final FlatBatchAddFlow flatBatchAddFlow_2 = new FlatBatchAddFlowBuilder()
553 .setFlowId(new FlowId("f2"))
554 .setBatchOrder(Uint16.TWO)
556 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
557 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow_1, flatBatchAddFlow_2));
559 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
561 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
563 Assert.assertEquals(2, batchChain.size());
565 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.any()))
566 .thenReturn(RpcResultBuilder
567 .<AddFlowsBatchOutput>failed()
568 .withResult(new AddFlowsBatchOutputBuilder()
569 .setBatchFailedFlowsOutput(BindingMap.ordered(
570 new BatchFailedFlowsOutputBuilder()
571 .setBatchOrder(Uint16.ZERO)
572 .setFlowId(new FlowId("f1"))
574 new BatchFailedFlowsOutputBuilder()
575 .setBatchOrder(Uint16.ONE)
576 .setFlowId(new FlowId("f2"))
579 .withError(ErrorType.APPLICATION, "ut-addFlowBatchError")
582 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
583 salFlatBatchService.executeBatchPlan(batchChain);
584 Assert.assertTrue(rpcResultFuture.isDone());
585 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
586 Assert.assertFalse(rpcResult.isSuccessful());
587 Assert.assertEquals(2, rpcResult.getErrors().size());
588 Assert.assertEquals(4, rpcResult.getResult().getBatchFailure().size());
590 Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
591 Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());