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.impl.services.batch;
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.base.Function;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.JdkFutureAdapters;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.concurrent.Future;
19 import javax.annotation.Nullable;
20 import org.opendaylight.openflowplugin.impl.util.FlatBatchUtil;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
23 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;
24 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;
25 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;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureGroupIdCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchInputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.BatchGroupOutputListGrouping;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchInputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.add.groups.batch.input.BatchAddGroups;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.add.groups.batch.input.BatchAddGroupsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.output.list.grouping.BatchFailedGroupsOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.remove.groups.batch.input.BatchRemoveGroups;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.remove.groups.batch.input.BatchRemoveGroupsBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.update.groups.batch.input.BatchUpdateGroups;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.update.groups.batch.input.BatchUpdateGroupsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
44 import org.opendaylight.yangtools.yang.common.RpcResult;
45 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
48 * transform between FlatBatch API and group batch API
50 public class FlatBatchGroupAdapters {
52 private FlatBatchGroupAdapters() {
53 throw new IllegalStateException("This class should not be instantiated.");
57 * @param planStep batch step containing changes of the same type
58 * @param node pointer for RPC routing
59 * @return input suitable for {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.SalGroupsBatchService#addGroupsBatch(AddGroupsBatchInput)}
61 public static AddGroupsBatchInput adaptFlatBatchAddGroup(final BatchPlanStep planStep, final NodeRef node) {
62 final List<BatchAddGroups> batchGroups = new ArrayList<>();
63 for (FlatBatchAddGroup batchAddGroup : planStep.<FlatBatchAddGroup>getTaskBag()) {
64 final BatchAddGroups addGroups = new BatchAddGroupsBuilder(batchAddGroup)
65 .setGroupId(batchAddGroup.getGroupId())
67 batchGroups.add(addGroups);
70 return new AddGroupsBatchInputBuilder()
71 .setBarrierAfter(planStep.isBarrierAfter())
73 .setBatchAddGroups(batchGroups)
78 * @param planStep batch step containing changes of the same type
79 * @param node pointer for RPC routing
80 * @return input suitable for {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.SalGroupsBatchService#removeGroupsBatch(RemoveGroupsBatchInput)}
82 public static RemoveGroupsBatchInput adaptFlatBatchRemoveGroup(final BatchPlanStep planStep, final NodeRef node) {
83 final List<BatchRemoveGroups> batchGroups = new ArrayList<>();
84 for (FlatBatchRemoveGroup batchRemoveGroup : planStep.<FlatBatchRemoveGroup>getTaskBag()) {
85 final BatchRemoveGroups removeGroups = new BatchRemoveGroupsBuilder(batchRemoveGroup)
86 .setGroupId(batchRemoveGroup.getGroupId())
88 batchGroups.add(removeGroups);
91 return new RemoveGroupsBatchInputBuilder()
92 .setBarrierAfter(planStep.isBarrierAfter())
94 .setBatchRemoveGroups(batchGroups)
99 * @param planStep batch step containing changes of the same type
100 * @param node pointer for RPC routing
101 * @return input suitable for {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.SalGroupsBatchService#updateGroupsBatch(UpdateGroupsBatchInput)}
103 public static UpdateGroupsBatchInput adaptFlatBatchUpdateGroup(final BatchPlanStep planStep, final NodeRef node) {
104 final List<BatchUpdateGroups> batchGroups = new ArrayList<>();
105 for (FlatBatchUpdateGroup batchUpdateGroup : planStep.<FlatBatchUpdateGroup>getTaskBag()) {
106 final BatchUpdateGroups updateGroups = new BatchUpdateGroupsBuilder(batchUpdateGroup)
108 batchGroups.add(updateGroups);
111 return new UpdateGroupsBatchInputBuilder()
112 .setBarrierAfter(planStep.isBarrierAfter())
114 .setBatchUpdateGroups(batchGroups)
119 * @param chainInput here all partial results are collected (values + errors)
120 * @param stepOffset offset of current batch plan step
121 * @return next chained result incorporating results of this step's batch
124 static <T extends BatchGroupOutputListGrouping> Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>
125 createBatchGroupChainingFunction(final RpcResult<ProcessFlatBatchOutput> chainInput,
126 final int stepOffset) {
127 return new Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>() {
130 public RpcResult<ProcessFlatBatchOutput> apply(@Nullable final RpcResult<T> input) {
131 // create rpcResult builder honoring both success/failure of current input and chained input + join errors
132 final RpcResultBuilder<ProcessFlatBatchOutput> output = FlatBatchUtil.mergeRpcResults(chainInput, input);
133 // convert values and add to chain values
134 final ProcessFlatBatchOutputBuilder outputBuilder = new ProcessFlatBatchOutputBuilder(chainInput.getResult());
135 final List<BatchFailure> batchFailures = wrapBatchGroupFailuresForFlat(input, stepOffset);
137 if (outputBuilder.getBatchFailure() == null) {
138 outputBuilder.setBatchFailure(new ArrayList<BatchFailure>(batchFailures.size()));
140 outputBuilder.getBatchFailure().addAll(batchFailures);
142 return output.withResult(outputBuilder.build()).build();
147 private static <T extends BatchGroupOutputListGrouping> List<BatchFailure> wrapBatchGroupFailuresForFlat(
148 final RpcResult<T> input, final int stepOffset) {
149 final List<BatchFailure> batchFailures = new ArrayList<>();
150 if (input.getResult().getBatchFailedGroupsOutput() != null) {
151 for (BatchFailedGroupsOutput stepOutput : input.getResult().getBatchFailedGroupsOutput()) {
152 final BatchFailure batchFailure = new BatchFailureBuilder()
153 .setBatchOrder(stepOffset + stepOutput.getBatchOrder())
154 .setBatchItemIdChoice(new FlatBatchFailureGroupIdCaseBuilder()
155 .setGroupId(stepOutput.getGroupId())
158 batchFailures.add(batchFailure);
161 return batchFailures;
165 * shortcut for {@link #createBatchGroupChainingFunction(RpcResult, int)} with conversion {@link ListenableFuture}
167 * @param <T> exact type of batch flow output
168 * @param chainInput here all partial results are collected (values + errors)
169 * @param resultUpdateGroupFuture batch group rpc-result (add/remove/update)
170 * @param currentOffset offset of current batch plan step with respect to entire chain of steps
171 * @return next chained result incorporating results of this step's batch
173 public static <T extends BatchGroupOutputListGrouping> ListenableFuture<RpcResult<ProcessFlatBatchOutput>>
174 adaptGroupBatchFutureForChain(final RpcResult<ProcessFlatBatchOutput> chainInput,
175 final Future<RpcResult<T>> resultUpdateGroupFuture,
176 final int currentOffset) {
177 return Futures.transform(JdkFutureAdapters.listenInPoolThread(resultUpdateGroupFuture),
178 FlatBatchGroupAdapters.<T>createBatchGroupChainingFunction(chainInput, currentOffset));