blob: e95c4179ee0dee8ea0d4fc756ca493017c2c2c0d [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;
20import com.google.common.collect.ImmutableSet;
21import org.onosproject.net.ConnectPoint;
22import org.onosproject.net.HostId;
23
24import java.util.Collection;
25import java.util.Map;
26import java.util.Objects;
27import java.util.Set;
28import java.util.concurrent.ConcurrentHashMap;
29import java.util.stream.Collectors;
30
31import static com.google.common.base.MoreObjects.toStringHelper;
32import static com.google.common.base.Preconditions.checkArgument;
33import static com.google.common.base.Preconditions.checkNotNull;
34
35/**
36 * Data regarding a multicast route, comprised of a type, multiple sources and multiple sinks.
37 */
38@Beta
39public final class McastRouteData {
40
41 private final ConcurrentHashMap<ConnectPoint, Boolean> sources = new ConcurrentHashMap<>();
42 private final ConcurrentHashMap<HostId, Set<ConnectPoint>> sinks = new ConcurrentHashMap<>();
43
44 private McastRouteData() {
45 }
46
47 /**
48 * Sources contained in the associated route.
49 *
50 * @return set of sources
51 */
52 public Set<ConnectPoint> sources() {
53 return ImmutableSet.copyOf(sources.keySet());
54 }
55
56 /**
57 * Sources contained in the associated route.
58 *
59 * @return map of hostIds and associated sinks
60 */
61 public Map<HostId, Set<ConnectPoint>> sinks() {
62 return ImmutableMap.copyOf(sinks);
63 }
64
65 /**
66 * Sources contained in the associated route.
67 *
68 * @return map of hostIds and associated sinks
69 */
70 public Set<ConnectPoint> allSinks() {
71 return sinks.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
72 }
73
74 /**
75 * Sinks contained in the associated route for the given host.
76 *
77 * @param hostId the host
78 * @return set of sinks
79 */
80 public Set<ConnectPoint> sinks(HostId hostId) {
81 return sinks.get(hostId);
82 }
83
84 /**
85 * Sinks contained in the associated route that are not bound to any host.
86 *
87 * @return set of sinks
88 */
89 public Set<ConnectPoint> nonHostSinks() {
90 return sinks.get(HostId.NONE);
91 }
92
93 /**
94 * Add the sources for the associated route.
95 *
96 * @param sources set of sources
97 */
98 public void addSources(Set<ConnectPoint> sources) {
99 checkArgument(!sources.contains(null));
Andrea Campanella7c8bcdf2018-03-26 23:29:11 -0700100 sources.forEach(source -> this.sources.put(source, true));
Andrea Campanella545edb42018-03-20 16:37:29 -0700101 }
102
103 /**
104 * Removes all the sources contained in the associated route.
105 */
106 public void removeSources() {
107 sources.clear();
108 }
109
110 /**
111 * Removes the given sources contained in the associated route.
112 *
113 * @param sources the sources to remove
114 */
115 public void removeSources(Set<ConnectPoint> sources) {
116 checkArgument(!sources.contains(null));
117 sources.forEach(this.sources::remove);
118 }
119
120 /**
121 * Adds sinks for a given host Id. If the Host Id is {@link HostId#NONE} the sinks are intended to be
122 * used at all times independently of the attached host.
123 *
124 * @param hostId the host
125 * @param sinks the sinks
126 */
127 public void addSinks(HostId hostId, Set<ConnectPoint> sinks) {
128 checkNotNull(hostId);
129 checkArgument(!sinks.contains(null));
Andrea Campanella7c8bcdf2018-03-26 23:29:11 -0700130 //if existing we add to current set, otherwise we put them all
131 if (this.sinks.containsKey(hostId)) {
132 this.sinks.get(hostId).addAll(sinks);
133 } else {
134 this.sinks.put(hostId, sinks);
135 }
Andrea Campanella545edb42018-03-20 16:37:29 -0700136 }
137
138 /**
139 * Adds sink for this route that are not associated directly with a given host.
140 *
141 * @param sinks the sinks
142 */
143 public void addNonHostSinks(Set<ConnectPoint> sinks) {
144 checkArgument(!sinks.contains(null));
145 this.sinks.put(HostId.NONE, sinks);
146 }
147
148 /**
149 * Removes all the sinks for this route.
150 */
151 public void removeSinks() {
152 sinks.clear();
153 }
154
155 /**
156 * Removes all the sinks for the given host for this route.
157 *
158 * @param hostId the host
159 */
160 public void removeSinks(HostId hostId) {
161 checkNotNull(hostId);
162 this.sinks.remove(hostId);
163 }
164
165 /**
166 * Removes all the given sinks for the given host for this route.
167 *
168 * @param hostId the host
169 * @param sinks the sinks to remove
170 */
171 public void removeSinks(HostId hostId, Set<ConnectPoint> sinks) {
172 checkNotNull(hostId);
173 checkArgument(!sinks.contains(null));
Andrea Campanella7c8bcdf2018-03-26 23:29:11 -0700174 //if existing we remove from current set, otherwise just skip them
175 if (this.sinks.containsKey(hostId)) {
176 this.sinks.get(hostId).removeAll(sinks);
177 }
Andrea Campanella545edb42018-03-20 16:37:29 -0700178 }
179
180 /**
181 * Returns if the route has no sinks.
182 *
183 * @return true if no sinks
184 */
185 public boolean isEmpty() {
186 return sinks.isEmpty();
187 }
188
189 /**
190 * Creates an empty route object.
191 *
192 * @return an empty muticast rout data object.
193 */
194 public static McastRouteData empty() {
195 return new McastRouteData();
196 }
197
198 @Override
199 public int hashCode() {
200 return Objects.hash(super.hashCode(), sources, sinks);
201 }
202
203 @Override
204 public boolean equals(Object obj) {
205 if (this == obj) {
206 return true;
207 }
208 if (!(obj instanceof McastRouteData)) {
209 return false;
210 }
211 final McastRouteData other = (McastRouteData) obj;
212
213 return super.equals(obj) &&
214 Objects.equals(sources(), other.sources()) &&
215 Objects.equals(sinks(), other.sinks());
216 }
217
218 @Override
219 public String toString() {
220 return toStringHelper(this)
221 .add("sources", sources())
222 .add("sinks", sinks())
223 .toString();
224 }
225}