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 com.google.common.util.concurrent.MoreExecutors;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.concurrent.Future;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
22 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;
23 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;
24 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;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCaseBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.BatchFlowOutputListGrouping;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlows;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlowsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlows;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlowsBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlows;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlowsBuilder;
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 flow batch API.
50 public final class FlatBatchFlowAdapters {
52 private FlatBatchFlowAdapters() {
56 * Adapt flat batch add flow.
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
60 * .opendaylight.flows.service.rev160314.SalFlowsBatchService#addFlowsBatch(AddFlowsBatchInput)}
62 public static AddFlowsBatchInput adaptFlatBatchAddFlow(final BatchPlanStep planStep, final NodeRef node) {
63 final List<BatchAddFlows> batchFlows = new ArrayList<>();
64 for (FlatBatchAddFlow batchAddFlows : planStep.<FlatBatchAddFlow>getTaskBag()) {
65 final BatchAddFlows addFlows = new BatchAddFlowsBuilder((Flow) batchAddFlows)
66 .setFlowId(batchAddFlows.getFlowId())
68 batchFlows.add(addFlows);
71 return new AddFlowsBatchInputBuilder()
72 .setBarrierAfter(planStep.isBarrierAfter())
74 .setBatchAddFlows(batchFlows)
79 * Adapt flat batch remove flow.
80 * @param planStep batch step containing changes of the same type
81 * @param node pointer for RPC routing
82 * @return input suitable for {@link org.opendaylight.yang.gen.v1.urn
83 * .opendaylight.flows.service.rev160314.SalFlowsBatchService#removeFlowsBatch(RemoveFlowsBatchInput)}
85 public static RemoveFlowsBatchInput adaptFlatBatchRemoveFlow(final BatchPlanStep planStep, final NodeRef node) {
86 final List<BatchRemoveFlows> batchFlows = new ArrayList<>();
87 for (FlatBatchRemoveFlow batchRemoveFlow : planStep.<FlatBatchRemoveFlow>getTaskBag()) {
88 final BatchRemoveFlows removeFlows = new BatchRemoveFlowsBuilder((Flow) batchRemoveFlow)
89 .setFlowId(batchRemoveFlow.getFlowId())
91 batchFlows.add(removeFlows);
94 return new RemoveFlowsBatchInputBuilder()
95 .setBarrierAfter(planStep.isBarrierAfter())
97 .setBatchRemoveFlows(batchFlows)
102 * Adapt flat batch update flow.
103 * @param planStep batch step containing changes of the same type
104 * @param node pointer for RPC routing
105 * @return input suitable for {@link org.opendaylight.yang.gen.v1.urn
106 * .opendaylight.flows.service.rev160314.SalFlowsBatchService#updateFlowsBatch(UpdateFlowsBatchInput)}
108 public static UpdateFlowsBatchInput adaptFlatBatchUpdateFlow(final BatchPlanStep planStep, final NodeRef node) {
109 final List<BatchUpdateFlows> batchFlows = new ArrayList<>();
110 for (FlatBatchUpdateFlow batchUpdateFlow : planStep.<FlatBatchUpdateFlow>getTaskBag()) {
111 final BatchUpdateFlows updateFlows = new BatchUpdateFlowsBuilder(batchUpdateFlow)
113 batchFlows.add(updateFlows);
116 return new UpdateFlowsBatchInputBuilder()
117 .setBarrierAfter(planStep.isBarrierAfter())
119 .setBatchUpdateFlows(batchFlows)
124 * Convert batch result.
125 * @param stepOffset offset of current batch plan step
126 * @return converted {@link ProcessFlatBatchOutput} RPC result
129 static <T extends BatchFlowOutputListGrouping> Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>
130 convertBatchFlowResult(final int stepOffset) {
131 return new Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>() {
133 public RpcResult<ProcessFlatBatchOutput> apply(final RpcResult<T> input) {
134 List<BatchFailure> batchFailures = wrapBatchFlowFailuresForFlat(input, stepOffset);
135 ProcessFlatBatchOutputBuilder outputBuilder =
136 new ProcessFlatBatchOutputBuilder().setBatchFailure(batchFailures);
137 return RpcResultBuilder.<ProcessFlatBatchOutput>status(input.isSuccessful())
138 .withRpcErrors(input.getErrors())
139 .withResult(outputBuilder.build())
145 private static <T extends BatchFlowOutputListGrouping> List<BatchFailure> wrapBatchFlowFailuresForFlat(
146 final RpcResult<T> input, final int stepOffset) {
147 final List<BatchFailure> batchFailures = new ArrayList<>();
148 if (input.getResult().getBatchFailedFlowsOutput() != null) {
149 for (BatchFailedFlowsOutput stepOutput : input.getResult().getBatchFailedFlowsOutput()) {
150 final BatchFailure batchFailure = new BatchFailureBuilder()
151 .setBatchOrder(stepOffset + stepOutput.getBatchOrder())
152 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
153 .setFlowId(stepOutput.getFlowId())
156 batchFailures.add(batchFailure);
159 return batchFailures;
163 * Shortcut for {@link #convertBatchFlowResult(int)} with conversion {@link ListenableFuture}.
165 * @param <T> exact type of batch flow output
166 * @param resultUpdateFlowFuture batch flow rpc-result (add/remove/update)
167 * @param currentOffset offset of current batch plan step with respect to entire chain of steps
168 * @return ListenableFuture with converted result {@link ProcessFlatBatchOutput}
170 public static <T extends BatchFlowOutputListGrouping> ListenableFuture<RpcResult<ProcessFlatBatchOutput>>
171 convertFlowBatchFutureForChain(final Future<RpcResult<T>> resultUpdateFlowFuture,
172 final int currentOffset) {
173 return Futures.transform(JdkFutureAdapters.listenInPoolThread(resultUpdateFlowFuture),
174 FlatBatchFlowAdapters.convertBatchFlowResult(currentOffset),
175 MoreExecutors.directExecutor());