2 * Copyright (c) 2016 Cisco Systems, Inc. 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.applications.frsync.impl.strategy;
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.collect.Iterators;
12 import com.google.common.collect.PeekingIterator;
13 import com.google.common.collect.Range;
14 import com.google.common.util.concurrent.FutureCallback;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.ListenableFuture;
17 import com.google.common.util.concurrent.MoreExecutors;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.LinkedHashMap;
21 import java.util.List;
23 import org.opendaylight.openflowplugin.applications.frsync.SyncPlanPushStrategy;
24 import org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox;
25 import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
26 import org.opendaylight.openflowplugin.applications.frsync.util.ReconcileUtil;
27 import org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInputBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.SalFlatBatchService;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchAddFlowCase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchAddFlowCaseBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchRemoveFlowCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchRemoveFlowCaseBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchUpdateFlowCase;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchUpdateFlowCaseBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlow;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlow;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlowBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlowKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlow;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlowBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlowKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchAddGroupCase;
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.FlatBatchRemoveGroupCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchRemoveGroupCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchUpdateGroupCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchUpdateGroupCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroup;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroupBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroupKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroup;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroupBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroupKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroup;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroupBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroupKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchAddMeterCase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchAddMeterCaseBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchRemoveMeterCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchRemoveMeterCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchUpdateMeterCase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchUpdateMeterCaseBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeter;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeterBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeterKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeter;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeterBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeterKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeter;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeterBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeterKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.BatchChoice;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.OriginalBatchedFlowBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.UpdatedBatchedFlowBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.OriginalBatchedGroupBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.UpdatedBatchedGroupBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.OriginalBatchedMeterBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.UpdatedBatchedMeterBuilder;
92 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
93 import org.opendaylight.yangtools.yang.binding.util.BindingMap.Builder;
94 import org.opendaylight.yangtools.yang.common.RpcResult;
95 import org.opendaylight.yangtools.yang.common.Uint16;
96 import org.slf4j.Logger;
97 import org.slf4j.LoggerFactory;
100 * Execute CRUD API for flow + group + meter involving flat-batch strategy.
102 public class SyncPlanPushStrategyFlatBatchImpl implements SyncPlanPushStrategy {
104 private static final Logger LOG = LoggerFactory.getLogger(SyncPlanPushStrategyFlatBatchImpl.class);
106 private SalFlatBatchService flatBatchService;
107 private TableForwarder tableForwarder;
110 public ListenableFuture<RpcResult<Void>> executeSyncStrategy(ListenableFuture<RpcResult<Void>> resultVehicle,
111 final SynchronizationDiffInput diffInput,
112 final SyncCrudCounters counters) {
113 // prepare default (full) counts
114 counters.getGroupCrudCounts().setAdded(ReconcileUtil.countTotalPushed(diffInput.getGroupsToAddOrUpdate()));
115 counters.getGroupCrudCounts().setUpdated(ReconcileUtil.countTotalUpdated(diffInput.getGroupsToAddOrUpdate()));
116 counters.getGroupCrudCounts().setRemoved(ReconcileUtil.countTotalPushed(diffInput.getGroupsToRemove()));
118 counters.getFlowCrudCounts().setAdded(ReconcileUtil.countTotalPushed(
119 diffInput.getFlowsToAddOrUpdate().values()));
120 counters.getFlowCrudCounts().setUpdated(ReconcileUtil.countTotalUpdated(
121 diffInput.getFlowsToAddOrUpdate().values()));
122 counters.getFlowCrudCounts().setRemoved(ReconcileUtil.countTotalPushed(diffInput.getFlowsToRemove().values()));
124 counters.getMeterCrudCounts().setAdded(diffInput.getMetersToAddOrUpdate().getItemsToPush().size());
125 counters.getMeterCrudCounts().setUpdated(diffInput.getMetersToAddOrUpdate().getItemsToUpdate().size());
126 counters.getMeterCrudCounts().setRemoved(diffInput.getMetersToRemove().getItemsToPush().size());
128 /* Tables - have to be pushed before groups */
129 // TODO enable table-update when ready
130 //resultVehicle = updateTableFeatures(nodeIdent, configTree);
132 resultVehicle = Futures.transformAsync(resultVehicle, input -> {
133 final List<Batch> batchBag = new ArrayList<>();
136 batchOrder = assembleAddOrUpdateGroups(batchBag, batchOrder, diffInput.getGroupsToAddOrUpdate());
137 batchOrder = assembleAddOrUpdateMeters(batchBag, batchOrder, diffInput.getMetersToAddOrUpdate());
138 batchOrder = assembleAddOrUpdateFlows(batchBag, batchOrder, diffInput.getFlowsToAddOrUpdate());
140 batchOrder = assembleRemoveFlows(batchBag, batchOrder, diffInput.getFlowsToRemove());
141 batchOrder = assembleRemoveMeters(batchBag, batchOrder, diffInput.getMetersToRemove());
142 batchOrder = assembleRemoveGroups(batchBag, batchOrder, diffInput.getGroupsToRemove());
144 LOG.trace("Index of last batch step: {}", batchOrder);
146 final ProcessFlatBatchInput flatBatchInput = new ProcessFlatBatchInputBuilder()
147 .setNode(new NodeRef(PathUtil.digNodePath(diffInput.getNodeIdent())))
148 // TODO: propagate from input
149 .setExitOnFirstError(false)
150 .setBatch(BindingMap.ordered(batchBag))
153 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
154 flatBatchService.processFlatBatch(flatBatchInput);
156 if (LOG.isDebugEnabled()) {
157 Futures.addCallback(rpcResultFuture, createCounterCallback(batchBag, batchOrder, counters),
158 MoreExecutors.directExecutor());
161 return Futures.transform(rpcResultFuture,
162 ReconcileUtil.createRpcResultToVoidFunction("flat-batch"),
163 MoreExecutors.directExecutor());
164 }, MoreExecutors.directExecutor());
165 return resultVehicle;
168 private static FutureCallback<RpcResult<ProcessFlatBatchOutput>> createCounterCallback(
169 final List<Batch> inputBatchBag, final int failureIndexLimit, final SyncCrudCounters counters) {
170 return new FutureCallback<>() {
172 public void onSuccess(final RpcResult<ProcessFlatBatchOutput> result) {
173 if (!result.isSuccessful() && result.getResult() != null
174 && !result.getResult().nonnullBatchFailure().isEmpty()) {
175 Map<Range<Uint16>, Batch> batchMap = mapBatchesToRanges(inputBatchBag, failureIndexLimit);
176 decrementBatchFailuresCounters(result.getResult().nonnullBatchFailure().values(), batchMap,
182 public void onFailure(final Throwable failure) {
188 private static void decrementBatchFailuresCounters(final Collection<BatchFailure> batchFailures,
189 final Map<Range<Uint16>, Batch> batchMap,
190 final SyncCrudCounters counters) {
191 for (BatchFailure batchFailure : batchFailures) {
192 for (Map.Entry<Range<Uint16>, Batch> rangeBatchEntry : batchMap.entrySet()) {
193 if (rangeBatchEntry.getKey().contains(batchFailure.getBatchOrder())) {
194 // get type and decrease
195 final BatchChoice batchChoice = rangeBatchEntry.getValue().getBatchChoice();
196 decrementCounters(batchChoice, counters);
203 static void decrementCounters(final BatchChoice batchChoice, final SyncCrudCounters counters) {
204 if (batchChoice instanceof FlatBatchAddFlowCase) {
205 counters.getFlowCrudCounts().decAdded();
206 } else if (batchChoice instanceof FlatBatchUpdateFlowCase) {
207 counters.getFlowCrudCounts().decUpdated();
208 } else if (batchChoice instanceof FlatBatchRemoveFlowCase) {
209 counters.getFlowCrudCounts().decRemoved();
210 } else if (batchChoice instanceof FlatBatchAddGroupCase) {
211 counters.getGroupCrudCounts().decAdded();
212 } else if (batchChoice instanceof FlatBatchUpdateGroupCase) {
213 counters.getGroupCrudCounts().decUpdated();
214 } else if (batchChoice instanceof FlatBatchRemoveGroupCase) {
215 counters.getGroupCrudCounts().decRemoved();
216 } else if (batchChoice instanceof FlatBatchAddMeterCase) {
217 counters.getMeterCrudCounts().decAdded();
218 } else if (batchChoice instanceof FlatBatchUpdateMeterCase) {
219 counters.getMeterCrudCounts().decUpdated();
220 } else if (batchChoice instanceof FlatBatchRemoveMeterCase) {
221 counters.getMeterCrudCounts().decRemoved();
225 static Map<Range<Uint16>, Batch> mapBatchesToRanges(final List<Batch> inputBatchBag, final int failureIndexLimit) {
226 final Map<Range<Uint16>, Batch> batchMap = new LinkedHashMap<>();
227 final PeekingIterator<Batch> batchPeekingIterator = Iterators.peekingIterator(inputBatchBag.iterator());
228 while (batchPeekingIterator.hasNext()) {
229 final Batch batch = batchPeekingIterator.next();
230 final int nextBatchOrder = batchPeekingIterator.hasNext()
231 ? batchPeekingIterator.peek().getBatchOrder().toJava()
233 batchMap.put(Range.closed(batch.getBatchOrder(), Uint16.valueOf(nextBatchOrder - 1)), batch);
239 static int assembleRemoveFlows(final List<Batch> batchBag, final int batchOrder,
240 final Map<TableKey, ItemSyncBox<Flow>> flowItemSyncTableMap) {
241 // process flow remove
242 int order = batchOrder;
243 if (flowItemSyncTableMap != null) {
244 for (Map.Entry<TableKey, ItemSyncBox<Flow>> syncBoxEntry : flowItemSyncTableMap.entrySet()) {
245 final ItemSyncBox<Flow> flowItemSyncBox = syncBoxEntry.getValue();
247 if (!flowItemSyncBox.getItemsToPush().isEmpty()) {
248 final Builder<FlatBatchRemoveFlowKey, FlatBatchRemoveFlow> flatBatchRemoveFlowBag =
249 BindingMap.orderedBuilder(flowItemSyncBox.getItemsToUpdate().size());
251 for (Flow flow : flowItemSyncBox.getItemsToPush()) {
252 flatBatchRemoveFlowBag.add(new FlatBatchRemoveFlowBuilder(flow)
253 .setBatchOrder(Uint16.valueOf(itemOrder++))
254 .setFlowId(flow.getId())
257 final Batch batch = new BatchBuilder()
258 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
259 .setFlatBatchRemoveFlow(flatBatchRemoveFlowBag.build())
261 .setBatchOrder(Uint16.valueOf(order))
272 static int assembleAddOrUpdateGroups(final List<Batch> batchBag, final int batchOrder,
273 final List<ItemSyncBox<Group>> groupsToAddOrUpdate) {
274 // process group add+update
275 int order = batchOrder;
276 if (groupsToAddOrUpdate != null) {
277 for (ItemSyncBox<Group> groupItemSyncBox : groupsToAddOrUpdate) {
278 if (!groupItemSyncBox.getItemsToPush().isEmpty()) {
279 final Builder<FlatBatchAddGroupKey, FlatBatchAddGroup> flatBatchAddGroupBag =
280 BindingMap.orderedBuilder(groupItemSyncBox.getItemsToPush().size());
282 for (Group group : groupItemSyncBox.getItemsToPush()) {
283 flatBatchAddGroupBag.add(new FlatBatchAddGroupBuilder(group)
284 .setBatchOrder(Uint16.valueOf(itemOrder++)).build());
286 final Batch batch = new BatchBuilder()
287 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
288 .setFlatBatchAddGroup(flatBatchAddGroupBag.build())
290 .setBatchOrder(Uint16.valueOf(order))
296 if (!groupItemSyncBox.getItemsToUpdate().isEmpty()) {
297 final Builder<FlatBatchUpdateGroupKey, FlatBatchUpdateGroup> flatBatchUpdateGroupBag =
298 BindingMap.orderedBuilder(groupItemSyncBox.getItemsToUpdate().size());
300 for (ItemSyncBox.ItemUpdateTuple<Group> groupUpdate : groupItemSyncBox.getItemsToUpdate()) {
301 flatBatchUpdateGroupBag.add(new FlatBatchUpdateGroupBuilder()
302 .setBatchOrder(Uint16.valueOf(itemOrder++))
303 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder(groupUpdate.getOriginal()).build())
304 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder(groupUpdate.getUpdated()).build())
307 final Batch batch = new BatchBuilder()
308 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
309 .setFlatBatchUpdateGroup(flatBatchUpdateGroupBag.build())
311 .setBatchOrder(Uint16.valueOf(order))
322 static int assembleRemoveGroups(final List<Batch> batchBag, final int batchOrder,
323 final List<ItemSyncBox<Group>> groupsToRemoveOrUpdate) {
324 // process group add+update
325 int order = batchOrder;
326 if (groupsToRemoveOrUpdate != null) {
327 for (ItemSyncBox<Group> groupItemSyncBox : groupsToRemoveOrUpdate) {
328 if (!groupItemSyncBox.getItemsToPush().isEmpty()) {
329 final Builder<FlatBatchRemoveGroupKey, FlatBatchRemoveGroup> flatBatchRemoveGroupBag =
330 BindingMap.orderedBuilder(groupItemSyncBox.getItemsToUpdate().size());
332 for (Group group : groupItemSyncBox.getItemsToPush()) {
333 flatBatchRemoveGroupBag.add(new FlatBatchRemoveGroupBuilder(group)
334 .setBatchOrder(Uint16.valueOf(itemOrder++)).build());
336 final Batch batch = new BatchBuilder()
337 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
338 .setFlatBatchRemoveGroup(flatBatchRemoveGroupBag.build())
340 .setBatchOrder(Uint16.valueOf(order))
351 static int assembleAddOrUpdateMeters(final List<Batch> batchBag, final int batchOrder,
352 final ItemSyncBox<Meter> meterItemSyncBox) {
353 // process meter add+update
354 int order = batchOrder;
355 if (meterItemSyncBox != null) {
356 if (!meterItemSyncBox.getItemsToPush().isEmpty()) {
357 final Builder<FlatBatchAddMeterKey, FlatBatchAddMeter> flatBatchAddMeterBag =
358 BindingMap.orderedBuilder(meterItemSyncBox.getItemsToPush().size());
360 for (Meter meter : meterItemSyncBox.getItemsToPush()) {
361 flatBatchAddMeterBag.add(new FlatBatchAddMeterBuilder(meter)
362 .setBatchOrder(Uint16.valueOf(itemOrder++))
365 final Batch batch = new BatchBuilder()
366 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
367 .setFlatBatchAddMeter(flatBatchAddMeterBag.build())
369 .setBatchOrder(Uint16.valueOf(order))
375 if (!meterItemSyncBox.getItemsToUpdate().isEmpty()) {
376 final Builder<FlatBatchUpdateMeterKey, FlatBatchUpdateMeter> flatBatchUpdateMeterBag =
377 BindingMap.orderedBuilder(meterItemSyncBox.getItemsToUpdate().size());
379 for (ItemSyncBox.ItemUpdateTuple<Meter> meterUpdate : meterItemSyncBox.getItemsToUpdate()) {
380 flatBatchUpdateMeterBag.add(new FlatBatchUpdateMeterBuilder()
381 .setBatchOrder(Uint16.valueOf(itemOrder++))
382 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder(meterUpdate.getOriginal()).build())
383 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder(meterUpdate.getUpdated()).build())
386 final Batch batch = new BatchBuilder()
387 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
388 .setFlatBatchUpdateMeter(flatBatchUpdateMeterBag.build())
390 .setBatchOrder(Uint16.valueOf(order))
400 static int assembleRemoveMeters(final List<Batch> batchBag, final int batchOrder,
401 final ItemSyncBox<Meter> meterItemSyncBox) {
402 // process meter remove
403 int order = batchOrder;
404 if (meterItemSyncBox != null && !meterItemSyncBox.getItemsToPush().isEmpty()) {
405 final Builder<FlatBatchRemoveMeterKey, FlatBatchRemoveMeter> flatBatchRemoveMeterBag =
406 BindingMap.orderedBuilder(meterItemSyncBox.getItemsToPush().size());
408 for (Meter meter : meterItemSyncBox.getItemsToPush()) {
409 flatBatchRemoveMeterBag.add(new FlatBatchRemoveMeterBuilder(meter)
410 .setBatchOrder(Uint16.valueOf(itemOrder++))
413 final Batch batch = new BatchBuilder()
414 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
415 .setFlatBatchRemoveMeter(flatBatchRemoveMeterBag.build())
417 .setBatchOrder(Uint16.valueOf(order))
426 static int assembleAddOrUpdateFlows(final List<Batch> batchBag, final int batchOrder,
427 final Map<TableKey, ItemSyncBox<Flow>> flowItemSyncTableMap) {
428 // process flow add+update
429 int order = batchOrder;
430 if (flowItemSyncTableMap != null) {
431 for (Map.Entry<TableKey, ItemSyncBox<Flow>> syncBoxEntry : flowItemSyncTableMap.entrySet()) {
432 final ItemSyncBox<Flow> flowItemSyncBox = syncBoxEntry.getValue();
434 if (!flowItemSyncBox.getItemsToPush().isEmpty()) {
435 final Builder<FlatBatchAddFlowKey, FlatBatchAddFlow> flatBatchAddFlowBag =
436 BindingMap.orderedBuilder(flowItemSyncBox.getItemsToPush().size());
438 for (Flow flow : flowItemSyncBox.getItemsToPush()) {
439 flatBatchAddFlowBag.add(new FlatBatchAddFlowBuilder(flow)
440 .setBatchOrder(Uint16.valueOf(itemOrder++))
441 .setFlowId(flow.getId())
444 final Batch batch = new BatchBuilder()
445 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
446 .setFlatBatchAddFlow(flatBatchAddFlowBag.build())
448 .setBatchOrder(Uint16.valueOf(order))
454 if (!flowItemSyncBox.getItemsToUpdate().isEmpty()) {
455 final Builder<FlatBatchUpdateFlowKey, FlatBatchUpdateFlow> flatBatchUpdateFlowBag =
456 BindingMap.orderedBuilder(flowItemSyncBox.getItemsToUpdate().size());
458 for (ItemSyncBox.ItemUpdateTuple<Flow> flowUpdate : flowItemSyncBox.getItemsToUpdate()) {
459 flatBatchUpdateFlowBag.add(new FlatBatchUpdateFlowBuilder()
460 .setBatchOrder(Uint16.valueOf(itemOrder++))
461 .setFlowId(flowUpdate.getUpdated().getId())
462 .setOriginalBatchedFlow(new OriginalBatchedFlowBuilder(flowUpdate.getOriginal()).build())
463 .setUpdatedBatchedFlow(new UpdatedBatchedFlowBuilder(flowUpdate.getUpdated()).build())
466 final Batch batch = new BatchBuilder()
467 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
468 .setFlatBatchUpdateFlow(flatBatchUpdateFlowBag.build())
470 .setBatchOrder(Uint16.valueOf(order))
480 public SyncPlanPushStrategyFlatBatchImpl setFlatBatchService(final SalFlatBatchService flatBatchService) {
481 this.flatBatchService = flatBatchService;
485 public SyncPlanPushStrategyFlatBatchImpl setTableForwarder(final TableForwarder tableForwarder) {
486 this.tableForwarder = tableForwarder;