4f8e15d8d56a543555497185269dd5f82cb5f9cd
[bgpcep.git] / pcep / topology-provider / src / main / java / org / opendaylight / bgpcep / pcep / topology / provider / PCEPRequest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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.bgpcep.pcep.topology.provider;
9
10 import com.google.common.base.Stopwatch;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import com.google.common.util.concurrent.SettableFuture;
13 import java.util.Timer;
14 import java.util.concurrent.TimeUnit;
15 import javax.annotation.concurrent.GuardedBy;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.lsp.metadata.Metadata;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 final class PCEPRequest {
22
23     private static final Logger LOG = LoggerFactory.getLogger(PCEPRequest.class);
24
25     private static final long MINIMUM_ELAPSED_TIME = 1;
26
27     enum State {
28         UNSENT,
29         UNACKED,
30         DONE,
31     }
32
33     private final SettableFuture<OperationResult> future;
34     private final Metadata metadata;
35     private volatile State state;
36     @GuardedBy("this")
37     private final Stopwatch stopwatch;
38     private final Timer timer;
39
40     PCEPRequest(final Metadata metadata) {
41         this.future = SettableFuture.create();
42         this.metadata = metadata;
43         this.state = State.UNSENT;
44         this.stopwatch = Stopwatch.createStarted();
45         this.timer = new Timer();
46     }
47
48     protected ListenableFuture<OperationResult> getFuture() {
49         return this.future;
50     }
51
52     public Metadata getMetadata() {
53         return this.metadata;
54     }
55
56     public State getState() {
57         return this.state;
58     }
59
60     Timer getTimer() {
61         return this.timer;
62     }
63
64     synchronized void done(final OperationResult result) {
65         if (this.state != State.DONE) {
66             LOG.debug("Request went from {} to {}", this.state, State.DONE);
67             this.state = State.DONE;
68             this.timer.cancel();
69             this.future.set(result);
70         }
71     }
72
73     synchronized void done() {
74         OperationResult result;
75         switch (this.state) {
76         case UNSENT:
77             result = OperationResults.UNSENT;
78             break;
79         case UNACKED:
80             result = OperationResults.NOACK;
81             break;
82         case DONE:
83             return;
84         default:
85             return;
86         }
87         done(result);
88     }
89
90     synchronized void sent() {
91         if (this.state == State.UNSENT) {
92             LOG.debug("Request went from {} to {}", this.state, State.UNACKED);
93             this.state = State.UNACKED;
94         }
95     }
96
97     synchronized long getElapsedMillis() {
98         final long elapsedNanos = this.stopwatch.elapsed().toNanos();
99         final long elapsedMillis = TimeUnit.NANOSECONDS.toMillis(elapsedNanos);
100         if (elapsedMillis == 0 && elapsedNanos > 0) {
101             return  MINIMUM_ELAPSED_TIME;
102         }
103         return elapsedMillis;
104     }
105 }