use of org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters in project openflowplugin by opendaylight.
the class SyncPlanPushStrategyFlatBatchImplTest method testExecuteSyncStrategy.
@Test
public void testExecuteSyncStrategy() throws Exception {
final SynchronizationDiffInput diffInput = new SynchronizationDiffInput(NODE_IDENT, groupsToAddOrUpdate, metersToAddOrUpdate, flowsToAddOrUpdate, flowsToRemove, metersToRemove, groupsToRemove);
Mockito.when(flatBatchService.processFlatBatch(Matchers.<ProcessFlatBatchInput>any())).thenReturn(RpcResultBuilder.success(new ProcessFlatBatchOutputBuilder().build()).buildFuture());
final SyncCrudCounters counters = new SyncCrudCounters();
final ListenableFuture<RpcResult<Void>> rpcResult = syncPlanPushStrategy.executeSyncStrategy(RpcResultBuilder.<Void>success().buildFuture(), diffInput, counters);
Mockito.verify(flatBatchService).processFlatBatch(processFlatBatchInputCpt.capture());
final ProcessFlatBatchInput processFlatBatchInput = processFlatBatchInputCpt.getValue();
Assert.assertFalse(processFlatBatchInput.isExitOnFirstError());
Assert.assertEquals(13, processFlatBatchInput.getBatch().size());
Assert.assertTrue(rpcResult.isDone());
Assert.assertTrue(rpcResult.get().isSuccessful());
Assert.assertEquals(6, counters.getFlowCrudCounts().getAdded());
Assert.assertEquals(3, counters.getFlowCrudCounts().getUpdated());
Assert.assertEquals(6, counters.getFlowCrudCounts().getRemoved());
Assert.assertEquals(6, counters.getGroupCrudCounts().getAdded());
Assert.assertEquals(3, counters.getGroupCrudCounts().getUpdated());
Assert.assertEquals(6, counters.getGroupCrudCounts().getRemoved());
Assert.assertEquals(3, counters.getMeterCrudCounts().getAdded());
Assert.assertEquals(3, counters.getMeterCrudCounts().getUpdated());
Assert.assertEquals(3, counters.getMeterCrudCounts().getRemoved());
}
use of org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters in project openflowplugin by opendaylight.
the class SyncPlanPushStrategyIncrementalImplTest method setUp.
@Before
public void setUp() throws Exception {
Mockito.when(flowCapableTxService.sendBarrier(Matchers.<SendBarrierInput>any())).thenReturn(RpcResultBuilder.success((Void) null).buildFuture());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(groupCommitter).add(Matchers.<InstanceIdentifier<Group>>any(), Matchers.<Group>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(groupCommitter).update(Matchers.<InstanceIdentifier<Group>>any(), Matchers.<Group>any(), Matchers.<Group>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(groupCommitter).remove(Matchers.<InstanceIdentifier<Group>>any(), Matchers.<Group>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(flowCommitter).add(Matchers.<InstanceIdentifier<Flow>>any(), Matchers.<Flow>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(flowCommitter).update(Matchers.<InstanceIdentifier<Flow>>any(), Matchers.<Flow>any(), Matchers.<Flow>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(flowCommitter).remove(Matchers.<InstanceIdentifier<Flow>>any(), Matchers.<Flow>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(meterCommitter).add(Matchers.<InstanceIdentifier<Meter>>any(), Matchers.<Meter>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(meterCommitter).update(Matchers.<InstanceIdentifier<Meter>>any(), Matchers.<Meter>any(), Matchers.<Meter>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(meterCommitter).remove(Matchers.<InstanceIdentifier<Meter>>any(), Matchers.<Meter>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
Mockito.doAnswer(createSalServiceFutureAnswer()).when(tableCommitter).update(Matchers.<InstanceIdentifier<TableFeatures>>any(), Matchers.<TableFeatures>any(), Matchers.<TableFeatures>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
syncPlanPushStrategy = new SyncPlanPushStrategyIncrementalImpl().setMeterForwarder(meterCommitter).setTableForwarder(tableCommitter).setGroupForwarder(groupCommitter).setFlowForwarder(flowCommitter).setTransactionService(flowCapableTxService);
counters = new SyncCrudCounters();
}
use of org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters in project openflowplugin by opendaylight.
the class SyncPlanPushStrategyIncrementalImpl method executeSyncStrategy.
@Override
public ListenableFuture<RpcResult<Void>> executeSyncStrategy(ListenableFuture<RpcResult<Void>> resultVehicle, final SynchronizationDiffInput diffInput, final SyncCrudCounters counters) {
final InstanceIdentifier<FlowCapableNode> nodeIdent = diffInput.getNodeIdent();
final NodeId nodeId = PathUtil.digNodeId(nodeIdent);
/* Tables - have to be pushed before groups */
// TODO enable table-update when ready
// resultVehicle = updateTableFeatures(nodeIdent, configTree);
resultVehicle = Futures.transformAsync(resultVehicle, input -> {
if (!input.isSuccessful()) {
// TODO chain errors but not skip processing on first error return Futures.immediateFuture(input);
// final ListenableFuture<RpcResult<Void>> singleVoidUpdateResult = Futures.transform(
// Futures.asList Arrays.asList(input, output),
// ReconcileUtil.<UpdateFlowOutput>createRpcResultCondenser("TODO"));
}
return addMissingGroups(nodeId, nodeIdent, diffInput.getGroupsToAddOrUpdate(), counters);
}, MoreExecutors.directExecutor());
Futures.addCallback(resultVehicle, FxChainUtil.logResultCallback(nodeId, "addMissingGroups"), MoreExecutors.directExecutor());
resultVehicle = Futures.transformAsync(resultVehicle, input -> {
if (!input.isSuccessful()) {
// TODO chain errors but not skip processing on first error return Futures.immediateFuture(input);
}
return addMissingMeters(nodeId, nodeIdent, diffInput.getMetersToAddOrUpdate(), counters);
}, MoreExecutors.directExecutor());
Futures.addCallback(resultVehicle, FxChainUtil.logResultCallback(nodeId, "addMissingMeters"), MoreExecutors.directExecutor());
resultVehicle = Futures.transformAsync(resultVehicle, input -> {
if (!input.isSuccessful()) {
// TODO chain errors but not skip processing on first error return Futures.immediateFuture(input);
}
return addMissingFlows(nodeId, nodeIdent, diffInput.getFlowsToAddOrUpdate(), counters);
}, MoreExecutors.directExecutor());
Futures.addCallback(resultVehicle, FxChainUtil.logResultCallback(nodeId, "addMissingFlows"), MoreExecutors.directExecutor());
resultVehicle = Futures.transformAsync(resultVehicle, input -> {
if (!input.isSuccessful()) {
// TODO chain errors but not skip processing on first error return Futures.immediateFuture(input);
}
return removeRedundantFlows(nodeId, nodeIdent, diffInput.getFlowsToRemove(), counters);
}, MoreExecutors.directExecutor());
Futures.addCallback(resultVehicle, FxChainUtil.logResultCallback(nodeId, "removeRedundantFlows"), MoreExecutors.directExecutor());
resultVehicle = Futures.transformAsync(resultVehicle, input -> {
if (!input.isSuccessful()) {
// TODO chain errors but not skip processing on first error return Futures.immediateFuture(input);
}
return removeRedundantMeters(nodeId, nodeIdent, diffInput.getMetersToRemove(), counters);
}, MoreExecutors.directExecutor());
Futures.addCallback(resultVehicle, FxChainUtil.logResultCallback(nodeId, "removeRedundantMeters"), MoreExecutors.directExecutor());
resultVehicle = Futures.transformAsync(resultVehicle, input -> {
if (!input.isSuccessful()) {
// TODO chain errors but not skip processing on first error return Futures.immediateFuture(input);
}
return removeRedundantGroups(nodeId, nodeIdent, diffInput.getGroupsToRemove(), counters);
}, MoreExecutors.directExecutor());
Futures.addCallback(resultVehicle, FxChainUtil.logResultCallback(nodeId, "removeRedundantGroups"), MoreExecutors.directExecutor());
return resultVehicle;
}
use of org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters in project openflowplugin by opendaylight.
the class SyncPlanPushStrategyIncrementalImpl method addMissingGroups.
ListenableFuture<RpcResult<Void>> addMissingGroups(final NodeId nodeId, final InstanceIdentifier<FlowCapableNode> nodeIdent, final List<ItemSyncBox<Group>> groupsAddPlan, final SyncCrudCounters counters) {
if (groupsAddPlan.isEmpty()) {
LOG.trace("no groups configured for node: {} -> SKIPPING", nodeId.getValue());
return RpcResultBuilder.<Void>success().buildFuture();
}
ListenableFuture<RpcResult<Void>> chainedResult;
try {
if (!groupsAddPlan.isEmpty()) {
final CrudCounts groupCrudCounts = counters.getGroupCrudCounts();
groupCrudCounts.setAdded(ReconcileUtil.countTotalPushed(groupsAddPlan));
groupCrudCounts.setUpdated(ReconcileUtil.countTotalUpdated(groupsAddPlan));
if (LOG.isDebugEnabled()) {
LOG.debug("adding groups: planSteps={}, toAddTotal={}, toUpdateTotal={}", groupsAddPlan.size(), groupCrudCounts.getAdded(), groupCrudCounts.getUpdated());
}
chainedResult = flushAddGroupPortionAndBarrier(nodeIdent, groupsAddPlan.get(0));
for (final ItemSyncBox<Group> groupsPortion : Iterables.skip(groupsAddPlan, 1)) {
chainedResult = Futures.transformAsync(chainedResult, input -> {
final ListenableFuture<RpcResult<Void>> result;
if (input.isSuccessful()) {
result = flushAddGroupPortionAndBarrier(nodeIdent, groupsPortion);
} else {
// pass through original unsuccessful rpcResult
result = Futures.immediateFuture(input);
}
return result;
}, MoreExecutors.directExecutor());
}
} else {
chainedResult = RpcResultBuilder.<Void>success().buildFuture();
}
} catch (IllegalStateException e) {
chainedResult = RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "failed to add missing groups", e).buildFuture();
}
return chainedResult;
}
use of org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters in project openflowplugin by opendaylight.
the class SyncReactorImpl method syncup.
@Override
public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> nodeIdent, final SyncupEntry syncupEntry) {
final NodeId nodeId = PathUtil.digNodeId(nodeIdent);
FlowCapableNode configTree = syncupEntry.getAfter();
FlowCapableNode operationalTree = syncupEntry.getBefore();
final SyncCrudCounters counters = new SyncCrudCounters();
/**
* instructions:
* - extract diff changes and prepare change steps in safe order
* - optimization: decide if updates needed
* - execute chosen implementation (e.g. conventional API, bulk API, flat bulk API)
* - recommended order follows:
* reconciliation strategy - phase 1: - add/update missing objects in following order:
* - table features - groups (reordered) - meters - flows
* reconciliation strategy - phase 2: - remove redundant objects in following order:
* - flows - meters - groups (reordered)
*/
final List<ItemSyncBox<Group>> groupsToAddOrUpdate = extractGroupsToAddOrUpdate(nodeId, configTree, operationalTree);
final ItemSyncBox<Meter> metersToAddOrUpdate = extractMetersToAddOrUpdate(nodeId, configTree, operationalTree);
final Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate = extractFlowsToAddOrUpdate(nodeId, configTree, operationalTree);
final Map<TableKey, ItemSyncBox<Flow>> flowsToRemove = extractFlowsToRemove(nodeId, configTree, operationalTree);
final ItemSyncBox<Meter> metersToRemove = extractMetersToRemove(nodeId, configTree, operationalTree);
final List<ItemSyncBox<Group>> groupsToRemove = extractGroupsToRemove(nodeId, configTree, operationalTree);
final SynchronizationDiffInput input = new SynchronizationDiffInput(nodeIdent, groupsToAddOrUpdate, metersToAddOrUpdate, flowsToAddOrUpdate, flowsToRemove, metersToRemove, groupsToRemove);
final ListenableFuture<RpcResult<Void>> bootstrapResultFuture = RpcResultBuilder.<Void>success().buildFuture();
final ListenableFuture<RpcResult<Void>> resultVehicle = syncPlanPushStrategy.executeSyncStrategy(bootstrapResultFuture, input, counters);
return Futures.transform(resultVehicle, input1 -> {
if (input1 == null) {
return false;
}
if (LOG.isDebugEnabled()) {
final CrudCounts flowCrudCounts = counters.getFlowCrudCounts();
final CrudCounts meterCrudCounts = counters.getMeterCrudCounts();
final CrudCounts groupCrudCounts = counters.getGroupCrudCounts();
LOG.debug("Syncup outcome[{}] (added/updated/removed): flow={}/{}/{}, group={}/{}/{}, " + "meter={}/{}/{}, errors={}", nodeId.getValue(), flowCrudCounts.getAdded(), flowCrudCounts.getUpdated(), flowCrudCounts.getRemoved(), groupCrudCounts.getAdded(), groupCrudCounts.getUpdated(), groupCrudCounts.getRemoved(), meterCrudCounts.getAdded(), meterCrudCounts.getUpdated(), meterCrudCounts.getRemoved(), Arrays.toString(input1.getErrors().toArray()));
}
return input1.isSuccessful();
}, MoreExecutors.directExecutor());
}
Aggregations