Supporting new paths computed by GNPy
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / gnpy / GnpyUtilitiesImpl.java
1 /*
2  * Copyright © 2018 Orange, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.transportpce.pce.gnpy;
10
11 import java.util.List;
12
13 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
14 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
15 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
16 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApiBuilder;
17 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.ServiceFileBuilder;
18 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.TopologyFileBuilder;
19 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Connections;
20 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Elements;
21 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.generic.path.properties.path.properties.PathRouteObjects;
22 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.service.PathRequest;
23 import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.synchronization.info.Synchronization;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev190624.PathComputationRequestInput;
25 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirection;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.AToZDirectionBuilder;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ZToADirection;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Class that implements the functions asked to gnpy.
35  *
36  * @author Ahmed Triki ( ahmed.triki@orange.com )
37  *
38  */
39
40 public class GnpyUtilitiesImpl {
41
42     private static final Logger LOG = LoggerFactory.getLogger(GnpyResult.class);
43     private NetworkTransactionService networkTransaction;
44     private PathComputationRequestInput input;
45     private GnpyTopoImpl gnpyTopo = null;
46     private GnpyResult gnpyAtoZ;
47     private GnpyResult gnpyZtoA;
48     private Long requestId;
49
50     public GnpyUtilitiesImpl(NetworkTransactionService networkTransaction, PathComputationRequestInput input) {
51         this.networkTransaction = networkTransaction;
52         this.gnpyTopo = new GnpyTopoImpl(networkTransaction);
53         this.input = input;
54         this.gnpyAtoZ = null;
55         this.gnpyZtoA = null;
56         this.requestId = (long) 0;
57     }
58
59     public boolean verifyComputationByGnpy(AToZDirection atoz, ZToADirection ztoa, PceConstraints pceHardConstraints)
60         throws Exception {
61         boolean isPcePathFeasible = false;
62         List<Elements> elementsList = gnpyTopo.getElements();
63         List<Connections> connectionsList = gnpyTopo.getConnections();
64
65         if (atoz == null || atoz.getAToZ() == null) {
66             LOG.error("In pceSendingPceRPC: empty atoz path");
67         } else {
68             GnpyServiceImpl gnpySvc = new GnpyServiceImpl(input, atoz, requestId, gnpyTopo, pceHardConstraints);
69             requestId++;
70             List<PathRequest> pathRequestList1 = gnpySvc.getPathRequest();
71             List<Synchronization> synchronizationList1 = gnpySvc.getSynchronization();
72             // Send the computed path A-to-Z to GNPY tool
73             String gnpyResponse1 = getGnpyResponse(elementsList, connectionsList, pathRequestList1,
74                 synchronizationList1);
75             // Analyze the response
76             if (gnpyResponse1 != null) {
77                 GnpyResult result = new GnpyResult(gnpyResponse1, gnpyTopo);
78                 result.analyzeResult();
79                 this.gnpyAtoZ = result;
80                 isPcePathFeasible = this.gnpyAtoZ.getPathFeasibility();
81             } else {
82                 LOG.error("No response from the GNPy server");
83             }
84         }
85
86         if (ztoa == null || ztoa.getZToA() == null) {
87             LOG.error("In pceSendingPceRPC: empty ztoa path");
88             isPcePathFeasible = false;
89         } else {
90             GnpyServiceImpl gnpySvc = new GnpyServiceImpl(input, ztoa, requestId, gnpyTopo, pceHardConstraints);
91             requestId++;
92             List<PathRequest> pathRequestList2 = gnpySvc.getPathRequest();
93             List<Synchronization> synchronizationList2 = gnpySvc.getSynchronization();
94             // Send the computed path Z-to-A to GNPY tool
95             String gnpyResponse2 = getGnpyResponse(elementsList, connectionsList, pathRequestList2,
96                 synchronizationList2);
97             // Analyze the response
98             if (gnpyResponse2 != null) {
99                 GnpyResult result = new GnpyResult(gnpyResponse2, gnpyTopo);
100                 result.analyzeResult();
101                 this.gnpyZtoA = result;
102                 isPcePathFeasible &= this.gnpyZtoA.getPathFeasibility();
103             } else {
104                 LOG.error("No response from the GNPy server");
105             }
106         }
107         return isPcePathFeasible;
108     }
109
110     public HardConstraints askNewPathFromGnpy(AToZDirection atoz, ZToADirection ztoa,
111         HardConstraints gnpyPathAsHC, PceConstraints pceHardConstraints) throws Exception {
112         boolean isPcePathFeasible = false;
113         List<Elements> elementsList = gnpyTopo.getElements();
114         List<Connections> connectionsList = gnpyTopo.getConnections();
115
116         // Ask a new path A-to-Z
117         if (atoz.getAToZWavelengthNumber() == null) {
118             LOG.info("The wavelength is null!");
119         }
120
121         AToZDirection atoztmp = new AToZDirectionBuilder().setRate(atoz.getRate())
122             .setAToZ(null).build();
123         GnpyServiceImpl gnpySvc = new GnpyServiceImpl(input, atoztmp, requestId, gnpyTopo, pceHardConstraints);
124         requestId++;
125         List<PathRequest> pathRequestList1 = gnpySvc.getPathRequest();
126         List<Synchronization> synchronizationList1 = gnpySvc.getSynchronization();
127
128         // Send the computed path A-to-Z to GNPY tool
129         String gnpyResponse1 = getGnpyResponse(elementsList, connectionsList, pathRequestList1, synchronizationList1);
130         // Analyze the response
131         if (gnpyResponse1 != null) {
132             GnpyResult result = new GnpyResult(gnpyResponse1, gnpyTopo);
133             LOG.debug("GNPy result created");
134             isPcePathFeasible = result.getPathFeasibility();
135             this.gnpyAtoZ = result;
136             if (isPcePathFeasible) {
137                 List<PathRouteObjects> pathRouteObjectList = result.analyzeResult();
138                 gnpyPathAsHC = result.computeHardConstraintsFromGnpyPath(pathRouteObjectList);
139             }
140         } else {
141             LOG.error("No response from the GNPy server");
142         }
143         return gnpyPathAsHC;
144     }
145
146     public String getGnpyResponse(List<Elements> elementsList, List<Connections> connectionsList,
147         List<PathRequest> pathRequestList, List<Synchronization> synchronizationList) throws Exception {
148         GnpyApi gnpyApi = new GnpyApiBuilder()
149             .setTopologyFile(
150                 new TopologyFileBuilder().setElements(elementsList).setConnections(connectionsList).build())
151             .setServiceFile(new ServiceFileBuilder().setPathRequest(pathRequestList).build()).build();
152         InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
153         String gnpyJson;
154         ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(networkTransaction);
155         gnpyJson = sd.createJsonStringFromDataObject(idGnpyApi, gnpyApi);
156         LOG.debug("GNPy Id: {} / json created : {}", idGnpyApi, gnpyJson);
157         ConnectToGnpyServer connect = new ConnectToGnpyServer();
158         String gnpyJsonModified = gnpyJson.replace("gnpy-eqpt-config:", "")
159             .replace("gnpy-path-computation-simplified:", "").replace("gnpy-network-topology:", "");
160         String gnpyResponse = connect.gnpyCnx(gnpyJsonModified);
161         return gnpyResponse;
162     }
163
164     public GnpyResult getGnpyAtoZ() {
165         return gnpyAtoZ;
166     }
167
168     public GnpyResult getGnpyZtoA() {
169         return gnpyZtoA;
170     }
171 }