BUG 1839 - HTTP delete of non existing data
[controller.git] / opendaylight / md-sal / statistics-manager / src / main / java / org / opendaylight / controller / md / statistics / manager / StatisticsRequestScheduler.java
1 /*
2  * Copyright IBM Corporation, 2013.  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.controller.md.statistics.manager;
9
10 import java.util.Collections;
11 import java.util.Iterator;
12 import java.util.LinkedHashMap;
13 import java.util.Map;
14 import java.util.Timer;
15 import java.util.TimerTask;
16 import java.util.concurrent.TimeUnit;
17
18 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
19 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
20 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * Main responsibility of the class is to check the MD-SAL data store read/write
27  * transaction accumulation level and send statistics request if number of pending
28  * read/write transactions are zero.
29  * @author avishnoi@in.ibm.com
30  *
31  */
32 @SuppressWarnings("rawtypes")
33 public class StatisticsRequestScheduler implements DataTransactionListener {
34
35     private static final Logger srsLogger = LoggerFactory.getLogger(StatisticsRequestScheduler.class);
36     private final Timer timer = new Timer("request-monitor", true);
37
38     // We need ordered retrieval, and O(1) contains operation
39     private final Map<AbstractStatsTracker,Integer> requestQueue =
40             Collections.synchronizedMap(new LinkedHashMap<AbstractStatsTracker,Integer>());
41
42     private Long PendingTransactions;
43
44     private long lastRequestTime = System.nanoTime();
45
46     private static final long REQUEST_MONITOR_INTERVAL = 1000;
47
48     private final TimerTask task = new TimerTask() {
49         @Override
50         public void run() {
51             try{
52                 long now = System.nanoTime();
53                 if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
54                     requestStatistics();
55                 }
56             }catch (IllegalArgumentException | IllegalStateException | NullPointerException e){
57                 srsLogger.warn("Exception occured while sending statistics request : {}",e);
58             }
59         }
60     };
61
62     public StatisticsRequestScheduler(){
63         PendingTransactions = (long) 0;
64     }
65
66     public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){
67         requestQueue.put(statsRequest, null);
68     }
69
70     public void removeRequestsFromSchedulerQueue(NodeRef node){
71         AbstractStatsTracker stats = null;
72         synchronized(requestQueue){
73             Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
74             while(nodesItr.hasNext()){
75                 stats = nodesItr.next().getKey();
76                 if(stats.getNodeRef().equals(node)){
77                     nodesItr.remove();
78                 }
79             }
80         }
81
82     }
83     public AbstractStatsTracker getNextRequestFromSchedulerQueue(){
84         //Remove first element
85         AbstractStatsTracker stats = null;
86         synchronized(requestQueue){
87             Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
88             if(nodesItr.hasNext()){
89                 stats = nodesItr.next().getKey();
90                 srsLogger.debug("{} chosen up for execution",stats.getNodeRef());
91                 nodesItr.remove();
92                 return stats;
93             }
94         }
95         return stats;
96     }
97
98     private void requestStatistics(){
99         AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue();
100         sendStatsRequest(stats);
101     }
102     @Override
103     public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) {
104
105         AbstractStatsTracker stats = null;
106         synchronized(PendingTransactions){
107             switch(status){
108             case SUBMITED:
109                 this.PendingTransactions++;
110                 break;
111             case COMMITED:
112             case FAILED:
113                 this.PendingTransactions--;
114                 if(PendingTransactions == 0){
115                     lastRequestTime = System.nanoTime();
116                     stats = this.getNextRequestFromSchedulerQueue();
117                 }
118                 srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size());
119                 break;
120             default:
121                 break;
122             }
123         }
124         sendStatsRequest(stats);
125     }
126
127     private void sendStatsRequest(AbstractStatsTracker stats){
128         if(stats != null){
129             try{
130                 stats.request();
131                 stats.increaseRequestCounter();
132             }catch(Exception e){
133                 srsLogger.warn("Statistics request was not sent successfully. Reason : {}",e.getMessage());
134             }
135         }
136     }
137     public void start(){
138         timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL);
139     }
140 }