| /* |
| * Copyright 2015-present Open Networking Foundation |
| * |
| * 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.onosproject.vtnrsc; |
| |
| import static com.google.common.base.MoreObjects.toStringHelper; |
| import static com.google.common.base.Preconditions.checkNotNull; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import org.onosproject.net.DeviceId; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| |
| /** |
| * Implementation of port chain. |
| */ |
| public final class DefaultPortChain implements PortChain { |
| |
| private final PortChainId portChainId; |
| private final TenantId tenantId; |
| private final String name; |
| private final String description; |
| private final List<PortPairGroupId> portPairGroupList; |
| private final List<FlowClassifierId> flowClassifierList; |
| private final PortChain oldPortChain; |
| |
| private final Map<FiveTuple, LoadBalanceId> sfcLoadBalanceIdMap = new ConcurrentHashMap<>(); |
| private final Map<LoadBalanceId, List<PortPairId>> sfcLoadBalancePathMap = new ConcurrentHashMap<>(); |
| private final Map<LoadBalanceId, List<DeviceId>> sfcClassifiersMap = new ConcurrentHashMap<>(); |
| private final Map<LoadBalanceId, List<DeviceId>> sfcForwardersMap = new ConcurrentHashMap<>(); |
| |
| /** |
| * Default constructor to create port chain. |
| * |
| * @param portChainId port chain id |
| * @param tenantId tenant id |
| * @param name name of port chain |
| * @param description description of port chain |
| * @param portPairGroupList port pair group list |
| * @param flowClassifierList flow classifier list |
| */ |
| private DefaultPortChain(PortChainId portChainId, TenantId tenantId, |
| String name, String description, |
| List<PortPairGroupId> portPairGroupList, |
| List<FlowClassifierId> flowClassifierList, |
| PortChain portChain) { |
| |
| this.portChainId = portChainId; |
| this.tenantId = tenantId; |
| this.name = name; |
| this.description = description; |
| this.portPairGroupList = portPairGroupList; |
| this.flowClassifierList = flowClassifierList; |
| this.oldPortChain = portChain; |
| } |
| |
| /** |
| * To create port chain for update with old port chain. |
| * |
| * @param newPortChain updated port chain |
| * @param oldPortChain old port chain |
| * @return port chain |
| */ |
| public static PortChain create(PortChain newPortChain, PortChain oldPortChain) { |
| return new DefaultPortChain(newPortChain.portChainId(), newPortChain.tenantId(), |
| newPortChain.name(), newPortChain.description(), |
| newPortChain.portPairGroups(), newPortChain.flowClassifiers(), oldPortChain); |
| } |
| |
| /** |
| * Match for two given paths. |
| * |
| * @param path1 path of sfc |
| * @param path2 path of sfc |
| * @return true if the given path are same false otherwise |
| */ |
| private boolean comparePath(List<PortPairId> path1, List<PortPairId> path2) { |
| Iterator it = path1.iterator(); |
| for (PortPairId portPairId: path2) { |
| if (!portPairId.equals(it.next())) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| @Override |
| public PortChainId portChainId() { |
| return portChainId; |
| } |
| |
| @Override |
| public TenantId tenantId() { |
| return tenantId; |
| } |
| |
| @Override |
| public String name() { |
| return name; |
| } |
| |
| @Override |
| public String description() { |
| return description; |
| } |
| |
| @Override |
| public List<PortPairGroupId> portPairGroups() { |
| return ImmutableList.copyOf(portPairGroupList); |
| } |
| |
| @Override |
| public List<FlowClassifierId> flowClassifiers() { |
| return ImmutableList.copyOf(flowClassifierList); |
| } |
| |
| @Override |
| public PortChain oldPortChain() { |
| return oldPortChain; |
| } |
| |
| @Override |
| public void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id, |
| List<PortPairId> path) { |
| this.sfcLoadBalanceIdMap.put(fiveTuple, id); |
| this.sfcLoadBalancePathMap.put(id, path); |
| } |
| |
| @Override |
| public void addSfcClassifiers(LoadBalanceId id, List<DeviceId> classifierList) { |
| this.sfcClassifiersMap.put(id, classifierList); |
| } |
| |
| @Override |
| public void addSfcForwarders(LoadBalanceId id, List<DeviceId> forwarderList) { |
| this.sfcForwardersMap.put(id, forwarderList); |
| } |
| |
| @Override |
| public void removeSfcClassifiers(LoadBalanceId id, List<DeviceId> classifierList) { |
| List<DeviceId> list = sfcClassifiersMap.get(id); |
| list.removeAll(classifierList); |
| this.sfcForwardersMap.put(id, list); |
| } |
| |
| @Override |
| public void removeSfcForwarders(LoadBalanceId id, List<DeviceId> forwarderList) { |
| List<DeviceId> list = sfcForwardersMap.get(id); |
| list.removeAll(forwarderList); |
| this.sfcForwardersMap.put(id, list); |
| } |
| |
| @Override |
| public List<DeviceId> getSfcClassifiers(LoadBalanceId id) { |
| return ImmutableList.copyOf(this.sfcClassifiersMap.get(id)); |
| } |
| |
| @Override |
| public List<DeviceId> getSfcForwarders(LoadBalanceId id) { |
| return ImmutableList.copyOf(this.sfcForwardersMap.get(id)); |
| } |
| |
| @Override |
| public LoadBalanceId getLoadBalanceId(FiveTuple fiveTuple) { |
| return this.sfcLoadBalanceIdMap.get(fiveTuple); |
| } |
| |
| @Override |
| public Set<FiveTuple> getLoadBalanceIdMapKeys() { |
| return ImmutableSet.copyOf(sfcLoadBalanceIdMap.keySet()); |
| } |
| |
| @Override |
| public Set<LoadBalanceId> getLoadBalancePathMapKeys() { |
| return ImmutableSet.copyOf(sfcLoadBalancePathMap.keySet()); |
| } |
| |
| @Override |
| public List<PortPairId> getLoadBalancePath(LoadBalanceId id) { |
| return ImmutableList.copyOf(this.sfcLoadBalancePathMap.get(id)); |
| } |
| |
| @Override |
| public List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple) { |
| return ImmutableList.copyOf(this.sfcLoadBalancePathMap.get(this.sfcLoadBalanceIdMap.get(fiveTuple))); |
| } |
| |
| @Override |
| public int getLoadBalancePathSize() { |
| if (sfcLoadBalanceIdMap.isEmpty()) { |
| return 0; |
| } |
| return sfcLoadBalanceIdMap.size(); |
| } |
| |
| @Override |
| public LoadBalanceId matchPath(List<PortPairId> path) { |
| |
| LoadBalanceId id = null; |
| for (Map.Entry<LoadBalanceId, List<PortPairId>> entry : sfcLoadBalancePathMap.entrySet()) { |
| List<PortPairId> tempPath = entry.getValue(); |
| if (comparePath(path, tempPath)) { |
| id = entry.getKey(); |
| break; |
| } |
| } |
| return id; |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(portChainId, tenantId, name, description, |
| portPairGroupList, flowClassifierList); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj instanceof DefaultPortChain) { |
| DefaultPortChain that = (DefaultPortChain) obj; |
| return Objects.equals(portChainId, that.portChainId) && |
| Objects.equals(tenantId, that.tenantId) && |
| Objects.equals(name, that.name) && |
| Objects.equals(description, that.description) && |
| Objects.equals(portPairGroupList, that.portPairGroupList) && |
| Objects.equals(flowClassifierList, that.flowClassifierList); |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean exactMatch(PortChain portChain) { |
| return this.equals(portChain) && |
| Objects.equals(this.portChainId, portChain.portChainId()) && |
| Objects.equals(this.tenantId, portChain.tenantId()); |
| } |
| |
| @Override |
| public String toString() { |
| return toStringHelper(this) |
| .add("id", portChainId.toString()) |
| .add("tenantId", tenantId.toString()) |
| .add("name", name) |
| .add("description", description) |
| .add("portPairGroupList", portPairGroupList) |
| .add("flowClassifier", flowClassifierList) |
| .toString(); |
| } |
| |
| /** |
| * To create an instance of the builder. |
| * |
| * @return instance of builder |
| */ |
| public static Builder builder() { |
| return new Builder(); |
| } |
| |
| /** |
| * Builder class for Port chain. |
| */ |
| public static final class Builder implements PortChain.Builder { |
| |
| private PortChainId portChainId; |
| private TenantId tenantId; |
| private String name; |
| private String description; |
| private List<PortPairGroupId> portPairGroupList; |
| private List<FlowClassifierId> flowClassifierList; |
| private PortChain portChain; |
| |
| @Override |
| public Builder setId(PortChainId portChainId) { |
| this.portChainId = portChainId; |
| return this; |
| } |
| |
| @Override |
| public Builder setTenantId(TenantId tenantId) { |
| this.tenantId = tenantId; |
| return this; |
| } |
| |
| @Override |
| public Builder setName(String name) { |
| this.name = name; |
| return this; |
| } |
| |
| @Override |
| public Builder setDescription(String description) { |
| this.description = description; |
| return this; |
| } |
| |
| @Override |
| public Builder setPortPairGroups(List<PortPairGroupId> portPairGroups) { |
| this.portPairGroupList = portPairGroups; |
| return this; |
| } |
| |
| @Override |
| public Builder setFlowClassifiers(List<FlowClassifierId> flowClassifiers) { |
| this.flowClassifierList = flowClassifiers; |
| return this; |
| } |
| |
| @Override |
| public PortChain build() { |
| |
| checkNotNull(portChainId, "Port chain id cannot be null"); |
| checkNotNull(tenantId, "Tenant id cannot be null"); |
| checkNotNull(portPairGroupList, "Port pair groups cannot be null"); |
| |
| return new DefaultPortChain(portChainId, tenantId, name, description, |
| portPairGroupList, flowClassifierList, portChain); |
| } |
| } |
| } |