blob: 91c02d87e0eef5bc428be9a08043c8653ba04883 [file] [log] [blame]
tom578ebdc2014-09-11 11:12:51 -07001package org.onlab.onos.net.trivial.host.impl;
tom7869ad92014-09-09 14:32:08 -07002
alshabib51622f72014-09-11 11:22:33 -07003import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
4import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
5import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
6import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
7
8import java.util.Collections;
9import java.util.HashSet;
10import java.util.Map;
11import java.util.Set;
12import java.util.concurrent.ConcurrentHashMap;
tom7869ad92014-09-09 14:32:08 -070013
14import org.onlab.onos.net.ConnectPoint;
Ayaka Koshibee5652752014-09-10 23:27:34 -070015import org.onlab.onos.net.DefaultHost;
tom7869ad92014-09-09 14:32:08 -070016import org.onlab.onos.net.DeviceId;
17import org.onlab.onos.net.Host;
18import org.onlab.onos.net.HostId;
19import org.onlab.onos.net.host.HostDescription;
20import org.onlab.onos.net.host.HostEvent;
21import org.onlab.onos.net.provider.ProviderId;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070022import org.onlab.packet.IpAddress;
23import org.onlab.packet.MacAddress;
24import org.onlab.packet.VlanId;
tom7869ad92014-09-09 14:32:08 -070025
Ayaka Koshibee5652752014-09-10 23:27:34 -070026import com.google.common.collect.HashMultimap;
27import com.google.common.collect.ImmutableSet;
28import com.google.common.collect.Multimap;
29
tom7869ad92014-09-09 14:32:08 -070030/**
31 * Manages inventory of end-station hosts using trivial in-memory
32 * implementation.
33 */
34public class SimpleHostStore {
35
36 private final Map<HostId, Host> hosts = new ConcurrentHashMap<>();
37
Ayaka Koshibee5652752014-09-10 23:27:34 -070038 // hosts sorted based on their location
39 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
tome615ee42014-09-11 10:52:10 -070040
tom7869ad92014-09-09 14:32:08 -070041 /**
42 * Creates a new host or updates the existing one based on the specified
43 * description.
44 *
45 * @param providerId provider identification
46 * @param hostId host identification
47 * @param hostDescription host description data
48 * @return appropriate event or null if no change resulted
49 */
50 HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
alshabib51622f72014-09-11 11:22:33 -070051 HostDescription hostDescription) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070052 Host host = hosts.get(hostId);
53 if (host == null) {
54 return createHost(providerId, hostId, hostDescription);
55 }
56 return updateHost(providerId, host, hostDescription);
57 }
58
59 // creates a new host and sends HOST_ADDED
60 private HostEvent createHost(ProviderId providerId, HostId hostId,
61 HostDescription descr) {
62 DefaultHost newhost = new DefaultHost(providerId, hostId,
63 descr.hwAddress(),
64 descr.vlan(),
65 descr.location(),
66 descr.ipAddresses());
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070067 synchronized (this) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070068 hosts.put(hostId, newhost);
69 locations.put(descr.location(), newhost);
70 }
71 return new HostEvent(HOST_ADDED, newhost);
72 }
73
74 // checks for type of update to host, sends appropriate event
75 private HostEvent updateHost(ProviderId providerId, Host host,
76 HostDescription descr) {
77 DefaultHost updated;
78 HostEvent event;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070079 // Consider only actual location (not timestamp) change?
80 if (!(host.location().port().equals(descr.location().port()))) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070081 updated = new DefaultHost(providerId, host.id(),
82 host.mac(),
83 host.vlan(),
84 descr.location(),
85 host.ipAddresses());
86 event = new HostEvent(HOST_MOVED, updated);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070087 } else if (!(host.ipAddresses().equals(descr.ipAddresses()))) {
88 updated = new DefaultHost(providerId, host.id(),
89 host.mac(),
90 host.vlan(),
91 descr.location(),
92 descr.ipAddresses());
93 event = new HostEvent(HOST_UPDATED, updated);
94 } else {
95 return null;
Ayaka Koshibee5652752014-09-10 23:27:34 -070096 }
97 synchronized (this) {
98 hosts.put(host.id(), updated);
99 locations.remove(host.location(), host);
100 locations.put(updated.location(), updated);
101 }
102 return event;
tom7869ad92014-09-09 14:32:08 -0700103 }
104
105 /**
106 * Removes the specified host from the inventory.
107 *
108 * @param hostId host identification
109 * @return remove even or null if host was not found
110 */
111 HostEvent removeHost(HostId hostId) {
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700112 synchronized (this) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700113 Host host = hosts.remove(hostId);
114 if (host != null) {
115 locations.remove((host.location()), host);
116 return new HostEvent(HOST_REMOVED, host);
117 }
118 return null;
119 }
tom7869ad92014-09-09 14:32:08 -0700120 }
121
122 /**
123 * Returns the number of hosts in the store.
124 *
125 * @return host count
126 */
127 int getHostCount() {
128 return hosts.size();
129 }
130
131 /**
132 * Returns a collection of all hosts in the store.
133 *
134 * @return iterable collection of all hosts
135 */
136 Iterable<Host> getHosts() {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700137 return Collections.unmodifiableSet(new HashSet<Host>(hosts.values()));
tom7869ad92014-09-09 14:32:08 -0700138 }
139
140 /**
141 * Returns the host with the specified identifer.
142 *
143 * @param hostId host identification
144 * @return host or null if not found
145 */
146 Host getHost(HostId hostId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700147 return hosts.get(hostId);
tom7869ad92014-09-09 14:32:08 -0700148 }
149
150 /**
151 * Returns the set of all hosts within the specified VLAN.
152 *
153 * @param vlanId vlan id
154 * @return set of hosts in the vlan
155 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700156 Set<Host> getHosts(VlanId vlanId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700157 Set<Host> vlanset = new HashSet<Host>();
158 for (Host h : hosts.values()) {
Ayaka Koshibe04a1a4e2014-09-11 14:31:29 -0700159 if (h.vlan().equals(vlanId)) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700160 vlanset.add(h);
161 }
162 }
163 return vlanset;
tom7869ad92014-09-09 14:32:08 -0700164 }
165
166 /**
167 * Returns the set of hosts with the specified MAC address.
168 *
169 * @param mac mac address
170 * @return set of hosts with the given mac
171 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700172 Set<Host> getHosts(MacAddress mac) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700173 Set<Host> macset = new HashSet<>();
174 for (Host h : hosts.values()) {
175 if (h.mac().equals(mac)) {
176 macset.add(h);
177 }
178 }
179 return macset;
tom7869ad92014-09-09 14:32:08 -0700180 }
181
182 /**
183 * Returns the set of hosts with the specified IP address.
184 *
185 * @param ip ip address
186 * @return set of hosts with the given IP
187 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700188 Set<Host> getHosts(IpAddress ip) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700189 Set<Host> ipset = new HashSet<>();
190 for (Host h : hosts.values()) {
191 if (h.ipAddresses().contains(ip)) {
192 ipset.add(h);
193 }
194 }
195 return ipset;
tom7869ad92014-09-09 14:32:08 -0700196 }
197
198 /**
199 * Returns the set of hosts whose location falls on the given connection point.
200 *
201 * @param connectPoint connection point
202 * @return set of hosts
203 */
204 Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700205 return ImmutableSet.copyOf(locations.get(connectPoint));
tom7869ad92014-09-09 14:32:08 -0700206 }
207
208 /**
209 * Returns the set of hosts whose location falls on the given device.
210 *
211 * @param deviceId infrastructure device identifier
212 * @return set of hosts
213 */
214 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700215 Set<Host> hostset = new HashSet<>();
216 for (ConnectPoint p : locations.keySet()) {
217 if (p.deviceId().equals(deviceId)) {
218 hostset.addAll(locations.get(p));
219 }
220 }
221 return hostset;
tom7869ad92014-09-09 14:32:08 -0700222 }
223
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700224}