| /* |
| * Copyright 2016 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.mefscaapi.translate; |
| |
| import org.onlab.util.Bandwidth; |
| import org.onosproject.cli.AbstractShellCommand; |
| import org.onosproject.ecord.carrierethernet.app.CarrierEthernetBandwidthProfile; |
| import org.onosproject.ecord.carrierethernet.app.CarrierEthernetConnection; |
| import org.onosproject.ecord.carrierethernet.app.CarrierEthernetUni; |
| import org.onosproject.ecord.carrierethernet.app.CarrierEthernetVirtualConnection; |
| import org.onlab.packet.VlanId; |
| import org.onosproject.mefscaapi.api.model.SCAETHFDFrEC; |
| import org.onosproject.mefscaapi.api.model.SCAETHFPPUNIN; |
| import org.onosproject.mefscaapi.api.model.SCAETHFPPUNINTransportPort; |
| import org.onosproject.mefscaapi.api.model.SCAETHFlowPoint; |
| import org.onosproject.mefscaapi.api.model.SCAETHFlowPointClassOfServiceIdentifierIp; |
| import org.onosproject.mefscaapi.api.model.SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier; |
| import org.onosproject.mefscaapi.api.model.SCAETHFlowPointIngressBandwidthProfilePerEvc; |
| import org.onosproject.net.ConnectPoint; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.net.PortNumber; |
| import org.onosproject.net.device.DeviceService; |
| import org.slf4j.Logger; |
| |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Set; |
| |
| import static org.slf4j.LoggerFactory.getLogger; |
| |
| /** |
| * Methods for translating between SCA API swagger-generated JAVA classes and CE App classes. |
| */ |
| public final class ScaApiTranslator { |
| |
| private static DeviceService deviceService = AbstractShellCommand.get(DeviceService.class); |
| |
| private static final Logger log = getLogger(ScaApiTranslator.class); |
| |
| // Not to be called |
| private ScaApiTranslator() { |
| } |
| |
| public static CarrierEthernetVirtualConnection toCarrierEthernetVirtualConnection(SCAETHFDFrEC scaethfdFrEC) { |
| |
| String evcId = scaethfdFrEC.getId(); |
| String evcCfgId = scaethfdFrEC.getEvcCfgIdentifier(); |
| CarrierEthernetVirtualConnection.Type evcType = |
| CarrierEthernetVirtualConnection.Type.valueOf(scaethfdFrEC.getEvcServiceType().name()); |
| Integer maxNumUni = scaethfdFrEC.getEvcStatusMaxNumUni(); |
| Set<CarrierEthernetUni> uniSet = new HashSet<>(); |
| |
| CarrierEthernetUni ceUni; |
| CarrierEthernetUni.Role ceUniRole = CarrierEthernetUni.Role.ROOT; |
| ListIterator<SCAETHFlowPoint> it = scaethfdFrEC.getSCAETHFlowPoints().listIterator(); |
| while (it.hasNext()) { |
| if (evcType.equals(CarrierEthernetConnection.Type.ROOT_MULTIPOINT)) { |
| ceUniRole = (it.nextIndex() == 0) ? CarrierEthernetUni.Role.ROOT : CarrierEthernetUni.Role.LEAF; |
| } |
| SCAETHFlowPoint scaFlowPoint = it.next(); |
| // Create new CE UNI |
| ceUni = toCarrierEthernetUni(scaFlowPoint, ceUniRole); |
| if (ceUni == null) { |
| return null; |
| } |
| uniSet.add(ceUni); |
| } |
| |
| return CarrierEthernetVirtualConnection.builder() |
| .id(evcId) |
| .cfgId(evcCfgId) |
| .type(evcType) |
| .maxNumUni(maxNumUni) |
| .uniSet(uniSet) |
| .build(); |
| } |
| |
| public static SCAETHFDFrEC fromCarrierEthernetVirtualConnection(CarrierEthernetVirtualConnection ceService) { |
| |
| SCAETHFDFrEC scaethfdFrEC = new SCAETHFDFrEC(); |
| |
| scaethfdFrEC.setId(ceService.id()); |
| scaethfdFrEC.setEvcCfgIdentifier(ceService.cfgId()); |
| scaethfdFrEC.setEvcServiceType(SCAETHFDFrEC.EvcServiceTypeEnum.valueOf(ceService.type().name())); |
| scaethfdFrEC.setEvcStatusMaxNumUni(ceService.maxNumUni()); |
| scaethfdFrEC.setState(SCAETHFDFrEC.StateEnum.valueOf(ceService.state().name())); |
| |
| List<SCAETHFlowPoint> scaFlowPointList = new ArrayList<>(); |
| SCAETHFlowPoint scaFlowpoint; |
| |
| Iterator<CarrierEthernetUni> it = ceService.uniSet().iterator(); |
| while (it.hasNext()) { |
| CarrierEthernetUni ceUni = it.next(); |
| // Create new SCA Flow Point from CE UNI (will also create an SCA UNI internally) |
| scaFlowpoint = fromCarrierEthernetUni(ceUni); |
| scaFlowPointList.add(scaFlowpoint); |
| } |
| |
| scaethfdFrEC.setSCAETHFlowPoints(scaFlowPointList); |
| |
| return scaethfdFrEC; |
| } |
| |
| public static CarrierEthernetUni toCarrierEthernetUni(SCAETHFlowPoint scaFlowPoint, |
| CarrierEthernetUni.Role ceUniRole) { |
| |
| // TODO: Check for null |
| |
| // Get SCA UNI from SCA Flow Point |
| SCAETHFPPUNIN scaUni = scaFlowPoint.getScaEthFppUniN(); |
| |
| // Get UNI id |
| String ceUniCfgId = scaUni.getInterfaceCfgIdentifier(); |
| |
| // Get CE UNI CE-VLAN id |
| VlanId ceVlanId = ((scaUni.getCeVlanId() == null) ? null : |
| VlanId.vlanId(Short.valueOf(scaUni.getCeVlanId()))); |
| |
| // TODO: Allow for both ingress and egress BW profiles |
| // Get CE UNI BW profile |
| CarrierEthernetBandwidthProfile ceBwp = getCeBwpFromScaFlowPoint(scaFlowPoint); |
| |
| // Get CE UNI connect point |
| DeviceId deviceId = DeviceId.deviceId(scaUni.getTransportPort().getHostname()); |
| if (deviceService.getDevice(deviceId) == null) { |
| log.error("Invalid deviceId {}", deviceId); |
| return null; |
| } |
| PortNumber portNumber = PortNumber.portNumber(scaUni.getTransportPort().getPort()); |
| if (deviceService.getPort(deviceId, portNumber) == null) { |
| log.error("Invalid port {} for device {}", portNumber, deviceId); |
| return null; |
| } |
| ConnectPoint ceUniCp = new ConnectPoint(deviceId, portNumber); |
| |
| // Create CE UNI |
| return CarrierEthernetUni.builder() |
| .cp(ceUniCp) |
| .cfgId(ceUniCfgId) |
| .role(ceUniRole) |
| .ceVlanId(ceVlanId) |
| .bwp(ceBwp) |
| .build(); |
| } |
| |
| public static SCAETHFlowPoint fromCarrierEthernetUni(CarrierEthernetUni ceUni) { |
| |
| SCAETHFlowPoint scaFlowPoint = new SCAETHFlowPoint(); |
| SCAETHFPPUNIN scaUni = new SCAETHFPPUNIN(); |
| |
| // Set SCA UNI Transport Port |
| SCAETHFPPUNINTransportPort scaPort = new SCAETHFPPUNINTransportPort(); |
| scaPort.setHostname(ceUni.cp().deviceId().toString()); |
| scaPort.setPort(ceUni.cp().port().toString()); |
| scaPort.setVendor(deviceService.getDevice(ceUni.cp().deviceId()).manufacturer()); |
| scaUni.setTransportPort(scaPort); |
| if (ceUni.ceVlanId() != null) { |
| scaUni.setCeVlanId(ceUni.ceVlanId().toString()); |
| } |
| |
| scaUni.setInterfaceCfgIdentifier(ceUni.cfgId()); |
| |
| // Add SCA UNI to SCA Flow Point |
| scaFlowPoint.setScaEthFppUniN(scaUni); |
| |
| // TODO: Allow for both ingress and egress BW profiles |
| // FIXME: A CE UNI may have multiple bandwidth profiles |
| |
| // Apply existing BW profile from CE UNI to SCA Flow Point (or UNI) |
| applyCeUniBwpToScaFlowPoint(ceUni, scaFlowPoint); |
| |
| // TODO: Check if the UNI type needs to be specified |
| |
| return scaFlowPoint; |
| } |
| |
| private static CarrierEthernetBandwidthProfile getCeBwpFromScaFlowPoint( |
| SCAETHFlowPoint scaFlowPoint) { |
| |
| SCAETHFPPUNIN scaUni = scaFlowPoint.getScaEthFppUniN(); |
| SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp = null; |
| SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier scaCosBwp = null; |
| String ceBwpId = null; |
| String ceBwpCfgId; |
| CarrierEthernetBandwidthProfile.Type ceBwpType; |
| |
| SCAETHFlowPointIngressBandwidthProfilePerEvc ifaceBwp = |
| scaUni.getInterfaceCfgIngressBwp(); |
| SCAETHFlowPointIngressBandwidthProfilePerEvc evcBwp = |
| scaFlowPoint.getIngressBandwidthProfilePerEvc(); |
| SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier cosBwp = |
| scaFlowPoint.getIngressBandwidthProfilePerClassOfServiceIdentifier(); |
| |
| // TODO: Complete the COS part |
| |
| // FIXME: Perform following check |
| /*Preconditions.checkArgument(ifaceBwp == null && evcBwp == null && cosBwp == null || |
| (ifaceBwp != null ^ evcBwp != null ^ cosBwp != null), |
| "Only up to one BW profile can be set per UNI");*/ |
| |
| if (evcBwp != null) { |
| scaBwp = evcBwp; |
| ceBwpCfgId = scaBwp.getBwpCfgIdentifier(); |
| ceBwpType = CarrierEthernetBandwidthProfile.Type.EVC; |
| } else if (ifaceBwp != null) { |
| scaBwp = ifaceBwp; |
| // Use the UNI connect point id |
| ceBwpId = scaUni.getTransportPort().getHostname() + "/" + scaUni.getTransportPort().getPort(); |
| ceBwpType = CarrierEthernetBandwidthProfile.Type.INTERFACE; |
| ceBwpCfgId = ifaceBwp.getBwpCfgIdentifier(); |
| if (ceBwpCfgId == null) { |
| ceBwpCfgId = ceBwpId; |
| } |
| } else if (cosBwp != null) { |
| // FIXME: Complete and test the COS part |
| scaCosBwp = cosBwp; |
| SCAETHFlowPointClassOfServiceIdentifierIp scaCosIdIp = |
| scaFlowPoint.getClassOfServiceIdentifierIp(); |
| if (scaCosIdIp == null) { |
| log.error("CoS ID is required for COS BW profile"); |
| return null; |
| } |
| ceBwpId = scaCosIdIp.getClassOfServiceName(); |
| ceBwpCfgId = scaCosBwp.getBwpCfgIdentifier(); |
| ceBwpType = CarrierEthernetBandwidthProfile.Type.COS; |
| } else { |
| return null; |
| } |
| |
| CeBwpParams ceBwpParams = scaBwp != null ? new CeBwpParams(scaBwp) : |
| new CeBwpParams(scaCosBwp); |
| |
| return CarrierEthernetBandwidthProfile.builder() |
| .id(ceBwpId) |
| .cfgId(ceBwpCfgId) |
| .type(ceBwpType) |
| .cir(ceBwpParams.cir()) |
| .cbs(ceBwpParams.cbs()) |
| .eir(ceBwpParams.eir()) |
| .ebs(ceBwpParams.ebs()) |
| .build(); |
| } |
| |
| private static class CeBwpParams { |
| |
| private Bandwidth cir = Bandwidth.bps((long) 0); |
| private Bandwidth eir = Bandwidth.bps((long) 0); |
| private long cbs = (long) 0; |
| private long ebs = (long) 0; |
| |
| CeBwpParams() {} |
| |
| CeBwpParams(SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp) { |
| if (scaBwp.getBwpCfgCir() != null) { |
| cir = Bandwidth.bps((long) scaBwp.getBwpCfgCir()); |
| } |
| if (scaBwp.getBwpCfgEir() != null) { |
| eir = Bandwidth.bps((long) scaBwp.getBwpCfgEir()); |
| } |
| if (scaBwp.getBwpCfgCbs() != null) { |
| cbs = (long) scaBwp.getBwpCfgCbs(); |
| } |
| if (scaBwp.getBwpCfgEbs() != null) { |
| ebs = (long) scaBwp.getBwpCfgEbs(); |
| } |
| } |
| |
| CeBwpParams(SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier scaBwp) { |
| if (scaBwp.getBwpCfgCir() != null) { |
| cir = Bandwidth.bps((long) scaBwp.getBwpCfgCir()); |
| } |
| if (scaBwp.getBwpCfgEir() != null) { |
| eir = Bandwidth.bps((long) scaBwp.getBwpCfgEir()); |
| } |
| if (scaBwp.getBwpCfgCbs() != null) { |
| cbs = (long) scaBwp.getBwpCfgCbs(); |
| } |
| if (scaBwp.getBwpCfgEbs() != null) { |
| ebs = (long) scaBwp.getBwpCfgEbs(); |
| } |
| } |
| |
| public Bandwidth cir() { |
| return cir; |
| } |
| |
| public Bandwidth eir() { |
| return eir; |
| } |
| |
| public long cbs() { |
| return cbs; |
| } |
| |
| public long ebs() { |
| return ebs; |
| } |
| } |
| |
| private static SCAETHFlowPoint applyCeUniBwpToScaFlowPoint( |
| CarrierEthernetUni ceUni, SCAETHFlowPoint scaFlowPoint) { |
| |
| CarrierEthernetBandwidthProfile ceBwp = ceUni.bwp(); |
| |
| SCAETHFlowPoint newScaFlowPoint = scaFlowPoint; |
| SCAETHFPPUNIN newScaUni = scaFlowPoint.getScaEthFppUniN(); |
| |
| if (ceBwp != null) { |
| // Prepare SCA bandwidth profile |
| SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp = new SCAETHFlowPointIngressBandwidthProfilePerEvc(); |
| |
| // TODO: Check for null? |
| scaBwp.setBwpCfgCir((int) ceBwp.cir().bps()); |
| scaBwp.setBwpCfgCbs((int) ceBwp.cbs()); |
| scaBwp.setBwpCfgEir((int) ceBwp.eir().bps()); |
| scaBwp.setBwpCfgEbs((int) ceBwp.ebs()); |
| |
| // TODO: Add the CoS part when it's ready from the CE app side |
| if (ceBwp.type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) { |
| newScaUni.setEvcId(ceBwp.id()); |
| newScaFlowPoint.setIngressBandwidthProfilePerEvc(scaBwp); |
| } else if (ceBwp.type().equals(CarrierEthernetBandwidthProfile.Type.INTERFACE)) { |
| newScaUni.setInterfaceCfgIdentifier(ceUni.cfgId()); |
| newScaUni.setInterfaceCfgIngressBwp(scaBwp); |
| } else { |
| log.error("Could not add BW profile for Flow Point {}", scaFlowPoint.toString()); |
| return null; |
| } |
| } |
| |
| newScaFlowPoint.setScaEthFppUniN(newScaUni); |
| |
| return newScaFlowPoint; |
| } |
| |
| } |