blob: d690821b2d1a4900e284b0fda5999fe03dce7fc3 [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
Toshio Koide2f570c12014-02-06 16:55:32 -080073 public Iterable<Link> getLinks() {
74 List<Link> linklist = new LinkedList<>();
75
76 for (Switch sw : switches.values()) {
77 Iterable<Link> links = sw.getOutgoingLinks();
78 for (Link l : links) {
79 linklist.add(l);
80 }
81 }
82 return linklist;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080083 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080084
Toshio Koide2f570c12014-02-06 16:55:32 -080085 @Override
86 public Iterable<Link> getOutgoingLinksFromSwitch(Long dpid) {
87 Switch sw = getSwitch(dpid);
88 if (sw == null) {
89 return Collections.emptyList();
90 }
91 Iterable<Link> links = sw.getOutgoingLinks();
92 if (links instanceof Collection) {
93 return Collections.unmodifiableCollection((Collection<Link>) links);
94 } else {
95 List<Link> linklist = new LinkedList<>();
96 for (Link l : links) {
97 linklist.add(l);
98 }
99 return linklist;
100 }
101 }
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -0800102
Toshio Koide2f570c12014-02-06 16:55:32 -0800103 @Override
104 public Iterable<Link> getIncomingLinksFromSwitch(Long dpid) {
105 Switch sw = getSwitch(dpid);
106 if (sw == null) {
107 return Collections.emptyList();
108 }
109 Iterable<Link> links = sw.getIncomingLinks();
110 if (links instanceof Collection) {
111 return Collections.unmodifiableCollection((Collection<Link>) links);
112 } else {
113 List<Link> linklist = new LinkedList<>();
114 for (Link l : links) {
115 linklist.add(l);
116 }
117 return linklist;
118 }
119 }
120
121
122 @Override
Pavlin Radoslavov06df22a2014-02-18 19:16:27 -0800123 public Iterable<Device> getDevicesByIp(InetAddress ipAddress) {
Toshio Koide2f570c12014-02-06 16:55:32 -0800124 Set<Device> devices = addr2Device.get(ipAddress);
125 if (devices == null) {
Yuta HIGUCHI8d9fddf2014-02-10 13:32:16 -0800126 return Collections.emptySet();
Toshio Koide2f570c12014-02-06 16:55:32 -0800127 }
128 return Collections.unmodifiableCollection(devices);
129 }
130
131 @Override
Toshio Koide6c9b7e82014-02-07 18:01:32 -0800132 public Device getDeviceByMac(MACAddress address) {
133 return mac2Device.get(address);
Toshio Koide2f570c12014-02-06 16:55:32 -0800134 }
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800135
136 protected void putDevice(Device device) {
137 mac2Device.put(device.getMacAddress(), device);
138 for (InetAddress ipAddr : device.getIpAddress()) {
139 Set<Device> devices = addr2Device.get(ipAddr);
140 if (devices == null) {
141 devices = new HashSet<>();
142 addr2Device.put(ipAddr, devices);
143 }
144 devices.add(device);
145 }
146 }
147
148 protected void removeDevice(Device device) {
149 mac2Device.remove(device.getMacAddress());
150 for (InetAddress ipAddr : device.getIpAddress()) {
151 Set<Device> devices = addr2Device.get(ipAddr);
152 if (devices != null) {
153 devices.remove(device);
154 if (devices.isEmpty())
155 addr2Device.remove(ipAddr);
156 }
157 }
158 }
Jonathan Hart26f291b2014-02-18 16:57:24 -0800159
160 @Override
161 public void acquireLock() {
162 readLock.lock();
163 }
164
165 @Override
166 public void releaseLock() {
167 readLock.unlock();
168 }
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800169}