import io.lighty.core.controller.api.LightyServices;
import java.util.Arrays;
import java.util.List;
+import org.opendaylight.mdsal.binding.api.NotificationService;
import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
import org.opendaylight.transportpce.common.crossconnect.CrossConnectImpl;
import org.opendaylight.transportpce.common.crossconnect.CrossConnectImpl121;
import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperationsImpl;
import org.opendaylight.transportpce.tapi.R2RTapiLinkDiscovery;
import org.opendaylight.transportpce.tapi.impl.TapiProvider;
+import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl;
import org.opendaylight.transportpce.tapi.topology.TapiNetconfTopologyListener;
import org.opendaylight.transportpce.tapi.topology.TapiNetworkModelService;
import org.opendaylight.transportpce.tapi.topology.TapiNetworkModelServiceImpl;
LOG.info("Creating tapi beans ...");
R2RTapiLinkDiscovery tapilinkDiscoveryImpl = new R2RTapiLinkDiscovery(lightyServices.getBindingDataBroker(),
deviceTransactionManager);
+ TapiRendererListenerImpl tapiRendererListenerImpl = new TapiRendererListenerImpl(lightyServices
+ .getBindingDataBroker());
+ TapiPceListenerImpl tapiPceListenerImpl = new TapiPceListenerImpl(lightyServices.getBindingDataBroker());
+ TapiServiceHandlerListenerImpl tapiServiceHandlerListener = new TapiServiceHandlerListenerImpl(lightyServices
+ .getBindingDataBroker());
TransportpceTapinetworkutilsService tapiNetworkutilsServiceImpl = new TapiNetworkUtilsImpl(
networkTransaction);
TapiNetworkModelService tapiNetworkModelService = new TapiNetworkModelServiceImpl(
new TapiNetconfTopologyListener(tapiNetworkModelService);
TapiPortMappingListener tapiPortMappingListener =
new TapiPortMappingListener(tapiNetworkModelService);
+
tapiProvider = initTapi(lightyServices, servicehandler, networkTransaction, serviceDataStoreOperations,
- tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl);
+ tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl, tapiPceListenerImpl,
+ tapiRendererListenerImpl, tapiServiceHandlerListener, lightyServices.getNotificationService());
if(activateNbiNotification) {
LOG.info("Creating nbi-notifications beans ...");
nbiNotificationsProvider = new NbiNotificationsProvider(
ServiceDataStoreOperations serviceDataStoreOperations,
TapiNetconfTopologyListener tapiNetConfTopologyListener,
TapiPortMappingListener tapiPortMappingListener,
- TransportpceTapinetworkutilsService tapiNetworkutilsServiceImpl) {
+ TransportpceTapinetworkutilsService tapiNetworkutilsServiceImpl,
+ TapiPceListenerImpl pceListenerImpl, TapiRendererListenerImpl rendererListenerImpl,
+ TapiServiceHandlerListenerImpl serviceHandlerListenerImpl,
+ NotificationService notificationService) {
return new TapiProvider(lightyServices.getBindingDataBroker(), lightyServices.getRpcProviderService(),
servicehandler, serviceDataStoreOperations, new TapiListener(), networkTransaction,
- tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl);
+ tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl, pceListenerImpl,
+ rendererListenerImpl, serviceHandlerListenerImpl, notificationService);
}
/**
import java.nio.charset.Charset;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.Service;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.sdnc.request.header.SdncRequestHeaderBuilder;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.RxDirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.SubrateEthSlaBuilder;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.TxDirectionBuilder;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.lgx.LgxBuilder;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.port.PortBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.ODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.common.types.rev181130.OTU4;
import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev190531.ServiceFormat;
import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInput;
import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInputBuilder;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.Node;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.TerminationPoint;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
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.ForwardingDirection;
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.common.rev181210.tapi.context.ServiceInterfacePoint;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ProtectionRole;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ServiceType;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPoint;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointKey;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointKey;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.end.point.CapacityBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.end.point.ServiceInterfacePointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.ConnectivityConstraint;
+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.edge.point.MappedServiceInterfacePointKey;
+import org.opendaylight.yangtools.yang.common.Uint16;
import org.opendaylight.yangtools.yang.common.Uint32;
import org.opendaylight.yangtools.yang.common.Uint64;
import org.slf4j.Logger;
private static final String OTSI_MC = "OTSi_MEDIA_CHANNEL";
private static final String TP = "TerminationPoint";
private static final String NODE = "Node";
+ private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
+ .getBytes(Charset.forName("UTF-8"))).toString());
private static final Logger LOG = LoggerFactory.getLogger(ConnectivityUtils.class);
private final ServiceDataStoreOperations serviceDataStoreOperations;
.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey,
org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection>
connectionFullMap; // this variable is for complete connection objects
+ private Map<String, Map<String, Boolean>> networkMap = new HashMap<>();
// TODO -> handle cases for which node id is ROADM-A1 and not ROADMA01 or XPDR-A1 and not XPDRA01
public ConnectivityUtils(ServiceDataStoreOperations serviceDataStoreOperations,
.setLifecycleState(LifecycleState.INSTALLED)
.setUuid(new Uuid(UUID.nameUUIDFromBytes(service.getServiceName().getBytes(Charset.forName("UTF-8")))
.toString()))
+ .setServiceLayer(mapServiceLayer(serviceAEnd.getServiceFormat()))
+ .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY)
.setConnectivityDirection(ForwardingDirection.BIDIRECTIONAL)
.setName(Map.of(name.key(), name))
.setConnection(connMap)
.build();
}
+ private LayerProtocolName mapServiceLayer(ServiceFormat serviceFormat) {
+ switch (serviceFormat) {
+ case OC:
+ case OTU:
+ return LayerProtocolName.PHOTONICMEDIA;
+ case ODU:
+ return LayerProtocolName.ODU;
+ case Ethernet:
+ return LayerProtocolName.DSR;
+ default:
+ LOG.info("Service layer mapping not supported for {}", serviceFormat.getName());
+ }
+ return null;
+ }
+
private Map<ConnectionKey, Connection> createConnectionsFromService(
org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.ServiceAEnd
serviceAEnd,
default:
LOG.error("Service Format not supported");
}
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.local._class.Name name =
+ new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.local._class.NameBuilder()
+ .setValueName("OpenROADM info")
+ .setValue(String.join("-", serviceZEnd.getClli(),
+ serviceZEnd.getTxDirection().getPort().getPortDeviceName(),
+ serviceZEnd.getTxDirection().getPort().getPortName()))
+ .build();
return endPointBuilder
.setServiceInterfacePoint(new ServiceInterfacePointBuilder()
.setServiceInterfacePointUuid(sipUuid)
.build())
+ .setName(Map.of(name.key(), name))
.setAdministrativeState(AdministrativeState.UNLOCKED)
.setDirection(PortDirection.BIDIRECTIONAL)
.setLifecycleState(LifecycleState.INSTALLED)
default:
LOG.error("Service Format not supported");
}
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.local._class.Name name =
+ new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.local._class.NameBuilder()
+ .setValueName("OpenROADM info")
+ .setValue(String.join("-", serviceAEnd.getClli(),
+ serviceAEnd.getTxDirection().getPort().getPortDeviceName(),
+ serviceAEnd.getTxDirection().getPort().getPortName()))
+ .build();
return endPointBuilder
.setServiceInterfacePoint(new ServiceInterfacePointBuilder()
.setServiceInterfacePointUuid(sipUuid)
.build())
+ .setName(Map.of(name.key(), name))
.setAdministrativeState(AdministrativeState.UNLOCKED)
.setDirection(PortDirection.BIDIRECTIONAL)
.setLifecycleState(LifecycleState.INSTALLED)
return nodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*") ? String.join("-", nodeid.split("-")[0], nodeid.split("-")[1])
: nodeid.split("-")[0];
}
+
+ public ServiceCreateInput createORServiceInput(CreateConnectivityServiceInput input, Uuid serviceUuid) {
+ // TODO: not taking into account all the constraints. Only using EndPoints and Connectivity Constraint.
+ Map<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPointKey,
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint>
+ endPointMap = input.getEndPoint();
+ ConnectivityConstraint constraint = input.getConnectivityConstraint();
+ ConnectionType connType = null;
+ ServiceFormat serviceFormat = null;
+ String nodeAid = String.join("+", endPointMap.values().stream().findFirst().get().getLocalId(), DSR);
+ String nodeZid = String.join("+", endPointMap.values().stream().skip(1).findFirst().get().getLocalId(), DSR);
+ LOG.debug("Node a = {}", nodeAid);
+ LOG.debug("Node z = {}", nodeZid);
+ switch (constraint.getServiceLayer().getIntValue()) {
+ case 0:
+ LOG.info("ODU");
+ connType = ConnectionType.Infrastructure;
+ serviceFormat = ServiceFormat.ODU;
+ break;
+ case 2:
+ LOG.info("DSR");
+ connType = ConnectionType.Service;
+ serviceFormat = ServiceFormat.Ethernet;
+ break;
+ case 3:
+ LOG.info("PHOTONIC");
+ connType = getConnectionTypePhtnc(endPointMap.values());
+ serviceFormat = getServiceFormatPhtnc(endPointMap.values());
+ if (serviceFormat.equals(ServiceFormat.OC)) {
+ nodeAid = String.join("+", endPointMap.values().stream().findFirst().get().getLocalId(),
+ PHTNC_MEDIA);
+ nodeZid = String.join("+", endPointMap.values().stream().skip(1).findFirst().get().getLocalId(),
+ PHTNC_MEDIA);
+ } else {
+ nodeAid = String.join("+", endPointMap.values().stream().findFirst().get().getLocalId(), OTSI);
+ nodeZid = String.join("+", endPointMap.values().stream().skip(1).findFirst().get().getLocalId(),
+ OTSI);
+ }
+ LOG.debug("Node a photonic = {}", nodeAid);
+ LOG.debug("Node z photonic = {}", nodeZid);
+ break;
+ default:
+ LOG.info("Service type {} not supported", constraint.getServiceLayer().getName());
+ }
+ // Requested Capacity for connectivity service
+ Uint64 capacity = input.getConnectivityConstraint().getRequestedCapacity().getTotalSize().getValue();
+ // map endpoints into service end points. Map the type of service from TAPI to OR
+ ServiceAEnd serviceAEnd = tapiEndPointToServiceAPoint(endPointMap.values().stream().findFirst().get(),
+ serviceFormat, nodeAid, capacity);
+ ServiceZEnd serviceZEnd = tapiEndPointToServiceZPoint(endPointMap.values().stream().skip(1).findFirst().get(),
+ serviceFormat, nodeZid, capacity);
+ if (serviceAEnd == null || serviceZEnd == null) {
+ LOG.error("Couldnt map endpoints to service end");
+ return null;
+ }
+ LOG.info("Service a end = {}", serviceAEnd);
+ LOG.info("Service z end = {}", serviceZEnd);
+ return new ServiceCreateInputBuilder()
+ .setServiceAEnd(serviceAEnd)
+ .setServiceZEnd(serviceZEnd)
+ .setConnectionType(connType)
+ .setServiceName(serviceUuid.getValue())
+ .setCommonId("common id")
+ .setSdncRequestHeader(new SdncRequestHeaderBuilder().setRequestId("request-1")
+ .setRpcAction(RpcActions.ServiceCreate).setNotificationUrl("notification url")
+ .setRequestSystemId("appname")
+ .build())
+ .setCustomer("customer")
+ .setDueDate(DateAndTime.getDefaultInstance("2018-06-15T00:00:01Z"))
+ .setOperatorContact("pw1234")
+ .build();
+ }
+
+ private ServiceZEnd tapiEndPointToServiceZPoint(
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint endPoint,
+ ServiceFormat serviceFormat, String nodeZid, Uint64 capacity) {
+ // TODO -> change way this is being created. The name includes only SPDR-SA1-XPDR1.
+ // Not the rest which is needed in the txPortDeviceName.
+ // It could be obtained from the SIP which has the NEP and includes all the OR name.
+ Uuid sipUuid = endPoint.getServiceInterfacePoint().getServiceInterfacePointUuid();
+ // Todo -> need to find the NEP associated to that SIP
+ Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeZid.getBytes(Charset.forName("UTF-8"))).toString());
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node =
+ this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid);
+ if (node == null) {
+ LOG.error("Node not found in datastore");
+ return null;
+ }
+ // TODO -> in case of a DSR service, for some requests we need the NETWORK PORT and not the CLIENT although the
+ // connection is between 2 CLIENT ports. Otherwise it will not work...
+ OwnedNodeEdgePoint nep = null;
+ for (OwnedNodeEdgePoint onep : node.getOwnedNodeEdgePoint().values()) {
+ if (onep.getMappedServiceInterfacePoint() == null) {
+ continue;
+ }
+ if (onep.getMappedServiceInterfacePoint().containsKey(new MappedServiceInterfacePointKey(sipUuid))) {
+ nep = onep;
+ break;
+ }
+ }
+ if (nep == null) {
+ LOG.error("Nep not found in datastore");
+ return null;
+ }
+ String nodeName = endPoint.getName().values().stream().findFirst().get().getValue();
+ String nodeid = String.join("-", nodeName.split("-")[0], nodeName.split("-")[1]);
+ String nepName = nep.getName().values().stream().findFirst().get().getValue();
+ String txPortDeviceName = nepName.split("\\+")[0];
+ String txPortName = nepName.split("\\+")[2];
+ String rxPortDeviceName = txPortDeviceName;
+ String rxPortName = txPortName;
+ LOG.debug("Node z id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
+ LOG.debug("Node z id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
+ if (serviceFormat.equals(ServiceFormat.ODU)) {
+ // TODO --> populate network map
+ populateNetworkMap(nodeid, txPortName);
+ }
+ if (serviceFormat.equals(ServiceFormat.Ethernet)) {
+ // TODO --> choose from network Map un network port which hasnt been used yet by another service.
+ // Set boolean to true and update txportName and so on
+ String updTxName = findFreeConfiguredNetworkPort(nodeid);
+ if (updTxName != null) {
+ txPortName = updTxName;
+ rxPortName = txPortName;
+ }
+ }
+ // TODO --> get clli from datastore?
+ String clli = "NodeSC";
+ LOG.info("Node z id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
+ LOG.info("Node z id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
+ ServiceZEndBuilder serviceZEndBuilder = new ServiceZEndBuilder()
+ .setClli(clli)
+ .setNodeId(new NodeIdType(nodeid))
+ .setOpticType(OpticTypes.Gray)
+ .setServiceFormat(serviceFormat)
+ .setServiceRate(Uint32.valueOf(capacity))
+ .setSubrateEthSla(new SubrateEthSlaBuilder().setSubrateEthSla(
+ new org.opendaylight.yang.gen.v1.http
+ .org.openroadm.common.service.types.rev190531.subrate.eth.sla.SubrateEthSlaBuilder()
+ .setCommittedBurstSize(Uint16.valueOf(64))
+ .setCommittedInfoRate(Uint32.valueOf(100000))
+ .build())
+ .build())
+ .setTxDirection(new TxDirectionBuilder()
+ .setPort(new PortBuilder()
+ .setPortDeviceName(txPortDeviceName)
+ .setPortName(txPortName)
+ .setPortRack(PORT_RACK_VALUE)
+ .setPortShelf("00")
+ .setPortType(PORT_TYPE)
+ .build())
+ .setLgx(new LgxBuilder()
+ .setLgxDeviceName(LGX_DEVICE_NAME)
+ .setLgxPortName(LGX_PORT_NAME)
+ .setLgxPortRack(PORT_RACK_VALUE)
+ .setLgxPortShelf("00")
+ .build())
+ .build())
+ .setRxDirection(new RxDirectionBuilder()
+ .setPort(new PortBuilder()
+ .setPortDeviceName(rxPortDeviceName)
+ .setPortName(rxPortName)
+ .setPortRack(PORT_RACK_VALUE)
+ .setPortShelf("00")
+ .setPortType(PORT_TYPE)
+ .build())
+ .setLgx(new LgxBuilder()
+ .setLgxDeviceName(LGX_DEVICE_NAME)
+ .setLgxPortName(LGX_PORT_NAME)
+ .setLgxPortRack(PORT_RACK_VALUE)
+ .setLgxPortShelf("00")
+ .build())
+ .build());
+ if (serviceFormat.equals(ServiceFormat.ODU)) {
+ serviceZEndBuilder.setOduServiceRate(ODU4.class);
+ }
+ if (serviceFormat.equals(ServiceFormat.OTU)) {
+ serviceZEndBuilder.setOtuServiceRate(OTU4.class);
+ }
+ return serviceZEndBuilder.build();
+ }
+
+ private ServiceAEnd tapiEndPointToServiceAPoint(
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint endPoint,
+ ServiceFormat serviceFormat, String nodeAid, Uint64 capacity) {
+ // TODO -> change way this is being created. The name includes only SPDR-SA1-XPDR1.
+ // Not the rest which is needed in the txPortDeviceName.
+ // It could be obtained from the SIP which has the NEP and includes all the OR name.
+ Uuid sipUuid = endPoint.getServiceInterfacePoint().getServiceInterfacePointUuid();
+ // Todo -> need to find the NEP associated to that SIP
+ Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeAid.getBytes(Charset.forName("UTF-8"))).toString());
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node =
+ this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid);
+ if (node == null) {
+ LOG.error("Node not found in datastore");
+ return null;
+ }
+ // TODO -> in case of a DSR service, for some requests we need the NETWORK PORT and not the CLIENT although the
+ // connection is between 2 CLIENT ports. Otherwise it will not work...
+ OwnedNodeEdgePoint nep = null;
+ for (OwnedNodeEdgePoint onep : node.getOwnedNodeEdgePoint().values()) {
+ if (onep.getMappedServiceInterfacePoint() == null) {
+ continue;
+ }
+ if (onep.getMappedServiceInterfacePoint().containsKey(new MappedServiceInterfacePointKey(sipUuid))) {
+ nep = onep;
+ break;
+ }
+ }
+ if (nep == null) {
+ LOG.error("Nep not found in datastore");
+ return null;
+ }
+ String nodeName = endPoint.getName().values().stream().findFirst().get().getValue();
+ String nodeid = String.join("-", nodeName.split("-")[0], nodeName.split("-")[1]);
+ String nepName = nep.getName().values().stream().findFirst().get().getValue();
+ String txPortDeviceName = nepName.split("\\+")[0];
+ String txPortName = nepName.split("\\+")[2];
+ String rxPortDeviceName = txPortDeviceName;
+ String rxPortName = txPortName;
+ LOG.debug("Node a id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
+ LOG.debug("Node a id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
+ if (serviceFormat.equals(ServiceFormat.ODU)) {
+ // TODO --> populate network map
+ populateNetworkMap(nodeid, txPortName);
+ }
+ if (serviceFormat.equals(ServiceFormat.Ethernet)) {
+ // TODO --> choose from network Map un network port which hasnt been used yet by another service.
+ // Set boolean to true and update txportName and so on
+ String updTxName = findFreeConfiguredNetworkPort(nodeid);
+ if (updTxName != null) {
+ txPortName = updTxName;
+ rxPortName = txPortName;
+ }
+ }
+ // TODO --> get clli from datastore?
+ String clli = "NodeSA";
+ LOG.info("Node a id = {}, txportDeviceName = {}, txPortName = {}", nodeid, txPortDeviceName, txPortName);
+ LOG.info("Node a id = {}, rxportDeviceName = {}, rxPortName = {}", nodeid, rxPortDeviceName, rxPortName);
+ ServiceAEndBuilder serviceAEndBuilder = new ServiceAEndBuilder()
+ .setClli(clli)
+ .setNodeId(new NodeIdType(nodeid))
+ .setOpticType(OpticTypes.Gray)
+ .setServiceFormat(serviceFormat)
+ .setServiceRate(Uint32.valueOf(capacity))
+ .setSubrateEthSla(new SubrateEthSlaBuilder().setSubrateEthSla(
+ new org.opendaylight.yang.gen.v1.http
+ .org.openroadm.common.service.types.rev190531.subrate.eth.sla.SubrateEthSlaBuilder()
+ .setCommittedBurstSize(Uint16.valueOf(64))
+ .setCommittedInfoRate(Uint32.valueOf(100000))
+ .build())
+ .build())
+ .setTxDirection(new TxDirectionBuilder()
+ .setPort(new PortBuilder()
+ .setPortDeviceName(txPortDeviceName)
+ .setPortName(txPortName)
+ .setPortRack(PORT_RACK_VALUE)
+ .setPortShelf("00")
+ .setPortType(PORT_TYPE)
+ .build())
+ .setLgx(new LgxBuilder()
+ .setLgxDeviceName(LGX_DEVICE_NAME)
+ .setLgxPortName(LGX_PORT_NAME)
+ .setLgxPortRack(PORT_RACK_VALUE)
+ .setLgxPortShelf("00")
+ .build())
+ .build())
+ .setRxDirection(new RxDirectionBuilder()
+ .setPort(new PortBuilder()
+ .setPortDeviceName(rxPortDeviceName)
+ .setPortName(rxPortName)
+ .setPortRack(PORT_RACK_VALUE)
+ .setPortShelf("00")
+ .setPortType(PORT_TYPE)
+ .build())
+ .setLgx(new LgxBuilder()
+ .setLgxDeviceName(LGX_DEVICE_NAME)
+ .setLgxPortName(LGX_PORT_NAME)
+ .setLgxPortRack(PORT_RACK_VALUE)
+ .setLgxPortShelf("00")
+ .build())
+ .build());
+ if (serviceFormat.equals(ServiceFormat.ODU)) {
+ serviceAEndBuilder.setOduServiceRate(ODU4.class);
+ }
+ if (serviceFormat.equals(ServiceFormat.OTU)) {
+ serviceAEndBuilder.setOtuServiceRate(OTU4.class);
+ }
+ return serviceAEndBuilder.build();
+ }
+
+ private String findFreeConfiguredNetworkPort(String nodeid) {
+ if (!this.networkMap.containsKey(nodeid)) {
+ return null;
+ }
+ Map<String, Boolean> netMap = this.networkMap.get(nodeid);
+ for (Map.Entry<String, Boolean> entry : netMap.entrySet()) {
+ if (!entry.getValue()) {
+ this.networkMap.get(nodeid).put(entry.getKey(), true);
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+
+ private void populateNetworkMap(String nodeid, String txPortName) {
+ Map<String, Boolean> netMap = new HashMap<>();
+ netMap.put(txPortName, false);
+ if (!this.networkMap.containsKey(nodeid)) {
+ this.networkMap.put(nodeid, netMap);
+ } else if (!this.networkMap.get(nodeid).containsKey(txPortName)) {
+ this.networkMap.get(nodeid).putAll(netMap);
+ }
+ }
+
+ private ConnectionType getConnectionTypePhtnc(Collection<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint> endPoints) {
+ if (endPoints.stream().anyMatch(ep -> ep.getName().values().stream()
+ .anyMatch(name -> name.getValue().contains("ROADM")))) {
+ // EndPoints are ROADMs
+ return ConnectionType.RoadmLine;
+ }
+ // EndPoints ar not ROADMs -> XPDR, MUXPDR, SWTICHPDR
+ return ConnectionType.Infrastructure;
+ }
+
+ private ServiceFormat getServiceFormatPhtnc(Collection<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint> endPoints) {
+ if (endPoints.stream().anyMatch(ep -> ep.getName().values().stream()
+ .anyMatch(name -> name.getValue().contains("ROADM")))) {
+ // EndPoints are ROADMs
+ return ServiceFormat.OC;
+ }
+ // EndPoints ar not ROADMs -> XPDR, MUXPDR, SWTICHPDR
+ return ServiceFormat.OTU;
+ }
}
package org.opendaylight.transportpce.tapi.connectivity;
import com.google.common.util.concurrent.ListenableFuture;
+import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ExecutionException;
import org.opendaylight.transportpce.common.OperationResult;
-import org.opendaylight.transportpce.tapi.utils.GenericServiceEndpoint;
-import org.opendaylight.transportpce.tapi.utils.MappingUtils;
+import org.opendaylight.transportpce.common.ResponseCodes;
+import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl;
+import org.opendaylight.transportpce.tapi.utils.TapiContext;
import org.opendaylight.transportpce.tapi.validation.CreateConnectivityServiceValidation;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.RpcActions;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.sdnc.request.header.SdncRequestHeaderBuilder;
import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.OrgOpenroadmServiceService;
import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInput;
import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateOutput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceDeleteOutput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.delete.input.ServiceDeleteReqInfo;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.delete.input.ServiceDeleteReqInfoBuilder;
+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.ForwardingDirection;
+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.BandwidthProfileBuilder;
+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.global._class.Name;
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.common.rev181210.tapi.context.ServiceInterfacePoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceOutput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionDetailsInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionDetailsOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionEndPointDetailsInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionEndPointDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionEndPointDetailsOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceDetailsInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceDetailsOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceListInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceListOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceListOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ServiceType;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.TapiConnectivityService;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.UpdateConnectivityServiceInput;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.UpdateConnectivityServiceOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPoint;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.end.point.CapacityBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.end.point.ServiceInterfacePointBuilder;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.output.ServiceBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connection.details.output.ConnectionBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connection.end.point.details.output.ConnectionEndPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.list.output.Service;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.list.output.ServiceKey;
+import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
private static final Logger LOG = LoggerFactory.getLogger(TapiConnectivityImpl.class);
private OrgOpenroadmServiceService serviceHandler;
+ private final TapiContext tapiContext;
+ private final ConnectivityUtils connectivityUtils;
+ private TapiPceListenerImpl pceListenerImpl;
+ private TapiRendererListenerImpl rendererListenerImpl;
+ private TapiServiceHandlerListenerImpl serviceHandlerListenerImpl;
- public TapiConnectivityImpl(OrgOpenroadmServiceService serviceHandler) {
+ public TapiConnectivityImpl(OrgOpenroadmServiceService serviceHandler, TapiContext tapiContext,
+ ConnectivityUtils connectivityUtils, TapiPceListenerImpl pceListenerImpl,
+ TapiRendererListenerImpl rendererListenerImpl,
+ TapiServiceHandlerListenerImpl serviceHandlerListenerImpl) {
LOG.info("inside TapiImpl constructor");
this.serviceHandler = serviceHandler;
+ this.tapiContext = tapiContext;
+ this.connectivityUtils = connectivityUtils;
+ this.pceListenerImpl = pceListenerImpl;
+ this.rendererListenerImpl = rendererListenerImpl;
+ this.serviceHandlerListenerImpl = serviceHandlerListenerImpl;
}
@Override
public ListenableFuture<RpcResult<CreateConnectivityServiceOutput>> createConnectivityService(
- CreateConnectivityServiceInput input) {
+ CreateConnectivityServiceInput input) {
+ // TODO: later version of TAPI models include Name as an input parameter in connectivity.yang
LOG.info("RPC create-connectivity received: {}", input.getEndPoint());
+ Uuid serviceUuid = new Uuid(UUID.randomUUID().toString());
+ this.pceListenerImpl.setInput(input);
+ this.pceListenerImpl.setServiceUuid(serviceUuid);
+ this.rendererListenerImpl.setServiceUuid(serviceUuid);
+ ListenableFuture<RpcResult<ServiceCreateOutput>> output = null;
OperationResult validationResult = CreateConnectivityServiceValidation.validateCreateConnectivityServiceRequest(
- input);
+ input);
if (validationResult.isSuccess()) {
LOG.info("input parameter of RPC create-connectivity are being handled");
- // check uuid of SIP in the map
- Map<Uuid, GenericServiceEndpoint> map = MappingUtils.getMap();
-
- if (map.containsKey(input.getEndPoint().values().stream().findFirst().get()
- .getServiceInterfacePoint().getServiceInterfacePointUuid())
- && map.containsKey(input.getEndPoint().values().stream().skip(1).findFirst().get()
- .getServiceInterfacePoint()
- .getServiceInterfacePointUuid())) {
- ServiceCreateInput sci = ConnectivityUtils.buildServiceCreateInput(
- map.get(input.getEndPoint().values().stream().findFirst().get()
- .getServiceInterfacePoint()
- .getServiceInterfacePointUuid()),
- map.get(input.getEndPoint().values().stream().skip(1).findFirst().get()
- .getServiceInterfacePoint()
- .getServiceInterfacePointUuid()));
- ListenableFuture<RpcResult<ServiceCreateOutput>> output = this.serviceHandler.serviceCreate(sci);
+ // check uuid of SIP in tapi context
+ Map<ServiceInterfacePointKey, ServiceInterfacePoint> sipMap = this.tapiContext.getTapiContext()
+ .getServiceInterfacePoint();
+ if (sipMap == null) {
+ return RpcResultBuilder.<CreateConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+ "SIP list is empty").buildFuture();
+ }
+ if (sipMap.containsKey(new ServiceInterfacePointKey(input.getEndPoint().values().stream().findFirst().get()
+ .getServiceInterfacePoint().getServiceInterfacePointUuid()))
+ && sipMap.containsKey(new ServiceInterfacePointKey(input.getEndPoint().values().stream().skip(1)
+ .findFirst().get().getServiceInterfacePoint().getServiceInterfacePointUuid()))) {
+ LOG.info("SIPs found in sipMap");
+ ServiceCreateInput sci = this.connectivityUtils.createORServiceInput(input, serviceUuid);
+ if (sci == null) {
+ return RpcResultBuilder.<CreateConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+ "Couldnt map Service create input").buildFuture();
+ }
+ LOG.info("Service Create input = {}", sci);
+ output = this.serviceHandler.serviceCreate(sci);
if (!output.isDone()) {
- return RpcResultBuilder.<CreateConnectivityServiceOutput>failed().buildFuture();
+ return RpcResultBuilder.<CreateConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+ "Service create RPC failed").buildFuture();
}
} else {
LOG.error("Unknown UUID");
+ return RpcResultBuilder.<CreateConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+ "SIPs do not exist in tapi context").buildFuture();
}
-
}
-
- Map<EndPointKey, EndPoint> endPointList = new HashMap<>();
- EndPoint endpoint1 = new EndPointBuilder()
- .setLocalId(UUID.randomUUID().toString())
- .setServiceInterfacePoint(new ServiceInterfacePointBuilder().setServiceInterfacePointUuid(new Uuid(UUID
- .randomUUID().toString())).build())
- .build();
- EndPoint endpoint2 = new EndPointBuilder()
- .setLocalId(UUID.randomUUID().toString())
- .setServiceInterfacePoint(new ServiceInterfacePointBuilder().setServiceInterfacePointUuid(new Uuid(UUID
- .randomUUID().toString())).build())
- .build();
- endPointList.put(endpoint1.key(), endpoint1);
- endPointList.put(endpoint2.key(), endpoint2);
- Connection connection = new ConnectionBuilder().setConnectionUuid(new Uuid(UUID.randomUUID().toString()))
+ try {
+ if (output == null) {
+ return RpcResultBuilder.<CreateConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+ "Failed to create service").buildFuture();
+ }
+ LOG.info("Service create request was successful");
+ if (output.get().getResult().getConfigurationResponseCommon().getResponseCode()
+ .equals(ResponseCodes.RESPONSE_FAILED)) {
+ return RpcResultBuilder.<CreateConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+ "Failed to create service").buildFuture();
+ }
+ LOG.info("Output of service request = {}", output.get().getResult());
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Error checking response code of service create", e);
+ }
+ // Connections and states should be created/updated when the pce and renderer are done :)
+ Map<EndPointKey, EndPoint> endPointList = createEndPoints(input.getEndPoint());
+ Name name = new NameBuilder()
+ .setValueName("Connectivity Service Name")
+ .setValue(serviceUuid.getValue())
.build();
ConnectivityService service = new ConnectivityServiceBuilder()
- .setUuid(new Uuid(UUID.randomUUID().toString()))
- .build();
- Name serviceName = new NameBuilder().setValueName("Service Name").setValue("SENDATE Service 1").build();
- CreateConnectivityServiceOutput output = new CreateConnectivityServiceOutputBuilder()
- .setService(new ServiceBuilder(service)
- .setUuid(new Uuid(UUID.randomUUID().toString()))
- .setName(Map.of(serviceName.key(), serviceName))
- .setServiceLayer(input.getEndPoint().values().stream().findFirst().get().getLayerProtocolName())
- .setEndPoint(endPointList)
- .setConnection(Map.of(connection.key(), connection))
- .build())
+ .setUuid(serviceUuid)
+ .setAdministrativeState(AdministrativeState.LOCKED)
+ .setOperationalState(OperationalState.DISABLED)
+ .setLifecycleState(LifecycleState.PLANNED)
+ .setServiceLayer(input.getConnectivityConstraint().getServiceLayer())
+ .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY)
+ .setConnectivityDirection(ForwardingDirection.BIDIRECTIONAL)
+ .setName(Map.of(name.key(), name))
+ .setConnection(new HashMap<>())
+ .setEndPoint(endPointList)
.build();
- return RpcResultBuilder.success(output).buildFuture();
+ // add to tapi context
+ this.tapiContext.updateConnectivityContext(Map.of(service.key(), service), new HashMap<>());
+ LOG.info("Created locked service in Datastore. Waiting for PCE and Renderer to complete tasks...");
+ // return ConnectivityServiceCreateOutput
+ return RpcResultBuilder.success(new CreateConnectivityServiceOutputBuilder()
+ .setService(new ServiceBuilder(service).build()).build()).buildFuture();
+ }
+
+ private Map<EndPointKey, EndPoint> createEndPoints(
+ Map<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPointKey,
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint> endPoints) {
+ Map<EndPointKey, EndPoint> endPointMap = new HashMap<>();
+ for (org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint ep:
+ endPoints.values()) {
+ EndPoint endpoint = new EndPointBuilder()
+ .setServiceInterfacePoint(new ServiceInterfacePointBuilder()
+ .setServiceInterfacePointUuid(ep.getServiceInterfacePoint().getServiceInterfacePointUuid())
+ .build())
+ .setName(ep.getName())
+ .setAdministrativeState(ep.getAdministrativeState())
+ .setDirection(ep.getDirection())
+ .setLifecycleState(ep.getLifecycleState())
+ .setOperationalState(ep.getOperationalState())
+ .setLayerProtocolName(ep.getLayerProtocolName())
+ .setCapacity(new CapacityBuilder()
+ .setTotalSize(new TotalSizeBuilder().build())
+ .setBandwidthProfile(new BandwidthProfileBuilder().build()) // TODO: implement bandwidth profile
+ .build())
+ .setProtectionRole(ep.getProtectionRole())
+ .setRole(ep.getRole())
+ .setLocalId(ep.getLocalId())
+ .build();
+ endPointMap.put(endpoint.key(), endpoint);
+ }
+ return endPointMap;
}
@Override
public ListenableFuture<RpcResult<GetConnectivityServiceDetailsOutput>> getConnectivityServiceDetails(
- GetConnectivityServiceDetailsInput input) {
+ GetConnectivityServiceDetailsInput input) {
// TODO Auto-generated method stub
- return null;
+ Uuid serviceUuid = new Uuid(input.getServiceIdOrName());
+ ConnectivityService service = this.tapiContext.getConnectivityService(serviceUuid);
+ if (service == null) {
+ LOG.error("Service {} doesnt exist in tapi context", input.getServiceIdOrName());
+ return RpcResultBuilder.<GetConnectivityServiceDetailsOutput>failed().withError(RpcError.ErrorType.RPC,
+ "Service doesnt exist in datastore").buildFuture();
+ }
+ return RpcResultBuilder.success(new GetConnectivityServiceDetailsOutputBuilder().setService(
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.details.output.ServiceBuilder(
+ service).build()).build()).buildFuture();
}
@Override
public ListenableFuture<RpcResult<UpdateConnectivityServiceOutput>> updateConnectivityService(
- UpdateConnectivityServiceInput input) {
- // TODO Auto-generated method stub
+ UpdateConnectivityServiceInput input) {
+ // TODO Auto-generated method stub. More complicated as it depends on what needs to be updated... left aside
return null;
}
@Override
public ListenableFuture<RpcResult<GetConnectionDetailsOutput>> getConnectionDetails(
- GetConnectionDetailsInput input) {
+ GetConnectionDetailsInput input) {
// TODO Auto-generated method stub
- return null;
+ Uuid connectionUuid = new Uuid(UUID.nameUUIDFromBytes(input.getConnectionIdOrName()
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Connection connection = this.tapiContext.getConnection(connectionUuid);
+ if (connection == null) {
+ LOG.error("Connection {} doesnt exist in tapi context", input.getConnectionIdOrName());
+ return RpcResultBuilder.<GetConnectionDetailsOutput>failed().withError(RpcError.ErrorType.RPC,
+ "Connection doesnt exist in datastore").buildFuture();
+ }
+ return RpcResultBuilder.success(new GetConnectionDetailsOutputBuilder().setConnection(
+ new ConnectionBuilder(connection).build()).build()).buildFuture();
}
@Override
public ListenableFuture<RpcResult<DeleteConnectivityServiceOutput>> deleteConnectivityService(
- DeleteConnectivityServiceInput input) {
+ DeleteConnectivityServiceInput input) {
//TODO Auto-generated method stub
- return null;
+ // TODO add try
+ Uuid serviceUuid = new Uuid(input.getServiceIdOrName());
+ this.tapiContext.deleteConnectivityService(serviceUuid);
+ ListenableFuture<RpcResult<ServiceDeleteOutput>> output =
+ this.serviceHandler.serviceDelete(new ServiceDeleteInputBuilder()
+ .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
+ .setServiceName(input.getServiceIdOrName())
+ .setTailRetention(ServiceDeleteReqInfo.TailRetention.No)
+ .build())
+ .setSdncRequestHeader(new SdncRequestHeaderBuilder()
+ .setRequestId("request-1")
+ .setRpcAction(RpcActions.ServiceDelete)
+ .setNotificationUrl("notification url")
+ .setRequestSystemId("appname")
+ .build())
+ .build());
+ if (output == null) {
+ return RpcResultBuilder.<DeleteConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+ "Failed to delete Link").buildFuture();
+ }
+ LOG.info("Service is being deleted and devices are being rolled back");
+ return RpcResultBuilder.success(new DeleteConnectivityServiceOutputBuilder().build()).buildFuture();
}
@Override
public ListenableFuture<RpcResult<GetConnectivityServiceListOutput>> getConnectivityServiceList(
- GetConnectivityServiceListInput input) {
+ GetConnectivityServiceListInput input) {
// TODO Auto-generated method stub
- return null;
+ Map<ConnectivityServiceKey, ConnectivityService> connMap = this.tapiContext.getConnectivityServices();
+ if (connMap == null) {
+ LOG.error("No services in tapi context");
+ return RpcResultBuilder.<GetConnectivityServiceListOutput>failed().withError(RpcError.ErrorType.RPC,
+ "No services exist in datastore").buildFuture();
+ }
+
+ Map<ServiceKey, Service> serviceMap = new HashMap<>();
+ for (ConnectivityService connectivityService: connMap.values()) {
+ Service service = new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.list.output.ServiceBuilder(
+ connectivityService).build();
+ serviceMap.put(service.key(), service);
+ }
+ return RpcResultBuilder.success(new GetConnectivityServiceListOutputBuilder().setService(serviceMap)
+ .build()).buildFuture();
}
@Override
public ListenableFuture<RpcResult<GetConnectionEndPointDetailsOutput>> getConnectionEndPointDetails(
- GetConnectionEndPointDetailsInput input) {
+ GetConnectionEndPointDetailsInput input) {
// TODO Auto-generated method stub
- return null;
+ Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName()
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNodeIdOrName()
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNepIdOrName()
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Uuid cepUuid = new Uuid(UUID.nameUUIDFromBytes(input.getCepIdOrName()
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ ConnectionEndPoint cep = this.tapiContext.getTapiCEP(topoUuid, nodeUuid, nepUuid, cepUuid);
+ if (cep == null) {
+ LOG.error("Cep doesnt exist in tapi context");
+ return RpcResultBuilder.<GetConnectionEndPointDetailsOutput>failed().withError(RpcError.ErrorType.RPC,
+ "No cep with given Uuid exists in datastore").buildFuture();
+ }
+ return RpcResultBuilder.success(new GetConnectionEndPointDetailsOutputBuilder().setConnectionEndPoint(
+ new ConnectionEndPointBuilder(cep).build()).build()).buildFuture();
}
}
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
+import org.opendaylight.mdsal.binding.api.NotificationService;
import org.opendaylight.mdsal.binding.api.RpcProviderService;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.transportpce.common.InstanceIdentifiers;
import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
import org.opendaylight.transportpce.tapi.connectivity.ConnectivityUtils;
import org.opendaylight.transportpce.tapi.connectivity.TapiConnectivityImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl;
import org.opendaylight.transportpce.tapi.topology.TapiNetconfTopologyListener;
import org.opendaylight.transportpce.tapi.topology.TapiPortMappingListener;
import org.opendaylight.transportpce.tapi.topology.TapiTopologyImpl;
import org.opendaylight.transportpce.tapi.utils.TapiContext;
import org.opendaylight.transportpce.tapi.utils.TapiInitialORMapping;
import org.opendaylight.transportpce.tapi.utils.TapiListener;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.TransportpcePceListener;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.Network;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210315.network.Nodes;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.TransportpceRendererListener;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.TransportpceServicehandlerListener;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.TransportpceTapinetworkutilsService;
import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.OrgOpenroadmServiceService;
import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.TapiConnectivityService;
private ObjectRegistration<TransportpceTapinetworkutilsService> tapiNetworkutilsServiceRpcRegistration;
private ListenerRegistration<TapiNetconfTopologyListener> dataTreeChangeListenerRegistration;
private ListenerRegistration<TapiPortMappingListener> mappingListenerListenerRegistration;
+ private ListenerRegistration<TransportpcePceListener> pcelistenerRegistration;
+ private ListenerRegistration<TransportpceRendererListener> rendererlistenerRegistration;
+ private ListenerRegistration<TransportpceServicehandlerListener> servicehandlerlistenerRegistration;
private final OrgOpenroadmServiceService serviceHandler;
private final ServiceDataStoreOperations serviceDataStoreOperations;
private final TapiListener tapiListener;
private TapiPortMappingListener tapiPortMappingListener;
private final NetworkTransactionService networkTransactionService;
private final TransportpceTapinetworkutilsService tapiNetworkUtils;
+ private TapiPceListenerImpl pceListenerImpl;
+ private TapiRendererListenerImpl rendererListenerImpl;
+ private TapiServiceHandlerListenerImpl serviceHandlerListenerImpl;
+ private final NotificationService notificationService;
public TapiProvider(DataBroker dataBroker, RpcProviderService rpcProviderService,
OrgOpenroadmServiceService serviceHandler, ServiceDataStoreOperations serviceDataStoreOperations,
TapiListener tapiListener, NetworkTransactionService networkTransactionService,
TapiNetconfTopologyListener topologyListener, TapiPortMappingListener tapiPortMappingListener,
- TransportpceTapinetworkutilsService tapiNetworkUtils) {
+ TransportpceTapinetworkutilsService tapiNetworkUtils, TapiPceListenerImpl pceListenerImpl,
+ TapiRendererListenerImpl rendererListenerImpl, TapiServiceHandlerListenerImpl serviceHandlerListenerImpl,
+ NotificationService notificationService) {
this.dataBroker = dataBroker;
this.rpcProviderService = rpcProviderService;
this.serviceHandler = serviceHandler;
this.topologyListener = topologyListener;
this.tapiPortMappingListener = tapiPortMappingListener;
this.tapiNetworkUtils = tapiNetworkUtils;
+ this.pceListenerImpl = pceListenerImpl;
+ this.rendererListenerImpl = rendererListenerImpl;
+ this.serviceHandlerListenerImpl = serviceHandlerListenerImpl;
+ this.notificationService = notificationService;
}
/**
tapiInitialORMapping.performTopoInitialMapping();
tapiInitialORMapping.performServInitialMapping();
- TapiConnectivityImpl tapi = new TapiConnectivityImpl(this.serviceHandler);
+ TapiConnectivityImpl tapi = new TapiConnectivityImpl(this.serviceHandler, tapiContext, connectivityUtils,
+ pceListenerImpl, rendererListenerImpl, serviceHandlerListenerImpl);
TapiTopologyImpl topo = new TapiTopologyImpl(this.dataBroker, tapiContext, topologyUtils);
rpcRegistration = rpcProviderService.registerRpcImplementation(TapiConnectivityService.class, tapi);
rpcProviderService.registerRpcImplementation(TapiTopologyService.class, topo);
InstanceIdentifier<ServiceInterfacePoints> sipIID = InstanceIdentifier.create(ServiceInterfacePoints.class);
dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
LogicalDatastoreType.CONFIGURATION, sipIID), tapiListener);
+ // Notification Listener
+ pcelistenerRegistration = notificationService.registerNotificationListener(pceListenerImpl);
+ rendererlistenerRegistration = notificationService.registerNotificationListener(rendererListenerImpl);
+ servicehandlerlistenerRegistration =
+ notificationService.registerNotificationListener(serviceHandlerListenerImpl);
}
/**
if (tapiNetworkutilsServiceRpcRegistration != null) {
tapiNetworkutilsServiceRpcRegistration.close();
}
+ pcelistenerRegistration.close();
+ rendererlistenerRegistration.close();
+ servicehandlerlistenerRegistration.close();
rpcRegistration.close();
}
}
--- /dev/null
+/*
+ * Copyright © 2021 Nokia, Inc. and others. 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.listeners;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Comparator;
+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 java.util.stream.Collectors;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.transportpce.common.network.RequestProcessor;
+import org.opendaylight.transportpce.tapi.topology.TopologyUtils;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.ServicePathRpcResult;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.TransportpcePceListener;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.service.path.rpc.result.PathDescription;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.service.path.rpc.result.PathDescriptionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.Node;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.TerminationPoint;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.RpcStatusEx;
+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.PortDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortRole;
+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.global._class.Name;
+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.connectivity.rev181210.Context1;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1Builder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.end.point.ClientNodeEdgePoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.end.point.ClientNodeEdgePointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepList;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepListBuilder;
+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.OwnedNodeEdgePointBuilder;
+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.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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TapiPceListenerImpl implements TransportpcePceListener {
+
+ private static final String DSR = "DSR";
+ private static final String ODU = "ODU";
+ private static final String E_ODU = "eODU";
+ private static final String I_ODU = "iODU";
+ private static final String OTSI = "OTSi";
+ private static final String E_OTSI = "eOTSi";
+ private static final String I_OTSI = "iOTSi";
+ private static final String PHTNC_MEDIA = "PHOTONIC_MEDIA";
+ private static final String MC = "MEDIA_CHANNEL";
+ private static final String OTSI_MC = "OTSi_MEDIA_CHANNEL";
+ private static final String TP = "TerminationPoint";
+ private static final String NODE = "Node";
+ private static final Logger LOG = LoggerFactory.getLogger(TapiPceListenerImpl.class);
+
+ private ServicePathRpcResult servicePathRpcResult;
+ private CreateConnectivityServiceInput input;
+ private Uuid serviceUuid;
+ private final DataBroker dataBroker;
+ private final NetworkTransactionService networkTransactionService;
+ private final Map<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey,
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection>
+ connectionFullMap; // this variable is for complete connection objects
+
+ public TapiPceListenerImpl(DataBroker dataBroker) {
+ this.connectionFullMap = new HashMap<>();
+ this.dataBroker = dataBroker;
+ this.networkTransactionService = new NetworkTransactionImpl(new RequestProcessor(this.dataBroker));
+ }
+
+ @Override
+ public void onServicePathRpcResult(ServicePathRpcResult notification) {
+ if (compareServicePathRpcResult(notification)) {
+ LOG.warn("ServicePathRpcResult already wired !");
+ return;
+ }
+ servicePathRpcResult = notification;
+ switch (servicePathRpcResult.getNotificationType().getIntValue()) {
+ /* path-computation-request. */
+ case 1:
+ onPathComputationResult(notification);
+ break;
+ /* cancel-resource-reserve. */
+ case 2:
+ onCancelResourceResult(notification.getServiceName());
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Process path computation request result.
+ * @param notification the result notification.
+ */
+ private void onPathComputationResult(ServicePathRpcResult notification) {
+ this.connectionFullMap.clear();
+ LOG.info("PCE '{}' Notification received : {}",servicePathRpcResult.getNotificationType().getName(),
+ notification);
+ if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
+ LOG.error("PCE path computation failed !");
+ return;
+ } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
+ LOG.warn("PCE path computation returned a Penging RpcStatusEx code!");
+ return;
+ } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
+ LOG.error("PCE path computation returned an unknown RpcStatusEx code!");
+ return;
+ }
+
+ LOG.info("PCE calculation done OK !");
+ if (servicePathRpcResult.getPathDescription() == null) {
+ LOG.error("'PathDescription' parameter is null ");
+ return;
+ }
+ PathDescription pathDescription = new PathDescriptionBuilder()
+ .setAToZDirection(servicePathRpcResult.getPathDescription().getAToZDirection())
+ .setZToADirection(servicePathRpcResult.getPathDescription().getZToADirection())
+ .build();
+ LOG.info("PathDescription gets : {}", pathDescription);
+ if (input == null) {
+ LOG.error("Input is null !");
+ return;
+ }
+ // Create connections and ceps for the connectivity service.
+ // Connections must be with a locked stated. As the renderer hasnt implemented yet the oc's
+ Map<ConnectionKey, Connection> connectionMap = createConnectionsAndCepsForService(pathDescription,
+ input.getConnectivityConstraint().getServiceLayer());
+ // add connections to connection context and to connectivity context
+ updateConnectionContextWithConn(this.connectionFullMap, connectionMap, serviceUuid);
+ }
+
+ private Map<ConnectionKey, Connection> createConnectionsAndCepsForService(PathDescription pathDescription,
+ LayerProtocolName serviceProtName) {
+ Map<ConnectionKey, Connection> connectionServMap = new HashMap<>();
+ // build lists with ROADM nodes, XPDR/MUX/SWITCH nodes, ROADM DEG TTPs, ROADM SRG TTPs, XPDR CLIENT TTPs
+ // and XPDR NETWORK TTPs (if any). From the path description. This will help to build the uuid of the CEPs
+ // and the connections
+ String resourceType;
+ List<String> xpdrClientTplist = new ArrayList<>();
+ List<String> xpdrNetworkTplist = new ArrayList<>();
+ List<String> rdmAddDropTplist = new ArrayList<>();
+ List<String> rdmDegTplist = new ArrayList<>();
+ List<String> rdmNodelist = new ArrayList<>();
+ List<String> xpdrNodelist = new ArrayList<>();
+ for (AToZ elem:pathDescription.getAToZDirection().getAToZ().values().stream()
+ .sorted(Comparator.comparing(AToZ::getId)).collect(Collectors.toList())) {
+ resourceType = elem.getResource().getResource().implementedInterface().getSimpleName();
+ switch (resourceType) {
+ case TP:
+ TerminationPoint tp = (TerminationPoint) elem.getResource().getResource();
+ String tpID = tp.getTpId();
+ String tpNode;
+ if (tpID.contains("CLIENT")) {
+ tpNode = tp.getTpNodeId();
+ if (!xpdrClientTplist.contains(String.join("+", tpNode, tpID))) {
+ xpdrClientTplist.add(String.join("+", tpNode, tpID));
+ }
+ }
+ if (tpID.contains("NETWORK")) {
+ tpNode = tp.getTpNodeId();
+ if (!xpdrNetworkTplist.contains(String.join("+", tpNode, tpID))) {
+ xpdrNetworkTplist.add(String.join("+", tpNode, tpID));
+ }
+ }
+ if (tpID.contains("PP")) {
+ tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
+ LOG.info("ROADM Node of tp = {}", tpNode);
+ if (!rdmAddDropTplist.contains(String.join("+", tpNode, tpID))) {
+ rdmAddDropTplist.add(String.join("+", tpNode, tpID));
+ }
+ }
+ if (tpID.contains("TTP")) {
+ tpNode = getIdBasedOnModelVersion(tp.getTpNodeId());
+ LOG.info("ROADM Node of tp = {}", tpNode);
+ if (!rdmDegTplist.contains(String.join("+", tpNode, tpID))) {
+ rdmDegTplist.add(String.join("+", tpNode, tpID));
+ }
+ }
+ break;
+ case NODE:
+ Node node = (Node) elem.getResource().getResource();
+ String nodeId = node.getNodeId();
+ if (nodeId.contains("XPDR") || nodeId.contains("SPDR") || nodeId.contains("MXPDR")) {
+ LOG.info("Node id = {}", nodeId);
+ if (!xpdrNodelist.contains(nodeId)) {
+ xpdrNodelist.add(nodeId); // should contain only 2
+ }
+ }
+ if (nodeId.contains("ROADM")) {
+ nodeId = getIdBasedOnModelVersion(nodeId);
+ LOG.info("Node id = {}", nodeId);
+ if (!rdmNodelist.contains(nodeId)) {
+ rdmNodelist.add(nodeId);
+ }
+ }
+ break;
+ default:
+ LOG.warn("Resource is a {}", resourceType);
+ }
+ }
+ LOG.info("ROADM node list = {}", rdmNodelist.toString());
+ LOG.info("ROADM degree list = {}", rdmDegTplist.toString());
+ LOG.info("ROADM addrop list = {}", rdmAddDropTplist.toString());
+ LOG.info("XPDR node list = {}", xpdrNodelist.toString());
+ LOG.info("XPDR network list = {}", xpdrNetworkTplist.toString());
+ LOG.info("XPDR client list = {}", xpdrClientTplist.toString());
+ // TODO -> for 10GB eth and ODU services there are no ROADMs in path description as they use the OTU link,
+ // but for 100GB eth all is created at once. Check if the roadm list is empty to determine whether we need
+ // to trigger all the steps or not
+ String edgeRoadm1 = "";
+ String edgeRoadm2 = "";
+ if (!rdmNodelist.isEmpty()) {
+ edgeRoadm1 = rdmNodelist.get(0);
+ edgeRoadm2 = rdmNodelist.get(rdmNodelist.size() - 1);
+ LOG.info("edgeRoadm1 = {}", edgeRoadm1);
+ LOG.info("edgeRoadm2 = {}", edgeRoadm2);
+ }
+ // create corresponding CEPs and Connections. Connections should be added to the corresponding context
+ // CEPs must be included in the topology context as an augmentation for each ONEP!!
+ switch (serviceProtName) {
+ case PHOTONICMEDIA:
+ // Identify number of ROADMs
+ // - XC Connection between MC CEPs mapped from MC NEPs (within a roadm)
+ // - XC Connection between OTSiMC CEPs mapped from OTSiMC NEPs (within a roadm)
+ // - Top Connection MC betwwen MC CEPs of different roadms
+ // - Top Connection OTSiMC betwwen OTSiMC CEPs of extreme roadms
+ connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
+ edgeRoadm1, edgeRoadm2));
+ if (!pathDescription.getAToZDirection().getAToZ().values().stream().findFirst().get().getId()
+ .contains("ROADM")) {
+ // - XC Connection OTSi betwwen iOTSi y eOTSi of xpdr
+ // - Top connection OTSi between network ports of xpdrs in the Photonic media layer -> i_OTSi
+ connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
+ }
+ break;
+ case ODU:
+ // Check if OC and OTU are created
+ if (!rdmNodelist.isEmpty()) {
+ connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
+ edgeRoadm1, edgeRoadm2));
+ connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
+ }
+ // - XC Connection OTSi betwwen iODU and eODU of xpdr
+ // - Top connection in the ODU layer, between xpdr iODU ports (?)
+ connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
+ break;
+ case DSR:
+ // Check if OC, OTU and ODU are created
+ // Check if OC, OTU and ODU are created
+ if (!rdmNodelist.isEmpty()) {
+ connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist,
+ edgeRoadm1, edgeRoadm2));
+ connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist));
+ connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist));
+ }
+ // Top connection in the DSR layer, between client ports of the xpdrs
+ connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNodelist));
+ break;
+ default:
+ LOG.error("Service type format {} not supported", serviceProtName.getName());
+ }
+ return connectionServMap;
+ }
+
+ /**
+ * Process cancel resource result.
+ * @param serviceName Service name to build uuid.
+ */
+ private void onCancelResourceResult(String serviceName) {
+ if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) {
+ LOG.info("PCE cancel resource failed !");
+ return;
+ } else if (servicePathRpcResult.getStatus() == RpcStatusEx.Pending) {
+ LOG.warn("PCE cancel returned a Penging RpcStatusEx code!");
+ return;
+ } else if (servicePathRpcResult.getStatus() != RpcStatusEx.Successful) {
+ LOG.error("PCE cancel returned an unknown RpcStatusEx code!");
+ return;
+ }
+ LOG.info("PCE cancel resource done OK !");
+ Uuid suuid = new Uuid(UUID.nameUUIDFromBytes(serviceName.getBytes(Charset.forName("UTF-8")))
+ .toString());
+ // get connections of connectivity service and remove them from tapi context and then remove
+ // service from context. The CEPs are maintained as they could be reused by another service
+ ConnectivityService connService = getConnectivityService(suuid);
+ if (connService == null) {
+ LOG.error("Service doesnt exist in tapi context");
+ return;
+ }
+ for (Connection connection:connService.getConnection().values()) {
+ deleteConnection(connection.getConnectionUuid());
+ }
+ deleteConnectivityService(suuid);
+ }
+
+ @SuppressFBWarnings(
+ value = "ES_COMPARING_STRINGS_WITH_EQ",
+ justification = "false positives, not strings but real object references comparisons")
+ private Boolean compareServicePathRpcResult(ServicePathRpcResult notification) {
+ if (servicePathRpcResult == null) {
+ return false;
+ }
+ if (servicePathRpcResult.getNotificationType() != notification.getNotificationType()) {
+ return false;
+ }
+ if (servicePathRpcResult.getServiceName() != notification.getServiceName()) {
+ return false;
+ }
+ if (servicePathRpcResult.getStatus() != notification.getStatus()) {
+ return false;
+ }
+ if (servicePathRpcResult.getStatusMessage() != notification.getStatusMessage()) {
+ return false;
+ }
+ return true;
+ }
+
+ private Map<ConnectionKey,Connection> createXpdrCepsAndConnectionsDsr(List<String> xpdrClientTplist,
+ List<String> xpdrNodelist) {
+ Map<ConnectionKey, Connection> connServMap = new HashMap<>();
+ Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
+ ConnectionEndPoint> cepMap = new HashMap<>();
+
+ // Create 1 cep per Xpdr in the CLIENT and a top connection DSR between the CLIENT xpdrs
+ for (String xpdr:xpdrNodelist) {
+ LOG.info("Creating ceps and xc for xpdr {}", xpdr);
+ String spcXpdrClient = xpdrClientTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
+
+ ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrClient, DSR, DSR, LayerProtocolName.DSR);
+ putXpdrCepInTopologyContext(xpdr, spcXpdrClient, DSR, DSR, netCep1);
+
+ cepMap.put(netCep1.key(), netCep1);
+ }
+
+ // DSR top connection between edge xpdr CLIENT DSR
+ String spcXpdr1 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
+ .get(0))).findFirst().get();
+ String spcXpdr2 = xpdrClientTplist.stream().filter(adp -> adp.contains(xpdrNodelist
+ .get(xpdrNodelist.size() - 1))).findFirst().get();
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, DSR, LayerProtocolName.DSR);
+ this.connectionFullMap.put(connection.key(), connection);
+
+ // ODU top connection that will be added to the service object
+ Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
+ connServMap.put(conn.key(), conn);
+
+ return connServMap;
+ }
+
+ private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsOdu(List<String> xpdrNetworkTplist,
+ List<String> xpdrNodelist) {
+ Map<ConnectionKey, Connection> connServMap = new HashMap<>();
+ Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
+ ConnectionEndPoint> cepMap = new HashMap<>();
+ // Create 1 cep per Xpdr in the I_ODU and E_ODU, X connection between iODU and eODU and a top
+ // connection iODU between the xpdrs
+ for (String xpdr:xpdrNodelist) {
+ LOG.info("Creating ceps and xc for xpdr {}", xpdr);
+ String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
+
+ ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, E_ODU, DSR, LayerProtocolName.ODU);
+ putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, E_ODU, DSR, netCep1);
+ ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrNetwork, I_ODU, DSR, LayerProtocolName.ODU);
+ putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, I_ODU, DSR, netCep2);
+
+ cepMap.put(netCep1.key(), netCep1);
+ cepMap.put(netCep2.key(), netCep2);
+
+ // Create x connection between I_ODU and E_ODU within xpdr
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection = createXCBetweenCeps(netCep1, netCep2, spcXpdrNetwork, spcXpdrNetwork, ODU,
+ LayerProtocolName.ODU);
+ this.connectionFullMap.put(connection.key(), connection);
+
+ // Create X connection that will be added to the service object
+ Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
+ connServMap.put(conn.key(), conn);
+ }
+
+ // ODU top connection between edge xpdr e_ODU
+ String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
+ .get(0))).findFirst().get();
+ String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
+ .get(xpdrNodelist.size() - 1))).findFirst().get();
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, E_ODU, LayerProtocolName.ODU);
+ this.connectionFullMap.put(connection.key(), connection);
+
+ // ODU top connection that will be added to the service object
+ Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
+ connServMap.put(conn.key(), conn);
+
+ return connServMap;
+ }
+
+ private Map<ConnectionKey, Connection> createXpdrCepsAndConnectionsPht(List<String> xpdrNetworkTplist,
+ List<String> xpdrNodelist) {
+ Map<ConnectionKey, Connection> connServMap = new HashMap<>();
+ Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
+ ConnectionEndPoint> cepMap = new HashMap<>();
+
+ // create ceps and x connections within xpdr
+ for (String xpdr:xpdrNodelist) {
+ LOG.info("Creating ceps and xc for xpdr {}", xpdr);
+ String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get();
+ // There should be 1 network tp per xpdr
+ // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
+ // 3 different MC CEPs giving different IDs to show that they are different
+ // Create 3 CEPs for each xpdr otsi node and the corresponding cross connection matchin the NEPs
+ ConnectionEndPoint netCep1 = createCepXpdr(spcXpdrNetwork, PHTNC_MEDIA, OTSI,
+ LayerProtocolName.PHOTONICMEDIA);
+ putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, PHTNC_MEDIA, OTSI, netCep1);
+ ConnectionEndPoint netCep2 = createCepXpdr(spcXpdrNetwork, E_OTSI, OTSI, LayerProtocolName.PHOTONICMEDIA);
+ putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, E_OTSI, OTSI, netCep2);
+ ConnectionEndPoint netCep3 = createCepXpdr(spcXpdrNetwork, I_OTSI, OTSI, LayerProtocolName.PHOTONICMEDIA);
+ putXpdrCepInTopologyContext(xpdr, spcXpdrNetwork, I_OTSI, OTSI, netCep3);
+ cepMap.put(netCep1.key(), netCep1);
+ cepMap.put(netCep2.key(), netCep2);
+ cepMap.put(netCep3.key(), netCep3);
+
+ // Create x connection between I_OTSi and E_OTSi within xpdr
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrNetwork, spcXpdrNetwork, OTSI,
+ LayerProtocolName.PHOTONICMEDIA);
+ this.connectionFullMap.put(connection.key(), connection);
+
+ // Create X connection that will be added to the service object
+ Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
+ connServMap.put(conn.key(), conn);
+ }
+ // OTSi top connection between edge I_OTSI Xpdr
+ String spcXpdr1 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
+ .get(0))).findFirst().get();
+ String spcXpdr2 = xpdrNetworkTplist.stream().filter(adp -> adp.contains(xpdrNodelist
+ .get(xpdrNodelist.size() - 1))).findFirst().get();
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, I_OTSI, LayerProtocolName.PHOTONICMEDIA);
+ this.connectionFullMap.put(connection.key(), connection);
+
+ // OTSi top connection that will be added to the service object
+ Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
+ connServMap.put(conn.key(), conn);
+
+
+ return connServMap;
+ }
+
+ private Map<ConnectionKey, Connection> createRoadmCepsAndConnections(List<String> rdmAddDropTplist,
+ List<String> rdmDegTplist,
+ List<String> rdmNodelist,
+ String edgeRoadm1, String edgeRoadm2) {
+ // TODO: will need to check if things exist already or not
+ Map<ConnectionKey, Connection> connServMap = new HashMap<>();
+ Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
+ ConnectionEndPoint> cepMap = new HashMap<>();
+ // create ceps and x connections within roadm
+ for (String roadm : rdmNodelist) {
+ LOG.info("Creating ceps and xc for roadm {}", roadm);
+ String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get();
+ LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD);
+ // There should be only 1 AD and 1 DEG per roadm
+ // TODO photonic media model should be updated to have the corresponding CEPs. I will just create
+ // 3 different MC CEPs giving different IDs to show that they are different
+ // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs
+ // created in the topology creation
+ // add CEPs to the topology to the corresponding ONEP
+ ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, PHTNC_MEDIA);
+ putRdmCepInTopologyContext(roadm, spcRdmAD, PHTNC_MEDIA, adCep1);
+ ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, MC);
+ putRdmCepInTopologyContext(roadm, spcRdmAD, MC, adCep2);
+ ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, OTSI_MC);
+ putRdmCepInTopologyContext(roadm, spcRdmAD, OTSI_MC, adCep3);
+ cepMap.put(adCep1.key(), adCep1);
+ cepMap.put(adCep2.key(), adCep2);
+ cepMap.put(adCep3.key(), adCep3);
+
+ String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get();
+ LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG);
+
+ ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, PHTNC_MEDIA);
+ putRdmCepInTopologyContext(roadm, spcRdmDEG, PHTNC_MEDIA, degCep1);
+ ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, MC);
+ putRdmCepInTopologyContext(roadm, spcRdmDEG, MC, degCep2);
+ ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, OTSI_MC);
+ putRdmCepInTopologyContext(roadm, spcRdmDEG, OTSI_MC, degCep3);
+ cepMap.put(degCep1.key(), degCep1);
+ cepMap.put(degCep2.key(), degCep2);
+ cepMap.put(degCep3.key(), degCep3);
+
+ LOG.info("Going to create cross connections for ROADM {}", roadm);
+ // Create X connections between MC and OTSi_MC for full map
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection1 = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, MC,
+ LayerProtocolName.PHOTONICMEDIA);
+ LOG.info("Cross connection 1 created = {}", connection1.toString());
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection2 = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, OTSI_MC,
+ LayerProtocolName.PHOTONICMEDIA);
+ LOG.info("Cross connection 2 created = {}", connection2.toString());
+ this.connectionFullMap.put(connection1.key(), connection1);
+ this.connectionFullMap.put(connection2.key(), connection2);
+
+ // Create X connections that will be added to the service object
+ Connection conn1 = new ConnectionBuilder().setConnectionUuid(connection1.getUuid()).build();
+ Connection conn2 = new ConnectionBuilder().setConnectionUuid(connection2.getUuid()).build();
+ connServMap.put(conn1.key(), conn1);
+ connServMap.put(conn2.key(), conn2);
+ }
+ LOG.info("Going to create top connections betwee roadms");
+ // create top connections between roadms: MC connections between AD MC CEPs of roadms
+ for (int i = 0; i < rdmNodelist.size(); i++) {
+ if (rdmNodelist.size() <= (i + 1)) {
+ LOG.info("Reached last roadm. No more MC connections");
+ break;
+ }
+ // Current roadm with roadm i + 1 --> MC
+ String roadm1 = rdmNodelist.get(i);
+ String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm1)).findFirst().get();
+ String roadm2 = rdmNodelist.get(i + 1);
+ String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm2)).findFirst().get();
+ LOG.info("Creating top connection from {} to {} between tps: {}-{}", roadm1, roadm2, spcRdmAD1, spcRdmAD2);
+
+ // Create top connections between MC for full map
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, MC, LayerProtocolName.PHOTONICMEDIA);
+ this.connectionFullMap.put(connection.key(), connection);
+ LOG.info("Top connection created = {}", connection.toString());
+
+ // Create top connections that will be added to the service object
+ Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
+ connServMap.put(conn.key(), conn);
+ }
+
+ // OTSiMC top connection between edge roadms
+ LOG.info("Going to created top connection between OTSiMC");
+ String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm1)).findFirst().get();
+ String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm2)).findFirst().get();
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, OTSI_MC,
+ LayerProtocolName.PHOTONICMEDIA);
+ this.connectionFullMap.put(connection.key(), connection);
+ LOG.info("Top connection created = {}", connection.toString());
+
+ // OTSiMC top connections that will be added to the service object
+ Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build();
+ connServMap.put(conn.key(), conn);
+ return connServMap;
+ }
+
+ private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ createTopConnection(String tp1, String tp2,
+ Map<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey,
+ ConnectionEndPoint> cepMap, String qual, LayerProtocolName topPortocol) {
+ // find cep for each AD MC of roadm 1 and 2
+ LOG.info("Top connection name = {}", String.join("+", "TOP", tp1, tp2, qual));
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep1 =
+ cepMap.get(new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(
+ new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp1.split("\\+")[0],
+ qual, tp1.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
+ .toString())));
+ LOG.info("ADCEP1 = {}", adCep1.toString());
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep1 =
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
+ .setNodeEdgePointUuid(adCep1.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeEdgePointUuid())
+ .setTopologyUuid(adCep1.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getTopologyUuid())
+ .setNodeUuid(adCep1.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeUuid())
+ .setConnectionEndPointUuid(adCep1.getUuid())
+ .build();
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep2 =
+ cepMap.get(new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(
+ new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp2.split("\\+")[0],
+ qual, tp2.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
+ .toString())));
+ LOG.info("ADCEP2 = {}", adCep2.toString());
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep2 =
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
+ .setNodeEdgePointUuid(adCep2.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeEdgePointUuid())
+ .setTopologyUuid(adCep2.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getTopologyUuid())
+ .setNodeUuid(adCep2.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeUuid())
+ .setConnectionEndPointUuid(adCep1.getUuid())
+ .build();
+ Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ceps = new HashMap<>();
+ ceps.put(cep1.key(), cep1);
+ ceps.put(cep2.key(), cep2);
+ Name connName = new NameBuilder()
+ .setValueName("Connection name")
+ .setValue(String.join("+", "TOP", tp1, tp2, qual))
+ .build();
+ // TODO: lower connection, supported link.......
+ return new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder()
+ .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "TOP", tp1, tp2, qual))
+ .getBytes(Charset.forName("UTF-8"))).toString()))
+ .setName(Map.of(connName.key(), connName))
+ .setConnectionEndPoint(ceps)
+ .setOperationalState(OperationalState.DISABLED)
+ .setLayerProtocolName(topPortocol)
+ .setLifecycleState(LifecycleState.POTENTIALAVAILABLE)
+ .setDirection(ForwardingDirection.BIDIRECTIONAL)
+ .build();
+ }
+
+ private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ createXCBetweenCeps(ConnectionEndPoint cep1, ConnectionEndPoint cep2, String tp1, String tp2, String qual,
+ LayerProtocolName xcProtocol) {
+ LOG.info("Creation cross connection between: {} and {}", tp1, tp2);
+ LOG.info("Cross connection name = {}", String.join("+", "XC", tp1, tp2, qual));
+ LOG.info("CEP1 = {}", cep1.getClientNodeEdgePoint().toString());
+ LOG.info("CEP2 = {}", cep2.getClientNodeEdgePoint().toString());
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ1 =
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
+ .setNodeEdgePointUuid(cep1.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeEdgePointUuid())
+ .setTopologyUuid(cep1.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getTopologyUuid())
+ .setNodeUuid(cep1.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeUuid())
+ .setConnectionEndPointUuid(cep1.getUuid())
+ .build();
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ2 =
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder()
+ .setNodeEdgePointUuid(cep2.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeEdgePointUuid())
+ .setTopologyUuid(cep2.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getTopologyUuid())
+ .setNodeUuid(cep2.getClientNodeEdgePoint()
+ .values().stream().findFirst().get().getNodeUuid())
+ .setConnectionEndPointUuid(cep2.getUuid())
+ .build();
+ Map<ConnectionEndPointKey, org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ceps = new HashMap<>();
+ ceps.put(cepServ1.key(), cepServ1);
+ ceps.put(cepServ2.key(), cepServ2);
+ Name connName = new NameBuilder()
+ .setValueName("Connection name")
+ .setValue(String.join("+", "XC", tp1, tp2, qual))
+ .build();
+ // TODO: lower connection, supported link.......
+ return new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder()
+ .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "XC", tp1, tp2, qual))
+ .getBytes(Charset.forName("UTF-8"))).toString()))
+ .setName(Map.of(connName.key(), connName))
+ .setConnectionEndPoint(ceps)
+ .setOperationalState(OperationalState.DISABLED)
+ .setLayerProtocolName(xcProtocol)
+ .setLifecycleState(LifecycleState.POTENTIALAVAILABLE)
+ .setDirection(ForwardingDirection.BIDIRECTIONAL)
+ .build();
+ }
+
+ private ConnectionEndPoint createCepRoadm(String id, String qualifier) {
+ LOG.info("NEP = {}", String.join("+", id.split("\\+")[0], qualifier, id.split("\\+")[1]));
+ Name cepName = new NameBuilder()
+ .setValueName("ConnectionEndPoint name")
+ .setValue(String.join("+", id.split("\\+")[0], qualifier,
+ id.split("\\+")[1]))
+ .build();
+ ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
+ .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
+ qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
+ .toString()))
+ .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
+ qualifier)).getBytes(Charset.forName("UTF-8")))
+ .toString()))
+ .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
+ .getBytes(Charset.forName("UTF-8"))).toString()))
+ .build();
+ // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
+ // TODO: add parent ONEP??
+ ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
+ .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
+ qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
+ .toString()))
+ .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
+ .setName(Map.of(cepName.key(), cepName))
+ .setConnectionPortRole(PortRole.SYMMETRIC)
+ .setConnectionPortDirection(PortDirection.BIDIRECTIONAL)
+ .setOperationalState(OperationalState.ENABLED)
+ .setLifecycleState(LifecycleState.INSTALLED)
+ .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA);
+ return cepBldr.build();
+ }
+
+ private ConnectionEndPoint createCepXpdr(String id, String qualifier, String nodeLayer,
+ LayerProtocolName cepProtocol) {
+ Name cepName = new NameBuilder()
+ .setValueName("ConnectionEndPoint name")
+ .setValue(String.join("+", id.split("\\+")[0], qualifier,
+ id.split("\\+")[1]))
+ .build();
+ ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder()
+ .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0],
+ qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
+ .toString()))
+ .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0],
+ nodeLayer)).getBytes(Charset.forName("UTF-8")))
+ .toString()))
+ .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
+ .getBytes(Charset.forName("UTF-8"))).toString()))
+ .build();
+ // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...)
+ // TODO: add parent ONEP??
+ ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder()
+ .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0],
+ qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8")))
+ .toString()))
+ .setClientNodeEdgePoint(Map.of(cnep.key(), cnep))
+ .setName(Map.of(cepName.key(), cepName))
+ .setConnectionPortRole(PortRole.SYMMETRIC)
+ .setConnectionPortDirection(PortDirection.BIDIRECTIONAL)
+ .setOperationalState(OperationalState.ENABLED)
+ .setLifecycleState(LifecycleState.INSTALLED)
+ .setLayerProtocolName(cepProtocol);
+ return cepBldr.build();
+ }
+
+ private void putRdmCepInTopologyContext(String node, String spcRdmAD, String qual, ConnectionEndPoint cep) {
+ LOG.info("NEP id before Merge = {}", String.join("+", node, qual, spcRdmAD.split("\\+")[1]));
+ LOG.info("Node of NEP id before Merge = {}", String.join("+", node, PHTNC_MEDIA));
+ // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
+ Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, PHTNC_MEDIA)
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcRdmAD.split("\\+")[1])
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
+ }
+
+ private void putXpdrCepInTopologyContext(String node, String spcXpdrNet, String qual, String nodeLayer,
+ ConnectionEndPoint cep) {
+ // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep
+ Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, nodeLayer)
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcXpdrNet.split("\\+")[1])
+ .getBytes(Charset.forName("UTF-8"))).toString());
+ updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep);
+ }
+
+ public void updateTopologyWithCep(Uuid topoUuid, Uuid nodeUuid, Uuid nepUuid, ConnectionEndPoint cep) {
+ // TODO: verify this is correct. Should we identify the context IID with the context UUID??
+ InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
+ .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
+ .child(Topology.class, new TopologyKey(topoUuid))
+ .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
+ new NodeKey(nodeUuid))
+ .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid))
+ .build();
+ try {
+ Optional<OwnedNodeEdgePoint> optionalOnep = this.networkTransactionService.read(
+ LogicalDatastoreType.OPERATIONAL, onepIID).get();
+ if (!optionalOnep.isPresent()) {
+ LOG.error("ONEP is not present in datastore");
+ return;
+ }
+ OwnedNodeEdgePoint onep = optionalOnep.get();
+ LOG.info("ONEP found = {}", onep.toString());
+ // TODO -> If cep exists -> skip merging to datasore
+ OwnedNodeEdgePoint1 onep1 = onep.augmentation(OwnedNodeEdgePoint1.class);
+ if (onep1 != null && onep1.getCepList() != null && onep1.getCepList().getConnectionEndPoint() != null) {
+ if (onep1.getCepList().getConnectionEndPoint().containsKey(
+ new org.opendaylight.yang.gen.v1
+ .urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(cep.key()))) {
+ LOG.info("CEP already in topology, skipping merge");
+ return;
+ }
+ }
+ // Updated ONEP
+ CepList cepList = new CepListBuilder().setConnectionEndPoint(Map.of(cep.key(), cep)).build();
+ OwnedNodeEdgePoint1 onep1Bldr = new OwnedNodeEdgePoint1Builder().setCepList(cepList).build();
+ OwnedNodeEdgePoint newOnep = new OwnedNodeEdgePointBuilder(onep)
+ .addAugmentation(onep1Bldr)
+ .build();
+ LOG.info("New ONEP is {}", newOnep.toString());
+ // merge in datastore
+ this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, onepIID,
+ newOnep);
+ this.networkTransactionService.commit().get();
+ LOG.info("CEP added successfully.");
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Couldnt update cep in topology", e);
+ }
+ }
+
+ private void updateConnectionContextWithConn(
+ Map<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey,
+ org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connFullMap,
+ Map<ConnectionKey, Connection> connMap, Uuid suuid) {
+ // TODO: verify this is correct. Should we identify the context IID with the context UUID??
+ try {
+ ConnectivityService connServ = getConnectivityService(suuid);
+ ConnectivityService updtConnServ = new ConnectivityServiceBuilder(connServ)
+ .setConnection(connMap)
+ .build();
+
+ // Perform the merge operation with the new conn service and the connection context updated
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext
+ connectivityContext = new ConnectivityContextBuilder()
+ .setConnectivityService(Map.of(updtConnServ.key(), updtConnServ))
+ .setConnection(connFullMap)
+ .build();
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivitycontextIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .build();
+ // merge in datastore
+ this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectivitycontextIID,
+ connectivityContext);
+ this.networkTransactionService.commit().get();
+ LOG.info("TAPI connectivity merged successfully.");
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to merge TAPI connectivity", e);
+ }
+ }
+
+ private ConnectivityService getConnectivityService(Uuid suuid) {
+ try {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<ConnectivityService> connectivityServIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
+ .build();
+
+ Optional<ConnectivityService> optConnServ =
+ this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get();
+ if (!optConnServ.isPresent()) {
+ LOG.error("Connectivity service not found in tapi context");
+ return null;
+ }
+ return optConnServ.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Connectivity service not found in tapi context. Error:", e);
+ return null;
+ }
+ }
+
+ private void deleteConnectivityService(Uuid suuid) {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<ConnectivityService> connectivityServIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
+ .build();
+ try {
+ this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
+ this.networkTransactionService.commit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to delete TAPI connectivity service", e);
+ }
+ }
+
+ private void deleteConnection(Uuid connectionUuid) {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<org.opendaylight.yang.gen.v1
+ .urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey(
+ connectionUuid))
+ .build();
+ try {
+ this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID);
+ this.networkTransactionService.commit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to delete TAPI connection", e);
+ }
+ }
+
+ private String getIdBasedOnModelVersion(String nodeid) {
+ return nodeid.matches("[A-Z]{5}-[A-Z0-9]{2}-.*")
+ ? String.join("-", nodeid.split("-")[0], nodeid.split("-")[1]) : nodeid.split("-")[0];
+ }
+
+ public void setInput(CreateConnectivityServiceInput input) {
+ this.input = input;
+ }
+
+ public void setServiceUuid(Uuid serviceUuid) {
+ this.serviceUuid = serviceUuid;
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2021 Nokia, Inc. and others. 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.listeners;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.nio.charset.Charset;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.transportpce.common.network.RequestProcessor;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.RendererRpcResultSp;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.TransportpceRendererListener;
+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.Context;
+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.connectivity.rev181210.Context1;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TapiRendererListenerImpl implements TransportpceRendererListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TapiRendererListenerImpl.class);
+ private final DataBroker dataBroker;
+ private Uuid serviceUuid;
+ private RendererRpcResultSp serviceRpcResultSp;
+ private final NetworkTransactionService networkTransactionService;
+
+ public TapiRendererListenerImpl(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ this.networkTransactionService = new NetworkTransactionImpl(new RequestProcessor(this.dataBroker));
+ }
+
+ @Override
+ public void onRendererRpcResultSp(RendererRpcResultSp notification) {
+ if (compareServiceRpcResultSp(notification)) {
+ LOG.warn("ServiceRpcResultSp already wired !");
+ return;
+ }
+ serviceRpcResultSp = notification;
+ int notifType = serviceRpcResultSp.getNotificationType().getIntValue();
+ LOG.info("Renderer '{}' Notification received : {}", serviceRpcResultSp.getNotificationType().getName(),
+ notification);
+ /* service-implementation-request. */
+ if (notifType == 3) {
+ onServiceImplementationResult(notification);
+ }
+ }
+
+ /**
+ * Process service implementation result for serviceName.
+ * @param notification RendererRpcResultSp
+ */
+ private void onServiceImplementationResult(RendererRpcResultSp notification) {
+ switch (serviceRpcResultSp.getStatus()) {
+ case Successful:
+ onSuccededServiceImplementation();
+ break;
+ case Failed:
+ onFailedServiceImplementation(notification.getServiceName());
+ break;
+ case Pending:
+ LOG.warn("Service Implementation still pending according to RpcStatusEx");
+ break;
+ default:
+ LOG.warn("Service Implementation has an unknown RpcStatusEx code");
+ break;
+ }
+ }
+
+ /**
+ * Process succeeded service implementation for service.
+ */
+ private void onSuccededServiceImplementation() {
+ LOG.info("Service implemented !");
+ // TODO: update Connections and Connectivity Service states
+ ConnectivityService connectivityService = getConnectivityService(this.serviceUuid);
+ if (connectivityService == null) {
+ LOG.error("Couldnt retrieve service from datastore");
+ return;
+ }
+ LOG.info("Connectivity service = {}", connectivityService.toString());
+ // TODO --> this throws error because the renderer goes really fast. Is this normal??
+ ConnectivityService updtConnServ = new ConnectivityServiceBuilder(connectivityService)
+ .setAdministrativeState(AdministrativeState.UNLOCKED)
+ .setLifecycleState(LifecycleState.INSTALLED)
+ .setOperationalState(OperationalState.ENABLED)
+ .build();
+ for (Connection connection:updtConnServ.getConnection().values()) {
+ updateConnectionState(connection.getConnectionUuid());
+ }
+ updateConnectivityService(updtConnServ);
+ }
+
+ /**
+ * Process failed service implementation for serviceName.
+ * @param serviceName String
+ */
+ private void onFailedServiceImplementation(String serviceName) {
+ LOG.error("Renderer implementation failed !");
+ LOG.info("PCE cancel resource done OK !");
+ Uuid suuid = new Uuid(UUID.nameUUIDFromBytes(serviceName.getBytes(Charset.forName("UTF-8")))
+ .toString());
+ // get connections of connectivity service and remove them from tapi context and then remove
+ // service from context. The CEPs are maintained as they could be reused by another service
+ ConnectivityService connService = getConnectivityService(suuid);
+ if (connService == null) {
+ LOG.error("Service doesnt exist in tapi context");
+ return;
+ }
+ for (Connection connection:connService.getConnection().values()) {
+ deleteConnection(connection.getConnectionUuid());
+ }
+ deleteConnectivityService(suuid);
+ }
+
+ @SuppressFBWarnings(
+ value = "ES_COMPARING_STRINGS_WITH_EQ",
+ justification = "false positives, not strings but real object references comparisons")
+ private Boolean compareServiceRpcResultSp(RendererRpcResultSp notification) {
+ if (serviceRpcResultSp == null) {
+ return false;
+ }
+ if (serviceRpcResultSp.getNotificationType() != notification.getNotificationType()) {
+ return false;
+ }
+ if (serviceRpcResultSp.getServiceName() != notification.getServiceName()) {
+ return false;
+ }
+ if (serviceRpcResultSp.getStatus() != notification.getStatus()) {
+ return false;
+ }
+ if (serviceRpcResultSp.getStatusMessage() != notification.getStatusMessage()) {
+ return false;
+ }
+ return true;
+ }
+
+ private ConnectivityService getConnectivityService(Uuid suuid) {
+ // TODO: verify this is correct. Should we identify the context IID with the context UUID??
+ try {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<ConnectivityService> connectivityServIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
+ .build();
+
+ Optional<ConnectivityService> optConnServ =
+ this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get();
+ if (!optConnServ.isPresent()) {
+ LOG.error("Connectivity service not found in tapi context");
+ return null;
+ }
+ return optConnServ.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to merge TAPI connectivity", e);
+ return null;
+ }
+ }
+
+ private void updateConnectionState(Uuid connectionUuid) {
+ // TODO: verify this is correct. Should we identify the context IID with the context UUID??
+ try {
+ // First read connection with connection uuid and update info
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
+ new ConnectionKey(connectionUuid))
+ .build();
+
+ Optional<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> optConn =
+ this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectionIID).get();
+ if (!optConn.isPresent()) {
+ LOG.error("Connection not found in tapi context");
+ return;
+ }
+ org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
+ newConnection = new ConnectionBuilder(optConn.get()).setLifecycleState(LifecycleState.INSTALLED)
+ .setOperationalState(OperationalState.ENABLED).build();
+ // merge in datastore
+ this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectionIID,
+ newConnection);
+ this.networkTransactionService.commit().get();
+ LOG.info("TAPI connection merged successfully.");
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to merge TAPI connection", e);
+ }
+ }
+
+ private void updateConnectivityService(ConnectivityService updtConnServ) {
+ // TODO: verify this is correct. Should we identify the context IID with the context UUID??
+ try {
+ // First read connectivity service with connectivity service uuid and update info
+ InstanceIdentifier<ConnectivityService> connServIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(ConnectivityService.class, new ConnectivityServiceKey(updtConnServ.getUuid()))
+ .build();
+
+ Optional<ConnectivityService> optConnServ =
+ this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connServIID).get();
+ if (!optConnServ.isPresent()) {
+ LOG.error("Connection not found in tapi context");
+ return;
+ }
+ ConnectivityService newConnServ = new ConnectivityServiceBuilder(updtConnServ).build();
+ // merge in datastore
+ this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connServIID,
+ newConnServ);
+ this.networkTransactionService.commit().get();
+ LOG.info("TAPI connectivity service merged successfully.");
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to merge TAPI connectivity service", e);
+ }
+ }
+
+ private void deleteConnectivityService(Uuid suuid) {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<ConnectivityService> connectivityServIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
+ .build();
+ try {
+ this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
+ this.networkTransactionService.commit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to delete TAPI connectivity service", e);
+ }
+ }
+
+ private void deleteConnection(Uuid connectionUuid) {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<org.opendaylight.yang.gen.v1
+ .urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey(
+ connectionUuid))
+ .build();
+ try {
+ this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID);
+ this.networkTransactionService.commit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to delete TAPI connection", e);
+ }
+ }
+
+ public void setServiceUuid(Uuid serviceUuid) {
+ this.serviceUuid = serviceUuid;
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2021 Nokia, Inc. and others. 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.listeners;
+
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.ServiceRpcResultSh;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev201125.TransportpceServicehandlerListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TapiServiceHandlerListenerImpl implements TransportpceServicehandlerListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TapiServiceHandlerListenerImpl.class);
+ private final DataBroker dataBroker;
+
+ public TapiServiceHandlerListenerImpl(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+
+ }
+
+ @Override
+ public void onServiceRpcResultSh(ServiceRpcResultSh notification) {
+ LOG.info("Avoid dataBroker error {}", dataBroker.getClass().getCanonicalName());
+ }
+}
public void convertNode(Node ietfNode, List<String> networkPorts) {
this.ietfNodeId = ietfNode.getNodeId().getValue();
if (ietfNode.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class)
- == null) {
+ == null) {
return;
}
this.ietfNodeType = ietfNode.augmentation(
org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class).getNodeType();
this.ietfNodeAdminState = ietfNode.augmentation(
- org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class)
+ org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class)
.getAdministrativeState();
this.ietfNodeOperState = ietfNode.augmentation(
- org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class)
+ org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class)
.getOperationalState();
this.oorNetworkPortList = ietfNode.augmentation(
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class)
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class)
.getTerminationPoint().values().stream()
.filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
- == OpenroadmTpType.XPONDERNETWORK.getIntValue()
- && networkPorts.contains(tp.getTpId().getValue()))
+ == OpenroadmTpType.XPONDERNETWORK.getIntValue()
+ && networkPorts.contains(tp.getTpId().getValue()))
.sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue()))
.collect(Collectors.toList());
if (!OpenroadmNodeType.TPDR.equals(this.ietfNodeType)) {
.values().stream().findFirst().get();
this.oorClientPortList = ietfNode.augmentation(
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1.class)
- .getTerminationPoint().values().stream()
- .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
- == OpenroadmTpType.XPONDERCLIENT.getIntValue())
- .sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue()))
- .collect(Collectors.toList());
+ .getTerminationPoint().values().stream()
+ .filter(tp -> tp.augmentation(TerminationPoint1.class).getTpType().getIntValue()
+ == OpenroadmTpType.XPONDERCLIENT.getIntValue())
+ .sorted((tp1, tp2) -> tp1.getTpId().getValue().compareTo(tp2.getTpId().getValue()))
+ .collect(Collectors.toList());
} else {
this.oorOduSwitchingPool = createOduSwitchingPoolForTp100G();
List<TpId> tpList = this.oorOduSwitchingPool.getNonBlockingList().values().stream()
List<String> linksToNotConvert = new ArrayList<>();
LOG.info("creation of {} otn links", otnLinkMap.size() / 2);
for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
- .Link otnlink : otnLinkList) {
+ .Link otnlink : otnLinkList) {
if (!linksToNotConvert.contains(otnlink.getLinkId().getValue())) {
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
.network.Link oppositeLink = otnLinkMap.get(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns
.yang.ietf.network.topology.rev180226.networks.network.LinkKey(otnlink.augmentation(
- org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
- .getOppositeLink()));
+ org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+ .getOppositeLink()));
Link tapiLink = createTapiLink(otnlink, oppositeLink);
linksToNotConvert.add(oppositeLink.getLinkId().getValue());
tapiLinks.put(tapiLink.key(), tapiLink);
for (TerminationPoint tp : this.oorNetworkPortList) {
TpId tpid1 = tp.getTpId();
TpId tpid2 = new TpId(tp.augmentation(
- org.opendaylight.yang.gen.v1.http.transportpce.topology.rev201019.TerminationPoint1.class)
+ org.opendaylight.yang.gen.v1.http.transportpce.topology.rev201019.TerminationPoint1.class)
.getAssociatedConnectionMapPort());
List<TpId> tpList = new ArrayList<>();
tpList.add(tpid1);
}
private List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node>
- pruneTapiPhotonicNodes() {
+ pruneTapiPhotonicNodes() {
List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node>
prunedTapiPhotonicNodes = new ArrayList<>();
List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> tapiPhotonicNodes
.filter(n -> LayerProtocolName.PHOTONICMEDIA.equals(n.getLayerProtocolName().get(0)))
.collect(Collectors.toList());
for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node
- : tapiPhotonicNodes) {
+ : tapiPhotonicNodes) {
Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepM = new HashMap<>();
for (Map.Entry<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> entry : node.getOwnedNodeEdgePoint().entrySet()) {
if (entry.getValue().getName().values().stream()
- .filter(name -> name.getValueName().startsWith("eNodeEdgePoint"))
- .count() > 0) {
+ .filter(name -> name.getValueName().startsWith("eNodeEdgePoint")).count() > 0) {
onepM.put(entry.getKey(), entry.getValue());
}
}
}
private Map<String, String> convertListNodeWithListNepToMapForUuidAndName(
- List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> nodes) {
+ List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> nodes) {
Map<String, String> uuidNameMap = new HashMap<>();
for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node : nodes) {
for (OwnedNodeEdgePoint nep : node.nonnullOwnedNodeEdgePoint().values()) {
}
private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node
- createTapiNode(Map<NameKey, Name> nodeNames, List<LayerProtocolName> layerProtocols) {
+ createTapiNode(Map<NameKey, Name> nodeNames, List<LayerProtocolName> layerProtocols) {
Uuid nodeUuid = null;
Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl = new HashMap<>();
Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupList = new HashMap<>();
.getValueName(), nodeNames.get(nodeNames.keySet().iterator().next()).getValue());
}
return new NodeBuilder()
- .setUuid(nodeUuid)
- .setName(nodeNames)
- .setLayerProtocolName(layerProtocols)
- .setAdministrativeState(setTapiAdminState(this.ietfNodeAdminState))
- .setOperationalState(setTapiOperationalState(this.ietfNodeOperState))
- .setLifecycleState(LifecycleState.INSTALLED)
- .setOwnedNodeEdgePoint(onepl)
- .setNodeRuleGroup(nodeRuleGroupList)
- .build();
+ .setUuid(nodeUuid)
+ .setName(nodeNames)
+ .setLayerProtocolName(layerProtocols)
+ .setAdministrativeState(setTapiAdminState(this.ietfNodeAdminState))
+ .setOperationalState(setTapiOperationalState(this.ietfNodeOperState))
+ .setLifecycleState(LifecycleState.INSTALLED)
+ .setOwnedNodeEdgePoint(onepl)
+ .setNodeRuleGroup(nodeRuleGroupList)
+ .build();
}
private AdministrativeState setTapiAdminState(AdminStates adminState) {
if (adminState == null) {
return null;
}
- return adminState.equals(AdminStates.InService)
- ? AdministrativeState.UNLOCKED : AdministrativeState.LOCKED;
+ return adminState.equals(AdminStates.InService) ? AdministrativeState.UNLOCKED : AdministrativeState.LOCKED;
}
private AdministrativeState setTapiAdminState(AdminStates adminState1, AdminStates adminState2) {
}
private Uuid getNodeUuid4Photonic(Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl,
- Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupList, Map<RuleKey, Rule> ruleList) {
+ Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupList, Map<RuleKey, Rule> ruleList) {
Uuid nodeUuid;
nodeUuid = this.uuidMap.get(String.join("+", this.ietfNodeId, OTSI));
// iNep creation on otsi node
for (int i = 0; i < oorNetworkPortList.size(); i++) {
Uuid nepUuid1 = new Uuid(UUID.nameUUIDFromBytes(
- (String.join("+", this.ietfNodeId, I_OTSI, oorNetworkPortList.get(i).getTpId().getValue()))
+ (String.join("+", this.ietfNodeId, I_OTSI, oorNetworkPortList.get(i).getTpId().getValue()))
.getBytes(Charset.forName("UTF-8")))
.toString());
this.uuidMap.put(String.join("+", this.ietfNodeId, I_OTSI, oorNetworkPortList.get(i).getTpId().getValue()),
// eNep creation on otsi node
for (int i = 0; i < oorNetworkPortList.size(); i++) {
Uuid nepUuid2 = new Uuid(UUID.nameUUIDFromBytes(
- (String.join("+", this.ietfNodeId, E_OTSI, oorNetworkPortList.get(i).getTpId().getValue()))
+ (String.join("+", this.ietfNodeId, E_OTSI, oorNetworkPortList.get(i).getTpId().getValue()))
.getBytes(Charset.forName("UTF-8")))
.toString());
this.uuidMap.put(String.join("+", this.ietfNodeId, E_OTSI, oorNetworkPortList.get(i).getTpId().getValue()),
nepList.put(enep.key(), enep);
NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder()
.setUuid(new Uuid(
- UUID.nameUUIDFromBytes(("otsi node rule group " + count).getBytes(Charset.forName("UTF-8")))
- .toString()))
+ UUID.nameUUIDFromBytes(("otsi node rule group " + count).getBytes(Charset.forName("UTF-8")))
+ .toString()))
.setRule(ruleList)
.setNodeEdgePoint(nepList)
.build();
}
private Uuid getNodeUuid4Dsr(Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl,
- Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupList, Map<RuleKey, Rule> ruleList) {
+ Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupList, Map<RuleKey, Rule> ruleList) {
Uuid nodeUuid;
nodeUuid = this.uuidMap.get(String.join("+", this.ietfNodeId, DSR));
// client nep creation on DSR/ODU node
for (int i = 0; i < oorClientPortList.size(); i++) {
Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(
(String.join("+", this.ietfNodeId, DSR, oorClientPortList.get(i).getTpId().getValue()))
- .getBytes(Charset.forName("UTF-8"))).toString());
+ .getBytes(Charset.forName("UTF-8"))).toString());
this.uuidMap.put(String.join("+", this.ietfNodeId, DSR, oorClientPortList.get(i).getTpId().getValue()),
nepUuid);
NameBuilder nameBldr = new NameBuilder().setValue(oorClientPortList.get(i).getTpId().getValue());
for (int i = 0; i < oorNetworkPortList.size(); i++) {
Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(
(String.join("+", this.ietfNodeId, DSR, oorNetworkPortList.get(i).getTpId().getValue()))
- .getBytes(Charset.forName("UTF-8"))).toString());
+ .getBytes(Charset.forName("UTF-8"))).toString());
this.uuidMap.put(String.join("+", this.ietfNodeId, DSR, oorNetworkPortList.get(i).getTpId().getValue()),
nepUuid);
Name onedName = new NameBuilder()
}
NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder()
.setUuid(new Uuid(
- UUID.nameUUIDFromBytes(("dsr node rule group " + count).getBytes(Charset.forName("UTF-8")))
- .toString()))
+ UUID.nameUUIDFromBytes(("dsr node rule group " + count).getBytes(Charset.forName("UTF-8")))
+ .toString()))
.setRule(ruleList)
.setNodeEdgePoint(nepList)
.build();
}
private OwnedNodeEdgePoint createNep(TerminationPoint oorTp, Map<NameKey, Name> nepNames,
- LayerProtocolName nepProtocol, LayerProtocolName nodeProtocol, boolean withSip, String keyword) {
+ LayerProtocolName nepProtocol, LayerProtocolName nodeProtocol, boolean withSip, String keyword) {
String key = String.join("+", keyword, oorTp.getTpId().getValue());
OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder()
.setUuid(this.uuidMap.get(key))
.setLinkPortDirection(PortDirection.BIDIRECTIONAL)
.setLinkPortRole(PortRole.SYMMETRIC)
.setAdministrativeState(setTapiAdminState(
- oorTp.augmentation(TerminationPoint1.class).getAdministrativeState()))
+ oorTp.augmentation(TerminationPoint1.class).getAdministrativeState()))
.setOperationalState(setTapiOperationalState(
- oorTp.augmentation(TerminationPoint1.class).getOperationalState()))
+ oorTp.augmentation(TerminationPoint1.class).getOperationalState()))
.setLifecycleState(LifecycleState.INSTALLED)
.setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
.setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
}
private Map<NodeRuleGroupKey, NodeRuleGroup> createNodeRuleGroupForRdmNode(Uuid nodeUuid,
- Collection<OwnedNodeEdgePoint> onepl) {
+ Collection<OwnedNodeEdgePoint> onepl) {
Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePointKey,
org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint>
nepMap = new HashMap<>();
}
private List<Class<? extends LAYERPROTOCOLQUALIFIER>> createSupportedCepLayerProtocolQualifier(TerminationPoint tp,
- LayerProtocolName lpn) {
+ LayerProtocolName lpn) {
Set<Class<? extends LAYERPROTOCOLQUALIFIER>> sclpqSet = new HashSet<>();
List<SupportedInterfaceCapability> sicList = new ArrayList<>(
tp.augmentation(org.opendaylight.yang.gen.v1.http
- .org.openroadm.otn.network.topology.rev200529.TerminationPoint1.class).getTpSupportedInterfaces()
- .getSupportedInterfaceCapability().values());
+ .org.openroadm.otn.network.topology.rev200529.TerminationPoint1.class).getTpSupportedInterfaces()
+ .getSupportedInterfaceCapability().values());
for (SupportedInterfaceCapability sic : sicList) {
switch (lpn.getName()) {
case "DSR":
break;
case "PHOTONIC_MEDIA":
if (sic.getIfCapType().getSimpleName().equals("IfOCHOTU4ODU4")
- || sic.getIfCapType().getSimpleName().equals("IfOCH")) {
+ || sic.getIfCapType().getSimpleName().equals("IfOCH")) {
sclpqSet.add(PHOTONICLAYERQUALIFIEROTSi.class);
sclpqSet.add(PHOTONICLAYERQUALIFIEROMS.class);
}
.build();
Link transiLink = new LinkBuilder()
.setUuid(new Uuid(
- UUID.nameUUIDFromBytes((String.join("--", this.ietfNodeId, sourceKey, destKey))
- .getBytes(Charset.forName("UTF-8")))
- .toString()))
+ UUID.nameUUIDFromBytes((String.join("--", this.ietfNodeId, sourceKey, destKey))
+ .getBytes(Charset.forName("UTF-8")))
+ .toString()))
.setName(Map.of(linkName.key(), linkName))
.setTransitionedLayerProtocolName(Arrays.asList(LayerProtocolName.ODU.getName(),
LayerProtocolName.PHOTONICMEDIA.getName()))
}
}
- private Link createTapiLink(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
- .networks.network.Link link,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link
- oppositeLink) {
+ private Link createTapiLink(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.network.topology.rev180226.networks.network.Link link,
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.network.topology.rev180226.networks.network.Link oppositeLink) {
String prefix = link.getLinkId().getValue().split("-")[0];
String sourceNode = link.getSource().getSourceNode().getValue();
String sourceTp = link.getSource().getSourceTp().toString();
.setValue(link.getLinkId().getValue())
.build();
return new LinkBuilder()
- .setUuid(new Uuid(
- UUID.nameUUIDFromBytes((link.getLinkId().getValue())
- .getBytes(Charset.forName("UTF-8")))
+ .setUuid(new Uuid(UUID.nameUUIDFromBytes((link.getLinkId().getValue())
+ .getBytes(Charset.forName("UTF-8")))
.toString()))
.setName(Map.of(linkName.key(), linkName))
.setLayerProtocolName(Arrays.asList(LayerProtocolName.ODU))
.build();
Link omsLink = new LinkBuilder()
.setUuid(new Uuid(
- UUID.nameUUIDFromBytes((String.join(" and ", photonicEntry.getValue(), rdmEntry.getValue()))
- .getBytes(Charset.forName("UTF-8")))
- .toString()))
+ UUID.nameUUIDFromBytes((String.join(" and ", photonicEntry.getValue(), rdmEntry.getValue()))
+ .getBytes(Charset.forName("UTF-8")))
+ .toString()))
.setName(Map.of(linkName.key(), linkName))
.setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA))
.setNodeEdgePoint(nepMap)
}
public Map<NodeKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node>
- getTapiNodes() {
+ getTapiNodes() {
return tapiNodes;
}
// TODO: verify this is correct. Should we identify the context IID with the context UUID??
try {
org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext
- connectivityContext = new ConnectivityContextBuilder()
- .setConnectivityService(connServMap)
- .setConnection(connectionFullMap)
- .build();
+ connectivityContext = new ConnectivityContextBuilder()
+ .setConnectivityService(connServMap)
+ .setConnection(connectionFullMap)
+ .build();
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
- .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivitycontextIID =
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivitycontextIID =
InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
- .child(org.opendaylight.yang.gen.v1.urn
- .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
- .build();
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .build();
// merge in datastore
this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectivitycontextIID,
- connectivityContext);
+ connectivityContext);
this.networkTransactionService.commit().get();
LOG.info("TAPI connectivity merged successfully.");
} catch (InterruptedException | ExecutionException e) {
return null;
}
}
+
+ public ConnectivityService getConnectivityService(Uuid serviceUuid) {
+ try {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<ConnectivityService> connectivityServIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(ConnectivityService.class, new ConnectivityServiceKey(serviceUuid))
+ .build();
+
+ Optional<ConnectivityService> optConnServ =
+ this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get();
+ if (!optConnServ.isPresent()) {
+ LOG.error("Connectivity service not found in tapi context");
+ return null;
+ }
+ return optConnServ.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Connectivity service not found in tapi context. Error:", e);
+ return null;
+ }
+ }
+
+ public void deleteConnectivityService(Uuid serviceUuid) {
+ ConnectivityService connectivityService = getConnectivityService(serviceUuid);
+ if (connectivityService == null) {
+ LOG.error("Service doesnt exist in tapi context");
+ return;
+ }
+ for (org.opendaylight.yang.gen.v1
+ .urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection connection:
+ connectivityService.getConnection().values()) {
+ deleteConnection(connection.getConnectionUuid());
+ }
+ InstanceIdentifier<ConnectivityService> connectivityServIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(ConnectivityService.class, new ConnectivityServiceKey(serviceUuid))
+ .build();
+ try {
+ this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
+ this.networkTransactionService.commit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to delete Connectivity service", e);
+ }
+ }
+
+ private void deleteConnection(Uuid connectionUuid) {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<org.opendaylight.yang.gen.v1
+ .urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
+ new org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey(
+ connectionUuid))
+ .build();
+ try {
+ this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID);
+ this.networkTransactionService.commit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to delete TAPI Connection", e);
+ }
+ }
+
+ public Connection getConnection(Uuid connectionUuid) {
+ try {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<Connection> connIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .child(Connection.class, new ConnectionKey(connectionUuid))
+ .build();
+
+ Optional<Connection> optConn =
+ this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get();
+ if (!optConn.isPresent()) {
+ LOG.error("Connection not found in tapi context");
+ return null;
+ }
+ return optConn.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Connection not found in tapi context. Error:", e);
+ return null;
+ }
+ }
+
+ public Map<ConnectivityServiceKey, ConnectivityService> getConnectivityServices() {
+ try {
+ // First read connectivity service with service uuid and update info
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivityContextIID =
+ InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
+ .build();
+
+ Optional<org.opendaylight.yang.gen.v1.urn
+ .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> optConnContext =
+ this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityContextIID)
+ .get();
+ if (!optConnContext.isPresent()) {
+ LOG.error("Connectivity context not found in tapi context");
+ return null;
+ }
+ return optConnContext.get().getConnectivityService();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Connectivity context not found in tapi context. Error:", e);
+ return null;
+ }
+ }
+
+ public ConnectionEndPoint getTapiCEP(Uuid topoUuid, Uuid nodeUuid, Uuid nepUuid, Uuid cepUuid) {
+ InstanceIdentifier<OwnedNodeEdgePoint> nepIID = InstanceIdentifier.builder(Context.class)
+ .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
+ .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
+ .child(Topology.class, new TopologyKey(topoUuid))
+ .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
+ new NodeKey(nodeUuid)).child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid)).build();
+ try {
+ Optional<OwnedNodeEdgePoint> optNode = this.networkTransactionService
+ .read(LogicalDatastoreType.OPERATIONAL, nepIID).get();
+ if (!optNode.isPresent()) {
+ LOG.error("Node is not present in datastore");
+ return null;
+ }
+ if (optNode.get().augmentation(OwnedNodeEdgePoint1.class) == null) {
+ LOG.error("Node doesnt have ceps");
+ return null;
+ }
+ return optNode.get().augmentation(OwnedNodeEdgePoint1.class).getCepList().getConnectionEndPoint()
+ .get(new ConnectionEndPointKey(cepUuid));
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Couldnt read node in topology");
+ return null;
+ }
+ }
}
<reference id="deviceTransactionManager"
interface="org.opendaylight.transportpce.common.device.DeviceTransactionManager" />
+ <reference id="notificationService"
+ interface="org.opendaylight.mdsal.binding.api.NotificationService"/>
+
<reference id="rpcProviderService"
interface="org.opendaylight.mdsal.binding.api.RpcProviderService"/>
class="org.opendaylight.transportpce.tapi.utils.TapiListener">
</bean>
+ <bean id="tapiPceListener" class="org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl">
+ <argument ref="dataBroker" />
+ </bean>
+
+ <bean id="tapiRendererListener" class="org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl">
+ <argument ref="dataBroker" />
+ </bean>
+
+ <bean id="tapiServiceHandlerListener" class="org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl">
+ <argument ref="dataBroker" />
+ </bean>
+
<bean id="tapiNetworkModelService" class="org.opendaylight.transportpce.tapi.topology.TapiNetworkModelServiceImpl">
<argument ref="tapilinkDiscoveryImpl" />
<argument ref="networkTransactionImpl" />
<argument ref="tapiNetconfTopologyListener" />
<argument ref="tapiPortMappingListener" />
<argument ref="tapiNetworkUtilsImpl" />
+ <argument ref="tapiPceListener" />
+ <argument ref="tapiRendererListener" />
+ <argument ref="tapiServiceHandlerListener" />
+ <argument ref="notificationService" />
</bean>
<bean id="tapiPortMappingListener" class="org.opendaylight.transportpce.tapi.topology.TapiPortMappingListener">