| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.opencord.cordvtn.api; |
| |
| import com.google.common.base.MoreObjects; |
| import com.google.common.base.Strings; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Sets; |
| import org.onlab.packet.IpAddress; |
| import org.onlab.packet.IpPrefix; |
| import org.openstack4j.model.network.Network; |
| import org.openstack4j.model.network.Subnet; |
| |
| import java.util.Objects; |
| import java.util.Set; |
| |
| import static com.google.common.base.Preconditions.checkArgument; |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static org.opencord.cordvtn.api.ServiceNetwork.ServiceNetworkType.PRIVATE; |
| |
| /** |
| * Representation of a network holding the basic virtual network and additional |
| * service network specific information. |
| * All the services making use of {@link CordVtnService} are intended to interface |
| * with this VtnNetwork, and not allowed to directly access {@link Network} or |
| * {@link ServiceNetwork}. |
| */ |
| public final class VtnNetwork extends ServiceNetwork { |
| |
| private static final String ERR_SEGMENT_ID_MISSING = "VTN network segment ID is missing"; |
| private static final String ERR_GATEWAY_IP_MISSING = "VTN subnet gateway IP is missing"; |
| |
| private final SegmentId segmentId; |
| private final IpPrefix subnet; |
| private final IpAddress serviceIp; |
| |
| private VtnNetwork(NetworkId id, |
| SegmentId segmentId, |
| IpPrefix subnet, |
| IpAddress serviceIp, |
| ServiceNetworkType type, |
| Set<ProviderNetwork> providers) { |
| super(id, type, providers); |
| this.segmentId = segmentId; |
| this.subnet = subnet; |
| this.serviceIp = serviceIp; |
| } |
| |
| /** |
| * Returns the network ID. |
| * |
| * @return network id |
| */ |
| public NetworkId id() { |
| return id; |
| } |
| |
| /** |
| * Returns the segment ID of this network. |
| * |
| * @return segment id |
| */ |
| public SegmentId segmentId() { |
| return segmentId; |
| } |
| |
| /** |
| * Returns the subnet used in this network. |
| * |
| * @return subnet |
| */ |
| public IpPrefix subnet() { |
| return subnet; |
| } |
| |
| /** |
| * Returns the service IP address of this network. |
| * |
| * @return ip address |
| */ |
| public IpAddress serviceIp() { |
| return serviceIp; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| |
| if (obj instanceof VtnNetwork) { |
| VtnNetwork that = (VtnNetwork) obj; |
| if (Objects.equals(id, that.id) && |
| Objects.equals(segmentId, that.segmentId) && |
| Objects.equals(subnet, that.subnet) && |
| Objects.equals(serviceIp, that.serviceIp) && |
| Objects.equals(type, that.type) && |
| Objects.equals(providers, that.providers)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(id, segmentId, subnet, serviceIp, type, providers); |
| } |
| |
| @Override |
| public String toString() { |
| return MoreObjects.toStringHelper(getClass()) |
| .add("id", id) |
| .add("segmentId", segmentId) |
| .add("subnet", subnet) |
| .add("serviceIp", serviceIp) |
| .add("type", type) |
| .add("providers", providers) |
| .toString(); |
| } |
| |
| /** |
| * Returns immutable VTN network with the supplied Neutron network, subnet, |
| * and additional service network information. |
| * |
| * @param network neutron network |
| * @param subnet neutron subnet |
| * @param serviceNet service network |
| * @return vtn network |
| */ |
| public static VtnNetwork of(Network network, Subnet subnet, ServiceNetwork serviceNet) { |
| validateNeutronNetwork(network, subnet); |
| if (serviceNet != null) { |
| checkArgument(Objects.equals(network.getId(), serviceNet.id().id())); |
| } |
| |
| return builder().id(NetworkId.of(network.getId())) |
| .segmentId(SegmentId.of(Long.valueOf(network.getProviderSegID()))) |
| .subnet(IpPrefix.valueOf(subnet.getCidr())) |
| .serviceIp(IpAddress.valueOf(subnet.getGateway())) |
| .type(serviceNet == null ? PRIVATE : serviceNet.type()) |
| .providers(serviceNet == null ? ImmutableSet.of() : serviceNet.providers()) |
| .build(); |
| } |
| |
| private static void validateNeutronNetwork(Network network, Subnet subnet) { |
| checkNotNull(network); |
| checkNotNull(subnet); |
| checkArgument(Objects.equals(network.getId(), subnet.getNetworkId())); |
| checkArgument(!Strings.isNullOrEmpty(network.getProviderSegID()), ERR_SEGMENT_ID_MISSING); |
| checkArgument(!Strings.isNullOrEmpty(subnet.getGateway()), ERR_GATEWAY_IP_MISSING); |
| } |
| |
| /** |
| * Returns new vtn network builder instance. |
| * |
| * @return vtn network builder |
| */ |
| public static Builder builder() { |
| return new Builder(); |
| } |
| |
| /** |
| * Returns new vtn network builder instance with copy of the given vtn network. |
| * |
| * @param vtnNet vtn network |
| * @return vtn network builder |
| */ |
| public static Builder builder(VtnNetwork vtnNet) { |
| return new Builder() |
| .id(vtnNet.id()) |
| .segmentId(vtnNet.segmentId()) |
| .subnet(vtnNet.subnet()) |
| .serviceIp(vtnNet.serviceIp()) |
| .type(vtnNet.type()) |
| .providers(vtnNet.providers()); |
| } |
| |
| /** |
| * Builder of the vtn network entities. |
| */ |
| public static final class Builder { |
| private NetworkId id; |
| private SegmentId segmentId; |
| private IpPrefix subnet; |
| private IpAddress serviceIp; |
| private ServiceNetworkType type; |
| private Set<ProviderNetwork> providers = ImmutableSet.of(); |
| |
| private Builder() { |
| } |
| |
| /** |
| * Builds an immutable vtn network. |
| * |
| * @return vtn network instance |
| */ |
| public VtnNetwork build() { |
| checkNotNull(id, "VTN network id cannot be null"); |
| checkNotNull(segmentId, "VTN network segment id cannot be null"); |
| checkNotNull(subnet, "VTN network subnet cannot be null"); |
| checkNotNull(serviceIp, "VTN network service IP cannot be null"); |
| checkNotNull(type, "VTN network type cannot be null"); |
| providers = providers == null ? ImmutableSet.of() : providers; |
| |
| return new VtnNetwork(id, segmentId, subnet, serviceIp, type, providers); |
| } |
| |
| /** |
| * Returns vtn network builder with the supplied network ID. |
| * |
| * @param id network id |
| * @return vtn network builder |
| */ |
| public Builder id(NetworkId id) { |
| this.id = id; |
| return this; |
| } |
| |
| /** |
| * Returns vtn network builder with the supplied segment ID. |
| * |
| * @param segmentId segment id |
| * @return vtn network builder |
| */ |
| public Builder segmentId(SegmentId segmentId) { |
| this.segmentId = segmentId; |
| return this; |
| } |
| |
| /** |
| * Returns vtn network builder with the supplied subnet. |
| * |
| * @param subnet subnet |
| * @return vtn network builder |
| */ |
| public Builder subnet(IpPrefix subnet) { |
| this.subnet = subnet; |
| return this; |
| } |
| |
| /** |
| * Returns vtn network service IP address. |
| * |
| * @param serviceIp service ip address |
| * @return vtn network builder |
| */ |
| public Builder serviceIp(IpAddress serviceIp) { |
| this.serviceIp = serviceIp; |
| return this; |
| } |
| |
| /** |
| * Returns vtn network builder with the supplied service network type. |
| * |
| * @param type service network type |
| * @return vtn network builder |
| */ |
| public Builder type(ServiceNetworkType type) { |
| this.type = type; |
| return this; |
| } |
| |
| /** |
| * Returns vtn network builder with the supplied provider service networks. |
| * |
| * @param providers provider service networks |
| * @return vtn network builder |
| */ |
| public Builder providers(Set<ProviderNetwork> providers) { |
| this.providers = providers; |
| return this; |
| } |
| |
| /** |
| * Returns vtn network builder with the given additional provider network. |
| * |
| * @param providerId provider network id |
| * @param type direct access type to the provider network |
| * @return vtn network builder |
| */ |
| public Builder addProvider(NetworkId providerId, Dependency.Type type) { |
| checkNotNull(providerId, "Provider network ID cannot be null"); |
| checkNotNull(type, "Provider network type cannot be null"); |
| |
| Set<ProviderNetwork> updated = Sets.newHashSet(this.providers); |
| updated.add(ProviderNetwork.of(providerId, type)); |
| this.providers = ImmutableSet.copyOf(updated); |
| return this; |
| } |
| |
| /** |
| * Returns vtn network builder without the given provider network. |
| * |
| * @param providerId provider network id |
| * @return vtn network builder |
| */ |
| public Builder delProvider(NetworkId providerId) { |
| checkNotNull(providerId, "Provider network ID cannot be null"); |
| |
| ProviderNetwork provider = this.providers.stream() |
| .filter(p -> Objects.equals(p.id(), providerId)) |
| .findAny().orElse(null); |
| if (provider != null) { |
| Set<ProviderNetwork> updated = Sets.newHashSet(this.providers); |
| updated.remove(provider); |
| this.providers = ImmutableSet.copyOf(updated); |
| } |
| return this; |
| } |
| } |
| } |