blob: ff2098e2a63f5c9b2314ec514c854ddecd90a2ec [file] [log] [blame]
tom578ebdc2014-09-11 11:12:51 -07001package org.onlab.onos.net.trivial.host.impl;
tom7869ad92014-09-09 14:32:08 -07002
3import org.onlab.onos.net.ConnectPoint;
Ayaka Koshibee5652752014-09-10 23:27:34 -07004import org.onlab.onos.net.DefaultHost;
tom7869ad92014-09-09 14:32:08 -07005import org.onlab.onos.net.DeviceId;
6import org.onlab.onos.net.Host;
7import org.onlab.onos.net.HostId;
8import org.onlab.onos.net.host.HostDescription;
9import org.onlab.onos.net.host.HostEvent;
10import org.onlab.onos.net.provider.ProviderId;
11import org.onlab.packet.IPv4;
12import org.onlab.packet.MACAddress;
13
Ayaka Koshibee5652752014-09-10 23:27:34 -070014import com.google.common.collect.HashMultimap;
15import com.google.common.collect.ImmutableSet;
16import com.google.common.collect.Multimap;
17
18import java.util.Collections;
19import java.util.HashSet;
tom7869ad92014-09-09 14:32:08 -070020import java.util.Map;
21import java.util.Set;
22import java.util.concurrent.ConcurrentHashMap;
23
Ayaka Koshibee5652752014-09-10 23:27:34 -070024import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
25import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
26import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
27import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
28
tom7869ad92014-09-09 14:32:08 -070029/**
30 * Manages inventory of end-station hosts using trivial in-memory
31 * implementation.
32 */
33public class SimpleHostStore {
34
35 private final Map<HostId, Host> hosts = new ConcurrentHashMap<>();
36
Ayaka Koshibee5652752014-09-10 23:27:34 -070037 // hosts sorted based on their location
38 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
tome615ee42014-09-11 10:52:10 -070039
tom7869ad92014-09-09 14:32:08 -070040 /**
41 * Creates a new host or updates the existing one based on the specified
42 * description.
43 *
44 * @param providerId provider identification
45 * @param hostId host identification
46 * @param hostDescription host description data
47 * @return appropriate event or null if no change resulted
48 */
49 HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
50 HostDescription hostDescription) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070051 Host host = hosts.get(hostId);
52 if (host == null) {
53 return createHost(providerId, hostId, hostDescription);
54 }
55 return updateHost(providerId, host, hostDescription);
56 }
57
58 // creates a new host and sends HOST_ADDED
59 private HostEvent createHost(ProviderId providerId, HostId hostId,
tome615ee42014-09-11 10:52:10 -070060 HostDescription descr) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070061 DefaultHost newhost = new DefaultHost(providerId, hostId,
tome615ee42014-09-11 10:52:10 -070062 descr.hwAddress(),
63 descr.vlan(),
64 descr.location(),
65 descr.ipAddresses());
66 synchronized (this) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070067 hosts.put(hostId, newhost);
68 locations.put(descr.location(), newhost);
69 }
70 return new HostEvent(HOST_ADDED, newhost);
71 }
72
73 // checks for type of update to host, sends appropriate event
74 private HostEvent updateHost(ProviderId providerId, Host host,
tome615ee42014-09-11 10:52:10 -070075 HostDescription descr) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070076 DefaultHost updated;
77 HostEvent event;
78 if (host.location().equals(descr.location())) {
79 updated = new DefaultHost(providerId, host.id(),
tome615ee42014-09-11 10:52:10 -070080 host.mac(),
81 host.vlan(),
82 host.location(),
83 descr.ipAddresses());
Ayaka Koshibee5652752014-09-10 23:27:34 -070084 event = new HostEvent(HOST_UPDATED, updated);
85 } else {
86 updated = new DefaultHost(providerId, host.id(),
tome615ee42014-09-11 10:52:10 -070087 host.mac(),
88 host.vlan(),
89 descr.location(),
90 host.ipAddresses());
Ayaka Koshibee5652752014-09-10 23:27:34 -070091 event = new HostEvent(HOST_MOVED, updated);
92 }
93 synchronized (this) {
94 hosts.put(host.id(), updated);
95 locations.remove(host.location(), host);
96 locations.put(updated.location(), updated);
97 }
98 return event;
tom7869ad92014-09-09 14:32:08 -070099 }
100
101 /**
102 * Removes the specified host from the inventory.
103 *
104 * @param hostId host identification
105 * @return remove even or null if host was not found
106 */
107 HostEvent removeHost(HostId hostId) {
tome615ee42014-09-11 10:52:10 -0700108 synchronized (this) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700109 Host host = hosts.remove(hostId);
110 if (host != null) {
111 locations.remove((host.location()), host);
112 return new HostEvent(HOST_REMOVED, host);
113 }
114 return null;
115 }
tom7869ad92014-09-09 14:32:08 -0700116 }
117
118 /**
119 * Returns the number of hosts in the store.
120 *
121 * @return host count
122 */
123 int getHostCount() {
124 return hosts.size();
125 }
126
127 /**
128 * Returns a collection of all hosts in the store.
129 *
130 * @return iterable collection of all hosts
131 */
132 Iterable<Host> getHosts() {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700133 return Collections.unmodifiableSet(new HashSet<Host>(hosts.values()));
tom7869ad92014-09-09 14:32:08 -0700134 }
135
136 /**
137 * Returns the host with the specified identifer.
138 *
139 * @param hostId host identification
140 * @return host or null if not found
141 */
142 Host getHost(HostId hostId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700143 return hosts.get(hostId);
tom7869ad92014-09-09 14:32:08 -0700144 }
145
146 /**
147 * Returns the set of all hosts within the specified VLAN.
148 *
149 * @param vlanId vlan id
150 * @return set of hosts in the vlan
151 */
152 Set<Host> getHosts(long vlanId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700153 Set<Host> vlanset = new HashSet<Host>();
154 for (Host h : hosts.values()) {
155 if (h.vlan() == vlanId) {
156 vlanset.add(h);
157 }
158 }
159 return vlanset;
tom7869ad92014-09-09 14:32:08 -0700160 }
161
162 /**
163 * Returns the set of hosts with the specified MAC address.
164 *
165 * @param mac mac address
166 * @return set of hosts with the given mac
167 */
168 Set<Host> getHosts(MACAddress mac) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700169 Set<Host> macset = new HashSet<>();
170 for (Host h : hosts.values()) {
171 if (h.mac().equals(mac)) {
172 macset.add(h);
173 }
174 }
175 return macset;
tom7869ad92014-09-09 14:32:08 -0700176 }
177
178 /**
179 * Returns the set of hosts with the specified IP address.
180 *
181 * @param ip ip address
182 * @return set of hosts with the given IP
183 */
184 Set<Host> getHosts(IPv4 ip) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700185 Set<Host> ipset = new HashSet<>();
186 for (Host h : hosts.values()) {
187 if (h.ipAddresses().contains(ip)) {
188 ipset.add(h);
189 }
190 }
191 return ipset;
tom7869ad92014-09-09 14:32:08 -0700192 }
193
194 /**
195 * Returns the set of hosts whose location falls on the given connection point.
196 *
197 * @param connectPoint connection point
198 * @return set of hosts
199 */
200 Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700201 return ImmutableSet.copyOf(locations.get(connectPoint));
tom7869ad92014-09-09 14:32:08 -0700202 }
203
204 /**
205 * Returns the set of hosts whose location falls on the given device.
206 *
207 * @param deviceId infrastructure device identifier
208 * @return set of hosts
209 */
210 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700211 Set<Host> hostset = new HashSet<>();
212 for (ConnectPoint p : locations.keySet()) {
213 if (p.deviceId().equals(deviceId)) {
214 hostset.addAll(locations.get(p));
215 }
216 }
217 return hostset;
tom7869ad92014-09-09 14:32:08 -0700218 }
219
tome615ee42014-09-11 10:52:10 -0700220}