7949cc0094d1c5142bb1287213a8c9df54b520b6
[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.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.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;
46
47 /**
48  * transform between FlatBatch API and flow batch API
49  */
50 public class FlatBatchFlowAdapters {
51
52     private FlatBatchFlowAdapters() {
53         throw new IllegalStateException("This class should not be instantiated.");
54     }
55
56     /**
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.flows.service.rev160314.SalFlowsBatchService#addFlowsBatch(AddFlowsBatchInput)}
60      */
61     public static AddFlowsBatchInput adaptFlatBatchAddFlow(final BatchPlanStep planStep, final NodeRef node) {
62         final List<BatchAddFlows> batchFlows = new ArrayList<>();
63         for (FlatBatchAddFlow batchAddFlows : planStep.<FlatBatchAddFlow>getTaskBag()) {
64             final BatchAddFlows addFlows = new BatchAddFlowsBuilder((Flow) batchAddFlows)
65                     .setFlowId(batchAddFlows.getFlowId())
66                     .build();
67             batchFlows.add(addFlows);
68         }
69
70         return new AddFlowsBatchInputBuilder()
71                 .setBarrierAfter(planStep.isBarrierAfter())
72                 .setNode(node)
73                 .setBatchAddFlows(batchFlows)
74                 .build();
75     }
76
77     /**
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.flows.service.rev160314.SalFlowsBatchService#removeFlowsBatch(RemoveFlowsBatchInput)}
81      */
82     public static RemoveFlowsBatchInput adaptFlatBatchRemoveFlow(final BatchPlanStep planStep, final NodeRef node) {
83         final List<BatchRemoveFlows> batchFlows = new ArrayList<>();
84         for (FlatBatchRemoveFlow batchRemoveFlow : planStep.<FlatBatchRemoveFlow>getTaskBag()) {
85             final BatchRemoveFlows removeFlows = new BatchRemoveFlowsBuilder((Flow) batchRemoveFlow)
86                     .setFlowId(batchRemoveFlow.getFlowId())
87                     .build();
88             batchFlows.add(removeFlows);
89         }
90
91         return new RemoveFlowsBatchInputBuilder()
92                 .setBarrierAfter(planStep.isBarrierAfter())
93                 .setNode(node)
94                 .setBatchRemoveFlows(batchFlows)
95                 .build();
96     }
97
98     /**
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.flows.service.rev160314.SalFlowsBatchService#updateFlowsBatch(UpdateFlowsBatchInput)}
102      */
103     public static UpdateFlowsBatchInput adaptFlatBatchUpdateFlow(final BatchPlanStep planStep, final NodeRef node) {
104         final List<BatchUpdateFlows> batchFlows = new ArrayList<>();
105         for (FlatBatchUpdateFlow batchUpdateFlow : planStep.<FlatBatchUpdateFlow>getTaskBag()) {
106             final BatchUpdateFlows updateFlows = new BatchUpdateFlowsBuilder(batchUpdateFlow)
107                     .build();
108             batchFlows.add(updateFlows);
109         }
110
111         return new UpdateFlowsBatchInputBuilder()
112                 .setBarrierAfter(planStep.isBarrierAfter())
113                 .setNode(node)
114                 .setBatchUpdateFlows(batchFlows)
115                 .build();
116     }
117
118     /**
119      * @param stepOffset offset of current batch plan step
120      * @return converted {@link ProcessFlatBatchOutput} RPC result
121      */
122     @VisibleForTesting
123     static <T extends BatchFlowOutputListGrouping> Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>
124     convertBatchFlowResult(final int stepOffset) {
125         return new Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>() {
126             @Nullable
127             @Override
128             public RpcResult<ProcessFlatBatchOutput> apply(@Nullable final RpcResult<T> input) {
129                 List<BatchFailure> batchFailures = wrapBatchFlowFailuresForFlat(input, stepOffset);
130                 ProcessFlatBatchOutputBuilder outputBuilder = new ProcessFlatBatchOutputBuilder().setBatchFailure(batchFailures);
131                 return RpcResultBuilder.<ProcessFlatBatchOutput>status(input.isSuccessful())
132                                        .withRpcErrors(input.getErrors())
133                                        .withResult(outputBuilder.build())
134                                        .build();
135             }
136         };
137     }
138
139     private static <T extends BatchFlowOutputListGrouping> List<BatchFailure> wrapBatchFlowFailuresForFlat(
140             final RpcResult<T> input, final int stepOffset) {
141         final List<BatchFailure> batchFailures = new ArrayList<>();
142         if (input.getResult().getBatchFailedFlowsOutput() != null) {
143             for (BatchFailedFlowsOutput stepOutput : input.getResult().getBatchFailedFlowsOutput()) {
144                 final BatchFailure batchFailure = new BatchFailureBuilder()
145                         .setBatchOrder(stepOffset + stepOutput.getBatchOrder())
146                         .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
147                                 .setFlowId(stepOutput.getFlowId())
148                                 .build())
149                         .build();
150                 batchFailures.add(batchFailure);
151             }
152         }
153         return batchFailures;
154     }
155
156     /**
157      * shortcut for {@link #convertBatchFlowResult(int)} with conversion {@link ListenableFuture}
158      *
159      * @param <T>                    exact type of batch flow output
160      * @param resultUpdateFlowFuture batch flow rpc-result (add/remove/update)
161      * @param currentOffset          offset of current batch plan step with respect to entire chain of steps
162      * @return ListenableFuture with converted result {@link ProcessFlatBatchOutput}
163      */
164     public static <T extends BatchFlowOutputListGrouping> ListenableFuture<RpcResult<ProcessFlatBatchOutput>>
165     convertFlowBatchFutureForChain(final Future<RpcResult<T>> resultUpdateFlowFuture,
166                                    final int currentOffset) {
167         return Futures.transform(JdkFutureAdapters.listenInPoolThread(resultUpdateFlowFuture),
168                 FlatBatchFlowAdapters.<T>convertBatchFlowResult(currentOffset));
169     }
170 }