package org.opendaylight.transportpce.pce.gnpy;
+import java.util.ArrayList;
import java.util.List;
-
+import java.util.stream.Collectors;
import org.opendaylight.transportpce.common.network.NetworkTransactionService;
import org.opendaylight.transportpce.pce.constraints.PceConstraints;
+import org.opendaylight.transportpce.pce.gnpy.consumer.GnpyConsumer;
import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApiBuilder;
import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.ServiceFileBuilder;
import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.TopologyFileBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Connections;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Elements;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.generic.path.properties.path.properties.PathRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.service.PathRequest;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.synchronization.info.Synchronization;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInput;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirectionBuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ZToADirection;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.Connections;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev210831.topo.Elements;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.Synchronization;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev210701.PathComputationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirection;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.yangtools.yang.common.Uint32;
/**
* Class that implements the functions asked to gnpy.
public class GnpyUtilitiesImpl {
- private static final Logger LOG = LoggerFactory.getLogger(GnpyResult.class);
- private NetworkTransactionService networkTransaction;
private PathComputationRequestInput input;
private GnpyTopoImpl gnpyTopo = null;
private GnpyResult gnpyAtoZ;
private GnpyResult gnpyZtoA;
- private Long requestId;
+ private Uint32 requestId;
+ private final GnpyConsumer gnpyConsumer;
- public GnpyUtilitiesImpl(NetworkTransactionService networkTransaction, PathComputationRequestInput input) {
- this.networkTransaction = networkTransaction;
+ public GnpyUtilitiesImpl(NetworkTransactionService networkTransaction, PathComputationRequestInput input,
+ GnpyConsumer gnpyConsumer)
+ throws GnpyException {
this.gnpyTopo = new GnpyTopoImpl(networkTransaction);
this.input = input;
this.gnpyAtoZ = null;
this.gnpyZtoA = null;
- this.requestId = (long) 0;
+ this.requestId = Uint32.valueOf(0);
+ this.gnpyConsumer = gnpyConsumer;
}
public boolean verifyComputationByGnpy(AToZDirection atoz, ZToADirection ztoa, PceConstraints pceHardConstraints)
- throws Exception {
- boolean isPcePathFeasible = false;
- List<Elements> elementsList = gnpyTopo.getElements();
- List<Connections> connectionsList = gnpyTopo.getConnections();
+ throws GnpyException {
- if (atoz == null || atoz.getAToZ() == null) {
- LOG.error("In pceSendingPceRPC: empty atoz path");
- } else {
- GnpyServiceImpl gnpySvc = new GnpyServiceImpl(input, atoz, requestId, gnpyTopo, pceHardConstraints);
- requestId++;
- List<PathRequest> pathRequestList1 = gnpySvc.getPathRequest();
- List<Synchronization> synchronizationList1 = gnpySvc.getSynchronization();
- // Send the computed path A-to-Z to GNPY tool
- String gnpyResponse1 = getGnpyResponse(elementsList, connectionsList, pathRequestList1,
- synchronizationList1);
- // Analyze the response
- if (gnpyResponse1 != null) {
- GnpyResult result = new GnpyResult(gnpyResponse1, gnpyTopo);
- result.analyzeResult();
- this.gnpyAtoZ = result;
- isPcePathFeasible = this.gnpyAtoZ.getPathFeasibility();
- } else {
- LOG.error("No response from the GNPy server");
- }
+ if (atoz == null || atoz.getAToZ() == null || ztoa == null || ztoa.getZToA() == null) {
+ throw new GnpyException("In GnpyUtilities: the path transmitted to Gnpy is null");
}
- if (ztoa == null || ztoa.getZToA() == null) {
- LOG.error("In pceSendingPceRPC: empty ztoa path");
- isPcePathFeasible = false;
- } else {
- GnpyServiceImpl gnpySvc = new GnpyServiceImpl(input, ztoa, requestId, gnpyTopo, pceHardConstraints);
- requestId++;
- List<PathRequest> pathRequestList2 = gnpySvc.getPathRequest();
- List<Synchronization> synchronizationList2 = gnpySvc.getSynchronization();
- // Send the computed path Z-to-A to GNPY tool
- String gnpyResponse2 = getGnpyResponse(elementsList, connectionsList, pathRequestList2,
- synchronizationList2);
- // Analyze the response
- if (gnpyResponse2 != null) {
- GnpyResult result = new GnpyResult(gnpyResponse2, gnpyTopo);
- result.analyzeResult();
- this.gnpyZtoA = result;
- isPcePathFeasible &= this.gnpyZtoA.getPathFeasibility();
- } else {
- LOG.error("No response from the GNPy server");
- }
- }
+ GnpyServiceImpl gnpySvc1 = new GnpyServiceImpl(input, atoz, requestId, gnpyTopo, pceHardConstraints);
+ this.gnpyAtoZ = gnpyResponseOneDirection(gnpySvc1);
+ boolean isPcePathFeasible = false;
+ isPcePathFeasible = this.gnpyAtoZ.getPathFeasibility();
+ GnpyServiceImpl gnpySvc2 = new GnpyServiceImpl(input, ztoa, requestId, gnpyTopo, pceHardConstraints);
+ this.gnpyZtoA = gnpyResponseOneDirection(gnpySvc2);
+ isPcePathFeasible &= this.gnpyZtoA.getPathFeasibility();
return isPcePathFeasible;
}
- public HardConstraints askNewPathFromGnpy(AToZDirection atoz, ZToADirection ztoa,
- HardConstraints gnpyPathAsHC, PceConstraints pceHardConstraints) throws Exception {
- boolean isPcePathFeasible = false;
- List<Elements> elementsList = gnpyTopo.getElements();
+ @SuppressWarnings("checkstyle:illegalcatch")
+ public GnpyResult gnpyResponseOneDirection(GnpyServiceImpl gnpySvc) throws GnpyException {
+ requestId = Uint32.valueOf((requestId.toJava()) + 1);
+ List<PathRequest> pathRequestList = new ArrayList<>(gnpySvc.getPathRequest().values());
+ List<Synchronization> synchronizationList = gnpySvc.getSynchronization();
+ // Send the computed path to GNPY tool
+ List<Elements> elementsList = new ArrayList<>(gnpyTopo.getElements().values());
List<Connections> connectionsList = gnpyTopo.getConnections();
-
- // Ask a new path A-to-Z
- if (atoz.getAToZWavelengthNumber() == null) {
- LOG.info("The wavelength is null!");
+ Result gnpyResponse = getGnpyResponse(elementsList, connectionsList, pathRequestList,
+ synchronizationList);
+ // Analyze the response
+ if (gnpyResponse == null) {
+ throw new GnpyException("In GnpyUtilities: no response from GNPy server");
}
+ GnpyResult result = new GnpyResult(gnpyResponse, gnpyTopo);
+ result.analyzeResult();
+ return result;
+ }
+
+ public HardConstraints askNewPathFromGnpy(PceConstraints pceHardConstraints)
+ throws GnpyException {
- AToZDirection atoztmp = new AToZDirectionBuilder().setRate(atoz.getRate())
- .setAToZ(null).build();
+ AToZDirection atoztmp = new AToZDirectionBuilder()
+ .setRate(input.getServiceAEnd().getServiceRate())
+ .build();
GnpyServiceImpl gnpySvc = new GnpyServiceImpl(input, atoztmp, requestId, gnpyTopo, pceHardConstraints);
- requestId++;
- List<PathRequest> pathRequestList1 = gnpySvc.getPathRequest();
- List<Synchronization> synchronizationList1 = gnpySvc.getSynchronization();
+ GnpyResult result = gnpyResponseOneDirection(gnpySvc);
- // Send the computed path A-to-Z to GNPY tool
- String gnpyResponse1 = getGnpyResponse(elementsList, connectionsList, pathRequestList1, synchronizationList1);
- // Analyze the response
- if (gnpyResponse1 != null) {
- GnpyResult result = new GnpyResult(gnpyResponse1, gnpyTopo);
- LOG.debug("GNPy result created");
- isPcePathFeasible = result.getPathFeasibility();
- this.gnpyAtoZ = result;
- if (isPcePathFeasible) {
- List<PathRouteObjects> pathRouteObjectList = result.analyzeResult();
- gnpyPathAsHC = result.computeHardConstraintsFromGnpyPath(pathRouteObjectList);
- }
- } else {
- LOG.error("No response from the GNPy server");
+ if (result == null) {
+ throw new GnpyException("In GnpyUtilities: no result from the GNPy server");
+ }
+
+ if (!result.getPathFeasibility()) {
+ return null;
}
- return gnpyPathAsHC;
+ List<PathRouteObjects> pathRouteObjectList = result.analyzeResult();
+ return result.computeHardConstraintsFromGnpyPath(pathRouteObjectList);
}
- public String getGnpyResponse(List<Elements> elementsList, List<Connections> connectionsList,
- List<PathRequest> pathRequestList, List<Synchronization> synchronizationList) throws Exception {
+ public Result getGnpyResponse(List<Elements> elementsList, List<Connections> connectionsList,
+ List<PathRequest> pathRequestList, List<Synchronization> synchronizationList) {
GnpyApi gnpyApi = new GnpyApiBuilder()
.setTopologyFile(
- new TopologyFileBuilder().setElements(elementsList).setConnections(connectionsList).build())
- .setServiceFile(new ServiceFileBuilder().setPathRequest(pathRequestList).build()).build();
- InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
- String gnpyJson;
- ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(networkTransaction);
- gnpyJson = sd.createJsonStringFromDataObject(idGnpyApi, gnpyApi);
- LOG.debug("GNPy Id: {} / json created : {}", idGnpyApi, gnpyJson);
- ConnectToGnpyServer connect = new ConnectToGnpyServer();
- String gnpyJsonModified = gnpyJson.replace("gnpy-eqpt-config:", "")
- .replace("gnpy-path-computation-simplified:", "").replace("gnpy-network-topology:", "");
- String gnpyResponse = connect.gnpyCnx(gnpyJsonModified);
- return gnpyResponse;
+ new TopologyFileBuilder()
+ .setElements(elementsList.stream().collect(Collectors.toMap(Elements::key, element -> element)))
+ .setConnections(connectionsList).build())
+ .setServiceFile(
+ new ServiceFileBuilder()
+ .setPathRequest(pathRequestList.stream()
+ .collect(Collectors.toMap(PathRequest::key, pathRequest -> pathRequest)))
+ .build())
+ .build();
+ return gnpyConsumer.computePaths(gnpyApi);
}
public GnpyResult getGnpyAtoZ() {