/* * Copyright © 2021 Nokia. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.transportpce.tapi.utils; import java.nio.charset.Charset; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.transportpce.common.network.NetworkTransactionService; import org.opendaylight.transportpce.tapi.TapiStringConstants; import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State; import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.CapacityUnit; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.TotalSizeBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.AvailableCapacityBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.TotalPotentialCapacityBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ProtectionType; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RestorationPolicy; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePoint; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointKey; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.ResilienceTypeBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristic; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristicBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristic; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristicBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristic; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristicBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanism; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanismBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.Uint64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TapiLink { private static final Logger LOG = LoggerFactory.getLogger(TapiLink.class); private final NetworkTransactionService networkTransactionService; public TapiLink(NetworkTransactionService networkTransactionService) { this.networkTransactionService = networkTransactionService; } public Link createTapiLink(String srcNodeid, String srcTpId, String dstNodeId, String dstTpId, String linkType, String srcNodeQual, String dstNodeQual, String srcTpQual, String dstTpQual, String adminState, String operState, List layerProtoNameList, List transLayerNameList, Uuid tapiTopoUuid) { Map nepList = new HashMap<>(); String sourceNodeKey = String.join("+", srcNodeid, srcNodeQual); String sourceNepKey = String.join("+", srcNodeid, srcTpQual, srcTpId); Uuid sourceUuidNode = new Uuid(UUID.nameUUIDFromBytes(sourceNodeKey.getBytes(Charset.forName("UTF-8"))) .toString()); Uuid sourceUuidTp = new Uuid(UUID.nameUUIDFromBytes(sourceNepKey.getBytes(Charset.forName("UTF-8"))) .toString()); String destNodeKey = String.join("+", dstNodeId, dstNodeQual); String destNepKey = String.join("+", dstNodeId, dstTpQual, dstTpId); String linkKey = String.join("to", sourceNepKey, destNepKey); Uuid destUuidNode = new Uuid(UUID.nameUUIDFromBytes(destNodeKey.getBytes(Charset.forName("UTF-8"))).toString()); Uuid destUuidTp = new Uuid(UUID.nameUUIDFromBytes(destNepKey.getBytes(Charset.forName("UTF-8"))).toString()); NodeEdgePoint sourceNep = new NodeEdgePointBuilder() .setTopologyUuid(tapiTopoUuid) .setNodeUuid(sourceUuidNode) .setNodeEdgePointUuid(sourceUuidTp) .build(); nepList.put(sourceNep.key(), sourceNep); NodeEdgePoint destNep = new NodeEdgePointBuilder() .setTopologyUuid(tapiTopoUuid) .setNodeUuid(destUuidNode) .setNodeEdgePointUuid(destUuidTp) .build(); nepList.put(destNep.key(), destNep); NameBuilder linkName = new NameBuilder(); // TODO: variables for each type switch (linkType) { case TapiStringConstants.OMS_RDM_RDM_LINK: LOG.info("Roadm to roadm link"); linkName .setValueName("OMS link name") .setValue(linkKey); break; case TapiStringConstants.TRANSITIONAL_LINK: LOG.info("Transitional link"); linkName .setValueName("transitional link name") .setValue(linkKey); break; case TapiStringConstants.OMS_XPDR_RDM_LINK: LOG.info("Xpdr to roadm link"); linkName .setValueName("XPDR-RDM link name") .setValue(linkKey); break; case TapiStringConstants.OTN_XPDR_XPDR_LINK: LOG.info("OTN Xpdr to roadm link"); linkName .setValueName("otn link name") .setValue(linkKey); break; default: LOG.warn("Type {} not recognized", linkType); return null; } // Todo: common aspects of links and set all attributes CostCharacteristic costCharacteristic = new CostCharacteristicBuilder() .setCostAlgorithm("Restricted Shortest Path - RSP") .setCostName("HOP_COUNT") .setCostValue("12345678") .build(); LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder() .setFixedLatencyCharacteristic("12345678") .setQueingLatencyCharacteristic("12345678") .setJitterCharacteristic("12345678") .setWanderCharacteristic("12345678") .setTrafficPropertyName("FIXED_LATENCY") .build(); RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder() .setRiskCharacteristicName("risk characteristic") .setRiskIdentifierList(List.of("risk identifier1", "risk identifier2")) .build(); ValidationMechanism validationMechanism = new ValidationMechanismBuilder() .setValidationMechanism("validation mechanism") .setValidationRobustness("validation robustness") .setLayerProtocolAdjacencyValidated("layer protocol adjacency") .build(); return new LinkBuilder() .setUuid(new Uuid( UUID.nameUUIDFromBytes(linkKey.getBytes(Charset.forName("UTF-8"))).toString())) .setName(Map.of(linkName.build().key(), linkName.build())) .setTransitionedLayerProtocolName(transLayerNameList) .setLayerProtocolName(layerProtoNameList) .setNodeEdgePoint(nepList) .setDirection(ForwardingDirection.BIDIRECTIONAL) .setAvailableCapacity(new AvailableCapacityBuilder().setTotalSize( new TotalSizeBuilder().setUnit(CapacityUnit.GBPS).setValue(Uint64.valueOf(100)).build()) .build()) .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON) .setRestorationPolicy(RestorationPolicy.NA) .build()) .setAdministrativeState(setTapiAdminState(adminState)) .setOperationalState(setTapiOperationalState(operState)) .setLifecycleState(LifecycleState.INSTALLED) .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().setTotalSize( new TotalSizeBuilder().setUnit(CapacityUnit.GBPS).setValue(Uint64.valueOf(100)).build()) .build()) .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic)) .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic)) .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic)) .setErrorCharacteristic("error") .setLossCharacteristic("loss") .setRepeatDeliveryCharacteristic("repeat delivery") .setDeliveryOrderCharacteristic("delivery order") .setUnavailableTimeCharacteristic("unavailable time") .setServerIntegrityProcessCharacteristic("server integrity process") .setValidationMechanism(Map.of(validationMechanism.key(), validationMechanism)) .build(); } public AdministrativeState setTapiAdminState(String adminState) { if (adminState == null) { return null; } return adminState.equals(AdminStates.InService.getName()) || adminState.equals(AdministrativeState.UNLOCKED.getName()) ? AdministrativeState.UNLOCKED : AdministrativeState.LOCKED; } public AdministrativeState setTapiAdminState(AdminStates adminState1, AdminStates adminState2) { if (adminState1 == null || adminState2 == null) { return null; } LOG.info("Admin state 1 = {}, andmin state 2 = {}", adminState1.getName(), adminState2.getName()); return AdminStates.InService.equals(adminState1) && AdminStates.InService.equals(adminState2) ? AdministrativeState.UNLOCKED : AdministrativeState.LOCKED; } public OperationalState setTapiOperationalState(String operState) { if (operState == null) { return null; } return operState.equals("inService") || operState.equals(OperationalState.ENABLED.getName()) ? OperationalState.ENABLED : OperationalState.DISABLED; } public OperationalState setTapiOperationalState(State operState1, State operState2) { if (operState1 == null || operState2 == null) { return null; } return State.InService.equals(operState1) && State.InService.equals(operState2) ? OperationalState.ENABLED : OperationalState.DISABLED; } public String getOperState(String srcNodeId, String destNodeId, String sourceTpId, String destTpId) { Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER .getBytes(Charset.forName("UTF-8"))).toString()); Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", srcNodeId, TapiStringConstants.PHTNC_MEDIA).getBytes(Charset.forName("UTF-8"))).toString()); Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", srcNodeId, TapiStringConstants.PHTNC_MEDIA, sourceTpId).getBytes(Charset.forName("UTF-8"))).toString()); InstanceIdentifier onepIID = InstanceIdentifier.builder(Context.class) .augmentation(Context1.class).child(TopologyContext.class) .child(Topology.class, new TopologyKey(tapiTopoUuid)).child(Node.class, new NodeKey(nodeUuid)) .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid)) .build(); Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", destNodeId, TapiStringConstants.PHTNC_MEDIA).getBytes(Charset.forName("UTF-8"))).toString()); Uuid nep1Uuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", destNodeId, TapiStringConstants.PHTNC_MEDIA, destTpId).getBytes(Charset.forName("UTF-8"))).toString()); InstanceIdentifier onep1IID = InstanceIdentifier.builder(Context.class) .augmentation(Context1.class).child(TopologyContext.class) .child(Topology.class, new TopologyKey(tapiTopoUuid)).child(Node.class, new NodeKey(node1Uuid)) .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nep1Uuid)) .build(); try { Optional optionalOnep = this.networkTransactionService.read( LogicalDatastoreType.OPERATIONAL, onepIID).get(); Optional optionalOnep1 = this.networkTransactionService.read( LogicalDatastoreType.OPERATIONAL, onep1IID).get(); if (!optionalOnep.isPresent() || !optionalOnep1.isPresent()) { LOG.error("One of the 2 neps doesnt exist in the datastore: {} OR {}", nepUuid, nep1Uuid); return null; } return optionalOnep.get().getOperationalState().equals(optionalOnep1.get().getOperationalState()) ? optionalOnep.get().getOperationalState().getName() : OperationalState.DISABLED.getName(); } catch (InterruptedException | ExecutionException e) { LOG.error("Failed getting Mapping data from portMapping",e); return null; } } public String getAdminState(String srcNodeId, String destNodeId, String sourceTpId, String destTpId) { Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER .getBytes(Charset.forName("UTF-8"))).toString()); Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", srcNodeId, TapiStringConstants.PHTNC_MEDIA).getBytes(Charset.forName("UTF-8"))).toString()); Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", srcNodeId, TapiStringConstants.PHTNC_MEDIA, sourceTpId).getBytes(Charset.forName("UTF-8"))).toString()); InstanceIdentifier onepIID = InstanceIdentifier.builder(Context.class) .augmentation(Context1.class).child(TopologyContext.class) .child(Topology.class, new TopologyKey(tapiTopoUuid)).child(Node.class, new NodeKey(nodeUuid)) .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid)) .build(); Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", destNodeId, TapiStringConstants.PHTNC_MEDIA).getBytes(Charset.forName("UTF-8"))).toString()); Uuid nep1Uuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", destNodeId, TapiStringConstants.PHTNC_MEDIA, destTpId).getBytes(Charset.forName("UTF-8"))).toString()); InstanceIdentifier onep1IID = InstanceIdentifier.builder(Context.class) .augmentation(Context1.class).child(TopologyContext.class) .child(Topology.class, new TopologyKey(tapiTopoUuid)).child(Node.class, new NodeKey(node1Uuid)) .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nep1Uuid)) .build(); try { Optional optionalOnep = this.networkTransactionService.read( LogicalDatastoreType.OPERATIONAL, onepIID).get(); Optional optionalOnep1 = this.networkTransactionService.read( LogicalDatastoreType.OPERATIONAL, onep1IID).get(); if (!optionalOnep.isPresent() || !optionalOnep1.isPresent()) { LOG.error("One of the 2 neps doesnt exist in the datastore: {} OR {}", nepUuid, nep1Uuid); return null; } return optionalOnep.get().getAdministrativeState().equals(optionalOnep1.get().getAdministrativeState()) ? optionalOnep.get().getAdministrativeState().getName() : AdministrativeState.UNLOCKED.getName(); } catch (InterruptedException | ExecutionException e) { LOG.error("Failed getting Mapping data from portMapping",e); return null; } } }