* <li>Node is deleted from operational cache is removed.</li>
* <li>Skip this event otherwise.</li>
* </ul>
- *
+ *
* @throws InterruptedException from syncup
*/
protected Optional<ListenableFuture<Boolean>> processNodeModification(
if (isAdd(modification) || isAddLogical(modification)) {
return reconciliation(modification);
}
+ // TODO: else = explicit reconciliation required
return skipModification(modification);
}
/**
* Remove if delete. Update only if FlowCapableNode Augmentation modified.
- *
+ *
* @param modification
*/
protected void updateCache(DataTreeModification<Node> modification) {
operationalSnaphot.updateCache(nodeId(modification), Optional.<FlowCapableNode>absent());
return;
}
-
+
operationalSnaphot.updateCache(nodeId(modification), Optional.fromNullable(flowCapableNodeAfter(modification)));
} catch(Exception e) {
LOG.error("update cache failed {}", nodeId(modification), e);
package org.opendaylight.openflowplugin.applications.frsync.impl.strategy;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.PeekingIterator;
+import com.google.common.collect.Range;
import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
+import javax.annotation.Nullable;
import org.opendaylight.openflowplugin.applications.frsync.SyncPlanPushStrategy;
import org.opendaylight.openflowplugin.applications.frsync.impl.TableForwarder;
import org.opendaylight.openflowplugin.applications.frsync.util.FxChainUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.SalFlatBatchService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.BatchChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
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;
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;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.meter._case.FlatBatchUpdateMeter;
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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
final InstanceIdentifier<FlowCapableNode> nodeIdent = diffInput.getNodeIdent();
final NodeId nodeId = PathUtil.digNodeId(nodeIdent);
+ // prepare default (full) counts
+ counters.getGroupCrudCounts().setAdded(ReconcileUtil.countTotalPushed(diffInput.getGroupsToAddOrUpdate()));
+ counters.getGroupCrudCounts().setUpdated(ReconcileUtil.countTotalUpdated(diffInput.getGroupsToAddOrUpdate()));
+ counters.getGroupCrudCounts().setRemoved(ReconcileUtil.countTotalPushed(diffInput.getGroupsToRemove()));
+
+ counters.getFlowCrudCounts().setAdded(ReconcileUtil.countTotalPushed(diffInput.getFlowsToAddOrUpdate().values()));
+ counters.getFlowCrudCounts().setUpdated(ReconcileUtil.countTotalUpdated(diffInput.getFlowsToAddOrUpdate().values()));
+ counters.getFlowCrudCounts().setRemoved(ReconcileUtil.countTotalPushed(diffInput.getFlowsToRemove().values()));
+
+ counters.getMeterCrudCounts().setAdded(diffInput.getMetersToAddOrUpdate().getItemsToPush().size());
+ counters.getMeterCrudCounts().setUpdated(diffInput.getMetersToAddOrUpdate().getItemsToUpdate().size());
+ counters.getMeterCrudCounts().setRemoved(diffInput.getMetersToRemove().getItemsToPush().size());
+
/* Tables - have to be pushed before groups */
// TODO enable table-update when ready
//resultVehicle = updateTableFeatures(nodeIdent, configTree);
final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = flatBatchService.processFlatBatch(flatBatchInput);
+ final int failureIndexLimit = batchOrder;
+
+ if (LOG.isDebugEnabled()) {
+ Futures.addCallback(JdkFutureAdapters.listenInPoolThread(rpcResultFuture),
+ createCounterCallback(batchBag, failureIndexLimit, counters));
+ }
+
return Futures.transform(JdkFutureAdapters.listenInPoolThread(rpcResultFuture),
ReconcileUtil.<ProcessFlatBatchOutput>createRpcResultToVoidFunction("flat-batch"));
}
return resultVehicle;
}
+ private FutureCallback<RpcResult<ProcessFlatBatchOutput>> createCounterCallback(final List<Batch> inputBatchBag,
+ final int failureIndexLimit,
+ final SyncCrudCounters counters) {
+ return new FutureCallback<RpcResult<ProcessFlatBatchOutput>>() {
+ @Override
+ public void onSuccess(@Nullable final RpcResult<ProcessFlatBatchOutput> result) {
+ if (!result.isSuccessful() && result.getResult() != null && !result.getResult().getBatchFailure().isEmpty()) {
+ Map<Range<Integer>, Batch> batchMap = mapBachesToRanges(inputBatchBag, failureIndexLimit);
+
+ for (BatchFailure batchFailure : result.getResult().getBatchFailure()) {
+ for (Map.Entry<Range<Integer>, Batch> rangeBatchEntry : batchMap.entrySet()) {
+ if (rangeBatchEntry.getKey().contains(batchFailure.getBatchOrder())) {
+ // get type and decrease
+ final BatchChoice batchChoice = rangeBatchEntry.getValue().getBatchChoice();
+ decrementCounters(batchChoice, counters);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ counters.resetAll();
+ }
+ };
+ }
+
+ static void decrementCounters(final BatchChoice batchChoice, final SyncCrudCounters counters) {
+ if (batchChoice instanceof FlatBatchAddFlowCase) {
+ counters.getFlowCrudCounts().decAdded();
+ } else if (batchChoice instanceof FlatBatchUpdateFlowCase) {
+ counters.getFlowCrudCounts().decUpdated();
+ } else if (batchChoice instanceof FlatBatchRemoveFlowCase) {
+ counters.getFlowCrudCounts().decRemoved();
+ } else if (batchChoice instanceof FlatBatchAddGroupCase) {
+ counters.getGroupCrudCounts().decAdded();
+ } else if (batchChoice instanceof FlatBatchUpdateGroupCase) {
+ counters.getGroupCrudCounts().decUpdated();
+ } else if (batchChoice instanceof FlatBatchRemoveGroupCase) {
+ counters.getGroupCrudCounts().decRemoved();
+ } else if (batchChoice instanceof FlatBatchAddMeterCase) {
+ counters.getMeterCrudCounts().decAdded();
+ } else if (batchChoice instanceof FlatBatchUpdateMeterCase) {
+ counters.getMeterCrudCounts().decUpdated();
+ } else if (batchChoice instanceof FlatBatchRemoveMeterCase) {
+ counters.getMeterCrudCounts().decRemoved();
+ }
+ }
+
+ static Map<Range<Integer>, Batch> mapBachesToRanges(final List<Batch> inputBatchBag, final int failureIndexLimit) {
+ final Map<Range<Integer>, Batch> batchMap = new LinkedHashMap<>();
+ final PeekingIterator<Batch> batchPeekingIterator = Iterators.peekingIterator(inputBatchBag.iterator());
+ while (batchPeekingIterator.hasNext()) {
+ final Batch batch = batchPeekingIterator.next();
+ final int nextBatchOrder = batchPeekingIterator.hasNext()
+ ? batchPeekingIterator.peek().getBatchOrder()
+ : failureIndexLimit;
+ batchMap.put(Range.closed(batch.getBatchOrder(), nextBatchOrder - 1), batch);
+ }
+ return batchMap;
+ }
+
+ private int getNextBatchLimit(final PeekingIterator<Batch> inputBatchIterator, final int failureIndexLimit) {
+ return inputBatchIterator.hasNext()
+ ? inputBatchIterator.peek().getBatchOrder()
+ : failureIndexLimit;
+ }
+
@VisibleForTesting
static int assembleRemoveFlows(final List<Batch> batchBag, int batchOrder, final Map<TableKey, ItemSyncBox<Flow>> flowItemSyncTableMap) {
// process flow remove
.setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
.setFlatBatchRemoveFlow(flatBatchRemoveFlowBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
}
.setBatchChoice(new FlatBatchAddGroupCaseBuilder()
.setFlatBatchAddGroup(flatBatchAddGroupBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
.setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
.setFlatBatchUpdateGroup(flatBatchUpdateGroupBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
}
.setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
.setFlatBatchRemoveGroup(flatBatchRemoveGroupBag)
.build())
- .setBatchOrder(batchOrder++)
- .build();
- batchBag.add(batch);
- }
-
- if (!groupItemSyncBox.getItemsToUpdate().isEmpty()) {
- final List<FlatBatchUpdateGroup> flatBatchUpdateGroupBag =
- new ArrayList<>(groupItemSyncBox.getItemsToUpdate().size());
- int itemOrder = 0;
- for (ItemSyncBox.ItemUpdateTuple<Group> groupUpdate : groupItemSyncBox.getItemsToUpdate()) {
- flatBatchUpdateGroupBag.add(new FlatBatchUpdateGroupBuilder()
- .setBatchOrder(itemOrder++)
- .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder(groupUpdate.getOriginal()).build())
- .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder(groupUpdate.getUpdated()).build())
- .build());
- }
- final Batch batch = new BatchBuilder()
- .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
- .setFlatBatchUpdateGroup(flatBatchUpdateGroupBag)
- .build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
}
.setBatchChoice(new FlatBatchAddMeterCaseBuilder()
.setFlatBatchAddMeter(flatBatchAddMeterBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
.setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
.setFlatBatchUpdateMeter(flatBatchUpdateMeterBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
}
.setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
.setFlatBatchRemoveMeter(flatBatchRemoveMeterBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
}
.setBatchChoice(new FlatBatchAddFlowCaseBuilder()
.setFlatBatchAddFlow(flatBatchAddFlowBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
.setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
.setFlatBatchUpdateFlow(flatBatchUpdateFlowBag)
.build())
- .setBatchOrder(batchOrder++)
+ .setBatchOrder(batchOrder)
.build();
+ batchOrder += itemOrder;
batchBag.add(batch);
}
}
public void incRemoved() {
removed++;
}
+
+ public void decAdded() {
+ added--;
+ }
+
+ public void decUpdated() {
+ updated--;
+ }
+
+ public void decRemoved() {
+ removed--;
+ }
}
public void setStartNano(final long startNano) {
this.startNano = startNano;
}
+
+ public void resetAll() {
+ getGroupCrudCounts().setUpdated(0);
+ getGroupCrudCounts().setAdded(0);
+ getGroupCrudCounts().setRemoved(0);
+
+ getFlowCrudCounts().setUpdated(0);
+ getFlowCrudCounts().setAdded(0);
+ getFlowCrudCounts().setRemoved(0);
+
+ getMeterCrudCounts().setUpdated(0);
+ getMeterCrudCounts().setAdded(0);
+ getMeterCrudCounts().setRemoved(0);
+ }
}
--- /dev/null
+/**
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.applications.frsync.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.BandId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DropBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.MeterBandHeadersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderBuilder;
+
+/**
+ * Provides create methods for dataObjects involved in
+ * {@link org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener} by inventory.
+ */
+public class DSInputFactory {
+ public static Group createGroup(final long groupIdValue) {
+ final Buckets buckets = new BucketsBuilder()
+ .setBucket(Collections.<Bucket>emptyList())
+ .build();
+ return new GroupBuilder()
+ .setGroupId(new GroupId(groupIdValue))
+ .setBuckets(buckets)
+ .build();
+ }
+
+ public static Group createGroupWithAction(final long groupIdValue) {
+ final Buckets buckets = new BucketsBuilder()
+ .setBucket(Collections.singletonList(new BucketBuilder()
+ .setAction(Collections.singletonList(new ActionBuilder()
+ .setAction(new OutputActionCaseBuilder()
+ .setOutputAction(new OutputActionBuilder()
+ .setOutputNodeConnector(new Uri("ut-port-1"))
+ .build())
+ .build())
+ .build()))
+ .build()))
+ .build();
+ return new GroupBuilder()
+ .setGroupId(new GroupId(groupIdValue))
+ .setBuckets(buckets)
+ .build();
+ }
+
+ public static Flow createFlow(final String flowIdValue, final int priority) {
+ return new FlowBuilder()
+ .setId(new FlowId(flowIdValue))
+ .setPriority(priority)
+ .setTableId((short) 42)
+ .setMatch(new MatchBuilder().build())
+ .build();
+ }
+
+ public static Flow createFlowWithInstruction(final String flowIdValue, final int priority) {
+ return new FlowBuilder()
+ .setId(new FlowId(flowIdValue))
+ .setPriority(priority)
+ .setTableId((short) 42)
+ .setMatch(new MatchBuilder().build())
+ .setInstructions(new InstructionsBuilder()
+ .setInstruction(Collections.singletonList(new InstructionBuilder()
+ .setInstruction(new ApplyActionsCaseBuilder()
+ .setApplyActions(new ApplyActionsBuilder()
+ .setAction(Collections.singletonList(new ActionBuilder()
+ .setAction(new OutputActionCaseBuilder()
+ .setOutputAction(new OutputActionBuilder()
+ .setOutputNodeConnector(new Uri("ut-port-1"))
+ .build())
+ .build())
+ .build()))
+ .build())
+ .build())
+ .build()))
+ .build())
+ .build();
+ }
+
+ public static Meter createMeter(final Long meterIdValue) {
+ return new MeterBuilder()
+ .setMeterId(new MeterId(meterIdValue))
+ .build();
+ }
+
+ public static Meter createMeterWithBody(final Long meterIdValue) {
+ return new MeterBuilder()
+ .setMeterId(new MeterId(meterIdValue))
+ .setMeterBandHeaders(new MeterBandHeadersBuilder()
+ .setMeterBandHeader(Collections.singletonList(new MeterBandHeaderBuilder()
+ .setBandId(new BandId(42L))
+ .setBandType(new DropBuilder()
+ .setDropRate(43L)
+ .build())
+ .build()))
+ .build())
+ .build();
+ }
+
+ public static Group createGroupWithPreconditions(final long groupIdValue, final long... requiredId) {
+ final List<Action> actionBag = new ArrayList<>();
+ for (long groupIdPrecondition : requiredId) {
+ final GroupAction groupAction = new GroupActionBuilder()
+ .setGroupId(groupIdPrecondition)
+ .build();
+ final GroupActionCase groupActionCase = new GroupActionCaseBuilder()
+ .setGroupAction(groupAction)
+ .build();
+ final Action action = new ActionBuilder()
+ .setAction(groupActionCase)
+ .build();
+ actionBag.add(action);
+ }
+
+ final Bucket bucket = new BucketBuilder()
+ .setAction(actionBag)
+ .build();
+ final Buckets buckets = new BucketsBuilder()
+ .setBucket(Collections.singletonList(bucket))
+ .build();
+
+ return new GroupBuilder()
+ .setGroupId(new GroupId(groupIdValue))
+ .setBuckets(buckets)
+ .build();
+ }
+}
package org.opendaylight.openflowplugin.applications.frsync.impl;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
+import org.mockito.Matchers;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.openflowplugin.applications.frsync.SyncPlanPushStrategy;
+import org.opendaylight.openflowplugin.applications.frsync.impl.strategy.SynchronizationDiffInput;
+import org.opendaylight.openflowplugin.applications.frsync.util.ReconcileUtil;
+import org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private ArgumentCaptor<Meter> meterUpdateCaptor;
@Captor
private ArgumentCaptor<TableFeatures> tableFeaturesCaptor;
+ @Captor
+ private ArgumentCaptor<SynchronizationDiffInput> syncDiffInputCaptor;
@Before
public void setUp() throws Exception {
@Test
public void testSyncup() throws Exception {
- // TODO: add test body as soon as strategies are settled
+ final FlowCapableNode configFcn = new FlowCapableNodeBuilder()
+ .setGroup(Collections.singletonList(DSInputFactory.createGroup(1L)))
+ .setTable(Collections.singletonList(new TableBuilder()
+ .setFlow(Collections.singletonList(DSInputFactory.createFlow("f1", 1)))
+ .build()))
+ .setMeter(Collections.singletonList(DSInputFactory.createMeter(1L)))
+ .build();
+
+ final FlowCapableNode operationalFcn = new FlowCapableNodeBuilder()
+ .setGroup(Collections.singletonList(DSInputFactory.createGroup(2L)))
+ .setTable(Collections.singletonList(new TableBuilder()
+ .setFlow(Collections.singletonList(DSInputFactory.createFlow("f2", 2)))
+ .build()))
+ .setMeter(Collections.singletonList(DSInputFactory.createMeter(2L)))
+ .build();
+
+ Mockito.when(syncPlanPushStrategy.executeSyncStrategy(
+ Matchers.<ListenableFuture<RpcResult<Void>>>any(),
+ Matchers.<SynchronizationDiffInput>any(),
+ Matchers.<SyncCrudCounters>any()))
+ .thenReturn(RpcResultBuilder.<Void>success().buildFuture());
+
+ final ListenableFuture<Boolean> syncupResult = reactor.syncup(NODE_IDENT, configFcn, operationalFcn);
+ try {
+ Assert.assertTrue(syncupResult.isDone());
+ final Boolean voidRpcResult = syncupResult.get(2, TimeUnit.SECONDS);
+ Assert.assertTrue(voidRpcResult);
+
+ Mockito.verify(syncPlanPushStrategy).executeSyncStrategy(
+ Matchers.<ListenableFuture<RpcResult<Void>>>any(),
+ syncDiffInputCaptor.capture(),
+ Matchers.<SyncCrudCounters>any()
+ );
+
+ final SynchronizationDiffInput diffInput = syncDiffInputCaptor.getValue();
+ Assert.assertEquals(1, ReconcileUtil.countTotalPushed(diffInput.getFlowsToAddOrUpdate().values()));
+ Assert.assertEquals(0, ReconcileUtil.countTotalUpdated(diffInput.getFlowsToAddOrUpdate().values()));
+ Assert.assertEquals(1, ReconcileUtil.countTotalPushed(diffInput.getFlowsToRemove().values()));
+
+ Assert.assertEquals(1, ReconcileUtil.countTotalPushed(diffInput.getGroupsToAddOrUpdate()));
+ Assert.assertEquals(0, ReconcileUtil.countTotalUpdated(diffInput.getGroupsToAddOrUpdate()));
+ Assert.assertEquals(1, ReconcileUtil.countTotalPushed(diffInput.getGroupsToRemove()));
+
+ Assert.assertEquals(1, diffInput.getMetersToAddOrUpdate().getItemsToPush().size());
+ Assert.assertEquals(0, diffInput.getMetersToAddOrUpdate().getItemsToUpdate().size());
+ Assert.assertEquals(1, diffInput.getMetersToRemove().getItemsToPush().size());
+ } catch (Exception e) {
+ LOG.warn("syncup failed", e);
+ Assert.fail("syncup failed: " + e.getMessage());
+ }
}
}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.applications.frsync.impl.strategy;
+
+import org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+
+/**
+ * Provides create methods for data involved in {@link SynchronizationDiffInput}.
+ */
+public class DiffInputFactory {
+ static ItemSyncBox<Group> createGroupSyncBox(final long... groupIDs) {
+ final ItemSyncBox<Group> groupBox = new ItemSyncBox<>();
+
+ for (long gid : groupIDs) {
+ groupBox.getItemsToPush().add(createPlainGroup(gid));
+ }
+ return groupBox;
+ }
+
+ static ItemSyncBox<Group> createGroupSyncBoxWithUpdates(final long... groupIDs) {
+ final ItemSyncBox<Group> groupBox = new ItemSyncBox<>();
+
+ for (long gid : groupIDs) {
+ groupBox.getItemsToPush().add(createPlainGroup(gid));
+ groupBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(createPlainGroup(gid + 50),
+ createPlainGroup(gid + 100)));
+ }
+ return groupBox;
+ }
+
+ static Group createPlainGroup(final long gid) {
+ return new GroupBuilder().setGroupId(new GroupId(gid)).build();
+ }
+
+ static ItemSyncBox<Meter> createMeterSyncBox(final long... meterIDs) {
+ final ItemSyncBox<Meter> groupBox = new ItemSyncBox<>();
+
+ for (long gid : meterIDs) {
+ groupBox.getItemsToPush().add(createPlainMeter(gid));
+ }
+ return groupBox;
+ }
+
+ static ItemSyncBox<Meter> createMeterSyncBoxWithUpdates(final long... meterIDs) {
+ final ItemSyncBox<Meter> groupBox = new ItemSyncBox<>();
+
+ for (long mid : meterIDs) {
+ groupBox.getItemsToPush().add(createPlainMeter(mid));
+ groupBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(createPlainMeter(mid + 50),
+ createPlainMeter(mid + 100)));
+ }
+ return groupBox;
+ }
+
+ static Meter createPlainMeter(final long mid) {
+ return new MeterBuilder().setMeterId(new MeterId(mid)).build();
+ }
+
+ static ItemSyncBox<Flow> createFlowSyncBox(final String... flowIDs) {
+ final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
+
+ for (String fid : flowIDs) {
+ flowBox.getItemsToPush().add(createPlainFlow(fid));
+ }
+ return flowBox;
+ }
+
+ static ItemSyncBox<Flow> createFlowSyncBoxWithUpdates(final String... flowIDs) {
+ final ItemSyncBox<Flow> groupBox = new ItemSyncBox<>();
+
+ for (String fid : flowIDs) {
+ groupBox.getItemsToPush().add(createPlainFlow(fid));
+ groupBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(createPlainFlow(fid + "orig"),
+ createPlainFlow(fid + "upd")));
+ }
+ return groupBox;
+ }
+
+ static Flow createPlainFlow(final String fid) {
+ return new FlowBuilder().setId(new FlowId(fid)).build();
+ }
+}
package org.opendaylight.openflowplugin.applications.frsync.impl.strategy;
import com.google.common.collect.Lists;
+import com.google.common.collect.Range;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Matchers;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowplugin.applications.frsync.impl.TableForwarder;
import org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox;
+import org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.SalFlatBatchService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
/**
* Test for {@link SyncPlanPushStrategyFlatBatchImpl}.
@Mock
private SalFlatBatchService flatBatchService;
@Mock
- private SalFlatBatchService tableUpdateService;
+ private TableForwarder tableForwarder;
+ @Captor
+ private ArgumentCaptor<ProcessFlatBatchInput> processFlatBatchInputCpt;
private List<ItemSyncBox<Group>> groupsToAddOrUpdate;
private List<ItemSyncBox<Group>> groupsToRemove;
private SyncPlanPushStrategyFlatBatchImpl syncPlanPushStrategy;
public SyncPlanPushStrategyFlatBatchImplTest() {
- groupsToAddOrUpdate = Lists.newArrayList(createGroupSyncBox(1, 2, 3), createGroupSyncBoxWithUpdates(4, 5, 6));
- groupsToRemove = Lists.newArrayList(createGroupSyncBox(1, 2, 3), createGroupSyncBox(4, 5, 6));
+ groupsToAddOrUpdate = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
+ DiffInputFactory.createGroupSyncBoxWithUpdates(4, 5, 6));
+ groupsToRemove = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
+ DiffInputFactory.createGroupSyncBox(4, 5, 6));
- metersToAddOrUpdate = createMeterSyncBoxWithUpdates(1, 2, 3);
- metersToRemove = createMeterSyncBox(1, 2, 3);
+ metersToAddOrUpdate = DiffInputFactory.createMeterSyncBoxWithUpdates(1, 2, 3);
+ metersToRemove = DiffInputFactory.createMeterSyncBox(1, 2, 3);
flowsToAddOrUpdate = new HashMap<>();
- flowsToAddOrUpdate.put(new TableKey((short) 0), createFlowSyncBox("1", "2", "3"));
- flowsToAddOrUpdate.put(new TableKey((short) 1), createFlowSyncBoxWithUpdates("4", "5", "6"));
+ flowsToAddOrUpdate.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
+ flowsToAddOrUpdate.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBoxWithUpdates("4", "5", "6"));
flowsToRemove = new HashMap<>();
- flowsToRemove.put(new TableKey((short) 0), createFlowSyncBox("1", "2", "3"));
- flowsToRemove.put(new TableKey((short) 1), createFlowSyncBox("4", "5", "6"));
- }
-
- private ItemSyncBox<Group> createGroupSyncBox(final long... groupIDs) {
- final ItemSyncBox<Group> groupBox = new ItemSyncBox<>();
-
- for (long gid : groupIDs) {
- groupBox.getItemsToPush().add(createPlainGroup(gid));
- }
- return groupBox;
- }
-
- private ItemSyncBox<Group> createGroupSyncBoxWithUpdates(final long... groupIDs) {
- final ItemSyncBox<Group> groupBox = new ItemSyncBox<>();
-
- for (long gid : groupIDs) {
- groupBox.getItemsToPush().add(createPlainGroup(gid));
- groupBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(createPlainGroup(gid),
- createPlainGroup(gid + 100)));
- }
- return groupBox;
- }
-
- private Group createPlainGroup(final long gid) {
- return new GroupBuilder().setGroupId(new GroupId(gid)).build();
- }
-
- private ItemSyncBox<Meter> createMeterSyncBox(final long... meterIDs) {
- final ItemSyncBox<Meter> groupBox = new ItemSyncBox<>();
-
- for (long gid : meterIDs) {
- groupBox.getItemsToPush().add(createPlainMeter(gid));
- }
- return groupBox;
- }
-
- private ItemSyncBox<Meter> createMeterSyncBoxWithUpdates(final long... meterIDs) {
- final ItemSyncBox<Meter> groupBox = new ItemSyncBox<>();
-
- for (long mid : meterIDs) {
- groupBox.getItemsToPush().add(createPlainMeter(mid));
- groupBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(createPlainMeter(mid),
- createPlainMeter(mid + 100)));
- }
- return groupBox;
- }
-
- private Meter createPlainMeter(final long mid) {
- return new MeterBuilder().setMeterId(new MeterId(mid)).build();
- }
-
- private ItemSyncBox<Flow> createFlowSyncBox(final String... flowIDs) {
- final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
-
- for (String fid : flowIDs) {
- flowBox.getItemsToPush().add(createPlainFlow(fid));
- }
- return flowBox;
- }
-
- private ItemSyncBox<Flow> createFlowSyncBoxWithUpdates(final String... flowIDs) {
- final ItemSyncBox<Flow> groupBox = new ItemSyncBox<>();
-
- for (String fid : flowIDs) {
- groupBox.getItemsToPush().add(createPlainFlow(fid));
- groupBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(createPlainFlow(fid),
- createPlainFlow(fid + "upd")));
- }
- return groupBox;
- }
-
- private Flow createPlainFlow(final String fid) {
- return new FlowBuilder().setId(new FlowId(fid)).build();
+ flowsToRemove.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
+ flowsToRemove.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBox("4", "5", "6"));
}
public void setUp() throws Exception {
syncPlanPushStrategy = new SyncPlanPushStrategyFlatBatchImpl();
syncPlanPushStrategy.setFlatBatchService(flatBatchService);
- syncPlanPushStrategy.setFlatBatchService(tableUpdateService);
+ syncPlanPushStrategy.setTableForwarder(tableForwarder);
batchBag = new ArrayList<>();
}
@Test
public void testExecuteSyncStrategy() throws Exception {
final SynchronizationDiffInput diffInput = new SynchronizationDiffInput(NODE_IDENT,
- groupsToAddOrUpdate, null, null, null, null, null);
+ 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());
}
@Test
public void testAssembleRemoveFlows() throws Exception {
final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleRemoveFlows(batchBag, 0, flowsToRemove);
- Assert.assertEquals(2, lastOrder);
+ Assert.assertEquals(6, lastOrder);
Assert.assertEquals(2, batchBag.size());
Assert.assertEquals(FlatBatchRemoveFlowCase.class, batchBag.get(0).getBatchChoice().getImplementedInterface());
Assert.assertEquals(3, ((FlatBatchRemoveFlowCase) batchBag.get(0).getBatchChoice())
public void testAssembleAddOrUpdateGroups() throws Exception {
final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleAddOrUpdateGroups(batchBag, 0, groupsToAddOrUpdate);
- Assert.assertEquals(3, lastOrder);
+ Assert.assertEquals(9, lastOrder);
Assert.assertEquals(3, batchBag.size());
Assert.assertEquals(FlatBatchAddGroupCase.class, batchBag.get(0).getBatchChoice().getImplementedInterface());
Assert.assertEquals(3, ((FlatBatchAddGroupCase) batchBag.get(0).getBatchChoice())
public void testAssembleRemoveGroups() throws Exception {
final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleRemoveGroups(batchBag, 0, groupsToRemove);
- Assert.assertEquals(2, lastOrder);
+ Assert.assertEquals(6, lastOrder);
Assert.assertEquals(2, batchBag.size());
Assert.assertEquals(FlatBatchRemoveGroupCase.class, batchBag.get(0).getBatchChoice().getImplementedInterface());
Assert.assertEquals(3, ((FlatBatchRemoveGroupCase) batchBag.get(0).getBatchChoice())
public void testAssembleAddOrUpdateMeters() throws Exception {
final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleAddOrUpdateMeters(batchBag, 0, metersToAddOrUpdate);
- Assert.assertEquals(2, lastOrder);
+ Assert.assertEquals(6, lastOrder);
Assert.assertEquals(2, batchBag.size());
Assert.assertEquals(FlatBatchAddMeterCase.class, batchBag.get(0).getBatchChoice().getImplementedInterface());
Assert.assertEquals(3, ((FlatBatchAddMeterCase) batchBag.get(0).getBatchChoice())
public void testAssembleRemoveMeters() throws Exception {
final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleRemoveMeters(batchBag, 0, metersToRemove);
- Assert.assertEquals(1, lastOrder);
+ Assert.assertEquals(3, lastOrder);
Assert.assertEquals(1, batchBag.size());
Assert.assertEquals(FlatBatchRemoveMeterCase.class, batchBag.get(0).getBatchChoice().getImplementedInterface());
Assert.assertEquals(3, ((FlatBatchRemoveMeterCase) batchBag.get(0).getBatchChoice())
public void testAssembleAddOrUpdateFlows() throws Exception {
final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleAddOrUpdateFlows(batchBag, 0, flowsToAddOrUpdate);
- Assert.assertEquals(3, lastOrder);
+ Assert.assertEquals(9, lastOrder);
Assert.assertEquals(3, batchBag.size());
Assert.assertEquals(FlatBatchAddFlowCase.class, batchBag.get(0).getBatchChoice().getImplementedInterface());
Assert.assertEquals(3, ((FlatBatchAddFlowCase) batchBag.get(0).getBatchChoice())
Assert.assertEquals(3, ((FlatBatchAddFlowCase) batchBag.get(2).getBatchChoice())
.getFlatBatchAddFlow().size());
}
+
+ @Test
+ public void testDecrementCounters() throws Exception {
+ final SyncCrudCounters counters = new SyncCrudCounters();
+ counters.getFlowCrudCounts().setAdded(100);
+ counters.getFlowCrudCounts().setUpdated(100);
+ counters.getFlowCrudCounts().setRemoved(100);
+
+ counters.getGroupCrudCounts().setAdded(100);
+ counters.getGroupCrudCounts().setUpdated(100);
+ counters.getGroupCrudCounts().setRemoved(100);
+
+ counters.getMeterCrudCounts().setAdded(100);
+ counters.getMeterCrudCounts().setUpdated(100);
+ counters.getMeterCrudCounts().setRemoved(100);
+
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchAddFlowCaseBuilder().build(), counters);
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchUpdateFlowCaseBuilder().build(), counters);
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchRemoveFlowCaseBuilder().build(), counters);
+
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchAddGroupCaseBuilder().build(), counters);
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchUpdateGroupCaseBuilder().build(), counters);
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchRemoveGroupCaseBuilder().build(), counters);
+
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchAddMeterCaseBuilder().build(), counters);
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchUpdateMeterCaseBuilder().build(), counters);
+ SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchRemoveMeterCaseBuilder().build(), counters);
+
+ Assert.assertEquals(99, counters.getFlowCrudCounts().getAdded());
+ Assert.assertEquals(99, counters.getFlowCrudCounts().getUpdated());
+ Assert.assertEquals(99, counters.getFlowCrudCounts().getRemoved());
+
+ Assert.assertEquals(99, counters.getGroupCrudCounts().getAdded());
+ Assert.assertEquals(99, counters.getGroupCrudCounts().getUpdated());
+ Assert.assertEquals(99, counters.getGroupCrudCounts().getRemoved());
+
+ Assert.assertEquals(99, counters.getMeterCrudCounts().getAdded());
+ Assert.assertEquals(99, counters.getMeterCrudCounts().getUpdated());
+ Assert.assertEquals(99, counters.getMeterCrudCounts().getRemoved());
+ }
+
+ @Test
+ public void testMapBachesToRanges() throws Exception {
+ final List<Batch> inputBatchBag = Lists.newArrayList(
+ new BatchBuilder().setBatchOrder(0).build(),
+ new BatchBuilder().setBatchOrder(5).build(),
+ new BatchBuilder().setBatchOrder(9).build(),
+ new BatchBuilder().setBatchOrder(15).build()
+ );
+ final Map<Range<Integer>, Batch> rangeBatchMap = SyncPlanPushStrategyFlatBatchImpl.mapBachesToRanges(inputBatchBag, 42);
+
+ Assert.assertEquals(4, rangeBatchMap.size());
+ int idx = 0;
+ final int[] lower = new int[]{0, 5, 9, 15};
+ final int[] upper = new int[]{4, 8, 14, 41};
+ for (Map.Entry<Range<Integer>, Batch> rangeBatchEntry : rangeBatchMap.entrySet()) {
+ Assert.assertEquals(lower[idx], rangeBatchEntry.getKey().lowerEndpoint().intValue());
+ Assert.assertEquals(upper[idx], rangeBatchEntry.getKey().upperEndpoint().intValue());
+ Assert.assertSame(inputBatchBag.get(idx), rangeBatchEntry.getValue());
+ idx++;
+ }
+ }
}
\ No newline at end of file
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.openflowplugin.applications.frsync.impl.DSInputFactory;
import org.opendaylight.openflowplugin.applications.frsync.impl.FlowForwarder;
import org.opendaylight.openflowplugin.applications.frsync.impl.GroupForwarder;
import org.opendaylight.openflowplugin.applications.frsync.impl.MeterForwarder;
import org.opendaylight.openflowplugin.applications.frsync.impl.TableForwarder;
import org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox;
import org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.BandId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DropBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.MeterBandHeadersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Future;
-
/**
* Test for {@link SyncPlanPushStrategyIncrementalImpl}.
*/
private SyncCrudCounters counters;
+ private List<ItemSyncBox<Group>> groupsToAddOrUpdate;
+ private List<ItemSyncBox<Group>> groupsToRemove;
+ private ItemSyncBox<Meter> metersToAddOrUpdate;
+ private ItemSyncBox<Meter> metersToRemove;
+ private Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate;
+ private Map<TableKey, ItemSyncBox<Flow>> flowsToRemove;
+
+ public SyncPlanPushStrategyIncrementalImplTest() {
+ groupsToAddOrUpdate = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
+ DiffInputFactory.createGroupSyncBoxWithUpdates(4, 5, 6));
+ groupsToRemove = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
+ DiffInputFactory.createGroupSyncBox(4, 5, 6));
+
+ metersToAddOrUpdate = DiffInputFactory.createMeterSyncBoxWithUpdates(1, 2, 3);
+ metersToRemove = DiffInputFactory.createMeterSyncBox(1, 2, 3);
+
+ flowsToAddOrUpdate = new HashMap<>();
+ flowsToAddOrUpdate.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
+ flowsToAddOrUpdate.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBoxWithUpdates("4", "5", "6"));
+ flowsToRemove = new HashMap<>();
+ flowsToRemove.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
+ flowsToRemove.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBox("4", "5", "6"));
+ }
+
@Test
public void testExecuteSyncStrategy() throws Exception {
+ final SynchronizationDiffInput diffInput = new SynchronizationDiffInput(NODE_IDENT,
+ groupsToAddOrUpdate, metersToAddOrUpdate, flowsToAddOrUpdate, flowsToRemove, metersToRemove, groupsToRemove);
+ final SyncCrudCounters counters = new SyncCrudCounters();
+ final ListenableFuture<RpcResult<Void>> rpcResult = syncPlanPushStrategy.executeSyncStrategy(
+ RpcResultBuilder.<Void>success().buildFuture(), diffInput, counters);
+
+ Mockito.verify(groupCommitter, Mockito.times(6)).add(Matchers.<InstanceIdentifier<Group>>any(),Matchers.<Group>any(),
+ Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(groupCommitter, Mockito.times(3)).update(Matchers.<InstanceIdentifier<Group>>any(),Matchers.<Group>any(),
+ Matchers.<Group>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(groupCommitter, Mockito.times(6)).remove(Matchers.<InstanceIdentifier<Group>>any(),Matchers.<Group>any(),
+ Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(flowCommitter, Mockito.times(6)).add(Matchers.<InstanceIdentifier<Flow>>any(),Matchers.<Flow>any(),
+ Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(flowCommitter, Mockito.times(3)).update(Matchers.<InstanceIdentifier<Flow>>any(),Matchers.<Flow>any(),
+ Matchers.<Flow>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(flowCommitter, Mockito.times(6)).remove(Matchers.<InstanceIdentifier<Flow>>any(),Matchers.<Flow>any(),
+ Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(meterCommitter, Mockito.times(3)).add(Matchers.<InstanceIdentifier<Meter>>any(), Matchers.<Meter>any(),
+ Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(meterCommitter, Mockito.times(3)).update(Matchers.<InstanceIdentifier<Meter>>any(), Matchers.<Meter>any(),
+ Matchers.<Meter>any(), Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+ Mockito.verify(meterCommitter, Mockito.times(3)).remove(Matchers.<InstanceIdentifier<Meter>>any(), Matchers.<Meter>any(),
+ Matchers.<InstanceIdentifier<FlowCapableNode>>any());
+
+ 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());
}
@Before
};
}
- private Group createGroup(final long groupIdValue) {
- final Buckets buckets = new BucketsBuilder()
- .setBucket(Collections.<Bucket>emptyList())
- .build();
- return new GroupBuilder()
- .setGroupId(new GroupId(groupIdValue))
- .setBuckets(buckets)
- .build();
- }
-
- private Group createGroupWithAction(final long groupIdValue) {
- final Buckets buckets = new BucketsBuilder()
- .setBucket(Collections.singletonList(new BucketBuilder()
- .setAction(Collections.singletonList(new ActionBuilder()
- .setAction(new OutputActionCaseBuilder()
- .setOutputAction(new OutputActionBuilder()
- .setOutputNodeConnector(new Uri("ut-port-1"))
- .build())
- .build())
- .build()))
- .build()))
- .build();
- return new GroupBuilder()
- .setGroupId(new GroupId(groupIdValue))
- .setBuckets(buckets)
- .build();
- }
-
- private Flow createFlow(final String flowIdValue, final int priority) {
- return new FlowBuilder()
- .setId(new FlowId(flowIdValue))
- .setPriority(priority)
- .setTableId((short) 42)
- .setMatch(new MatchBuilder().build())
- .build();
- }
-
- private Flow createFlowWithInstruction(final String flowIdValue, final int priority) {
- return new FlowBuilder()
- .setId(new FlowId(flowIdValue))
- .setPriority(priority)
- .setTableId((short) 42)
- .setMatch(new MatchBuilder().build())
- .setInstructions(new InstructionsBuilder()
- .setInstruction(Collections.singletonList(new InstructionBuilder()
- .setInstruction(new ApplyActionsCaseBuilder()
- .setApplyActions(new ApplyActionsBuilder()
- .setAction(Collections.singletonList(new ActionBuilder()
- .setAction(new OutputActionCaseBuilder()
- .setOutputAction(new OutputActionBuilder()
- .setOutputNodeConnector(new Uri("ut-port-1"))
- .build())
- .build())
- .build()))
- .build())
- .build())
- .build()))
- .build())
- .build();
- }
-
- private Meter createMeter(final Long meterIdValue) {
- return new MeterBuilder()
- .setMeterId(new MeterId(meterIdValue))
- .build();
- }
-
- private Meter createMeterWithBody(final Long meterIdValue) {
- return new MeterBuilder()
- .setMeterId(new MeterId(meterIdValue))
- .setMeterBandHeaders(new MeterBandHeadersBuilder()
- .setMeterBandHeader(Collections.singletonList(new MeterBandHeaderBuilder()
- .setBandId(new BandId(42L))
- .setBandType(new DropBuilder()
- .setDropRate(43L)
- .build())
- .build()))
- .build())
- .build();
- }
-
- private Group createGroupWithPreconditions(final long groupIdValue, final long... requiredId) {
- final List<Action> actionBag = new ArrayList<>();
- for (long groupIdPrecondition : requiredId) {
- final GroupAction groupAction = new GroupActionBuilder()
- .setGroupId(groupIdPrecondition)
- .build();
- final GroupActionCase groupActionCase = new GroupActionCaseBuilder()
- .setGroupAction(groupAction)
- .build();
- final Action action = new ActionBuilder()
- .setAction(groupActionCase)
- .build();
- actionBag.add(action);
- }
-
- final Bucket bucket = new BucketBuilder()
- .setAction(actionBag)
- .build();
- final Buckets buckets = new BucketsBuilder()
- .setBucket(Collections.singletonList(bucket))
- .build();
-
- return new GroupBuilder()
- .setGroupId(new GroupId(groupIdValue))
- .setBuckets(buckets)
- .build();
- }
-
@Test
public void testAddMissingFlows() throws Exception {
Mockito.when(flowCommitter.add(Matchers.<InstanceIdentifier<Flow>>any(), flowCaptor.capture(),
.thenReturn(RpcResultBuilder.success(new AddFlowOutputBuilder().build()).buildFuture());
final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
- flowBox.getItemsToPush().add(createFlow("f3", 3));
- flowBox.getItemsToPush().add(createFlow("f4", 4));
+ flowBox.getItemsToPush().add(DSInputFactory.createFlow("f3", 3));
+ flowBox.getItemsToPush().add(DSInputFactory.createFlow("f4", 4));
final Map<TableKey, ItemSyncBox<Flow>> flowBoxMap = new LinkedHashMap<>();
flowBoxMap.put(new TableKey((short) 0), flowBox);
.thenReturn(RpcResultBuilder.success(new RemoveFlowOutputBuilder().build()).buildFuture());
final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
- flowBox.getItemsToPush().add(createFlow("f3", 3));
- flowBox.getItemsToPush().add(createFlow("f4", 4));
+ flowBox.getItemsToPush().add(DSInputFactory.createFlow("f3", 3));
+ flowBox.getItemsToPush().add(DSInputFactory.createFlow("f4", 4));
final Map<TableKey, ItemSyncBox<Flow>> flowBoxMap = new LinkedHashMap<>();
flowBoxMap.put(new TableKey((short) 0), flowBox);
.thenReturn(RpcResultBuilder.success(new UpdateFlowOutputBuilder().build()).buildFuture());
final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
- flowBox.getItemsToPush().add(createFlow("f3", 3));
- flowBox.getItemsToPush().add(createFlow("f4", 4));
+ flowBox.getItemsToPush().add(DSInputFactory.createFlow("f3", 3));
+ flowBox.getItemsToPush().add(DSInputFactory.createFlow("f4", 4));
flowBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
- createFlow("f1", 1), createFlowWithInstruction("f1", 1)));
+ DSInputFactory.createFlow("f1", 1), DSInputFactory.createFlowWithInstruction("f1", 1)));
final Map<TableKey, ItemSyncBox<Flow>> flowBoxMap = new LinkedHashMap<>();
flowBoxMap.put(new TableKey((short) 0), flowBox);
.thenReturn(RpcResultBuilder.success(new AddMeterOutputBuilder().build()).buildFuture());
final ItemSyncBox<Meter> meterSyncBox = new ItemSyncBox<>();
- meterSyncBox.getItemsToPush().add(createMeter(2L));
- meterSyncBox.getItemsToPush().add(createMeter(4L));
+ meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(2L));
+ meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(4L));
final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingMeters(
NODE_ID, NODE_IDENT, meterSyncBox, counters);
.thenReturn(RpcResultBuilder.success(new UpdateMeterOutputBuilder().build()).buildFuture());
final ItemSyncBox<Meter> meterSyncBox = new ItemSyncBox<>();
- meterSyncBox.getItemsToPush().add(createMeter(2L));
- meterSyncBox.getItemsToPush().add(createMeter(4L));
+ meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(2L));
+ meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(4L));
meterSyncBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
- createMeter(1L), createMeterWithBody(1L)));
+ DSInputFactory.createMeter(1L), DSInputFactory.createMeterWithBody(1L)));
final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingMeters(
NODE_ID, NODE_IDENT, meterSyncBox, counters);
.thenReturn(RpcResultBuilder.success(new RemoveMeterOutputBuilder().build()).buildFuture());
final ItemSyncBox<Meter> meterSyncBox = new ItemSyncBox<>();
- meterSyncBox.getItemsToPush().add(createMeter(2L));
- meterSyncBox.getItemsToPush().add(createMeter(4L));
+ meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(2L));
+ meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(4L));
meterSyncBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
- createMeter(1L), createMeterWithBody(1L)));
+ DSInputFactory.createMeter(1L), DSInputFactory.createMeterWithBody(1L)));
final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.removeRedundantMeters(
NODE_ID, NODE_IDENT, meterSyncBox, counters);
.thenReturn(RpcResultBuilder.success(new AddGroupOutputBuilder().build()).buildFuture());
ItemSyncBox<Group> groupBox1 = new ItemSyncBox<>();
- groupBox1.getItemsToPush().add(createGroup(2L));
+ groupBox1.getItemsToPush().add(DSInputFactory.createGroup(2L));
ItemSyncBox<Group> groupBox2 = new ItemSyncBox<>();
- groupBox2.getItemsToPush().add(createGroupWithPreconditions(3L, 2L));
- groupBox2.getItemsToPush().add(createGroupWithPreconditions(4L, 2L));
+ groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(3L, 2L));
+ groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(4L, 2L));
ItemSyncBox<Group> groupBox3 = new ItemSyncBox<>();
- groupBox3.getItemsToPush().add(createGroupWithPreconditions(5L, 3L, 4L));
+ groupBox3.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(5L, 3L, 4L));
final List<ItemSyncBox<Group>> groupBoxLot = Lists.newArrayList(groupBox1, groupBox2, groupBox3);
.thenReturn(RpcResultBuilder.success(new UpdateGroupOutputBuilder().build()).buildFuture());
ItemSyncBox<Group> groupBox1 = new ItemSyncBox<>();
- groupBox1.getItemsToPush().add(createGroup(2L));
+ groupBox1.getItemsToPush().add(DSInputFactory.createGroup(2L));
groupBox1.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
- createGroup(1L), createGroupWithAction(1L)));
+ DSInputFactory.createGroup(1L), DSInputFactory.createGroupWithAction(1L)));
ItemSyncBox<Group> groupBox2 = new ItemSyncBox<>();
- groupBox2.getItemsToPush().add(createGroupWithPreconditions(3L, 2L));
- groupBox2.getItemsToPush().add(createGroupWithPreconditions(4L, 2L));
+ groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(3L, 2L));
+ groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(4L, 2L));
ItemSyncBox<Group> groupBox3 = new ItemSyncBox<>();
- groupBox3.getItemsToPush().add(createGroupWithPreconditions(5L, 3L, 4L));
+ groupBox3.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(5L, 3L, 4L));
final List<ItemSyncBox<Group>> groupBoxLot = Lists.newArrayList(groupBox1, groupBox2, groupBox3);
final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingGroups(
.thenReturn(RpcResultBuilder.success(new RemoveGroupOutputBuilder().build()).buildFuture());
ItemSyncBox<Group> groupBox1 = new ItemSyncBox<>();
- groupBox1.getItemsToPush().add(createGroup(2L));
+ groupBox1.getItemsToPush().add(DSInputFactory.createGroup(2L));
groupBox1.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
- createGroup(1L), createGroupWithAction(1L)));
+ DSInputFactory.createGroup(1L), DSInputFactory.createGroupWithAction(1L)));
ItemSyncBox<Group> groupBox2 = new ItemSyncBox<>();
- groupBox2.getItemsToPush().add(createGroupWithPreconditions(3L, 2L));
- groupBox2.getItemsToPush().add(createGroupWithPreconditions(4L, 2L));
+ groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(3L, 2L));
+ groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(4L, 2L));
ItemSyncBox<Group> groupBox3 = new ItemSyncBox<>();
- groupBox3.getItemsToPush().add(createGroupWithPreconditions(5L, 3L, 4L));
+ groupBox3.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(5L, 3L, 4L));
final List<ItemSyncBox<Group>> groupBoxLot = Lists.newArrayList(groupBox1, groupBox2, groupBox3);
final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.removeRedundantGroups(