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 io.netty.util.concurrent.Future;
11 import io.netty.util.concurrent.GenericFutureListener;
13 import java.util.Collections;
15 import org.opendaylight.controller.sal.common.util.RpcErrors;
16 import org.opendaylight.controller.sal.common.util.Rpcs;
17 import org.opendaylight.yangtools.yang.common.RpcError;
18 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
19 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
20 import org.opendaylight.yangtools.yang.common.RpcResult;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
24 import com.google.common.base.Preconditions;
25 import com.google.common.util.concurrent.ListenableFuture;
26 import com.google.common.util.concurrent.SettableFuture;
29 * This class holds all the context we need for sending a single message down the tube.
30 * A MessageHolder (used in queue) and the actual listener. It is not a thing of beauty,
31 * but it keeps us from allocating unnecessary objects in the egress path.
33 abstract class AbstractRpcListener<T> implements GenericFutureListener<Future<Void>>, ChannelOutboundQueue.MessageHolder<Object> {
34 private static final Logger LOG = LoggerFactory.getLogger(AbstractRpcListener.class);
35 private static final String APPLICATION_TAG = "OPENFLOW_LIBRARY";
36 private static final String TAG = "OPENFLOW";
37 private final SettableFuture<RpcResult<T>> result = SettableFuture.create();
38 private final String failureInfo;
39 private Object message;
42 * Create RcpError object
44 * @param severity - error severity
46 * @param cause - details of reason
49 static RpcError buildRpcError(final String info, final ErrorSeverity severity, final String message,
50 final Throwable cause) {
51 RpcError error = RpcErrors.getRpcError(APPLICATION_TAG, TAG, info, severity, message,
52 ErrorType.RPC, cause);
56 AbstractRpcListener(final Object message, final String failureInfo) {
57 this.failureInfo = Preconditions.checkNotNull(failureInfo);
58 this.message = Preconditions.checkNotNull(message);
61 public final ListenableFuture<RpcResult<T>> getResult() {
66 public final void operationComplete(final Future<Void> future) {
67 if (!future.isSuccess()) {
68 LOG.debug("operation failed");
69 failedRpc(future.cause());
71 LOG.debug("operation complete");
72 operationSuccessful();
77 public final Object takeMessage() {
78 final Object ret = message;
79 Preconditions.checkState(ret != null, "Message has already been taken");
85 public final GenericFutureListener<Future<Void>> takeListener() {
89 protected abstract void operationSuccessful();
91 protected final void failedRpc(final Throwable cause) {
92 final RpcError rpcError = buildRpcError(
93 failureInfo, ErrorSeverity.ERROR, "check switch connection", cause);
94 result.set(Rpcs.getRpcResult(
97 Collections.singletonList(rpcError)));
100 protected final void successfulRpc(final T value) {
101 result.set(Rpcs.getRpcResult(
104 Collections.<RpcError>emptyList()));