Maintaining code - Move buildRpcError method into AbstractRpcListener
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / connection / AbstractRpcListener.java
1 /*
2  * Copyright (c) 2014 Pantheon Technologies s.r.o. 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.openflowjava.protocol.impl.connection;
9
10 import io.netty.util.concurrent.Future;
11 import io.netty.util.concurrent.GenericFutureListener;
12
13 import java.util.Collections;
14
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;
23
24 import com.google.common.base.Preconditions;
25 import com.google.common.util.concurrent.ListenableFuture;
26 import com.google.common.util.concurrent.SettableFuture;
27
28 /**
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.
32  */
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;
40
41     /**
42      * Create RcpError object
43      * @param info
44      * @param severity - error severity
45      * @param message
46      * @param cause - details of reason
47      * @return
48      */
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);
53         return error;
54     }
55
56     AbstractRpcListener(final Object message, final String failureInfo) {
57         this.failureInfo = Preconditions.checkNotNull(failureInfo);
58         this.message = Preconditions.checkNotNull(message);
59     }
60
61     public final ListenableFuture<RpcResult<T>> getResult() {
62         return result;
63     }
64
65     @Override
66     public final void operationComplete(final Future<Void> future) {
67         if (!future.isSuccess()) {
68             LOG.debug("operation failed");
69             failedRpc(future.cause());
70         } else {
71             LOG.debug("operation complete");
72             operationSuccessful();
73         }
74     }
75
76     @Override
77     public final Object takeMessage() {
78         final Object ret = message;
79         Preconditions.checkState(ret != null, "Message has already been taken");
80         message = null;
81         return ret;
82     }
83
84     @Override
85     public final GenericFutureListener<Future<Void>> takeListener() {
86         return this;
87     }
88
89     protected abstract void operationSuccessful();
90
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(
95                 false,
96                 (T)null,
97                 Collections.singletonList(rpcError)));
98     }
99
100     protected final void successfulRpc(final T value) {
101         result.set(Rpcs.getRpcResult(
102                 true,
103                 value,
104                 Collections.<RpcError>emptyList()));
105     }
106 }