2 * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.openflowjava.protocol.impl.core.connection;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import com.google.common.util.concurrent.SettableFuture;
15 import io.netty.util.concurrent.Future;
16 import io.netty.util.concurrent.GenericFutureListener;
17 import org.opendaylight.yangtools.yang.common.ErrorTag;
18 import org.opendaylight.yangtools.yang.common.ErrorType;
19 import org.opendaylight.yangtools.yang.common.RpcError;
20 import org.opendaylight.yangtools.yang.common.RpcResult;
21 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * This class holds all the context we need for sending a single message down the tube.
27 * A MessageHolder (used in queue) and the actual listener. It is not a thing of beauty,
28 * but it keeps us from allocating unnecessary objects in the egress path.
30 abstract class AbstractRpcListener<T> implements GenericFutureListener<Future<Void>>,
31 ChannelOutboundQueue.MessageHolder<Object> {
32 private static final Logger LOG = LoggerFactory.getLogger(AbstractRpcListener.class);
33 private static final String APPLICATION_TAG = "OPENFLOW_LIBRARY";
34 private static final ErrorTag TAG = new ErrorTag("OPENFLOW");
35 private final SettableFuture<RpcResult<T>> result = SettableFuture.create();
36 private final String failureInfo;
37 private Object message;
40 * Create RcpError object.
42 * @param info error info
43 * @param message error message
44 * @param cause - details of reason
47 static RpcError buildRpcError(final String info, final String message, final Throwable cause) {
48 return RpcResultBuilder.newError(ErrorType.RPC, TAG, message, APPLICATION_TAG, info, cause);
51 AbstractRpcListener(final Object message, final String failureInfo) {
52 this.failureInfo = requireNonNull(failureInfo);
53 this.message = requireNonNull(message);
56 public final ListenableFuture<RpcResult<T>> getResult() {
61 public final void operationComplete(final Future<Void> future) {
62 if (!future.isSuccess()) {
63 LOG.debug("operation failed");
64 failedRpc(future.cause());
66 LOG.debug("operation complete");
67 operationSuccessful();
72 public final Object takeMessage() {
73 final Object ret = message;
74 checkState(ret != null, "Message has already been taken");
80 public final GenericFutureListener<Future<Void>> takeListener() {
84 protected abstract void operationSuccessful();
86 protected final void failedRpc(final Throwable cause) {
87 final RpcError rpcError = buildRpcError(failureInfo, "check switch connection", cause);
88 result.set(RpcResultBuilder.<T>failed().withRpcError(rpcError).build());
91 protected final void successfulRpc(final T value) {
92 result.set(RpcResultBuilder.success(value).build());