blob: 2eeec705efb04bb7fbcdd7fe8c558b47797852dc [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2* 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**/
17
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;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080027import org.openflow.protocol.OFFeaturesReply;
28import org.openflow.protocol.statistics.OFStatistics;
29import org.openflow.protocol.statistics.OFStatisticsType;
30import org.openflow.util.HexString;
31import org.restlet.resource.Get;
32import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
35/**
36 * Return switch statistics information for all switches
37 * @author readams
38 */
39public class AllSwitchStatisticsResource extends SwitchResourceBase {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070040 protected final static Logger log =
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080041 LoggerFactory.getLogger(AllSwitchStatisticsResource.class);
42
43 @Get("json")
44 public Map<String, Object> retrieve() {
45 String statType = (String) getRequestAttributes().get("statType");
46 return retrieveInternal(statType);
47 }
48
49 public Map<String, Object> retrieveInternal(String statType) {
50 HashMap<String, Object> model = new HashMap<String, Object>();
51
52 OFStatisticsType type = null;
53 REQUESTTYPE rType = null;
54
55 if (statType.equals("port")) {
56 type = OFStatisticsType.PORT;
57 rType = REQUESTTYPE.OFSTATS;
58 } else if (statType.equals("queue")) {
59 type = OFStatisticsType.QUEUE;
60 rType = REQUESTTYPE.OFSTATS;
61 } else if (statType.equals("flow")) {
62 type = OFStatisticsType.FLOW;
63 rType = REQUESTTYPE.OFSTATS;
64 } else if (statType.equals("aggregate")) {
65 type = OFStatisticsType.AGGREGATE;
66 rType = REQUESTTYPE.OFSTATS;
67 } else if (statType.equals("desc")) {
68 type = OFStatisticsType.DESC;
69 rType = REQUESTTYPE.OFSTATS;
70 } else if (statType.equals("table")) {
71 type = OFStatisticsType.TABLE;
72 rType = REQUESTTYPE.OFSTATS;
73 } else if (statType.equals("features")) {
74 rType = REQUESTTYPE.OFFEATURES;
75 } else {
76 return model;
77 }
78
79 IFloodlightProviderService floodlightProvider =
80 (IFloodlightProviderService)getContext().getAttributes().
81 get(IFloodlightProviderService.class.getCanonicalName());
82 Long[] switchDpids = floodlightProvider.getSwitches().keySet().toArray(new Long[0]);
83 List<GetConcurrentStatsThread> activeThreads = new ArrayList<GetConcurrentStatsThread>(switchDpids.length);
84 List<GetConcurrentStatsThread> pendingRemovalThreads = new ArrayList<GetConcurrentStatsThread>();
85 GetConcurrentStatsThread t;
86 for (Long l : switchDpids) {
87 t = new GetConcurrentStatsThread(l, rType, type);
88 activeThreads.add(t);
89 t.start();
90 }
91
92 // Join all the threads after the timeout. Set a hard timeout
93 // of 12 seconds for the threads to finish. If the thread has not
94 // finished the switch has not replied yet and therefore we won't
95 // add the switch's stats to the reply.
96 for (int iSleepCycles = 0; iSleepCycles < 12; iSleepCycles++) {
97 for (GetConcurrentStatsThread curThread : activeThreads) {
98 if (curThread.getState() == State.TERMINATED) {
99 if (rType == REQUESTTYPE.OFSTATS) {
100 model.put(HexString.toHexString(curThread.getSwitchId()), curThread.getStatisticsReply());
101 } else if (rType == REQUESTTYPE.OFFEATURES) {
102 model.put(HexString.toHexString(curThread.getSwitchId()), curThread.getFeaturesReply());
103 }
104 pendingRemovalThreads.add(curThread);
105 }
106 }
107
108 // remove the threads that have completed the queries to the switches
109 for (GetConcurrentStatsThread curThread : pendingRemovalThreads) {
110 activeThreads.remove(curThread);
111 }
112 // clear the list so we don't try to double remove them
113 pendingRemovalThreads.clear();
114
115 // if we are done finish early so we don't always get the worst case
116 if (activeThreads.isEmpty()) {
117 break;
118 }
119
120 // sleep for 1 s here
121 try {
122 Thread.sleep(1000);
123 } catch (InterruptedException e) {
124 log.error("Interrupted while waiting for statistics", e);
125 }
126 }
127
128 return model;
129 }
130
131 protected class GetConcurrentStatsThread extends Thread {
132 private List<OFStatistics> switchReply;
133 private long switchId;
134 private OFStatisticsType statType;
135 private REQUESTTYPE requestType;
136 private OFFeaturesReply featuresReply;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800137
138 public GetConcurrentStatsThread(long switchId, REQUESTTYPE requestType, OFStatisticsType statType) {
139 this.switchId = switchId;
140 this.requestType = requestType;
141 this.statType = statType;
142 this.switchReply = null;
143 this.featuresReply = null;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800144 }
145
146 public List<OFStatistics> getStatisticsReply() {
147 return switchReply;
148 }
149
150 public OFFeaturesReply getFeaturesReply() {
151 return featuresReply;
152 }
153
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800154 public long getSwitchId() {
155 return switchId;
156 }
157
158 public void run() {
159 if ((requestType == REQUESTTYPE.OFSTATS) && (statType != null)) {
160 switchReply = getSwitchStatistics(switchId, statType);
161 } else if (requestType == REQUESTTYPE.OFFEATURES) {
162 featuresReply = getSwitchFeaturesReply(switchId);
163 }
164 }
165 }
166}