BUG-9141: Fix Stateful07TopologySessionListener failing test
[bgpcep.git] / pcep / topology-provider / src / main / java / org / opendaylight / bgpcep / pcep / topology / provider / PCEPRequest.java
old mode 100644 (file)
new mode 100755 (executable)
index e6849f4..4f8e15d
@@ -7,30 +7,99 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
+import com.google.common.base.Stopwatch;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
-
+import java.util.Timer;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.concurrent.GuardedBy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.lsp.metadata.Metadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 final class PCEPRequest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PCEPRequest.class);
+
+    private static final long MINIMUM_ELAPSED_TIME = 1;
+
+    enum State {
+        UNSENT,
+        UNACKED,
+        DONE,
+    }
+
     private final SettableFuture<OperationResult> future;
     private final Metadata metadata;
+    private volatile State state;
+    @GuardedBy("this")
+    private final Stopwatch stopwatch;
+    private final Timer timer;
 
     PCEPRequest(final Metadata metadata) {
         this.future = SettableFuture.create();
         this.metadata = metadata;
+        this.state = State.UNSENT;
+        this.stopwatch = Stopwatch.createStarted();
+        this.timer = new Timer();
     }
 
     protected ListenableFuture<OperationResult> getFuture() {
-        return future;
+        return this.future;
     }
 
-    public void setResult(final OperationResult result) {
-        future.set(result);
+    public Metadata getMetadata() {
+        return this.metadata;
     }
 
-    public Metadata getMetadata() {
-        return metadata;
+    public State getState() {
+        return this.state;
+    }
+
+    Timer getTimer() {
+        return this.timer;
+    }
+
+    synchronized void done(final OperationResult result) {
+        if (this.state != State.DONE) {
+            LOG.debug("Request went from {} to {}", this.state, State.DONE);
+            this.state = State.DONE;
+            this.timer.cancel();
+            this.future.set(result);
+        }
+    }
+
+    synchronized void done() {
+        OperationResult result;
+        switch (this.state) {
+        case UNSENT:
+            result = OperationResults.UNSENT;
+            break;
+        case UNACKED:
+            result = OperationResults.NOACK;
+            break;
+        case DONE:
+            return;
+        default:
+            return;
+        }
+        done(result);
+    }
+
+    synchronized void sent() {
+        if (this.state == State.UNSENT) {
+            LOG.debug("Request went from {} to {}", this.state, State.UNACKED);
+            this.state = State.UNACKED;
+        }
+    }
+
+    synchronized long getElapsedMillis() {
+        final long elapsedNanos = this.stopwatch.elapsed().toNanos();
+        final long elapsedMillis = TimeUnit.NANOSECONDS.toMillis(elapsedNanos);
+        if (elapsedMillis == 0 && elapsedNanos > 0) {
+            return  MINIMUM_ELAPSED_TIME;
+        }
+        return elapsedMillis;
     }
-}
\ No newline at end of file
+}