blob: e142de79e1978b7ec9322f2c6627a5e1e5d13237 [file] [log] [blame]
tom7869ad92014-09-09 14:32:08 -07001package org.onlab.onos.net.trivial.impl;
2
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;
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070011import org.onlab.packet.IPAddress;
tom7869ad92014-09-09 14:32:08 -070012import 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();
tom7869ad92014-09-09 14:32:08 -070039 /**
40 * Creates a new host or updates the existing one based on the specified
41 * description.
42 *
43 * @param providerId provider identification
44 * @param hostId host identification
45 * @param hostDescription host description data
46 * @return appropriate event or null if no change resulted
47 */
48 HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
49 HostDescription hostDescription) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070050 Host host = hosts.get(hostId);
51 if (host == null) {
52 return createHost(providerId, hostId, hostDescription);
53 }
54 return updateHost(providerId, host, hostDescription);
55 }
56
57 // creates a new host and sends HOST_ADDED
58 private HostEvent createHost(ProviderId providerId, HostId hostId,
59 HostDescription descr) {
60 DefaultHost newhost = new DefaultHost(providerId, hostId,
61 descr.hwAddress(),
62 descr.vlan(),
63 descr.location(),
64 descr.ipAddresses());
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070065 synchronized (this) {
Ayaka Koshibee5652752014-09-10 23:27:34 -070066 hosts.put(hostId, newhost);
67 locations.put(descr.location(), newhost);
68 }
69 return new HostEvent(HOST_ADDED, newhost);
70 }
71
72 // checks for type of update to host, sends appropriate event
73 private HostEvent updateHost(ProviderId providerId, Host host,
74 HostDescription descr) {
75 DefaultHost updated;
76 HostEvent event;
77 if (host.location().equals(descr.location())) {
78 updated = new DefaultHost(providerId, host.id(),
79 host.mac(),
80 host.vlan(),
81 host.location(),
82 descr.ipAddresses());
83 event = new HostEvent(HOST_UPDATED, updated);
84 } else {
85 updated = new DefaultHost(providerId, host.id(),
86 host.mac(),
87 host.vlan(),
88 descr.location(),
89 host.ipAddresses());
90 event = new HostEvent(HOST_MOVED, updated);
91 }
92 synchronized (this) {
93 hosts.put(host.id(), updated);
94 locations.remove(host.location(), host);
95 locations.put(updated.location(), updated);
96 }
97 return event;
tom7869ad92014-09-09 14:32:08 -070098 }
99
100 /**
101 * Removes the specified host from the inventory.
102 *
103 * @param hostId host identification
104 * @return remove even or null if host was not found
105 */
106 HostEvent removeHost(HostId hostId) {
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700107 synchronized (this) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700108 Host host = hosts.remove(hostId);
109 if (host != null) {
110 locations.remove((host.location()), host);
111 return new HostEvent(HOST_REMOVED, host);
112 }
113 return null;
114 }
tom7869ad92014-09-09 14:32:08 -0700115 }
116
117 /**
118 * Returns the number of hosts in the store.
119 *
120 * @return host count
121 */
122 int getHostCount() {
123 return hosts.size();
124 }
125
126 /**
127 * Returns a collection of all hosts in the store.
128 *
129 * @return iterable collection of all hosts
130 */
131 Iterable<Host> getHosts() {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700132 return Collections.unmodifiableSet(new HashSet<Host>(hosts.values()));
tom7869ad92014-09-09 14:32:08 -0700133 }
134
135 /**
136 * Returns the host with the specified identifer.
137 *
138 * @param hostId host identification
139 * @return host or null if not found
140 */
141 Host getHost(HostId hostId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700142 return hosts.get(hostId);
tom7869ad92014-09-09 14:32:08 -0700143 }
144
145 /**
146 * Returns the set of all hosts within the specified VLAN.
147 *
148 * @param vlanId vlan id
149 * @return set of hosts in the vlan
150 */
151 Set<Host> getHosts(long vlanId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700152 Set<Host> vlanset = new HashSet<Host>();
153 for (Host h : hosts.values()) {
154 if (h.vlan() == vlanId) {
155 vlanset.add(h);
156 }
157 }
158 return vlanset;
tom7869ad92014-09-09 14:32:08 -0700159 }
160
161 /**
162 * Returns the set of hosts with the specified MAC address.
163 *
164 * @param mac mac address
165 * @return set of hosts with the given mac
166 */
167 Set<Host> getHosts(MACAddress mac) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700168 Set<Host> macset = new HashSet<>();
169 for (Host h : hosts.values()) {
170 if (h.mac().equals(mac)) {
171 macset.add(h);
172 }
173 }
174 return macset;
tom7869ad92014-09-09 14:32:08 -0700175 }
176
177 /**
178 * Returns the set of hosts with the specified IP address.
179 *
180 * @param ip ip address
181 * @return set of hosts with the given IP
182 */
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700183 Set<Host> getHosts(IPAddress ip) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700184 Set<Host> ipset = new HashSet<>();
185 for (Host h : hosts.values()) {
186 if (h.ipAddresses().contains(ip)) {
187 ipset.add(h);
188 }
189 }
190 return ipset;
tom7869ad92014-09-09 14:32:08 -0700191 }
192
193 /**
194 * Returns the set of hosts whose location falls on the given connection point.
195 *
196 * @param connectPoint connection point
197 * @return set of hosts
198 */
199 Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700200 return ImmutableSet.copyOf(locations.get(connectPoint));
tom7869ad92014-09-09 14:32:08 -0700201 }
202
203 /**
204 * Returns the set of hosts whose location falls on the given device.
205 *
206 * @param deviceId infrastructure device identifier
207 * @return set of hosts
208 */
209 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Ayaka Koshibee5652752014-09-10 23:27:34 -0700210 Set<Host> hostset = new HashSet<>();
211 for (ConnectPoint p : locations.keySet()) {
212 if (p.deviceId().equals(deviceId)) {
213 hostset.addAll(locations.get(p));
214 }
215 }
216 return hostset;
tom7869ad92014-09-09 14:32:08 -0700217 }
218
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700219}