/* * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.openflowplugin.impl.util; import com.google.common.base.Function; import com.google.common.util.concurrent.AsyncFunction; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.JdkFutureAdapters; import com.google.common.util.concurrent.ListenableFuture; import javax.annotation.Nullable; import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; import org.opendaylight.yangtools.yang.common.RpcResult; /** * provides barrier message chaining and factory methods */ public final class BarrierUtil { private BarrierUtil() { throw new IllegalStateException("This class should not be instantiated."); } /** * chain a barrier message - regardless of previous result and use given {@link Function} to combine * original result and barrier result * * @param <T> type of input future * @param input future to chain barrier to * @param nodeRef target device * @param transactionService barrier service * @param compositeTransform * @return future holding both results (input and of the barrier) */ public static <T> ListenableFuture<RpcResult<T>> chainBarrier( final ListenableFuture<RpcResult<T>> input, final NodeRef nodeRef, final FlowCapableTransactionService transactionService, final Function<Pair<RpcResult<T>, RpcResult<Void>>, RpcResult<T>> compositeTransform) { final MutablePair<RpcResult<T>, RpcResult<Void>> resultPair = new MutablePair<>(); // store input result and append barrier final ListenableFuture<RpcResult<Void>> barrierResult = Futures.transform(input, new AsyncFunction<RpcResult<T>, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(@Nullable final RpcResult<T> interInput) throws Exception { resultPair.setLeft(interInput); final SendBarrierInput barrierInput = createSendBarrierInput(nodeRef); return JdkFutureAdapters.listenInPoolThread(transactionService.sendBarrier(barrierInput)); } }); // store barrier result and return initiated pair final ListenableFuture<Pair<RpcResult<T>, RpcResult<Void>>> compositeResult = Futures.transform( barrierResult, new Function<RpcResult<Void>, Pair<RpcResult<T>, RpcResult<Void>>>() { @Nullable @Override public Pair<RpcResult<T>, RpcResult<Void>> apply(@Nullable final RpcResult<Void> input) { resultPair.setRight(input); return resultPair; } }); // append assembling transform to barrier result return Futures.transform(compositeResult, compositeTransform); } /** * @param nodeRef rpc routing context * @return input for {@link FlowCapableTransactionService#sendBarrier(SendBarrierInput)} */ public static SendBarrierInput createSendBarrierInput(final NodeRef nodeRef) { return new SendBarrierInputBuilder() .setNode(nodeRef) .build(); } }