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
9 package org.opendaylight.openflowplugin.applications.frsync.impl.strategy;
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.collect.Iterators;
13 import com.google.common.collect.PeekingIterator;
14 import com.google.common.collect.Range;
15 import com.google.common.util.concurrent.AsyncFunction;
16 import com.google.common.util.concurrent.FutureCallback;
17 import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.JdkFutureAdapters;
19 import com.google.common.util.concurrent.ListenableFuture;
20 import java.util.ArrayList;
21 import java.util.LinkedHashMap;
22 import java.util.List;
24 import java.util.concurrent.Future;
25 import javax.annotation.Nullable;
26 import org.opendaylight.openflowplugin.applications.frsync.SyncPlanPushStrategy;
27 import org.opendaylight.openflowplugin.applications.frsync.impl.TableForwarder;
28 import org.opendaylight.openflowplugin.applications.frsync.util.FxChainUtil;
29 import org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox;
30 import org.opendaylight.openflowplugin.applications.frsync.util.PathUtil;
31 import org.opendaylight.openflowplugin.applications.frsync.util.ReconcileUtil;
32 import org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInputBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.SalFlatBatchService;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.BatchChoice;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
58 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;
59 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;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.group._case.FlatBatchAddGroup;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.group._case.FlatBatchAddGroupBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.meter._case.FlatBatchAddMeter;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.meter._case.FlatBatchAddMeterBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.flow._case.FlatBatchRemoveFlow;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.flow._case.FlatBatchRemoveFlowBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.group._case.FlatBatchRemoveGroup;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.group._case.FlatBatchRemoveGroupBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.meter._case.FlatBatchRemoveMeter;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.meter._case.FlatBatchRemoveMeterBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.flow._case.FlatBatchUpdateFlow;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.flow._case.FlatBatchUpdateFlowBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.group._case.FlatBatchUpdateGroup;
73 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;
74 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;
75 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;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.OriginalBatchedFlowBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.UpdatedBatchedFlowBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.OriginalBatchedGroupBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.UpdatedBatchedGroupBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.OriginalBatchedMeterBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.UpdatedBatchedMeterBuilder;
90 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
91 import org.opendaylight.yangtools.yang.common.RpcResult;
92 import org.slf4j.Logger;
93 import org.slf4j.LoggerFactory;
96 * Execute CRUD API for flow + group + meter involving flat-batch strategy.
98 public class SyncPlanPushStrategyFlatBatchImpl implements SyncPlanPushStrategy {
100 private static final Logger LOG = LoggerFactory.getLogger(SyncPlanPushStrategyFlatBatchImpl.class);
102 private SalFlatBatchService flatBatchService;
103 private TableForwarder tableForwarder;
106 public ListenableFuture<RpcResult<Void>> executeSyncStrategy(ListenableFuture<RpcResult<Void>> resultVehicle,
107 final SynchronizationDiffInput diffInput,
108 final SyncCrudCounters counters) {
109 final InstanceIdentifier<FlowCapableNode> nodeIdent = diffInput.getNodeIdent();
110 final NodeId nodeId = PathUtil.digNodeId(nodeIdent);
112 // prepare default (full) counts
113 counters.getGroupCrudCounts().setAdded(ReconcileUtil.countTotalPushed(diffInput.getGroupsToAddOrUpdate()));
114 counters.getGroupCrudCounts().setUpdated(ReconcileUtil.countTotalUpdated(diffInput.getGroupsToAddOrUpdate()));
115 counters.getGroupCrudCounts().setRemoved(ReconcileUtil.countTotalPushed(diffInput.getGroupsToRemove()));
117 counters.getFlowCrudCounts().setAdded(ReconcileUtil.countTotalPushed(diffInput.getFlowsToAddOrUpdate().values()));
118 counters.getFlowCrudCounts().setUpdated(ReconcileUtil.countTotalUpdated(diffInput.getFlowsToAddOrUpdate().values()));
119 counters.getFlowCrudCounts().setRemoved(ReconcileUtil.countTotalPushed(diffInput.getFlowsToRemove().values()));
121 counters.getMeterCrudCounts().setAdded(diffInput.getMetersToAddOrUpdate().getItemsToPush().size());
122 counters.getMeterCrudCounts().setUpdated(diffInput.getMetersToAddOrUpdate().getItemsToUpdate().size());
123 counters.getMeterCrudCounts().setRemoved(diffInput.getMetersToRemove().getItemsToPush().size());
125 /* Tables - have to be pushed before groups */
126 // TODO enable table-update when ready
127 //resultVehicle = updateTableFeatures(nodeIdent, configTree);
129 resultVehicle = Futures.transform(resultVehicle, new AsyncFunction<RpcResult<Void>, RpcResult<Void>>() {
131 public ListenableFuture<RpcResult<Void>> apply(final RpcResult<Void> input) throws Exception {
132 if (!input.isSuccessful()) {
133 //TODO chain errors but not skip processing on first error return Futures.immediateFuture(input);
134 //final ListenableFuture<RpcResult<Void>> singleVoidUpdateResult = Futures.transform(
135 // Futures.asList Arrays.asList(input, output),
136 // ReconcileUtil.<UpdateFlowOutput>createRpcResultCondenser("TODO"));
139 final List<Batch> batchBag = new ArrayList<>();
142 batchOrder = assembleAddOrUpdateGroups(batchBag, batchOrder, diffInput.getGroupsToAddOrUpdate());
143 batchOrder = assembleAddOrUpdateMeters(batchBag, batchOrder, diffInput.getMetersToAddOrUpdate());
144 batchOrder = assembleAddOrUpdateFlows(batchBag, batchOrder, diffInput.getFlowsToAddOrUpdate());
146 batchOrder = assembleRemoveFlows(batchBag, batchOrder, diffInput.getFlowsToRemove());
147 batchOrder = assembleRemoveMeters(batchBag, batchOrder, diffInput.getMetersToRemove());
148 batchOrder = assembleRemoveGroups(batchBag, batchOrder, diffInput.getGroupsToRemove());
150 LOG.trace("Index of last batch step: {}", batchOrder);
152 final ProcessFlatBatchInput flatBatchInput = new ProcessFlatBatchInputBuilder()
153 .setNode(new NodeRef(PathUtil.digNodePath(diffInput.getNodeIdent())))
154 .setExitOnFirstError(false) // TODO: propagate from input
158 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = flatBatchService.processFlatBatch(flatBatchInput);
160 final int failureIndexLimit = batchOrder;
162 if (LOG.isDebugEnabled()) {
163 Futures.addCallback(JdkFutureAdapters.listenInPoolThread(rpcResultFuture),
164 createCounterCallback(batchBag, failureIndexLimit, counters));
167 return Futures.transform(JdkFutureAdapters.listenInPoolThread(rpcResultFuture),
168 ReconcileUtil.<ProcessFlatBatchOutput>createRpcResultToVoidFunction("flat-batch"));
172 Futures.addCallback(resultVehicle, FxChainUtil.logResultCallback(nodeId, "flat-batch"));
173 return resultVehicle;
176 private FutureCallback<RpcResult<ProcessFlatBatchOutput>> createCounterCallback(final List<Batch> inputBatchBag,
177 final int failureIndexLimit,
178 final SyncCrudCounters counters) {
179 return new FutureCallback<RpcResult<ProcessFlatBatchOutput>>() {
181 public void onSuccess(@Nullable final RpcResult<ProcessFlatBatchOutput> result) {
182 if (!result.isSuccessful() && result.getResult() != null && !result.getResult().getBatchFailure().isEmpty()) {
183 Map<Range<Integer>, Batch> batchMap = mapBatchesToRanges(inputBatchBag, failureIndexLimit);
185 for (BatchFailure batchFailure : result.getResult().getBatchFailure()) {
186 for (Map.Entry<Range<Integer>, Batch> rangeBatchEntry : batchMap.entrySet()) {
187 if (rangeBatchEntry.getKey().contains(batchFailure.getBatchOrder())) {
188 // get type and decrease
189 final BatchChoice batchChoice = rangeBatchEntry.getValue().getBatchChoice();
190 decrementCounters(batchChoice, counters);
199 public void onFailure(final Throwable t) {
205 static void decrementCounters(final BatchChoice batchChoice, final SyncCrudCounters counters) {
206 if (batchChoice instanceof FlatBatchAddFlowCase) {
207 counters.getFlowCrudCounts().decAdded();
208 } else if (batchChoice instanceof FlatBatchUpdateFlowCase) {
209 counters.getFlowCrudCounts().decUpdated();
210 } else if (batchChoice instanceof FlatBatchRemoveFlowCase) {
211 counters.getFlowCrudCounts().decRemoved();
212 } else if (batchChoice instanceof FlatBatchAddGroupCase) {
213 counters.getGroupCrudCounts().decAdded();
214 } else if (batchChoice instanceof FlatBatchUpdateGroupCase) {
215 counters.getGroupCrudCounts().decUpdated();
216 } else if (batchChoice instanceof FlatBatchRemoveGroupCase) {
217 counters.getGroupCrudCounts().decRemoved();
218 } else if (batchChoice instanceof FlatBatchAddMeterCase) {
219 counters.getMeterCrudCounts().decAdded();
220 } else if (batchChoice instanceof FlatBatchUpdateMeterCase) {
221 counters.getMeterCrudCounts().decUpdated();
222 } else if (batchChoice instanceof FlatBatchRemoveMeterCase) {
223 counters.getMeterCrudCounts().decRemoved();
227 static Map<Range<Integer>, Batch> mapBatchesToRanges(final List<Batch> inputBatchBag, final int failureIndexLimit) {
228 final Map<Range<Integer>, Batch> batchMap = new LinkedHashMap<>();
229 final PeekingIterator<Batch> batchPeekingIterator = Iterators.peekingIterator(inputBatchBag.iterator());
230 while (batchPeekingIterator.hasNext()) {
231 final Batch batch = batchPeekingIterator.next();
232 final int nextBatchOrder = batchPeekingIterator.hasNext()
233 ? batchPeekingIterator.peek().getBatchOrder()
235 batchMap.put(Range.closed(batch.getBatchOrder(), nextBatchOrder - 1), batch);
240 private int getNextBatchLimit(final PeekingIterator<Batch> inputBatchIterator, final int failureIndexLimit) {
241 return inputBatchIterator.hasNext()
242 ? inputBatchIterator.peek().getBatchOrder()
247 static int assembleRemoveFlows(final List<Batch> batchBag, int batchOrder, final Map<TableKey, ItemSyncBox<Flow>> flowItemSyncTableMap) {
248 // process flow remove
249 if (flowItemSyncTableMap != null) {
250 for (Map.Entry<TableKey, ItemSyncBox<Flow>> syncBoxEntry : flowItemSyncTableMap.entrySet()) {
251 final ItemSyncBox<Flow> flowItemSyncBox = syncBoxEntry.getValue();
253 if (!flowItemSyncBox.getItemsToPush().isEmpty()) {
254 final List<FlatBatchRemoveFlow> flatBatchRemoveFlowBag =
255 new ArrayList<>(flowItemSyncBox.getItemsToUpdate().size());
257 for (Flow flow : flowItemSyncBox.getItemsToPush()) {
258 flatBatchRemoveFlowBag.add(new FlatBatchRemoveFlowBuilder(flow)
259 .setBatchOrder(itemOrder++)
260 .setFlowId(flow.getId())
263 final Batch batch = new BatchBuilder()
264 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
265 .setFlatBatchRemoveFlow(flatBatchRemoveFlowBag)
267 .setBatchOrder(batchOrder)
269 batchOrder += itemOrder;
278 static int assembleAddOrUpdateGroups(final List<Batch> batchBag, int batchOrder, final List<ItemSyncBox<Group>> groupsToAddOrUpdate) {
279 // process group add+update
280 if (groupsToAddOrUpdate != null) {
281 for (ItemSyncBox<Group> groupItemSyncBox : groupsToAddOrUpdate) {
282 if (!groupItemSyncBox.getItemsToPush().isEmpty()) {
283 final List<FlatBatchAddGroup> flatBatchAddGroupBag =
284 new ArrayList<>(groupItemSyncBox.getItemsToUpdate().size());
286 for (Group group : groupItemSyncBox.getItemsToPush()) {
287 flatBatchAddGroupBag.add(new FlatBatchAddGroupBuilder(group).setBatchOrder(itemOrder++).build());
289 final Batch batch = new BatchBuilder()
290 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
291 .setFlatBatchAddGroup(flatBatchAddGroupBag)
293 .setBatchOrder(batchOrder)
295 batchOrder += itemOrder;
299 if (!groupItemSyncBox.getItemsToUpdate().isEmpty()) {
300 final List<FlatBatchUpdateGroup> flatBatchUpdateGroupBag =
301 new ArrayList<>(groupItemSyncBox.getItemsToUpdate().size());
303 for (ItemSyncBox.ItemUpdateTuple<Group> groupUpdate : groupItemSyncBox.getItemsToUpdate()) {
304 flatBatchUpdateGroupBag.add(new FlatBatchUpdateGroupBuilder()
305 .setBatchOrder(itemOrder++)
306 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder(groupUpdate.getOriginal()).build())
307 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder(groupUpdate.getUpdated()).build())
310 final Batch batch = new BatchBuilder()
311 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
312 .setFlatBatchUpdateGroup(flatBatchUpdateGroupBag)
314 .setBatchOrder(batchOrder)
316 batchOrder += itemOrder;
325 static int assembleRemoveGroups(final List<Batch> batchBag, int batchOrder, final List<ItemSyncBox<Group>> groupsToRemoveOrUpdate) {
326 // process group add+update
327 if (groupsToRemoveOrUpdate != null) {
328 for (ItemSyncBox<Group> groupItemSyncBox : groupsToRemoveOrUpdate) {
329 if (!groupItemSyncBox.getItemsToPush().isEmpty()) {
330 final List<FlatBatchRemoveGroup> flatBatchRemoveGroupBag =
331 new ArrayList<>(groupItemSyncBox.getItemsToUpdate().size());
333 for (Group group : groupItemSyncBox.getItemsToPush()) {
334 flatBatchRemoveGroupBag.add(new FlatBatchRemoveGroupBuilder(group).setBatchOrder(itemOrder++).build());
336 final Batch batch = new BatchBuilder()
337 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
338 .setFlatBatchRemoveGroup(flatBatchRemoveGroupBag)
340 .setBatchOrder(batchOrder)
342 batchOrder += itemOrder;
351 static int assembleAddOrUpdateMeters(final List<Batch> batchBag, int batchOrder, final ItemSyncBox<Meter> meterItemSyncBox) {
352 // process meter add+update
353 if (meterItemSyncBox != null) {
354 if (!meterItemSyncBox.getItemsToPush().isEmpty()) {
355 final List<FlatBatchAddMeter> flatBatchAddMeterBag =
356 new ArrayList<>(meterItemSyncBox.getItemsToUpdate().size());
358 for (Meter meter : meterItemSyncBox.getItemsToPush()) {
359 flatBatchAddMeterBag.add(new FlatBatchAddMeterBuilder(meter).setBatchOrder(itemOrder++).build());
361 final Batch batch = new BatchBuilder()
362 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
363 .setFlatBatchAddMeter(flatBatchAddMeterBag)
365 .setBatchOrder(batchOrder)
367 batchOrder += itemOrder;
371 if (!meterItemSyncBox.getItemsToUpdate().isEmpty()) {
372 final List<FlatBatchUpdateMeter> flatBatchUpdateMeterBag =
373 new ArrayList<>(meterItemSyncBox.getItemsToUpdate().size());
375 for (ItemSyncBox.ItemUpdateTuple<Meter> meterUpdate : meterItemSyncBox.getItemsToUpdate()) {
376 flatBatchUpdateMeterBag.add(new FlatBatchUpdateMeterBuilder()
377 .setBatchOrder(itemOrder++)
378 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder(meterUpdate.getOriginal()).build())
379 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder(meterUpdate.getUpdated()).build())
382 final Batch batch = new BatchBuilder()
383 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
384 .setFlatBatchUpdateMeter(flatBatchUpdateMeterBag)
386 .setBatchOrder(batchOrder)
388 batchOrder += itemOrder;
396 static int assembleRemoveMeters(final List<Batch> batchBag, int batchOrder, final ItemSyncBox<Meter> meterItemSyncBox) {
397 // process meter remove
398 if (meterItemSyncBox != null) {
399 if (!meterItemSyncBox.getItemsToPush().isEmpty()) {
400 final List<FlatBatchRemoveMeter> flatBatchRemoveMeterBag =
401 new ArrayList<>(meterItemSyncBox.getItemsToUpdate().size());
403 for (Meter meter : meterItemSyncBox.getItemsToPush()) {
404 flatBatchRemoveMeterBag.add(new FlatBatchRemoveMeterBuilder(meter).setBatchOrder(itemOrder++).build());
406 final Batch batch = new BatchBuilder()
407 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
408 .setFlatBatchRemoveMeter(flatBatchRemoveMeterBag)
410 .setBatchOrder(batchOrder)
412 batchOrder += itemOrder;
420 static int assembleAddOrUpdateFlows(final List<Batch> batchBag, int batchOrder, final Map<TableKey, ItemSyncBox<Flow>> flowItemSyncTableMap) {
421 // process flow add+update
422 if (flowItemSyncTableMap != null) {
423 for (Map.Entry<TableKey, ItemSyncBox<Flow>> syncBoxEntry : flowItemSyncTableMap.entrySet()) {
424 final ItemSyncBox<Flow> flowItemSyncBox = syncBoxEntry.getValue();
426 if (!flowItemSyncBox.getItemsToPush().isEmpty()) {
427 final List<FlatBatchAddFlow> flatBatchAddFlowBag =
428 new ArrayList<>(flowItemSyncBox.getItemsToUpdate().size());
430 for (Flow flow : flowItemSyncBox.getItemsToPush()) {
431 flatBatchAddFlowBag.add(new FlatBatchAddFlowBuilder(flow)
432 .setBatchOrder(itemOrder++)
433 .setFlowId(flow.getId())
436 final Batch batch = new BatchBuilder()
437 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
438 .setFlatBatchAddFlow(flatBatchAddFlowBag)
440 .setBatchOrder(batchOrder)
442 batchOrder += itemOrder;
446 if (!flowItemSyncBox.getItemsToUpdate().isEmpty()) {
447 final List<FlatBatchUpdateFlow> flatBatchUpdateFlowBag =
448 new ArrayList<>(flowItemSyncBox.getItemsToUpdate().size());
450 for (ItemSyncBox.ItemUpdateTuple<Flow> flowUpdate : flowItemSyncBox.getItemsToUpdate()) {
451 flatBatchUpdateFlowBag.add(new FlatBatchUpdateFlowBuilder()
452 .setBatchOrder(itemOrder++)
453 .setFlowId(flowUpdate.getUpdated().getId())
454 .setOriginalBatchedFlow(new OriginalBatchedFlowBuilder(flowUpdate.getOriginal()).build())
455 .setUpdatedBatchedFlow(new UpdatedBatchedFlowBuilder(flowUpdate.getUpdated()).build())
458 final Batch batch = new BatchBuilder()
459 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
460 .setFlatBatchUpdateFlow(flatBatchUpdateFlowBag)
462 .setBatchOrder(batchOrder)
464 batchOrder += itemOrder;
472 public SyncPlanPushStrategyFlatBatchImpl setFlatBatchService(final SalFlatBatchService flatBatchService) {
473 this.flatBatchService = flatBatchService;
477 public SyncPlanPushStrategyFlatBatchImpl setTableForwarder(final TableForwarder tableForwarder) {
478 this.tableForwarder = tableForwarder;