Skip to content
Snippets Groups Projects
Commit 70a1426d authored by Ryan Izard's avatar Ryan Izard
Browse files

Added support for features request message via the REST API. Changed the case...

Added support for features request message via the REST API. Changed the case of some JSON keys to camel.
parent 44fa180a
No related branches found
No related tags found
No related merge requests found
/**
* Copyright 2011, Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
* Copyright 2011, Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
package net.floodlightcontroller.core.web;
......@@ -39,165 +39,173 @@ import org.slf4j.LoggerFactory;
* @author readams
*/
public class AllSwitchStatisticsResource extends SwitchResourceBase {
protected static Logger log =
LoggerFactory.getLogger(AllSwitchStatisticsResource.class);
@Get("json")
public Map<String, StatsReply> retrieve() {
String statType = (String) getRequestAttributes().get(CoreWebRoutable.STR_STAT_TYPE);
return retrieveInternal(statType);
}
private Map<String, StatsReply> retrieveInternal(String statType) {
HashMap<String, StatsReply> model = new HashMap<String, StatsReply>();
OFStatsType type = null;
REQUESTTYPE rType = null;
switch (statType) {
case OFStatsTypeStrings.PORT:
type = OFStatsType.PORT;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.QUEUE:
type = OFStatsType.QUEUE;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.FLOW:
type = OFStatsType.FLOW;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.AGGREGATE:
type = OFStatsType.AGGREGATE;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.DESC:
type = OFStatsType.DESC;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.TABLE:
type = OFStatsType.TABLE;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.GROUP:
type = OFStatsType.GROUP;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.GROUP_DESC:
type = OFStatsType.GROUP_DESC;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.GROUP_FEATURES:
type = OFStatsType.GROUP_FEATURES;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.METER:
type = OFStatsType.METER;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.METER_CONFIG:
type = OFStatsType.METER_CONFIG;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.METER_FEATURES:
type = OFStatsType.METER_FEATURES;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.FEATURES:
rType = REQUESTTYPE.OFFEATURES;
break;
default:
return model;
}
IOFSwitchService switchService = (IOFSwitchService) getContext().getAttributes().
get(IOFSwitchService.class.getCanonicalName());
Set<DatapathId> switchDpids = switchService.getAllSwitchDpids();
List<GetConcurrentStatsThread> activeThreads = new ArrayList<GetConcurrentStatsThread>(switchDpids.size());
List<GetConcurrentStatsThread> pendingRemovalThreads = new ArrayList<GetConcurrentStatsThread>();
GetConcurrentStatsThread t;
for (DatapathId l : switchDpids) {
t = new GetConcurrentStatsThread(l, rType, type);
activeThreads.add(t);
t.start();
}
// Join all the threads after the timeout. Set a hard timeout
// of 12 seconds for the threads to finish. If the thread has not
// finished the switch has not replied yet and therefore we won't
// add the switch's stats to the reply.
for (int iSleepCycles = 0; iSleepCycles < 12; iSleepCycles++) {
for (GetConcurrentStatsThread curThread : activeThreads) {
if (curThread.getState() == State.TERMINATED) {
if (rType == REQUESTTYPE.OFSTATS) {
model.put(curThread.getSwitchId().toString(), new StatsReply(curThread.getSwitchId(), curThread.getStatisticsReply(), type));
} else if (rType == REQUESTTYPE.OFFEATURES) {
model.put(curThread.getSwitchId().toString(), new StatsReply(curThread.getSwitchId(), curThread.getFeaturesReply(), type));
}
pendingRemovalThreads.add(curThread);
}
}
// remove the threads that have completed the queries to the switches
for (GetConcurrentStatsThread curThread : pendingRemovalThreads) {
activeThreads.remove(curThread);
}
// clear the list so we don't try to double remove them
pendingRemovalThreads.clear();
// if we are done finish early so we don't always get the worst case
if (activeThreads.isEmpty()) {
break;
}
// sleep for 1 s here
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
log.error("Interrupted while waiting for statistics", e);
}
}
return model;
}
protected class GetConcurrentStatsThread extends Thread {
private List<OFStatsReply> switchReply;
private DatapathId switchId;
private OFStatsType statType;
private REQUESTTYPE requestType;
private OFFeaturesReply featuresReply;
public GetConcurrentStatsThread(DatapathId switchId, REQUESTTYPE requestType, OFStatsType statType) {
this.switchId = switchId;
this.requestType = requestType;
this.statType = statType;
this.switchReply = null;
this.featuresReply = null;
}
public List<OFStatsReply> getStatisticsReply() {
return switchReply;
}
public OFFeaturesReply getFeaturesReply() {
return featuresReply;
}
public DatapathId getSwitchId() {
return switchId;
}
@Override
public void run() {
if ((requestType == REQUESTTYPE.OFSTATS) && (statType != null)) {
switchReply = getSwitchStatistics(switchId, statType);
} else if (requestType == REQUESTTYPE.OFFEATURES) {
featuresReply = getSwitchFeaturesReply(switchId);
}
}
}
protected static Logger log =
LoggerFactory.getLogger(AllSwitchStatisticsResource.class);
@Get("json")
public Map<String, StatsReply> retrieve() {
String statType = (String) getRequestAttributes().get(CoreWebRoutable.STR_STAT_TYPE);
return retrieveInternal(statType);
}
private Map<String, StatsReply> retrieveInternal(String statType) {
HashMap<String, StatsReply> model = new HashMap<String, StatsReply>();
OFStatsType type = null;
REQUESTTYPE rType = null;
switch (statType) {
case OFStatsTypeStrings.PORT:
type = OFStatsType.PORT;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.PORT_DESC:
type = OFStatsType.PORT_DESC;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.QUEUE:
type = OFStatsType.QUEUE;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.FLOW:
type = OFStatsType.FLOW;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.AGGREGATE:
type = OFStatsType.AGGREGATE;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.DESC:
type = OFStatsType.DESC;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.TABLE:
type = OFStatsType.TABLE;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.TABLE_FEATURES:
type = OFStatsType.TABLE_FEATURES;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.GROUP:
type = OFStatsType.GROUP;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.GROUP_DESC:
type = OFStatsType.GROUP_DESC;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.GROUP_FEATURES:
type = OFStatsType.GROUP_FEATURES;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.METER:
type = OFStatsType.METER;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.METER_CONFIG:
type = OFStatsType.METER_CONFIG;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.METER_FEATURES:
type = OFStatsType.METER_FEATURES;
rType = REQUESTTYPE.OFSTATS;
break;
case OFStatsTypeStrings.FEATURES:
rType = REQUESTTYPE.OFFEATURES;
break;
default:
return model;
}
IOFSwitchService switchService = (IOFSwitchService) getContext().getAttributes().
get(IOFSwitchService.class.getCanonicalName());
Set<DatapathId> switchDpids = switchService.getAllSwitchDpids();
List<GetConcurrentStatsThread> activeThreads = new ArrayList<GetConcurrentStatsThread>(switchDpids.size());
List<GetConcurrentStatsThread> pendingRemovalThreads = new ArrayList<GetConcurrentStatsThread>();
GetConcurrentStatsThread t;
for (DatapathId l : switchDpids) {
t = new GetConcurrentStatsThread(l, rType, type);
activeThreads.add(t);
t.start();
}
// Join all the threads after the timeout. Set a hard timeout
// of 12 seconds for the threads to finish. If the thread has not
// finished the switch has not replied yet and therefore we won't
// add the switch's stats to the reply.
for (int iSleepCycles = 0; iSleepCycles < 12; iSleepCycles++) {
for (GetConcurrentStatsThread curThread : activeThreads) {
if (curThread.getState() == State.TERMINATED) {
if (rType == REQUESTTYPE.OFSTATS) {
model.put(curThread.getSwitchId().toString(), new StatsReply(curThread.getSwitchId(), curThread.getStatisticsReply(), type));
} else if (rType == REQUESTTYPE.OFFEATURES) {
model.put(curThread.getSwitchId().toString(), new StatsReply(curThread.getSwitchId(), curThread.getFeaturesReply(), type));
}
pendingRemovalThreads.add(curThread);
}
}
// remove the threads that have completed the queries to the switches
for (GetConcurrentStatsThread curThread : pendingRemovalThreads) {
activeThreads.remove(curThread);
}
// clear the list so we don't try to double remove them
pendingRemovalThreads.clear();
// if we are done finish early so we don't always get the worst case
if (activeThreads.isEmpty()) {
break;
}
// sleep for 1 s here
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
log.error("Interrupted while waiting for statistics", e);
}
}
return model;
}
protected class GetConcurrentStatsThread extends Thread {
private List<OFStatsReply> switchReply;
private DatapathId switchId;
private OFStatsType statType;
private REQUESTTYPE requestType;
private OFFeaturesReply featuresReply;
public GetConcurrentStatsThread(DatapathId switchId, REQUESTTYPE requestType, OFStatsType statType) {
this.switchId = switchId;
this.requestType = requestType;
this.statType = statType;
this.switchReply = null;
this.featuresReply = null;
}
public List<OFStatsReply> getStatisticsReply() {
return switchReply;
}
public OFFeaturesReply getFeaturesReply() {
return featuresReply;
}
public DatapathId getSwitchId() {
return switchId;
}
@Override
public void run() {
if ((requestType == REQUESTTYPE.OFSTATS) && (statType != null)) {
switchReply = getSwitchStatistics(switchId, statType);
} else if (requestType == REQUESTTYPE.OFFEATURES) {
featuresReply = getSwitchFeaturesReply(switchId);
}
}
}
}
......@@ -54,9 +54,7 @@ public class SwitchStatisticsResource extends SwitchResourceBase {
}
// stop if the DPID is invalid or is not presently connected
if (!switchId.equals(DatapathId.NONE) && switchService.getSwitch(switchId) != null) {
// TODO these strings should be defined someplace. StatsReply.java?
if (!switchId.equals(DatapathId.NONE) && switchService.getSwitch(switchId) != null) {
// at this point, the switch DPID is valid AND exists; what about the OFStatsType?
switch (statType) {
case OFStatsTypeStrings.PORT:
......@@ -119,6 +117,9 @@ public class SwitchStatisticsResource extends SwitchResourceBase {
values = getSwitchFeaturesReply(switchId);
result.setStatType(OFStatsType.EXPERIMENTER);
break;
case OFStatsTypeStrings.FEATURES:
values = getSwitchFeaturesReply(switchId);
result.setStatType(null); // we will assume anything in "values" with a null stattype is "features"
default:
log.error("Invalid or unimplemented stat request type {}", statType);
break;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment