blob: e6abf2d834509bec4a203a3f22816f7810779824 [file] [log] [blame]
/**
* 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;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.annotations.LogMessageDoc;
import net.onrc.onos.core.drivermanager.OFSwitchImplCPqD13;
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry;
import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry;
import org.projectfloodlight.openflow.protocol.OFGroupStatsReply;
import org.projectfloodlight.openflow.protocol.OFMatchV3;
import org.projectfloodlight.openflow.protocol.OFOxmList;
import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortStatsRequest;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsRequest;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;
import org.projectfloodlight.openflow.util.HexString;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class for server resources related to switches
*
* @author readams
*/
public class SwitchResourceBase extends ServerResource {
protected final static Logger log = LoggerFactory.getLogger(SwitchResourceBase.class);
public enum REQUESTTYPE {
OFSTATS,
OFFEATURES
}
@Override
protected void doInit() throws ResourceException {
super.doInit();
}
@LogMessageDoc(level = "ERROR",
message = "Failure retrieving statistics from switch {switch}",
explanation = "An error occurred while retrieving statistics" +
"from the switch",
recommendation = LogMessageDoc.CHECK_SWITCH + " " +
LogMessageDoc.GENERIC_ACTION)
protected List<?> getSwitchStatistics(long switchId,
OFStatsType statType) {
IFloodlightProviderService floodlightProvider =
(IFloodlightProviderService) getContext().getAttributes().
get(IFloodlightProviderService.class.getCanonicalName());
IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
Future<List<OFStatsReply>> future;
List<OFStatsReply> values = null;
if (sw != null) {
OFStatsRequest<?> req = null;
if (statType == OFStatsType.FLOW) {
log.debug("Switch Flow Stats req sent for switch {}",
sw.getStringId());
OFMatchV3 match = sw.getFactory().buildMatchV3()
.setOxmList(OFOxmList.EMPTY).build();
req = sw.getFactory()
.buildFlowStatsRequest()
.setMatch(match)
.setOutPort(OFPort.ANY)
.setTableId(TableId.ALL)
.setXid(sw.getNextTransactionId()).build();
List<OFFlowStatsEntryMod> flowStats = new ArrayList<OFFlowStatsEntryMod>();
try {
future = sw.getStatistics(req);
values = future.get(10, TimeUnit.SECONDS);
for (OFFlowStatsEntry entry : ((OFFlowStatsReply)values.get(0)).getEntries()) {
OFFlowStatsEntryMod entryMod = new OFFlowStatsEntryMod(entry);
flowStats.add(entryMod);
}
log.debug("Switch flow Stats Entries from switch {} are {}",
sw.getStringId(), flowStats);
} catch (Exception e) {
log.error("Failure retrieving statistics from switch " + sw, e);
}
return flowStats;
}
else if (statType == OFStatsType.PORT){
log.debug("Switch Port Stats: req sent for all "
+ "ports in switch {}", sw.getStringId());
List<OFPortStatsEntryMod> portStats = null;
req = sw.getFactory()
.buildPortStatsRequest()
.setPortNo(OFPort.ANY).setXid
(sw.getNextTransactionId()).build();
try {
future = sw.getStatistics(req);
values = future.get(10, TimeUnit.SECONDS);
portStats = new ArrayList<OFPortStatsEntryMod>();
for (OFPortStatsEntry entry : ((OFPortStatsReply)values.get(0)).getEntries()) {
OFPortStatsEntryMod entryMod = new OFPortStatsEntryMod(entry);
portStats.add(entryMod);
}
log.debug("Switch Port Stats Entries from switch {} are {}",
sw.getStringId(), portStats);
} catch (Exception e) {
log.error("Failure retrieving statistics from switch " + sw, e);
}
return portStats;
}
else if (statType == OFStatsType.GROUP){
log.debug("Switch Group Stats: req sent for all "
+ "ports in switch {}", sw.getStringId());
req = sw.getFactory().buildGroupStatsRequest().setXid
(sw.getNextTransactionId()).build();
List<OFGroupStatsEntryMod> groupStats = new ArrayList<OFGroupStatsEntryMod>();
try {
future = sw.getStatistics(req);
values = future.get(10, TimeUnit.SECONDS);
for (OFGroupStatsEntry entry : ((OFGroupStatsReply)values.get(0)).getEntries()) {
OFGroupStatsEntryMod entryMod = new OFGroupStatsEntryMod(entry);
groupStats.add(entryMod);
}
log.debug("Switch Group Stats Entries from switch {} are {}",
sw.getStringId(), groupStats);
} catch (Exception e) {
log.error("Failure retrieving statistics from switch " + sw, e);
}
return groupStats;
}
else if (statType == OFStatsType.GROUP_DESC){
log.debug("Switch Group Desc Stats: req sent for all "
+ "ports in switch {}", sw.getStringId());
List<OFGroupDescStatsEntryMod> GroupDescStats= new ArrayList<OFGroupDescStatsEntryMod>();
req = sw.getFactory().buildGroupDescStatsRequest().setXid
(sw.getNextTransactionId()).build();
try {
future = sw.getStatistics(req);
values = future.get(10, TimeUnit.SECONDS);
for (OFGroupDescStatsEntry entry : ((OFGroupDescStatsReply)values.get(0)).getEntries()) {
OFGroupDescStatsEntryMod entryMod = new OFGroupDescStatsEntryMod(entry);
GroupDescStats.add(entryMod);
}
log.debug("Switch Group_Desc Stats Entries from switch {} are {}",
sw.getStringId(), GroupDescStats);
} catch (Exception e) {
log.error("Failure retrieving statistics from switch " + sw, e);
}
return GroupDescStats;
}
/*else if (statType == OFStatisticsType.AGGREGATE) {
OFAggregateStatisticsRequest specificReq = new OFAggregateStatisticsRequest();
OFMatch match = new OFMatch();
match.setWildcards(0xffffffff);
specificReq.setMatch(match);
specificReq.setOutPort(OFPort.OFPP_NONE.getValue());
specificReq.setTableId((byte) 0xff);
req.setStatistics(Collections.singletonList((OFStatistics) specificReq));
requestLength += specificReq.getLength();
} /*else if (statType == OFStatisticsType.QUEUE) {
OFQueueStatisticsRequest specificReq = new OFQueueStatisticsRequest();
specificReq.setPortNumber(OFPort.OFPP_ALL.getValue());
// LOOK! openflowj does not define OFPQ_ALL! pulled this from openflow.h
// note that I haven't seen this work yet though...
specificReq.setQueueId(0xffffffff);
req.setStatistics(Collections.singletonList((OFStatistics) specificReq));
requestLength += specificReq.getLength();
} else if (statType == OFStatisticsType.DESC ||
statType == OFStatisticsType.TABLE) {
// pass - nothing todo besides set the type above
}*/
// XXX S fix when we fix stats
try {
future = sw.getStatistics(req);
values = future.get(10, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("Failure retrieving statistics from switch " + sw, e);
}
}
return values;
}
protected Object getSwitchStatistics(String switchId, OFStatsType statType) {
return getSwitchStatistics(HexString.toLong(switchId), statType);
}
//TODO: Java doc
protected List<?> getSwitchStatisticsForTable(long switchId,
OFStatsType statType, String tableType) {
IFloodlightProviderService floodlightProvider =
(IFloodlightProviderService) getContext().getAttributes().
get(IFloodlightProviderService.class.getCanonicalName());
IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
Future<List<OFStatsReply>> future;
List<OFStatsReply> values = null;
//getting tableId from CPqD driver
TableId tableId;
if (sw != null) {
if((tableId = ((OFSwitchImplCPqD13) sw).getTableId(tableType)) == null){
log.error("Invalid tableType {} " + tableType);
return null;
}
OFStatsRequest<?> req = null;
if (statType == OFStatsType.FLOW) {
log.debug("Switch Flow Stats req for table {} sent to switch {}",
tableType,sw.getStringId());
OFMatchV3 match = sw.getFactory().buildMatchV3()
.setOxmList(OFOxmList.EMPTY).build();
req = sw.getFactory()
.buildFlowStatsRequest()
.setMatch(match)
.setOutPort(OFPort.ANY)
.setTableId(tableId)
.setXid(sw.getNextTransactionId()).build();
List<OFFlowStatsEntryMod> flowStats = new ArrayList<OFFlowStatsEntryMod>();
try {
future = sw.getStatistics(req);
values = future.get(10, TimeUnit.SECONDS);
for (OFFlowStatsEntry entry : ((OFFlowStatsReply)values.get(0)).getEntries()) {
OFFlowStatsEntryMod entryMod = new OFFlowStatsEntryMod(entry);
flowStats.add(entryMod);
}
log.debug("Switch flow Stats Entries for table {} from switch {} are {}",
tableType, sw.getStringId(), flowStats);
} catch (Exception e) {
log.error("Failure retrieving per table statistics from switch " + sw, e);
}
return flowStats;
}
}
//should never get to this point
log.error("Failure retrieving {} table statistics from switch {}",tableType, sw);
return null;
}
protected OFFeaturesReply getSwitchFeaturesReply(long switchId) {
IFloodlightProviderService floodlightProvider =
(IFloodlightProviderService) getContext().getAttributes().
get(IFloodlightProviderService.class.getCanonicalName());
IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
//uture<OFFeaturesReply> future;
OFFeaturesReply featuresReply = null;
if (sw != null) {
// XXX S fix when we fix stats
try {
//future = sw.getFeaturesReplyFromSwitch();
//featuresReply = future.get(10, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("Failure getting features reply from switch" + sw, e);
}
}
return featuresReply;
}
protected OFFeaturesReply getSwitchFeaturesReply(String switchId) {
return getSwitchFeaturesReply(HexString.toLong(switchId));
}
}