GNPy migration to Aluminium
[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.ArrayList;
12 import java.util.List;
13 import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
14 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
15 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
16 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
17 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApiBuilder;
18 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.ServiceFileBuilder;
19 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.TopologyFileBuilder;
20 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Connections;
21 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Elements;
22 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathRouteObjects;
23 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
24 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.Synchronization;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.AToZDirection;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.AToZDirectionBuilder;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.ZToADirection;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.opendaylight.yangtools.yang.common.Uint32;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * Class that implements the functions asked to gnpy.
37  *
38  * @author Ahmed Triki ( ahmed.triki@orange.com )
39  *
40  */
41
42 public class GnpyUtilitiesImpl {
43
44     private static final Logger LOG = LoggerFactory.getLogger(GnpyUtilitiesImpl.class);
45     private NetworkTransactionService networkTransaction;
46     private PathComputationRequestInput input;
47     private GnpyTopoImpl gnpyTopo = null;
48     private GnpyResult gnpyAtoZ;
49     private GnpyResult gnpyZtoA;
50     private Uint32 requestId;
51     private BindingDOMCodecServices bindingDOMCodecServices;
52
53
54     public GnpyUtilitiesImpl(NetworkTransactionService networkTransaction, PathComputationRequestInput input,
55             BindingDOMCodecServices bindingDOMCodecServices)
56         throws GnpyException {
57
58         this.networkTransaction = networkTransaction;
59         this.gnpyTopo = new GnpyTopoImpl(networkTransaction);
60         this.input = input;
61         this.gnpyAtoZ = null;
62         this.gnpyZtoA = null;
63         this.requestId = Uint32.valueOf(0);
64         this.bindingDOMCodecServices = bindingDOMCodecServices;
65     }
66
67     public boolean verifyComputationByGnpy(AToZDirection atoz, ZToADirection ztoa, PceConstraints pceHardConstraints)
68         throws GnpyException, Exception {
69
70         if (atoz == null || atoz.getAToZ() == null || ztoa == null || ztoa.getZToA() == null) {
71             throw new GnpyException("In GnpyUtilities: the path transmitted to Gnpy is null");
72         }
73
74         GnpyServiceImpl gnpySvc1 = new GnpyServiceImpl(input, atoz, requestId, gnpyTopo, pceHardConstraints);
75         this.gnpyAtoZ = gnpyResponseOneDirection(gnpySvc1);
76         boolean isPcePathFeasible = false;
77         isPcePathFeasible = this.gnpyAtoZ.getPathFeasibility();
78         GnpyServiceImpl gnpySvc2 = new GnpyServiceImpl(input, ztoa, requestId, gnpyTopo, pceHardConstraints);
79         this.gnpyZtoA = gnpyResponseOneDirection(gnpySvc2);
80         isPcePathFeasible &= this.gnpyZtoA.getPathFeasibility();
81         return isPcePathFeasible;
82     }
83
84     public GnpyResult gnpyResponseOneDirection(GnpyServiceImpl gnpySvc) throws GnpyException, Exception {
85         requestId = Uint32.valueOf((requestId.toJava()) + 1);
86         List<PathRequest> pathRequestList = new ArrayList<>(gnpySvc.getPathRequest().values());
87         List<Synchronization> synchronizationList = gnpySvc.getSynchronization();
88         // Send the computed path to GNPY tool
89         List<Elements> elementsList = new ArrayList<>(gnpyTopo.getElements().values());
90         List<Connections> connectionsList = gnpyTopo.getConnections();
91         String gnpyResponse = getGnpyResponse(elementsList, connectionsList, pathRequestList,
92             synchronizationList);
93         // Analyze the response
94         if (gnpyResponse == null) {
95             throw new GnpyException("In GnpyUtilities: no response from GNPy server");
96         }
97         GnpyResult result = new GnpyResult(gnpyResponse, gnpyTopo, bindingDOMCodecServices);
98         result.analyzeResult();
99         return result;
100     }
101
102     public HardConstraints askNewPathFromGnpy(PceConstraints pceHardConstraints)
103             throws GnpyException, Exception {
104
105         AToZDirection atoztmp = new AToZDirectionBuilder()
106             .setRate(input.getServiceAEnd().getServiceRate())
107             .build();
108         GnpyServiceImpl gnpySvc = new GnpyServiceImpl(input, atoztmp, requestId, gnpyTopo, pceHardConstraints);
109         GnpyResult result = gnpyResponseOneDirection(gnpySvc);
110
111         if (result == null) {
112             throw new GnpyException("In GnpyUtilities: no result from the GNPy server");
113         }
114
115         if (!result.getPathFeasibility()) {
116             return null;
117         }
118         List<PathRouteObjects> pathRouteObjectList = result.analyzeResult();
119         return result.computeHardConstraintsFromGnpyPath(pathRouteObjectList);
120     }
121
122     public String getGnpyResponse(List<Elements> elementsList, List<Connections> connectionsList,
123         List<PathRequest> pathRequestList, List<Synchronization> synchronizationList)
124                 throws GnpyException, Exception {
125         GnpyApi gnpyApi = new GnpyApiBuilder()
126             .setTopologyFile(
127                 new TopologyFileBuilder().setElements(elementsList).setConnections(connectionsList).build())
128             .setServiceFile(
129                 new ServiceFileBuilder().setPathRequest(pathRequestList).build())
130             .build();
131         InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
132         String gnpyJson;
133         ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(bindingDOMCodecServices);
134         gnpyJson = sd.createJsonStringFromDataObject(idGnpyApi, gnpyApi);
135         LOG.debug("GNPy Id: {} / json created : {}", idGnpyApi, gnpyJson);
136         ConnectToGnpyServer connect = new ConnectToGnpyServer();
137         String gnpyJsonModified = gnpyJson
138             .replace("gnpy-eqpt-config:", "")
139             .replace("gnpy-path-computation-simplified:", "")
140             .replace("gnpy-network-topology:", "");
141
142         return connect.returnGnpyResponse(gnpyJsonModified);
143     }
144
145     public GnpyResult getGnpyAtoZ() {
146         return gnpyAtoZ;
147     }
148
149     public GnpyResult getGnpyZtoA() {
150         return gnpyZtoA;
151     }
152 }