4b8820bd9b430317e7dd4a6b0ddd6d65d091e0ea
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / connection / OutboundQueueEntry.java
1 /*
2  * Copyright (c) 2015 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.core.connection;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.FutureCallback;
12 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 final class OutboundQueueEntry {
20     private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueEntry.class);
21     private FutureCallback<OfHeader> callback;
22     private OfHeader message;
23     private boolean completed;
24     private boolean barrier;
25     private volatile boolean committed;
26
27     void commit(final OfHeader message, final FutureCallback<OfHeader> callback) {
28         this.message = message;
29         this.callback = callback;
30         this.barrier = message instanceof BarrierInput;
31
32         // Volatile write, needs to be last
33         committed = true;
34     }
35
36     void reset() {
37         barrier = false;
38         callback = null;
39         completed = false;
40         message = null;
41
42         // Volatile write, needs to be last
43         committed = false;
44     }
45
46     boolean isBarrier() {
47         return barrier;
48     }
49
50     boolean isCommitted() {
51         return committed;
52     }
53
54     boolean isCompleted() {
55         return completed;
56     }
57
58     OfHeader takeMessage() {
59         final OfHeader ret = message;
60         message = null;
61         return ret;
62     }
63
64     boolean complete(final OfHeader response) {
65         Preconditions.checkState(!completed, "Attempted to complete a completed message with response %s", response);
66
67         // Multipart requests are special, we have to look at them to see
68         // if there is something outstanding and adjust ourselves accordingly
69         final boolean reallyComplete;
70         if (response instanceof MultipartReplyMessage) {
71             reallyComplete = !((MultipartReplyMessage) response).getFlags().isOFPMPFREQMORE();
72             LOG.debug("Multipart reply {}", response);
73         } else {
74             reallyComplete = true;
75         }
76
77         completed = reallyComplete;
78         if (callback != null) {
79             callback.onSuccess(response);
80             if (reallyComplete) {
81                 // We will not need the callback anymore, make sure it can be GC'd
82                 callback = null;
83             }
84         }
85         LOG.debug("Entry {} completed {} with response {}", this, completed, response);
86         return reallyComplete;
87     }
88
89     void fail(final OutboundQueueException cause) {
90         if (!completed) {
91             completed = true;
92             if (callback != null) {
93                 callback.onFailure(cause);
94                 callback = null;
95             }
96         } else {
97             LOG.warn("Ignoring failure {} for completed message", cause);
98         }
99     }
100 }