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