1ebc300c75ac80c05a5ae6e8dc8b88366468f1c6
[controller.git] / opendaylight / forwardingrulesmanager / implementation / src / main / java / org / opendaylight / controller / forwardingrulesmanager / internal / FlowEntryDistributionOrderFutureTask.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
9 /**
10  * Class which will monitor the completion of a FlowEntryDistributionOrder it
11  * implements a Future interface so it can be inspected by who is waiting for
12  * it.
13  */
14 package org.opendaylight.controller.forwardingrulesmanager.internal;
15
16 import java.util.concurrent.CountDownLatch;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
19 import java.util.concurrent.TimeUnit;
20 import java.util.concurrent.TimeoutException;
21
22 import org.opendaylight.controller.forwardingrulesmanager.implementation.data.FlowEntryDistributionOrder;
23 import org.opendaylight.controller.sal.utils.Status;
24 import org.opendaylight.controller.sal.utils.StatusCode;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * Class which will monitor the completion of a FlowEntryDistributionOrder it
30  * implements a Future interface so it can be inspected by who is waiting for
31  * it.
32  */
33 final class FlowEntryDistributionOrderFutureTask implements Future<Status> {
34     private final FlowEntryDistributionOrder order;
35     private boolean amICancelled;
36     private CountDownLatch waitingLatch;
37     private Status retStatus;
38     private static final Logger logger = LoggerFactory.getLogger(FlowEntryDistributionOrderFutureTask.class);
39
40     /**
41      * @param order
42      *            for which we are monitoring the execution
43      */
44     FlowEntryDistributionOrderFutureTask(FlowEntryDistributionOrder order) {
45         // Order being monitored
46         this.order = order;
47         this.amICancelled = false;
48         // We need to wait for one completion to happen
49         this.waitingLatch = new CountDownLatch(1);
50         // No return status yet!
51         this.retStatus = new Status(StatusCode.UNDEFINED);
52     }
53
54     @Override
55     public boolean cancel(boolean mayInterruptIfRunning) {
56         return false;
57     }
58
59     @Override
60     public Status get() throws InterruptedException, ExecutionException {
61         logger.trace("Getting status for order {}", this.order);
62         // If i'm done lets return the status as many times as caller wants
63         if (this.waitingLatch.getCount() == 0L) {
64             logger.trace("get returns the status without waiting");
65             return retStatus;
66         }
67
68         logger.trace("Start waiting for status to come back");
69         // Wait till someone signal that we are done
70         this.waitingLatch.await();
71
72         logger.trace("Waiting for the status is over, returning it");
73         // Return the known status
74         return retStatus;
75     }
76
77     @Override
78     public Status get(long timeout, TimeUnit unit) throws InterruptedException,
79             ExecutionException, TimeoutException {
80         logger.trace("Getting status for order {}", this.order);
81         // If i'm done lets return the status as many times as caller wants
82         if (this.waitingLatch.getCount() == 0L) {
83             logger.trace("get returns the status without waiting");
84             return retStatus;
85         }
86
87         logger.trace("Start waiting for status to come back");
88         // Wait till someone signal that we are done
89         this.waitingLatch.await(timeout, unit);
90
91         logger.trace("Waiting for the status is over, returning it");
92         // Return the known status, could also be null if didn't return
93         return retStatus;
94     }
95
96     @Override
97     public boolean isCancelled() {
98         return this.amICancelled;
99     }
100
101     @Override
102     public boolean isDone() {
103         return (this.waitingLatch.getCount() == 0L);
104     }
105
106     /**
107      * Used by the thread that gets back the status for the order so can unblock
108      * an eventual caller waiting on the result to comes back
109      *
110      * @param order
111      * @param retStatus
112      */
113     void gotStatus(FlowEntryDistributionOrder order, Status retStatus) {
114         logger.trace("Got status for order:{} \n Status:{}", order, retStatus);
115         if (!order.equals(this.order)) {
116             logger.error("Didn't get a result for an order we did issue order expected:{}, order received:{}",
117                     this.order, order);
118             // Weird we got a call for an order we didn't make
119             return;
120         }
121         this.retStatus = retStatus;
122         // Now we are not waiting any longer
123         this.waitingLatch.countDown();
124         logger.trace("Unlocked the Future");
125     }
126 }