2 * Copyright (c) 2015 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 com.google.common.annotations.VisibleForTesting;
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.FutureCallback;
13 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
21 final class OutboundQueueEntry {
22 private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueEntry.class);
23 private FutureCallback<OfHeader> callback;
24 private OfHeader message;
25 private boolean completed;
26 private boolean barrier;
27 private volatile boolean committed;
28 private OutboundQueueException lastException = null;
30 void commit(final OfHeader message, final FutureCallback<OfHeader> callback) {
32 LOG.warn("Can't commit a completed message.");
33 if (callback != null) {
34 callback.onFailure(lastException);
37 this.message = message;
38 this.callback = callback;
39 this.barrier = message instanceof BarrierInput;
41 // Volatile write, needs to be last
42 this.committed = true;
52 // Volatile write, needs to be last
60 boolean isCommitted() {
64 boolean isCompleted() {
68 OfHeader takeMessage() {
69 final OfHeader ret = message;
71 checkCompletionNeed();
77 private void checkCompletionNeed() {
78 if (callback == null || (message instanceof PacketOutInput)) {
80 if (callback != null) {
81 callback.onSuccess(null);
88 boolean complete(final OfHeader response) {
89 Preconditions.checkState(!completed, "Attempted to complete a completed message with response %s", response);
91 // Multipart requests are special, we have to look at them to see
92 // if there is something outstanding and adjust ourselves accordingly
93 final boolean reallyComplete;
94 if (response instanceof MultipartReplyMessage) {
95 reallyComplete = !((MultipartReplyMessage) response).getFlags().isOFPMPFREQMORE();
96 LOG.debug("Multipart reply {}", response);
98 reallyComplete = true;
101 completed = reallyComplete;
102 if (callback != null) {
103 callback.onSuccess(response);
104 if (reallyComplete) {
105 // We will not need the callback anymore, make sure it can be GC'd
109 LOG.debug("Entry {} completed {} with response {}", this, completed, response);
110 return reallyComplete;
113 void fail(final OutboundQueueException cause) {
115 lastException = cause;
117 if (callback != null) {
118 callback.onFailure(cause);
122 LOG.warn("Ignoring failure {} for completed message", cause);
127 /** This method is only for testing to prove that after queue entry is completed there is not callback future */
128 boolean hasCallback() {
129 return (callback != null);