blob: a343c39f4fb0c1a35b64ec5ccb8a8d5c7dba8cf0 [file] [log] [blame]
Andrea Campanella545edb42018-03-20 16:37:29 -07001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.mcast.api;
17
18import com.google.common.annotations.Beta;
19import com.google.common.collect.ImmutableMap;
Andrea Campanella545edb42018-03-20 16:37:29 -070020import org.onosproject.net.ConnectPoint;
21import org.onosproject.net.HostId;
22
23import java.util.Collection;
24import java.util.Map;
25import java.util.Objects;
26import java.util.Set;
27import java.util.concurrent.ConcurrentHashMap;
28import java.util.stream.Collectors;
29
30import static com.google.common.base.MoreObjects.toStringHelper;
31import static com.google.common.base.Preconditions.checkArgument;
32import static com.google.common.base.Preconditions.checkNotNull;
33
34/**
35 * Data regarding a multicast route, comprised of a type, multiple sources and multiple sinks.
36 */
37@Beta
38public final class McastRouteData {
39
Andrea Campanella0ddf9b82018-04-27 15:54:42 +020040 private final ConcurrentHashMap<HostId, Set<ConnectPoint>> sources = new ConcurrentHashMap<>();
Andrea Campanella545edb42018-03-20 16:37:29 -070041 private final ConcurrentHashMap<HostId, Set<ConnectPoint>> sinks = new ConcurrentHashMap<>();
42
43 private McastRouteData() {
44 }
45
46 /**
47 * Sources contained in the associated route.
48 *
49 * @return set of sources
50 */
Andrea Campanella0ddf9b82018-04-27 15:54:42 +020051 public Map<HostId, Set<ConnectPoint>> sources() {
52 return ImmutableMap.copyOf(sources);
Andrea Campanella545edb42018-03-20 16:37:29 -070053 }
54
55 /**
56 * Sources contained in the associated route.
57 *
Andrea Campanella0ddf9b82018-04-27 15:54:42 +020058 * @return map of hostIds and associated sources
59 */
60 public Set<ConnectPoint> allSources() {
61 return sources.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
62 }
63
64 /**
65 * Sources contained in the associated route for the given host.
66 *
67 * @param hostId the host
68 * @return set of sources
69 */
70 public Set<ConnectPoint> sources(HostId hostId) {
71 return sources.get(hostId);
72 }
73
74 /**
75 * Sources contained in the associated route that are not bound to any host.
76 *
77 * @return set of sources
78 */
79 public Set<ConnectPoint> nonHostSources() {
80 return sources.get(HostId.NONE);
81 }
82
83 /**
84 * Sinks contained in the associated route.
85 *
Andrea Campanella545edb42018-03-20 16:37:29 -070086 * @return map of hostIds and associated sinks
87 */
88 public Map<HostId, Set<ConnectPoint>> sinks() {
89 return ImmutableMap.copyOf(sinks);
90 }
91
92 /**
93 * Sources contained in the associated route.
94 *
95 * @return map of hostIds and associated sinks
96 */
97 public Set<ConnectPoint> allSinks() {
98 return sinks.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
99 }
100
101 /**
102 * Sinks contained in the associated route for the given host.
103 *
104 * @param hostId the host
105 * @return set of sinks
106 */
107 public Set<ConnectPoint> sinks(HostId hostId) {
108 return sinks.get(hostId);
109 }
110
111 /**
112 * Sinks contained in the associated route that are not bound to any host.
113 *
114 * @return set of sinks
115 */
116 public Set<ConnectPoint> nonHostSinks() {
117 return sinks.get(HostId.NONE);
118 }
119
120 /**
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200121 * Adds sources for a given host Id. If the Host Id is {@link HostId#NONE} the sources are intended to be
122 * used at all times independently of the attached host.
Andrea Campanella545edb42018-03-20 16:37:29 -0700123 *
Ilayda Ozdemirad741712020-06-10 08:31:27 +0000124 * @param hostId the host
125 * @param sources the sources
Andrea Campanella545edb42018-03-20 16:37:29 -0700126 */
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200127 public void addSources(HostId hostId, Set<ConnectPoint> sources) {
128 checkNotNull(hostId);
Andrea Campanella545edb42018-03-20 16:37:29 -0700129 checkArgument(!sources.contains(null));
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200130 //if existing we add to current set, otherwise we put them all
131 this.sources.compute(hostId, (host, existingSources) -> {
132 if (existingSources != null) {
133 existingSources.addAll(sources);
134 return existingSources;
135 } else {
136 return sources;
137 }
138 });
139 }
140
141 /**
142 * Adds sources for this route that are not associated directly with a given host.
143 *
144 * @param sources the sources
145 */
146 public void addNonHostSources(Set<ConnectPoint> sources) {
147 checkArgument(!sources.contains(null));
148 addSources(HostId.NONE, sources);
Andrea Campanella545edb42018-03-20 16:37:29 -0700149 }
150
151 /**
152 * Removes all the sources contained in the associated route.
153 */
154 public void removeSources() {
155 sources.clear();
156 }
157
158 /**
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200159 * Removes the given source contained in the associated route.
Andrea Campanella545edb42018-03-20 16:37:29 -0700160 *
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200161 * @param source the source to remove
162 */
163 public void removeSource(HostId source) {
164 checkNotNull(source);
165 sources.remove(source);
166 }
167
168 /**
169 * Removes all the given sources for the given host for this route.
170 *
171 * @param hostId the host
Andrea Campanella545edb42018-03-20 16:37:29 -0700172 * @param sources the sources to remove
173 */
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200174 public void removeSources(HostId hostId, Set<ConnectPoint> sources) {
175 checkNotNull(hostId);
Andrea Campanella545edb42018-03-20 16:37:29 -0700176 checkArgument(!sources.contains(null));
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200177 //if existing we remove from current set, otherwise just skip them
178 this.sources.compute(hostId, (host, existingSources) -> {
179 if (existingSources != null) {
180 existingSources.removeAll(sources);
181 }
182 return existingSources;
183 });
Andrea Campanella545edb42018-03-20 16:37:29 -0700184 }
185
186 /**
187 * Adds sinks for a given host Id. If the Host Id is {@link HostId#NONE} the sinks are intended to be
188 * used at all times independently of the attached host.
189 *
190 * @param hostId the host
191 * @param sinks the sinks
192 */
193 public void addSinks(HostId hostId, Set<ConnectPoint> sinks) {
194 checkNotNull(hostId);
195 checkArgument(!sinks.contains(null));
Andrea Campanella7c8bcdf2018-03-26 23:29:11 -0700196 //if existing we add to current set, otherwise we put them all
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200197 this.sinks.compute(hostId, (host, existingSinks) -> {
198 if (existingSinks != null) {
199 existingSinks.addAll(sinks);
200 return existingSinks;
201 } else {
202 return sinks;
203 }
204 });
Andrea Campanella545edb42018-03-20 16:37:29 -0700205 }
206
207 /**
208 * Adds sink for this route that are not associated directly with a given host.
209 *
210 * @param sinks the sinks
211 */
212 public void addNonHostSinks(Set<ConnectPoint> sinks) {
213 checkArgument(!sinks.contains(null));
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200214 this.addSinks(HostId.NONE, sinks);
Andrea Campanella545edb42018-03-20 16:37:29 -0700215 }
216
217 /**
218 * Removes all the sinks for this route.
219 */
220 public void removeSinks() {
221 sinks.clear();
222 }
223
224 /**
225 * Removes all the sinks for the given host for this route.
226 *
227 * @param hostId the host
228 */
229 public void removeSinks(HostId hostId) {
230 checkNotNull(hostId);
231 this.sinks.remove(hostId);
232 }
233
234 /**
235 * Removes all the given sinks for the given host for this route.
236 *
237 * @param hostId the host
238 * @param sinks the sinks to remove
239 */
240 public void removeSinks(HostId hostId, Set<ConnectPoint> sinks) {
241 checkNotNull(hostId);
242 checkArgument(!sinks.contains(null));
Andrea Campanella7c8bcdf2018-03-26 23:29:11 -0700243 //if existing we remove from current set, otherwise just skip them
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200244 this.sinks.compute(hostId, (host, existingSinks) -> {
245 if (existingSinks != null) {
246 existingSinks.removeAll(sinks);
247 }
248 return existingSinks;
249 });
Andrea Campanella545edb42018-03-20 16:37:29 -0700250 }
251
252 /**
253 * Returns if the route has no sinks.
254 *
255 * @return true if no sinks
256 */
257 public boolean isEmpty() {
258 return sinks.isEmpty();
259 }
260
261 /**
262 * Creates an empty route object.
263 *
264 * @return an empty muticast rout data object.
265 */
266 public static McastRouteData empty() {
267 return new McastRouteData();
268 }
269
270 @Override
271 public int hashCode() {
272 return Objects.hash(super.hashCode(), sources, sinks);
273 }
274
275 @Override
276 public boolean equals(Object obj) {
277 if (this == obj) {
278 return true;
279 }
280 if (!(obj instanceof McastRouteData)) {
281 return false;
282 }
283 final McastRouteData other = (McastRouteData) obj;
284
285 return super.equals(obj) &&
286 Objects.equals(sources(), other.sources()) &&
287 Objects.equals(sinks(), other.sinks());
288 }
289
290 @Override
291 public String toString() {
292 return toStringHelper(this)
293 .add("sources", sources())
294 .add("sinks", sinks())
295 .toString();
296 }
297}