blob: 84cac7b8fc3dc7dc188c564b2c475965958b198b [file] [log] [blame]
Hyunsun Mooneaf75e62016-09-27 16:40:23 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
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 */
Hyunsun Moonfd5a24e2016-10-19 19:15:48 -070016package org.opencord.cordvtn.api.net;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070017
18import com.google.common.base.MoreObjects;
19import com.google.common.base.Strings;
20import com.google.common.collect.ImmutableSet;
21import com.google.common.collect.Sets;
22import org.onlab.packet.IpAddress;
23import org.onlab.packet.IpPrefix;
Hyunsun Moonfd5a24e2016-10-19 19:15:48 -070024import org.opencord.cordvtn.api.dependency.Dependency;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070025import org.openstack4j.model.network.Network;
26import org.openstack4j.model.network.Subnet;
27
28import java.util.Objects;
29import java.util.Set;
30
31import static com.google.common.base.Preconditions.checkArgument;
32import static com.google.common.base.Preconditions.checkNotNull;
Hyunsun Moonfd5a24e2016-10-19 19:15:48 -070033import static org.opencord.cordvtn.api.net.ServiceNetwork.ServiceNetworkType.PRIVATE;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070034
35/**
Hyunsun Moon5c143952016-10-19 18:34:46 -070036 * Representation of a network holding the basic virtual network and additional
37 * service network specific information.
Hyunsun Moonfd5a24e2016-10-19 19:15:48 -070038 * All the services making use of CordVtnService are intended to interface
Hyunsun Moon5c143952016-10-19 18:34:46 -070039 * with this VtnNetwork, and not allowed to directly access {@link Network} or
40 * {@link ServiceNetwork}.
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070041 */
42public final class VtnNetwork extends ServiceNetwork {
43
44 private static final String ERR_SEGMENT_ID_MISSING = "VTN network segment ID is missing";
45 private static final String ERR_GATEWAY_IP_MISSING = "VTN subnet gateway IP is missing";
46
47 private final SegmentId segmentId;
48 private final IpPrefix subnet;
49 private final IpAddress serviceIp;
50
51 private VtnNetwork(NetworkId id,
52 SegmentId segmentId,
53 IpPrefix subnet,
54 IpAddress serviceIp,
55 ServiceNetworkType type,
56 Set<ProviderNetwork> providers) {
57 super(id, type, providers);
58 this.segmentId = segmentId;
59 this.subnet = subnet;
60 this.serviceIp = serviceIp;
61 }
62
63 /**
64 * Returns the network ID.
65 *
66 * @return network id
67 */
68 public NetworkId id() {
69 return id;
70 }
71
72 /**
73 * Returns the segment ID of this network.
74 *
75 * @return segment id
76 */
77 public SegmentId segmentId() {
78 return segmentId;
79 }
80
81 /**
82 * Returns the subnet used in this network.
83 *
84 * @return subnet
85 */
86 public IpPrefix subnet() {
87 return subnet;
88 }
89
90 /**
91 * Returns the service IP address of this network.
92 *
93 * @return ip address
94 */
95 public IpAddress serviceIp() {
96 return serviceIp;
97 }
98
99 @Override
100 public boolean equals(Object obj) {
101 if (this == obj) {
102 return true;
103 }
104
105 if (obj instanceof VtnNetwork) {
106 VtnNetwork that = (VtnNetwork) obj;
107 if (Objects.equals(id, that.id) &&
108 Objects.equals(segmentId, that.segmentId) &&
109 Objects.equals(subnet, that.subnet) &&
110 Objects.equals(serviceIp, that.serviceIp) &&
111 Objects.equals(type, that.type) &&
112 Objects.equals(providers, that.providers)) {
113 return true;
114 }
115 }
116 return false;
117 }
118
119 @Override
120 public int hashCode() {
121 return Objects.hash(id, segmentId, subnet, serviceIp, type, providers);
122 }
123
124 @Override
125 public String toString() {
126 return MoreObjects.toStringHelper(getClass())
127 .add("id", id)
128 .add("segmentId", segmentId)
129 .add("subnet", subnet)
130 .add("serviceIp", serviceIp)
131 .add("type", type)
132 .add("providers", providers)
133 .toString();
134 }
135
136 /**
137 * Returns immutable VTN network with the supplied Neutron network, subnet,
138 * and additional service network information.
139 *
140 * @param network neutron network
141 * @param subnet neutron subnet
142 * @param serviceNet service network
143 * @return vtn network
144 */
145 public static VtnNetwork of(Network network, Subnet subnet, ServiceNetwork serviceNet) {
146 validateNeutronNetwork(network, subnet);
147 if (serviceNet != null) {
148 checkArgument(Objects.equals(network.getId(), serviceNet.id().id()));
149 }
150
151 return builder().id(NetworkId.of(network.getId()))
152 .segmentId(SegmentId.of(Long.valueOf(network.getProviderSegID())))
153 .subnet(IpPrefix.valueOf(subnet.getCidr()))
154 .serviceIp(IpAddress.valueOf(subnet.getGateway()))
155 .type(serviceNet == null ? PRIVATE : serviceNet.type())
156 .providers(serviceNet == null ? ImmutableSet.of() : serviceNet.providers())
157 .build();
158 }
159
160 private static void validateNeutronNetwork(Network network, Subnet subnet) {
161 checkNotNull(network);
162 checkNotNull(subnet);
163 checkArgument(Objects.equals(network.getId(), subnet.getNetworkId()));
164 checkArgument(!Strings.isNullOrEmpty(network.getProviderSegID()), ERR_SEGMENT_ID_MISSING);
165 checkArgument(!Strings.isNullOrEmpty(subnet.getGateway()), ERR_GATEWAY_IP_MISSING);
166 }
167
168 /**
169 * Returns new vtn network builder instance.
170 *
171 * @return vtn network builder
172 */
173 public static Builder builder() {
174 return new Builder();
175 }
176
177 /**
178 * Returns new vtn network builder instance with copy of the given vtn network.
179 *
180 * @param vtnNet vtn network
181 * @return vtn network builder
182 */
183 public static Builder builder(VtnNetwork vtnNet) {
184 return new Builder()
185 .id(vtnNet.id())
186 .segmentId(vtnNet.segmentId())
187 .subnet(vtnNet.subnet())
188 .serviceIp(vtnNet.serviceIp())
189 .type(vtnNet.type())
190 .providers(vtnNet.providers());
191 }
192
193 /**
194 * Builder of the vtn network entities.
195 */
196 public static final class Builder {
197 private NetworkId id;
198 private SegmentId segmentId;
199 private IpPrefix subnet;
200 private IpAddress serviceIp;
201 private ServiceNetworkType type;
202 private Set<ProviderNetwork> providers = ImmutableSet.of();
203
204 private Builder() {
205 }
206
207 /**
208 * Builds an immutable vtn network.
209 *
210 * @return vtn network instance
211 */
212 public VtnNetwork build() {
213 checkNotNull(id, "VTN network id cannot be null");
214 checkNotNull(segmentId, "VTN network segment id cannot be null");
215 checkNotNull(subnet, "VTN network subnet cannot be null");
216 checkNotNull(serviceIp, "VTN network service IP cannot be null");
217 checkNotNull(type, "VTN network type cannot be null");
218 providers = providers == null ? ImmutableSet.of() : providers;
219
220 return new VtnNetwork(id, segmentId, subnet, serviceIp, type, providers);
221 }
222
223 /**
224 * Returns vtn network builder with the supplied network ID.
225 *
226 * @param id network id
227 * @return vtn network builder
228 */
229 public Builder id(NetworkId id) {
230 this.id = id;
231 return this;
232 }
233
234 /**
235 * Returns vtn network builder with the supplied segment ID.
236 *
237 * @param segmentId segment id
238 * @return vtn network builder
239 */
240 public Builder segmentId(SegmentId segmentId) {
241 this.segmentId = segmentId;
242 return this;
243 }
244
245 /**
246 * Returns vtn network builder with the supplied subnet.
247 *
248 * @param subnet subnet
249 * @return vtn network builder
250 */
251 public Builder subnet(IpPrefix subnet) {
252 this.subnet = subnet;
253 return this;
254 }
255
256 /**
257 * Returns vtn network service IP address.
258 *
259 * @param serviceIp service ip address
260 * @return vtn network builder
261 */
262 public Builder serviceIp(IpAddress serviceIp) {
263 this.serviceIp = serviceIp;
264 return this;
265 }
266
267 /**
268 * Returns vtn network builder with the supplied service network type.
269 *
270 * @param type service network type
271 * @return vtn network builder
272 */
273 public Builder type(ServiceNetworkType type) {
274 this.type = type;
275 return this;
276 }
277
278 /**
279 * Returns vtn network builder with the supplied provider service networks.
280 *
281 * @param providers provider service networks
282 * @return vtn network builder
283 */
284 public Builder providers(Set<ProviderNetwork> providers) {
285 this.providers = providers;
286 return this;
287 }
288
289 /**
290 * Returns vtn network builder with the given additional provider network.
291 *
292 * @param providerId provider network id
293 * @param type direct access type to the provider network
294 * @return vtn network builder
295 */
296 public Builder addProvider(NetworkId providerId, Dependency.Type type) {
297 checkNotNull(providerId, "Provider network ID cannot be null");
298 checkNotNull(type, "Provider network type cannot be null");
299
300 Set<ProviderNetwork> updated = Sets.newHashSet(this.providers);
301 updated.add(ProviderNetwork.of(providerId, type));
302 this.providers = ImmutableSet.copyOf(updated);
303 return this;
304 }
305
306 /**
307 * Returns vtn network builder without the given provider network.
308 *
309 * @param providerId provider network id
310 * @return vtn network builder
311 */
312 public Builder delProvider(NetworkId providerId) {
313 checkNotNull(providerId, "Provider network ID cannot be null");
314
315 ProviderNetwork provider = this.providers.stream()
316 .filter(p -> Objects.equals(p.id(), providerId))
317 .findAny().orElse(null);
318 if (provider != null) {
319 Set<ProviderNetwork> updated = Sets.newHashSet(this.providers);
320 updated.remove(provider);
321 this.providers = ImmutableSet.copyOf(updated);
322 }
323 return this;
324 }
325 }
326}