Decompose RPC implementation classes
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / util / BarrierUtil.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 package org.opendaylight.openflowplugin.impl.util;
9
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.base.Function;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import com.google.common.util.concurrent.MoreExecutors;
15 import org.apache.commons.lang3.tuple.MutablePair;
16 import org.apache.commons.lang3.tuple.Pair;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrier;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInputBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierOutput;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
23 import org.opendaylight.yangtools.yang.common.RpcResult;
24
25 /**
26  * Provides barrier message chaining and factory methods.
27  */
28 public final class BarrierUtil {
29     private BarrierUtil() {
30         // Hidden on purpose
31     }
32
33     /**
34      * Chain a barrier message - regardless of previous result and use given {@link Function} to combine
35      * original result and barrier result.
36      *
37      * @param <T>                type of input future
38      * @param input              future to chain barrier to
39      * @param nodeRef            target device
40      * @param sendBarrier        barrier service
41      * @param compositeTransform composite transform
42      * @return future holding both results (input and of the barrier)
43      */
44     public static <T> ListenableFuture<RpcResult<T>> chainBarrier(final ListenableFuture<RpcResult<T>> input,
45             final NodeRef nodeRef, final SendBarrier sendBarrier,
46             final Function<Pair<RpcResult<T>, RpcResult<SendBarrierOutput>>, RpcResult<T>> compositeTransform) {
47         final var resultPair = new MutablePair<RpcResult<T>, RpcResult<SendBarrierOutput>>();
48
49         // store input result and append barrier
50         final var barrierResult = Futures.transformAsync(input, interInput -> {
51             resultPair.setLeft(interInput);
52             return sendBarrier.invoke(createSendBarrierInput(nodeRef));
53         }, MoreExecutors.directExecutor());
54         // store barrier result and return initiated pair
55         final var compositeResult = Futures.transform(barrierResult, input1 -> {
56             resultPair.setRight(input1);
57             return resultPair;
58         }, MoreExecutors.directExecutor());
59         // append assembling transform to barrier result
60         return Futures.transform(compositeResult, compositeTransform, MoreExecutors.directExecutor());
61     }
62
63     /**
64      * Creates barrier input.
65      *
66      * @param nodeRef rpc routing context
67      * @return input for {@link FlowCapableTransactionService#sendBarrier(SendBarrierInput)}
68      */
69     @VisibleForTesting
70     static SendBarrierInput createSendBarrierInput(final NodeRef nodeRef) {
71         return new SendBarrierInputBuilder().setNode(nodeRef).build();
72     }
73 }