blob: 874bf37c66ac838169574af4a47701b3ac1f41f2 [file] [log] [blame]
package net.onrc.onos.ofcontroller.networkgraph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.onrc.onos.datastore.topology.RCPort;
import net.onrc.onos.datastore.topology.RCSwitch;
import edu.stanford.ramcloud.JRamCloud.ObjectDoesntExistException;
import edu.stanford.ramcloud.JRamCloud.WrongVersionException;
/**
* Switch Object stored in In-memory Topology.
*
* TODO REMOVE following design memo: This object itself may hold the DBObject,
* but this Object itself will not issue any read/write to the DataStore.
*/
public class SwitchImpl extends NetworkGraphObject implements Switch {
private Long dpid;
// These needs to be ConcurrentCollecton if allowing Graph to be accessed Concurrently
private final Map<Long, Port> ports;
public SwitchImpl(NetworkGraph graph, Long dpid) {
super(graph);
this.dpid = dpid;
ports = new HashMap<Long, Port>();
}
@Override
public Long getDpid() {
return dpid;
}
@Override
public Collection<Port> getPorts() {
return Collections.unmodifiableCollection(ports.values());
}
@Override
public Port getPort(Long number) {
return ports.get(number);
}
@Override
public Iterable<Switch> getNeighbors() {
Set<Switch> neighbors = new HashSet<>();
for (Link link : getOutgoingLinks()) {
neighbors.add(link.getDestinationSwitch());
}
// XXX should incoming considered neighbor?
for (Link link : getIncomingLinks()) {
neighbors.add(link.getSourceSwitch());
}
return neighbors;
}
@Override
public Link getLinkToNeighbor(Long neighborDpid) {
for (Link link : getOutgoingLinks()) {
if (link.getDestinationSwitch().getDpid().equals(neighborDpid) ) {
return link;
}
}
return null;
}
@Override
public Collection<Device> getDevices() {
// TODO Should switch also store a list of attached devices to avoid
// calculating this every time?
List<Device> devices = new ArrayList<Device>();
for (Port port : ports.values()) {
for (Device device : port.getDevices()) {
devices.add(device);
}
}
return devices;
}
public void addPort(Port port) {
this.ports.put(port.getNumber(), port);
}
public Port removePort(Port port) {
Port p = this.ports.remove(port.getNumber());
return p;
}
public Port addPort(Long portNumber) {
PortImpl port = new PortImpl(graph, this, portNumber);
ports.put(port.getNumber(), port);
return port;
}
public void store() {
RCSwitch rcSwitch = new RCSwitch(dpid);
for (Port port : ports.values()) {
RCPort rcPort = new RCPort(dpid, (long)port.getNumber());
rcSwitch.addPortId(rcPort.getId());
}
try {
rcSwitch.update();
} catch (ObjectDoesntExistException | WrongVersionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public Iterable<Link> getOutgoingLinks() {
LinkedList<Link> links = new LinkedList<Link>();
for (Port port: getPorts()) {
Link link = port.getOutgoingLink();
if (link != null) {
links.add(link);
}
}
return links;
}
@Override
public Iterable<Link> getIncomingLinks() {
LinkedList<Link> links = new LinkedList<Link>();
for (Port port: getPorts()) {
Link link = port.getIncomingLink();
if (link != null) {
links.add(link);
}
}
return links;
}
}