blob: 276215b73e5119de0039a189e22fa862d643e870 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080017
18package net.floodlightcontroller.core.web;
19
20import java.lang.Thread.State;
21import java.util.ArrayList;
22import java.util.HashMap;
23import java.util.List;
24import java.util.Map;
25
26import net.floodlightcontroller.core.IFloodlightProviderService;
Jonathan Harta99ec672014-04-03 11:30:34 -070027
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080028import org.openflow.protocol.OFFeaturesReply;
29import org.openflow.protocol.statistics.OFStatistics;
30import org.openflow.protocol.statistics.OFStatisticsType;
31import org.openflow.util.HexString;
32import org.restlet.resource.Get;
33import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
36/**
37 * Return switch statistics information for all switches
Ray Milkey269ffb92014-04-03 14:43:30 -070038 *
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080039 * @author readams
40 */
41public class AllSwitchStatisticsResource extends SwitchResourceBase {
Ray Milkey269ffb92014-04-03 14:43:30 -070042 protected final static Logger log =
43 LoggerFactory.getLogger(AllSwitchStatisticsResource.class);
44
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080045 @Get("json")
Ray Milkey269ffb92014-04-03 14:43:30 -070046 public Map<String, Object> retrieve() {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080047 String statType = (String) getRequestAttributes().get("statType");
48 return retrieveInternal(statType);
49 }
Ray Milkey269ffb92014-04-03 14:43:30 -070050
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080051 public Map<String, Object> retrieveInternal(String statType) {
52 HashMap<String, Object> model = new HashMap<String, Object>();
53
54 OFStatisticsType type = null;
55 REQUESTTYPE rType = null;
Ray Milkey269ffb92014-04-03 14:43:30 -070056
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080057 if (statType.equals("port")) {
58 type = OFStatisticsType.PORT;
59 rType = REQUESTTYPE.OFSTATS;
60 } else if (statType.equals("queue")) {
61 type = OFStatisticsType.QUEUE;
62 rType = REQUESTTYPE.OFSTATS;
63 } else if (statType.equals("flow")) {
64 type = OFStatisticsType.FLOW;
65 rType = REQUESTTYPE.OFSTATS;
66 } else if (statType.equals("aggregate")) {
67 type = OFStatisticsType.AGGREGATE;
68 rType = REQUESTTYPE.OFSTATS;
69 } else if (statType.equals("desc")) {
70 type = OFStatisticsType.DESC;
71 rType = REQUESTTYPE.OFSTATS;
72 } else if (statType.equals("table")) {
73 type = OFStatisticsType.TABLE;
74 rType = REQUESTTYPE.OFSTATS;
75 } else if (statType.equals("features")) {
76 rType = REQUESTTYPE.OFFEATURES;
77 } else {
78 return model;
79 }
Ray Milkey269ffb92014-04-03 14:43:30 -070080
81 IFloodlightProviderService floodlightProvider =
82 (IFloodlightProviderService) getContext().getAttributes().
83 get(IFloodlightProviderService.class.getCanonicalName());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080084 Long[] switchDpids = floodlightProvider.getSwitches().keySet().toArray(new Long[0]);
85 List<GetConcurrentStatsThread> activeThreads = new ArrayList<GetConcurrentStatsThread>(switchDpids.length);
86 List<GetConcurrentStatsThread> pendingRemovalThreads = new ArrayList<GetConcurrentStatsThread>();
87 GetConcurrentStatsThread t;
88 for (Long l : switchDpids) {
89 t = new GetConcurrentStatsThread(l, rType, type);
90 activeThreads.add(t);
91 t.start();
92 }
Ray Milkey269ffb92014-04-03 14:43:30 -070093
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080094 // Join all the threads after the timeout. Set a hard timeout
95 // of 12 seconds for the threads to finish. If the thread has not
96 // finished the switch has not replied yet and therefore we won't
97 // add the switch's stats to the reply.
98 for (int iSleepCycles = 0; iSleepCycles < 12; iSleepCycles++) {
99 for (GetConcurrentStatsThread curThread : activeThreads) {
100 if (curThread.getState() == State.TERMINATED) {
101 if (rType == REQUESTTYPE.OFSTATS) {
102 model.put(HexString.toHexString(curThread.getSwitchId()), curThread.getStatisticsReply());
103 } else if (rType == REQUESTTYPE.OFFEATURES) {
104 model.put(HexString.toHexString(curThread.getSwitchId()), curThread.getFeaturesReply());
105 }
106 pendingRemovalThreads.add(curThread);
107 }
108 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700109
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800110 // remove the threads that have completed the queries to the switches
111 for (GetConcurrentStatsThread curThread : pendingRemovalThreads) {
112 activeThreads.remove(curThread);
113 }
114 // clear the list so we don't try to double remove them
115 pendingRemovalThreads.clear();
Ray Milkey269ffb92014-04-03 14:43:30 -0700116
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800117 // if we are done finish early so we don't always get the worst case
118 if (activeThreads.isEmpty()) {
119 break;
120 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700121
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800122 // sleep for 1 s here
123 try {
124 Thread.sleep(1000);
125 } catch (InterruptedException e) {
126 log.error("Interrupted while waiting for statistics", e);
127 }
128 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700129
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800130 return model;
131 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700132
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800133 protected class GetConcurrentStatsThread extends Thread {
134 private List<OFStatistics> switchReply;
135 private long switchId;
136 private OFStatisticsType statType;
137 private REQUESTTYPE requestType;
138 private OFFeaturesReply featuresReply;
Ray Milkey269ffb92014-04-03 14:43:30 -0700139
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800140 public GetConcurrentStatsThread(long switchId, REQUESTTYPE requestType, OFStatisticsType statType) {
141 this.switchId = switchId;
142 this.requestType = requestType;
143 this.statType = statType;
144 this.switchReply = null;
145 this.featuresReply = null;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800146 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700147
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800148 public List<OFStatistics> getStatisticsReply() {
149 return switchReply;
150 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700151
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800152 public OFFeaturesReply getFeaturesReply() {
153 return featuresReply;
154 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700155
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800156 public long getSwitchId() {
157 return switchId;
158 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700159
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800160 public void run() {
161 if ((requestType == REQUESTTYPE.OFSTATS) && (statType != null)) {
162 switchReply = getSwitchStatistics(switchId, statType);
163 } else if (requestType == REQUESTTYPE.OFFEATURES) {
164 featuresReply = getSwitchFeaturesReply(switchId);
165 }
166 }
167 }
168}