Merge "Fixed the log level."
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / services / batch / FlatBatchMeterAdapters.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.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.meter._case.FlatBatchAddMeter;
24 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;
25 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;
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.FlatBatchFailureMeterIdCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchInputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.BatchMeterOutputListGrouping;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchInputBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchInputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.add.meters.batch.input.BatchAddMeters;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.add.meters.batch.input.BatchAddMetersBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.output.list.grouping.BatchFailedMetersOutput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.remove.meters.batch.input.BatchRemoveMeters;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.remove.meters.batch.input.BatchRemoveMetersBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.update.meters.batch.input.BatchUpdateMeters;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.update.meters.batch.input.BatchUpdateMetersBuilder;
44 import org.opendaylight.yangtools.yang.common.RpcResult;
45 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
46
47 /**
48  * transform between FlatBatch API and meter batch API
49  */
50 public class FlatBatchMeterAdapters {
51
52     private FlatBatchMeterAdapters() {
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.meters.service.rev160316.SalMetersBatchService#addMetersBatch(AddMetersBatchInput)}
60      */
61     public static AddMetersBatchInput adaptFlatBatchAddMeter(final BatchPlanStep planStep, final NodeRef node) {
62         final List<BatchAddMeters> batchMeters = new ArrayList<>();
63         for (FlatBatchAddMeter batchAddMeter : planStep.<FlatBatchAddMeter>getTaskBag()) {
64             final BatchAddMeters addMeters = new BatchAddMetersBuilder(batchAddMeter)
65                     .setMeterId(batchAddMeter.getMeterId())
66                     .build();
67             batchMeters.add(addMeters);
68         }
69
70         return new AddMetersBatchInputBuilder()
71                 .setBarrierAfter(planStep.isBarrierAfter())
72                 .setNode(node)
73                 .setBatchAddMeters(batchMeters)
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.meters.service.rev160316.SalMetersBatchService#removeMetersBatch(RemoveMetersBatchInput)}
81      */
82     public static RemoveMetersBatchInput adaptFlatBatchRemoveMeter(final BatchPlanStep planStep, final NodeRef node) {
83         final List<BatchRemoveMeters> batchMeters = new ArrayList<>();
84         for (FlatBatchRemoveMeter batchRemoveMeter : planStep.<FlatBatchRemoveMeter>getTaskBag()) {
85             final BatchRemoveMeters removeMeters = new BatchRemoveMetersBuilder(batchRemoveMeter)
86                     .setMeterId(batchRemoveMeter.getMeterId())
87                     .build();
88             batchMeters.add(removeMeters);
89         }
90
91         return new RemoveMetersBatchInputBuilder()
92                 .setBarrierAfter(planStep.isBarrierAfter())
93                 .setNode(node)
94                 .setBatchRemoveMeters(batchMeters)
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.meters.service.rev160316.SalMetersBatchService#updateMetersBatch(UpdateMetersBatchInput)}
102      */
103     public static UpdateMetersBatchInput adaptFlatBatchUpdateMeter(final BatchPlanStep planStep, final NodeRef node) {
104         final List<BatchUpdateMeters> batchMeters = new ArrayList<>();
105         for (FlatBatchUpdateMeter batchUpdateMeter : planStep.<FlatBatchUpdateMeter>getTaskBag()) {
106             final BatchUpdateMeters updateMeters = new BatchUpdateMetersBuilder(batchUpdateMeter)
107                     .build();
108             batchMeters.add(updateMeters);
109         }
110
111         return new UpdateMetersBatchInputBuilder()
112                 .setBarrierAfter(planStep.isBarrierAfter())
113                 .setNode(node)
114                 .setBatchUpdateMeters(batchMeters)
115                 .build();
116     }
117
118     /**
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
122      */
123     @VisibleForTesting
124     static <T extends BatchMeterOutputListGrouping> Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>
125     createBatchMeterChainingFunction(final RpcResult<ProcessFlatBatchOutput> chainInput,
126                                      final int stepOffset) {
127         return new Function<RpcResult<T>, RpcResult<ProcessFlatBatchOutput>>() {
128             @Nullable
129             @Override
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 = wrapBatchMeterFailuresForFlat(input, stepOffset);
136                 // join values
137                 if (outputBuilder.getBatchFailure() == null) {
138                     outputBuilder.setBatchFailure(new ArrayList<BatchFailure>(batchFailures.size()));
139                 }
140                 outputBuilder.getBatchFailure().addAll(batchFailures);
141
142                 return output.withResult(outputBuilder.build()).build();
143             }
144         };
145     }
146
147     private static <T extends BatchMeterOutputListGrouping> List<BatchFailure> wrapBatchMeterFailuresForFlat(
148             final RpcResult<T> input, final int stepOffset) {
149         final List<BatchFailure> batchFailures = new ArrayList<>();
150         if (input.getResult().getBatchFailedMetersOutput() != null) {
151             for (BatchFailedMetersOutput stepOutput : input.getResult().getBatchFailedMetersOutput()) {
152                 final BatchFailure batchFailure = new BatchFailureBuilder()
153                         .setBatchOrder(stepOffset + stepOutput.getBatchOrder())
154                         .setBatchItemIdChoice(new FlatBatchFailureMeterIdCaseBuilder()
155                                 .setMeterId(stepOutput.getMeterId())
156                                 .build())
157                         .build();
158                 batchFailures.add(batchFailure);
159             }
160         }
161         return batchFailures;
162     }
163
164     /**
165      * shortcut for {@link #createBatchMeterChainingFunction(RpcResult, int)} with conversion {@link ListenableFuture}
166      *
167      * @param <T>                     exact type of batch flow output
168      * @param chainInput              here all partial results are collected (values + errors)
169      * @param resultUpdateMeterFuture 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
172      */
173     public static <T extends BatchMeterOutputListGrouping> ListenableFuture<RpcResult<ProcessFlatBatchOutput>>
174     adaptMeterBatchFutureForChain(final RpcResult<ProcessFlatBatchOutput> chainInput,
175                                   final Future<RpcResult<T>> resultUpdateMeterFuture,
176                                   final int currentOffset) {
177         return Futures.transform(JdkFutureAdapters.listenInPoolThread(resultUpdateMeterFuture),
178                 FlatBatchMeterAdapters.<T>createBatchMeterChainingFunction(chainInput, currentOffset));
179     }
180 }