Skip to content
Snippets Groups Projects
Commit 0e4bd761 authored by abat's avatar abat
Browse files

Merge into master from pull request #216:

 	Greatly enhance the information returned by the controller switch REST API (https://github.com/floodlight/floodlight/pull/216)
parents 935881a1 90e92e08
No related branches found
No related tags found
No related merge requests found
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
package net.floodlightcontroller.core.internal; package net.floodlightcontroller.core.internal;
import java.io.IOException; import java.io.IOException;
import java.net.SocketAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -37,11 +39,14 @@ import net.floodlightcontroller.core.IFloodlightProviderService; ...@@ -37,11 +39,14 @@ import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IFloodlightProviderService.Role; import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.types.MacVlanPair; import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
import net.floodlightcontroller.threadpool.IThreadPoolService; import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.util.TimedCache; import net.floodlightcontroller.util.TimedCache;
import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.ser.ToStringSerializer;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.openflow.protocol.OFFeaturesReply; import org.openflow.protocol.OFFeaturesReply;
import org.openflow.protocol.OFFlowMod; import org.openflow.protocol.OFFlowMod;
...@@ -82,8 +87,6 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -82,8 +87,6 @@ public class OFSwitchImpl implements IOFSwitch {
protected Channel channel; protected Channel channel;
protected AtomicInteger transactionIdSource; protected AtomicInteger transactionIdSource;
protected Map<Short, OFPhysicalPort> ports; protected Map<Short, OFPhysicalPort> ports;
protected Long switchClusterId;
protected Map<MacVlanPair,Short> macVlanToPortMap;
protected Map<Integer,OFStatisticsFuture> statsFutureMap; protected Map<Integer,OFStatisticsFuture> statsFutureMap;
protected Map<Integer, IOFMessageListener> iofMsgListenersMap; protected Map<Integer, IOFMessageListener> iofMsgListenersMap;
protected boolean connected; protected boolean connected;
...@@ -132,7 +135,6 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -132,7 +135,6 @@ public class OFSwitchImpl implements IOFSwitch {
this.connectedSince = new Date(); this.connectedSince = new Date();
this.transactionIdSource = new AtomicInteger(); this.transactionIdSource = new AtomicInteger();
this.ports = new ConcurrentHashMap<Short, OFPhysicalPort>(); this.ports = new ConcurrentHashMap<Short, OFPhysicalPort>();
this.switchClusterId = null;
this.connected = true; this.connected = true;
this.statsFutureMap = new ConcurrentHashMap<Integer,OFStatisticsFuture>(); this.statsFutureMap = new ConcurrentHashMap<Integer,OFStatisticsFuture>();
this.iofMsgListenersMap = new ConcurrentHashMap<Integer,IOFMessageListener>(); this.iofMsgListenersMap = new ConcurrentHashMap<Integer,IOFMessageListener>();
...@@ -241,27 +243,20 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -241,27 +243,20 @@ public class OFSwitchImpl implements IOFSwitch {
channel.close(); channel.close();
} }
@JsonIgnore
public OFFeaturesReply getFeaturesReply() { public OFFeaturesReply getFeaturesReply() {
return this.featuresReply; return this.featuresReply;
} }
public void setSwitchClusterId(Long id) {
this.switchClusterId = id;
}
public Long getSwitchClusterId() {
return switchClusterId;
}
public synchronized void setFeaturesReply(OFFeaturesReply featuresReply) { public synchronized void setFeaturesReply(OFFeaturesReply featuresReply) {
this.featuresReply = featuresReply; this.featuresReply = featuresReply;
for (OFPhysicalPort port : featuresReply.getPorts()) { for (OFPhysicalPort port : featuresReply.getPorts()) {
ports.put(port.getPortNumber(), port); ports.put(port.getPortNumber(), port);
} }
this.switchClusterId = featuresReply.getDatapathId();
this.stringId = HexString.toHexString(featuresReply.getDatapathId()); this.stringId = HexString.toHexString(featuresReply.getDatapathId());
} }
@JsonIgnore
public synchronized List<OFPhysicalPort> getEnabledPorts() { public synchronized List<OFPhysicalPort> getEnabledPorts() {
List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>(); List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>();
for (OFPhysicalPort port : ports.values()) { for (OFPhysicalPort port : ports.values()) {
...@@ -280,9 +275,15 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -280,9 +275,15 @@ public class OFSwitchImpl implements IOFSwitch {
ports.put(port.getPortNumber(), port); ports.put(port.getPortNumber(), port);
} }
@JsonIgnore
public Map<Short, OFPhysicalPort> getPorts() { public Map<Short, OFPhysicalPort> getPorts() {
return ports; return ports;
} }
@JsonProperty("ports")
public Collection<OFPhysicalPort> getPortCollection() {
return ports.values();
}
public synchronized void deletePort(short portNumber) { public synchronized void deletePort(short portNumber) {
ports.remove(portNumber); ports.remove(portNumber);
...@@ -306,12 +307,15 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -306,12 +307,15 @@ public class OFSwitchImpl implements IOFSwitch {
} }
@Override @Override
@JsonSerialize(using=DPIDSerializer.class)
@JsonProperty("dpid")
public long getId() { public long getId() {
if (this.featuresReply == null) if (this.featuresReply == null)
throw new RuntimeException("Features reply has not yet been set"); throw new RuntimeException("Features reply has not yet been set");
return this.featuresReply.getDatapathId(); return this.featuresReply.getDatapathId();
} }
@JsonIgnore
@Override @Override
public String getStringId() { public String getStringId() {
return stringId; return stringId;
...@@ -335,6 +339,7 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -335,6 +339,7 @@ public class OFSwitchImpl implements IOFSwitch {
return connectedSince; return connectedSince;
} }
@JsonIgnore
@Override @Override
public int getNextTransactionId() { public int getNextTransactionId() {
return this.transactionIdSource.incrementAndGet(); return this.transactionIdSource.incrementAndGet();
...@@ -409,6 +414,7 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -409,6 +414,7 @@ public class OFSwitchImpl implements IOFSwitch {
this.threadPool = tp; this.threadPool = tp;
} }
@JsonIgnore
@Override @Override
public synchronized boolean isConnected() { public synchronized boolean isConnected() {
return connected; return connected;
...@@ -424,6 +430,7 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -424,6 +430,7 @@ public class OFSwitchImpl implements IOFSwitch {
return role; return role;
} }
@JsonIgnore
@Override @Override
public boolean isActive() { public boolean isActive() {
return (role != Role.SLAVE); return (role != Role.SLAVE);
...@@ -469,6 +476,7 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -469,6 +476,7 @@ public class OFSwitchImpl implements IOFSwitch {
} }
@Override @Override
@JsonIgnore
public Map<Short, Long> getPortBroadcastHits() { public Map<Short, Long> getPortBroadcastHits() {
return this.portBroadcastCacheHitMap; return this.portBroadcastCacheHitMap;
} }
...@@ -517,6 +525,15 @@ public class OFSwitchImpl implements IOFSwitch { ...@@ -517,6 +525,15 @@ public class OFSwitchImpl implements IOFSwitch {
public Lock getListenerWriteLock() { public Lock getListenerWriteLock() {
return listenerLock.writeLock(); return listenerLock.writeLock();
} }
/**
* Get the IP Address for the switch
* @return the inet address
*/
@JsonSerialize(using=ToStringSerializer.class)
public SocketAddress getInetAddress() {
return channel.getRemoteAddress();
}
/** /**
* Send NX role request message to the switch requesting the specified role. * Send NX role request message to the switch requesting the specified role.
......
...@@ -17,10 +17,7 @@ ...@@ -17,10 +17,7 @@
package net.floodlightcontroller.core.web; package net.floodlightcontroller.core.web;
import java.util.ArrayList; import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitch;
...@@ -34,18 +31,10 @@ import org.restlet.resource.ServerResource; ...@@ -34,18 +31,10 @@ import org.restlet.resource.ServerResource;
*/ */
public class ControllerSwitchesResource extends ServerResource { public class ControllerSwitchesResource extends ServerResource {
@Get("json") @Get("json")
public List<Map<String, String>> retrieve() { public Collection<IOFSwitch> retrieve() {
List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>();
IFloodlightProviderService floodlightProvider = IFloodlightProviderService floodlightProvider =
(IFloodlightProviderService)getContext().getAttributes(). (IFloodlightProviderService)getContext().getAttributes().
get(IFloodlightProviderService.class.getCanonicalName()); get(IFloodlightProviderService.class.getCanonicalName());
Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches(); return floodlightProvider.getSwitches().values();
for (IOFSwitch s: switches.values()) {
Map<String, String> m = new HashMap<String, String>();
m.put("dpid", s.getStringId());
switchIds.add(m);
}
return switchIds;
} }
} }
/** /**
* Copyright 2011, Big Switch Networks, Inc. * Copyright 2011,2012 Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University * Originally created by David Erickson, Stanford University
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* under the License. * under the License.
**/ **/
package org.openflow.protocol.serializers; package net.floodlightcontroller.core.web.serializers;
import java.io.IOException; import java.io.IOException;
...@@ -23,35 +23,18 @@ import org.codehaus.jackson.JsonGenerator; ...@@ -23,35 +23,18 @@ import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer; import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider; import org.codehaus.jackson.map.SerializerProvider;
import org.openflow.protocol.OFPhysicalPort;
import org.openflow.util.HexString; import org.openflow.util.HexString;
public class OFPhysicalPortJSONSerializer extends JsonSerializer<OFPhysicalPort> { /**
* Serialize a MAC as colon-separated hexadecimal
/** */
* Performs the serialization of a OFPhysicalPort object public class ByteArrayMACSerializer extends JsonSerializer<byte[]> {
*/
@Override
public void serialize(OFPhysicalPort port, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException {
jGen.writeStartObject();
jGen.writeNumberField("advertisedFeatures", port.getAdvertisedFeatures());
jGen.writeNumberField("config", port.getConfig());
jGen.writeNumberField("currentFeatures", port.getCurrentFeatures());
jGen.writeStringField("hardwareAddress", HexString.toHexString(port.getHardwareAddress()));
jGen.writeStringField("name", port.getName());
jGen.writeNumberField("peerFeatures", port.getPeerFeatures());
jGen.writeNumberField("portNumber", port.getPortNumber());
jGen.writeNumberField("state", port.getState());
jGen.writeNumberField("supportedFeatures", port.getSupportedFeatures());
jGen.writeEndObject();
}
/**
* Tells SimpleModule that we are the serializer for OFPhysicalPort
*/
@Override @Override
public Class<OFPhysicalPort> handledType() { public void serialize(byte[] mac, JsonGenerator jGen,
return OFPhysicalPort.class; SerializerProvider serializer)
throws IOException, JsonProcessingException {
jGen.writeString(HexString.toHexString(mac));
} }
} }
/**
* Copyright 2011,2012 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.serializers;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
/**
* Serialize a short value as an unsigned short
*/
public class UShortSerializer extends JsonSerializer<Short> {
@Override
public void serialize(Short s, JsonGenerator jGen,
SerializerProvider serializer) throws IOException,
JsonProcessingException {
if (s == null) jGen.writeNull();
else jGen.writeNumber(s.shortValue() & 0xffff);
}
}
...@@ -21,16 +21,16 @@ import java.io.UnsupportedEncodingException; ...@@ -21,16 +21,16 @@ import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;
import net.floodlightcontroller.core.web.serializers.ByteArrayMACSerializer;
import net.floodlightcontroller.core.web.serializers.UShortSerializer;
import org.codehaus.jackson.map.annotate.JsonSerialize; import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
import org.openflow.protocol.serializers.OFPhysicalPortJSONSerializer;
/** /**
* Represents ofp_phy_port * Represents ofp_phy_port
* @author David Erickson (daviderickson@cs.stanford.edu) - Mar 25, 2010 * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 25, 2010
*/ */
@JsonSerialize(using=OFPhysicalPortJSONSerializer.class)
public class OFPhysicalPort { public class OFPhysicalPort {
public static int MINIMUM_LENGTH = 48; public static int MINIMUM_LENGTH = 48;
public static int OFP_ETH_ALEN = 6; public static int OFP_ETH_ALEN = 6;
...@@ -221,6 +221,7 @@ public class OFPhysicalPort { ...@@ -221,6 +221,7 @@ public class OFPhysicalPort {
/** /**
* @return the portNumber * @return the portNumber
*/ */
@JsonSerialize(using=UShortSerializer.class)
public short getPortNumber() { public short getPortNumber() {
return portNumber; return portNumber;
} }
...@@ -235,6 +236,7 @@ public class OFPhysicalPort { ...@@ -235,6 +236,7 @@ public class OFPhysicalPort {
/** /**
* @return the hardwareAddress * @return the hardwareAddress
*/ */
@JsonSerialize(using=ByteArrayMACSerializer.class)
public byte[] getHardwareAddress() { public byte[] getHardwareAddress() {
return hardwareAddress; return hardwareAddress;
} }
......
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