943d61a556abe0daafcdba67680c682e1f88fbb4
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / services / batch / FlatBatchFlowAdapters.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.openflowplugin.impl.services.batch;
10
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.ListenableFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import java.util.ArrayList;
17 import java.util.List;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
20 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;
21 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;
22 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;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInputBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.BatchFlowOutputListGrouping;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlows;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlowsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlows;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlowsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlows;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlowsBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
42 import org.opendaylight.yangtools.yang.common.RpcResult;
43 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
44
45 /**
46  * Transform between FlatBatch API and flow batch API.
47  */
48 public final class FlatBatchFlowAdapters {
49
50     private FlatBatchFlowAdapters() {
51     }
52
53     /**
54      * Adapt flat batch add flow.
55      * @param planStep batch step containing changes of the same type
56      * @param node     pointer for RPC routing
57      * @return input suitable for {@link org.opendaylight.yang.gen.v1.urn
58      * .opendaylight.flows.service.rev160314.SalFlowsBatchService#addFlowsBatch(AddFlowsBatchInput)}
59      */
60     public static AddFlowsBatchInput adaptFlatBatchAddFlow(final BatchPlanStep planStep, final NodeRef node) {
61         final List<BatchAddFlows> batchFlows = new ArrayList<>();
62         for (FlatBatchAddFlow batchAddFlows : planStep.<FlatBatchAddFlow>getTaskBag()) {
63             final BatchAddFlows addFlows = new BatchAddFlowsBuilder((Flow) batchAddFlows)
64                     .setFlowId(batchAddFlows.getFlowId())
65                     .build();
66             batchFlows.add(addFlows);
67         }
68
69         return new AddFlowsBatchInputBuilder()
70                 .setBarrierAfter(planStep.isBarrierAfter())
71                 .setNode(node)
72                 .setBatchAddFlows(batchFlows)
73                 .build();
74     }
75
76     /**
77      * Adapt flat batch remove flow.
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
81      * .opendaylight.flows.service.rev160314.SalFlowsBatchService#removeFlowsBatch(RemoveFlowsBatchInput)}
82      */
83     public static RemoveFlowsBatchInput adaptFlatBatchRemoveFlow(final BatchPlanStep planStep, final NodeRef node) {
84         final List<BatchRemoveFlows> batchFlows = new ArrayList<>();
85         for (FlatBatchRemoveFlow batchRemoveFlow : planStep.<FlatBatchRemoveFlow>getTaskBag()) {
86             final BatchRemoveFlows removeFlows = new BatchRemoveFlowsBuilder((Flow) batchRemoveFlow)
87                     .setFlowId(batchRemoveFlow.getFlowId())
88                     .build();
89             batchFlows.add(removeFlows);
90         }
91
92         return new RemoveFlowsBatchInputBuilder()
93                 .setBarrierAfter(planStep.isBarrierAfter())
94                 .setNode(node)
95                 .setBatchRemoveFlows(batchFlows)
96                 .build();
97     }
98
99     /**
100      * Adapt flat batch update flow.
101      * @param planStep batch step containing changes of the same type
102      * @param node     pointer for RPC routing
103      * @return input suitable for {@link org.opendaylight.yang.gen.v1.urn
104      * .opendaylight.flows.service.rev160314.SalFlowsBatchService#updateFlowsBatch(UpdateFlowsBatchInput)}
105      */
106     public static UpdateFlowsBatchInput adaptFlatBatchUpdateFlow(final BatchPlanStep planStep, final NodeRef node) {
107         final List<BatchUpdateFlows> batchFlows = new ArrayList<>();
108         for (FlatBatchUpdateFlow batchUpdateFlow : planStep.<FlatBatchUpdateFlow>getTaskBag()) {
109             final BatchUpdateFlows updateFlows = new BatchUpdateFlowsBuilder(batchUpdateFlow)
110                     .build();
111             batchFlows.add(updateFlows);
112         }
113
114         return new UpdateFlowsBatchInputBuilder()
115                 .setBarrierAfter(planStep.isBarrierAfter())
116                 .setNode(node)
117                 .setBatchUpdateFlows(batchFlows)
118                 .build();
119     }
120
121     /**
122      * Convert batch result.
123      * @param stepOffset offset of current batch plan step
124      * @return converted {@link ProcessFlatBatchOutput} RPC result
125      */
126     @VisibleForTesting
127     static <T extends BatchFlowOutputListGrouping> Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>
128         convertBatchFlowResult(final int stepOffset) {
129         return input -> {
130             List<BatchFailure> batchFailures = wrapBatchFlowFailuresForFlat(input, stepOffset);
131             ProcessFlatBatchOutputBuilder outputBuilder =
132                     new ProcessFlatBatchOutputBuilder().setBatchFailure(batchFailures);
133             return RpcResultBuilder.<ProcessFlatBatchOutput>status(input.isSuccessful())
134                                    .withRpcErrors(input.getErrors())
135                                    .withResult(outputBuilder.build())
136                                    .build();
137         };
138     }
139
140     private static <T extends BatchFlowOutputListGrouping> List<BatchFailure> wrapBatchFlowFailuresForFlat(
141             final RpcResult<T> input, final int stepOffset) {
142         final List<BatchFailure> batchFailures = new ArrayList<>();
143         if (input.getResult().getBatchFailedFlowsOutput() != null) {
144             for (BatchFailedFlowsOutput stepOutput : input.getResult().getBatchFailedFlowsOutput()) {
145                 final BatchFailure batchFailure = new BatchFailureBuilder()
146                         .setBatchOrder(stepOffset + stepOutput.getBatchOrder().toJava())
147                         .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
148                                 .setFlowId(stepOutput.getFlowId())
149                                 .build())
150                         .build();
151                 batchFailures.add(batchFailure);
152             }
153         }
154         return batchFailures;
155     }
156
157     /**
158      * Shortcut for {@link #convertBatchFlowResult(int)} with conversion {@link ListenableFuture}.
159      *
160      * @param <T>                    exact type of batch flow output
161      * @param resultUpdateFlowFuture batch flow rpc-result (add/remove/update)
162      * @param currentOffset          offset of current batch plan step with respect to entire chain of steps
163      * @return ListenableFuture with converted result {@link ProcessFlatBatchOutput}
164      */
165     public static <T extends BatchFlowOutputListGrouping> ListenableFuture<RpcResult<ProcessFlatBatchOutput>>
166         convertFlowBatchFutureForChain(final ListenableFuture<RpcResult<T>> resultUpdateFlowFuture,
167                                    final int currentOffset) {
168         return Futures.transform(resultUpdateFlowFuture, FlatBatchFlowAdapters.convertBatchFlowResult(currentOffset),
169                 MoreExecutors.directExecutor());
170     }
171 }