Konstantinos Kanonakis | 0c37448 | 2017-01-18 15:03:47 -0600 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2016 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 | */ |
| 16 | package org.onosproject.mefscaapi.translate; |
| 17 | |
| 18 | import org.onlab.util.Bandwidth; |
| 19 | import org.onosproject.cli.AbstractShellCommand; |
| 20 | import org.onosproject.ecord.carrierethernet.app.CarrierEthernetBandwidthProfile; |
| 21 | import org.onosproject.ecord.carrierethernet.app.CarrierEthernetConnection; |
| 22 | import org.onosproject.ecord.carrierethernet.app.CarrierEthernetUni; |
| 23 | import org.onosproject.ecord.carrierethernet.app.CarrierEthernetVirtualConnection; |
| 24 | import org.onlab.packet.VlanId; |
| 25 | import org.onosproject.mefscaapi.api.model.SCAETHFDFrEC; |
| 26 | import org.onosproject.mefscaapi.api.model.SCAETHFPPUNIN; |
| 27 | import org.onosproject.mefscaapi.api.model.SCAETHFPPUNINTransportPort; |
| 28 | import org.onosproject.mefscaapi.api.model.SCAETHFlowPoint; |
| 29 | import org.onosproject.mefscaapi.api.model.SCAETHFlowPointClassOfServiceIdentifierIp; |
| 30 | import org.onosproject.mefscaapi.api.model.SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier; |
| 31 | import org.onosproject.mefscaapi.api.model.SCAETHFlowPointIngressBandwidthProfilePerEvc; |
| 32 | import org.onosproject.net.ConnectPoint; |
| 33 | import org.onosproject.net.DeviceId; |
| 34 | import org.onosproject.net.PortNumber; |
| 35 | import org.onosproject.net.device.DeviceService; |
| 36 | import org.slf4j.Logger; |
| 37 | |
| 38 | import java.util.ArrayList; |
| 39 | import java.util.HashSet; |
| 40 | import java.util.Iterator; |
| 41 | import java.util.List; |
| 42 | import java.util.ListIterator; |
| 43 | import java.util.Set; |
| 44 | |
| 45 | import static org.slf4j.LoggerFactory.getLogger; |
| 46 | |
| 47 | /** |
| 48 | * Methods for translating between SCA API swagger-generated JAVA classes and CE App classes. |
| 49 | */ |
| 50 | public final class ScaApiTranslator { |
| 51 | |
| 52 | private static DeviceService deviceService = AbstractShellCommand.get(DeviceService.class); |
| 53 | |
| 54 | private static final Logger log = getLogger(ScaApiTranslator.class); |
| 55 | |
| 56 | // Not to be called |
| 57 | private ScaApiTranslator() { |
| 58 | } |
| 59 | |
| 60 | public static CarrierEthernetVirtualConnection toCarrierEthernetVirtualConnection(SCAETHFDFrEC scaethfdFrEC) { |
| 61 | |
| 62 | String evcId = scaethfdFrEC.getId(); |
| 63 | String evcCfgId = scaethfdFrEC.getEvcCfgIdentifier(); |
| 64 | CarrierEthernetVirtualConnection.Type evcType = |
| 65 | CarrierEthernetVirtualConnection.Type.valueOf(scaethfdFrEC.getEvcServiceType().name()); |
| 66 | Integer maxNumUni = scaethfdFrEC.getEvcStatusMaxNumUni(); |
| 67 | Set<CarrierEthernetUni> uniSet = new HashSet<>(); |
| 68 | |
| 69 | CarrierEthernetUni ceUni; |
| 70 | CarrierEthernetUni.Role ceUniRole = CarrierEthernetUni.Role.ROOT; |
| 71 | ListIterator<SCAETHFlowPoint> it = scaethfdFrEC.getSCAETHFlowPoints().listIterator(); |
| 72 | while (it.hasNext()) { |
| 73 | if (evcType.equals(CarrierEthernetConnection.Type.ROOT_MULTIPOINT)) { |
| 74 | ceUniRole = (it.nextIndex() == 0) ? CarrierEthernetUni.Role.ROOT : CarrierEthernetUni.Role.LEAF; |
| 75 | } |
| 76 | SCAETHFlowPoint scaFlowPoint = it.next(); |
| 77 | // Create new CE UNI |
| 78 | ceUni = toCarrierEthernetUni(scaFlowPoint, ceUniRole); |
| 79 | if (ceUni == null) { |
| 80 | return null; |
| 81 | } |
| 82 | uniSet.add(ceUni); |
| 83 | } |
| 84 | |
| 85 | return CarrierEthernetVirtualConnection.builder() |
| 86 | .id(evcId) |
| 87 | .cfgId(evcCfgId) |
| 88 | .type(evcType) |
| 89 | .maxNumUni(maxNumUni) |
| 90 | .uniSet(uniSet) |
| 91 | .build(); |
| 92 | } |
| 93 | |
| 94 | public static SCAETHFDFrEC fromCarrierEthernetVirtualConnection(CarrierEthernetVirtualConnection ceService) { |
| 95 | |
| 96 | SCAETHFDFrEC scaethfdFrEC = new SCAETHFDFrEC(); |
| 97 | |
| 98 | scaethfdFrEC.setId(ceService.id()); |
| 99 | scaethfdFrEC.setEvcCfgIdentifier(ceService.cfgId()); |
| 100 | scaethfdFrEC.setEvcServiceType(SCAETHFDFrEC.EvcServiceTypeEnum.valueOf(ceService.type().name())); |
| 101 | scaethfdFrEC.setEvcStatusMaxNumUni(ceService.maxNumUni()); |
| 102 | scaethfdFrEC.setState(SCAETHFDFrEC.StateEnum.valueOf(ceService.state().name())); |
| 103 | |
| 104 | List<SCAETHFlowPoint> scaFlowPointList = new ArrayList<>(); |
| 105 | SCAETHFlowPoint scaFlowpoint; |
| 106 | |
| 107 | Iterator<CarrierEthernetUni> it = ceService.uniSet().iterator(); |
| 108 | while (it.hasNext()) { |
| 109 | CarrierEthernetUni ceUni = it.next(); |
| 110 | // Create new SCA Flow Point from CE UNI (will also create an SCA UNI internally) |
| 111 | scaFlowpoint = fromCarrierEthernetUni(ceUni); |
| 112 | scaFlowPointList.add(scaFlowpoint); |
| 113 | } |
| 114 | |
| 115 | scaethfdFrEC.setSCAETHFlowPoints(scaFlowPointList); |
| 116 | |
| 117 | return scaethfdFrEC; |
| 118 | } |
| 119 | |
| 120 | public static CarrierEthernetUni toCarrierEthernetUni(SCAETHFlowPoint scaFlowPoint, |
| 121 | CarrierEthernetUni.Role ceUniRole) { |
| 122 | |
| 123 | // TODO: Check for null |
| 124 | |
| 125 | // Get SCA UNI from SCA Flow Point |
| 126 | SCAETHFPPUNIN scaUni = scaFlowPoint.getScaEthFppUniN(); |
| 127 | |
| 128 | // Get UNI id |
| 129 | String ceUniCfgId = scaUni.getInterfaceCfgIdentifier(); |
| 130 | |
| 131 | // Get CE UNI CE-VLAN id |
| 132 | VlanId ceVlanId = ((scaUni.getCeVlanId() == null) ? null : |
| 133 | VlanId.vlanId(Short.valueOf(scaUni.getCeVlanId()))); |
| 134 | |
| 135 | // TODO: Allow for both ingress and egress BW profiles |
| 136 | // Get CE UNI BW profile |
| 137 | CarrierEthernetBandwidthProfile ceBwp = getCeBwpFromScaFlowPoint(scaFlowPoint); |
| 138 | |
| 139 | // Get CE UNI connect point |
| 140 | DeviceId deviceId = DeviceId.deviceId(scaUni.getTransportPort().getHostname()); |
| 141 | if (deviceService.getDevice(deviceId) == null) { |
| 142 | log.error("Invalid deviceId {}", deviceId); |
| 143 | return null; |
| 144 | } |
| 145 | PortNumber portNumber = PortNumber.portNumber(scaUni.getTransportPort().getPort()); |
| 146 | if (deviceService.getPort(deviceId, portNumber) == null) { |
| 147 | log.error("Invalid port {} for device {}", portNumber, deviceId); |
| 148 | return null; |
| 149 | } |
| 150 | ConnectPoint ceUniCp = new ConnectPoint(deviceId, portNumber); |
| 151 | |
| 152 | // Create CE UNI |
| 153 | return CarrierEthernetUni.builder() |
| 154 | .cp(ceUniCp) |
| 155 | .cfgId(ceUniCfgId) |
| 156 | .role(ceUniRole) |
| 157 | .ceVlanId(ceVlanId) |
| 158 | .bwp(ceBwp) |
| 159 | .build(); |
| 160 | } |
| 161 | |
| 162 | public static SCAETHFlowPoint fromCarrierEthernetUni(CarrierEthernetUni ceUni) { |
| 163 | |
| 164 | SCAETHFlowPoint scaFlowPoint = new SCAETHFlowPoint(); |
| 165 | SCAETHFPPUNIN scaUni = new SCAETHFPPUNIN(); |
| 166 | |
| 167 | // Set SCA UNI Transport Port |
| 168 | SCAETHFPPUNINTransportPort scaPort = new SCAETHFPPUNINTransportPort(); |
| 169 | scaPort.setHostname(ceUni.cp().deviceId().toString()); |
| 170 | scaPort.setPort(ceUni.cp().port().toString()); |
| 171 | scaPort.setVendor(deviceService.getDevice(ceUni.cp().deviceId()).manufacturer()); |
| 172 | scaUni.setTransportPort(scaPort); |
| 173 | if (ceUni.ceVlanId() != null) { |
| 174 | scaUni.setCeVlanId(ceUni.ceVlanId().toString()); |
| 175 | } |
| 176 | |
| 177 | scaUni.setInterfaceCfgIdentifier(ceUni.cfgId()); |
| 178 | |
| 179 | // Add SCA UNI to SCA Flow Point |
| 180 | scaFlowPoint.setScaEthFppUniN(scaUni); |
| 181 | |
| 182 | // TODO: Allow for both ingress and egress BW profiles |
| 183 | // FIXME: A CE UNI may have multiple bandwidth profiles |
| 184 | |
| 185 | // Apply existing BW profile from CE UNI to SCA Flow Point (or UNI) |
| 186 | applyCeUniBwpToScaFlowPoint(ceUni, scaFlowPoint); |
| 187 | |
| 188 | // TODO: Check if the UNI type needs to be specified |
| 189 | |
| 190 | return scaFlowPoint; |
| 191 | } |
| 192 | |
| 193 | private static CarrierEthernetBandwidthProfile getCeBwpFromScaFlowPoint( |
| 194 | SCAETHFlowPoint scaFlowPoint) { |
| 195 | |
| 196 | SCAETHFPPUNIN scaUni = scaFlowPoint.getScaEthFppUniN(); |
| 197 | SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp = null; |
| 198 | SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier scaCosBwp = null; |
| 199 | String ceBwpId = null; |
| 200 | String ceBwpCfgId; |
| 201 | CarrierEthernetBandwidthProfile.Type ceBwpType; |
| 202 | |
| 203 | SCAETHFlowPointIngressBandwidthProfilePerEvc ifaceBwp = |
| 204 | scaUni.getInterfaceCfgIngressBwp(); |
| 205 | SCAETHFlowPointIngressBandwidthProfilePerEvc evcBwp = |
| 206 | scaFlowPoint.getIngressBandwidthProfilePerEvc(); |
| 207 | SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier cosBwp = |
| 208 | scaFlowPoint.getIngressBandwidthProfilePerClassOfServiceIdentifier(); |
| 209 | |
| 210 | // TODO: Complete the COS part |
| 211 | |
| 212 | // FIXME: Perform following check |
| 213 | /*Preconditions.checkArgument(ifaceBwp == null && evcBwp == null && cosBwp == null || |
| 214 | (ifaceBwp != null ^ evcBwp != null ^ cosBwp != null), |
| 215 | "Only up to one BW profile can be set per UNI");*/ |
| 216 | |
| 217 | if (evcBwp != null) { |
| 218 | scaBwp = evcBwp; |
| 219 | ceBwpCfgId = scaBwp.getBwpCfgIdentifier(); |
| 220 | ceBwpType = CarrierEthernetBandwidthProfile.Type.EVC; |
| 221 | } else if (ifaceBwp != null) { |
| 222 | scaBwp = ifaceBwp; |
| 223 | // Use the UNI connect point id |
| 224 | ceBwpId = scaUni.getTransportPort().getHostname() + "/" + scaUni.getTransportPort().getPort(); |
| 225 | ceBwpType = CarrierEthernetBandwidthProfile.Type.INTERFACE; |
| 226 | ceBwpCfgId = ifaceBwp.getBwpCfgIdentifier(); |
| 227 | if (ceBwpCfgId == null) { |
| 228 | ceBwpCfgId = ceBwpId; |
| 229 | } |
| 230 | } else if (cosBwp != null) { |
| 231 | // FIXME: Complete and test the COS part |
| 232 | scaCosBwp = cosBwp; |
| 233 | SCAETHFlowPointClassOfServiceIdentifierIp scaCosIdIp = |
| 234 | scaFlowPoint.getClassOfServiceIdentifierIp(); |
| 235 | if (scaCosIdIp == null) { |
| 236 | log.error("CoS ID is required for COS BW profile"); |
| 237 | return null; |
| 238 | } |
| 239 | ceBwpId = scaCosIdIp.getClassOfServiceName(); |
| 240 | ceBwpCfgId = scaCosBwp.getBwpCfgIdentifier(); |
| 241 | ceBwpType = CarrierEthernetBandwidthProfile.Type.COS; |
| 242 | } else { |
| 243 | return null; |
| 244 | } |
| 245 | |
| 246 | CeBwpParams ceBwpParams = scaBwp != null ? new CeBwpParams(scaBwp) : |
| 247 | new CeBwpParams(scaCosBwp); |
| 248 | |
| 249 | return CarrierEthernetBandwidthProfile.builder() |
| 250 | .id(ceBwpId) |
| 251 | .cfgId(ceBwpCfgId) |
| 252 | .type(ceBwpType) |
| 253 | .cir(ceBwpParams.cir()) |
| 254 | .cbs(ceBwpParams.cbs()) |
| 255 | .eir(ceBwpParams.eir()) |
| 256 | .ebs(ceBwpParams.ebs()) |
| 257 | .build(); |
| 258 | } |
| 259 | |
| 260 | private static class CeBwpParams { |
| 261 | |
| 262 | private Bandwidth cir = Bandwidth.bps((long) 0); |
| 263 | private Bandwidth eir = Bandwidth.bps((long) 0); |
| 264 | private long cbs = (long) 0; |
| 265 | private long ebs = (long) 0; |
| 266 | |
| 267 | CeBwpParams() {} |
| 268 | |
| 269 | CeBwpParams(SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp) { |
| 270 | if (scaBwp.getBwpCfgCir() != null) { |
| 271 | cir = Bandwidth.bps((long) scaBwp.getBwpCfgCir()); |
| 272 | } |
| 273 | if (scaBwp.getBwpCfgEir() != null) { |
| 274 | eir = Bandwidth.bps((long) scaBwp.getBwpCfgEir()); |
| 275 | } |
| 276 | if (scaBwp.getBwpCfgCbs() != null) { |
| 277 | cbs = (long) scaBwp.getBwpCfgCbs(); |
| 278 | } |
| 279 | if (scaBwp.getBwpCfgEbs() != null) { |
| 280 | ebs = (long) scaBwp.getBwpCfgEbs(); |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | CeBwpParams(SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier scaBwp) { |
| 285 | if (scaBwp.getBwpCfgCir() != null) { |
| 286 | cir = Bandwidth.bps((long) scaBwp.getBwpCfgCir()); |
| 287 | } |
| 288 | if (scaBwp.getBwpCfgEir() != null) { |
| 289 | eir = Bandwidth.bps((long) scaBwp.getBwpCfgEir()); |
| 290 | } |
| 291 | if (scaBwp.getBwpCfgCbs() != null) { |
| 292 | cbs = (long) scaBwp.getBwpCfgCbs(); |
| 293 | } |
| 294 | if (scaBwp.getBwpCfgEbs() != null) { |
| 295 | ebs = (long) scaBwp.getBwpCfgEbs(); |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | public Bandwidth cir() { |
| 300 | return cir; |
| 301 | } |
| 302 | |
| 303 | public Bandwidth eir() { |
| 304 | return eir; |
| 305 | } |
| 306 | |
| 307 | public long cbs() { |
| 308 | return cbs; |
| 309 | } |
| 310 | |
| 311 | public long ebs() { |
| 312 | return ebs; |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | private static SCAETHFlowPoint applyCeUniBwpToScaFlowPoint( |
| 317 | CarrierEthernetUni ceUni, SCAETHFlowPoint scaFlowPoint) { |
| 318 | |
| 319 | CarrierEthernetBandwidthProfile ceBwp = ceUni.bwp(); |
| 320 | |
| 321 | SCAETHFlowPoint newScaFlowPoint = scaFlowPoint; |
| 322 | SCAETHFPPUNIN newScaUni = scaFlowPoint.getScaEthFppUniN(); |
| 323 | |
| 324 | if (ceBwp != null) { |
| 325 | // Prepare SCA bandwidth profile |
| 326 | SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp = new SCAETHFlowPointIngressBandwidthProfilePerEvc(); |
| 327 | |
| 328 | // TODO: Check for null? |
| 329 | scaBwp.setBwpCfgCir((int) ceBwp.cir().bps()); |
| 330 | scaBwp.setBwpCfgCbs((int) ceBwp.cbs()); |
| 331 | scaBwp.setBwpCfgEir((int) ceBwp.eir().bps()); |
| 332 | scaBwp.setBwpCfgEbs((int) ceBwp.ebs()); |
| 333 | |
| 334 | // TODO: Add the CoS part when it's ready from the CE app side |
| 335 | if (ceBwp.type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) { |
| 336 | newScaUni.setEvcId(ceBwp.id()); |
| 337 | newScaFlowPoint.setIngressBandwidthProfilePerEvc(scaBwp); |
| 338 | } else if (ceBwp.type().equals(CarrierEthernetBandwidthProfile.Type.INTERFACE)) { |
| 339 | newScaUni.setInterfaceCfgIdentifier(ceUni.cfgId()); |
| 340 | newScaUni.setInterfaceCfgIngressBwp(scaBwp); |
| 341 | } else { |
| 342 | log.error("Could not add BW profile for Flow Point {}", scaFlowPoint.toString()); |
| 343 | return null; |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | newScaFlowPoint.setScaEthFppUniN(newScaUni); |
| 348 | |
| 349 | return newScaFlowPoint; |
| 350 | } |
| 351 | |
| 352 | } |