blob: 2153905b9582c82b449bd02edd0686fbf25977c1 [file] [log] [blame]
Yuta HIGUCHI80829d12014-02-05 20:16:56 -08001package net.onrc.onos.ofcontroller.networkgraph;
2
3import java.net.InetAddress;
4import java.util.Collection;
5import java.util.Collections;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -08006import java.util.HashSet;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -08007import java.util.LinkedList;
8import java.util.List;
9import java.util.Set;
10import java.util.concurrent.ConcurrentHashMap;
11import java.util.concurrent.ConcurrentMap;
Jonathan Hart26f291b2014-02-18 16:57:24 -080012import java.util.concurrent.locks.Lock;
13import java.util.concurrent.locks.ReadWriteLock;
14import java.util.concurrent.locks.ReentrantReadWriteLock;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080015
16import net.floodlightcontroller.util.MACAddress;
17
18import org.slf4j.Logger;
19import org.slf4j.LoggerFactory;
20
Pavlin Radoslavov6397a7f2014-02-18 14:56:52 -080021public class NetworkGraphImpl implements NetworkGraph {
Toshio Koide2f570c12014-02-06 16:55:32 -080022 @SuppressWarnings("unused")
Pavlin Radoslavov6397a7f2014-02-18 14:56:52 -080023 private static final Logger log = LoggerFactory.getLogger(NetworkGraphImpl.class);
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080024
Toshio Koide2f570c12014-02-06 16:55:32 -080025 // DPID -> Switch
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080026 private ConcurrentMap<Long, Switch> switches;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080027
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080028 private ConcurrentMap<InetAddress, Set<Device>> addr2Device;
29 private ConcurrentMap<MACAddress, Device> mac2Device;
Jonathan Hart26f291b2014-02-18 16:57:24 -080030
31 private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
32 private Lock readLock = readWriteLock.readLock();
33 // TODO use the write lock after refactor
34 private Lock writeLock = readWriteLock.writeLock();
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080035
Pavlin Radoslavov6397a7f2014-02-18 14:56:52 -080036 public NetworkGraphImpl() {
Toshio Koide2f570c12014-02-06 16:55:32 -080037 // TODO: Does these object need to be stored in Concurrent Collection?
38 switches = new ConcurrentHashMap<>();
39 addr2Device = new ConcurrentHashMap<>();
40 mac2Device = new ConcurrentHashMap<>();
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080041 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080042
Toshio Koide2f570c12014-02-06 16:55:32 -080043 @Override
44 public Switch getSwitch(Long dpid) {
45 // TODO Check if it is safe to directly return this Object.
46 return switches.get(dpid);
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080047 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080048
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080049 protected void putSwitch(Switch sw) {
50 switches.put(sw.getDpid(), sw);
51 }
52
53 protected void removeSwitch(Long dpid) {
54 switches.remove(dpid);
55 }
56
Toshio Koide2f570c12014-02-06 16:55:32 -080057 @Override
58 public Iterable<Switch> getSwitches() {
59 // TODO Check if it is safe to directly return this Object.
60 return Collections.unmodifiableCollection(switches.values());
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080061 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080062
Toshio Koide2f570c12014-02-06 16:55:32 -080063 @Override
Pavlin Radoslavov06df22a2014-02-18 19:16:27 -080064 public Port getPort(Long dpid, Long number) {
65 Switch sw = getSwitch(dpid);
66 if (sw != null) {
67 return sw.getPort(number);
68 }
69 return null;
70 }
71
72 @Override
Pavlin Radoslavov7c8f69a2014-02-19 19:01:45 -080073 public Link getLink(Long dpid, Long number) {
74 Port srcPort = getPort(dpid, number);
75 if (srcPort == null)
76 return null;
77 return srcPort.getOutgoingLink();
78 }
79
80 @Override
81 public Link getLink(Long srcDpid, Long srcNumber, Long dstDpid,
82 Long dstNumber) {
83 Link link = getLink(srcDpid, srcNumber);
84 if (link == null)
85 return null;
86 if (link.getDstSwitch().getDpid() != dstDpid)
87 return null;
88 if (link.getDstPort().getNumber() != dstNumber)
89 return null;
90 return link;
91 }
92
93 @Override
Toshio Koide2f570c12014-02-06 16:55:32 -080094 public Iterable<Link> getLinks() {
95 List<Link> linklist = new LinkedList<>();
96
97 for (Switch sw : switches.values()) {
98 Iterable<Link> links = sw.getOutgoingLinks();
99 for (Link l : links) {
100 linklist.add(l);
101 }
102 }
103 return linklist;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800104 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800105
Toshio Koide2f570c12014-02-06 16:55:32 -0800106 @Override
Pavlin Radoslavov06df22a2014-02-18 19:16:27 -0800107 public Iterable<Device> getDevicesByIp(InetAddress ipAddress) {
Toshio Koide2f570c12014-02-06 16:55:32 -0800108 Set<Device> devices = addr2Device.get(ipAddress);
109 if (devices == null) {
Yuta HIGUCHI8d9fddf2014-02-10 13:32:16 -0800110 return Collections.emptySet();
Toshio Koide2f570c12014-02-06 16:55:32 -0800111 }
112 return Collections.unmodifiableCollection(devices);
113 }
114
115 @Override
Toshio Koide6c9b7e82014-02-07 18:01:32 -0800116 public Device getDeviceByMac(MACAddress address) {
117 return mac2Device.get(address);
Toshio Koide2f570c12014-02-06 16:55:32 -0800118 }
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800119
120 protected void putDevice(Device device) {
121 mac2Device.put(device.getMacAddress(), device);
122 for (InetAddress ipAddr : device.getIpAddress()) {
123 Set<Device> devices = addr2Device.get(ipAddr);
124 if (devices == null) {
125 devices = new HashSet<>();
126 addr2Device.put(ipAddr, devices);
127 }
128 devices.add(device);
129 }
130 }
131
132 protected void removeDevice(Device device) {
133 mac2Device.remove(device.getMacAddress());
134 for (InetAddress ipAddr : device.getIpAddress()) {
135 Set<Device> devices = addr2Device.get(ipAddr);
136 if (devices != null) {
137 devices.remove(device);
138 if (devices.isEmpty())
139 addr2Device.remove(ipAddr);
140 }
141 }
142 }
Jonathan Hart26f291b2014-02-18 16:57:24 -0800143
144 @Override
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800145 public void acquireReadLock() {
Jonathan Hart26f291b2014-02-18 16:57:24 -0800146 readLock.lock();
147 }
148
149 @Override
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800150 public void releaseReadLock() {
Jonathan Hart26f291b2014-02-18 16:57:24 -0800151 readLock.unlock();
152 }
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800153
154 protected void acquireWriteLock() {
155 writeLock.lock();
156 }
157
158 protected void releaseWriteLock() {
159 writeLock.unlock();
160 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800161}