GNPy client refactor
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / gnpy / GnpyResult.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.math.BigDecimal;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.stream.Collectors;
20 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
21 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.NumUnnumHop;
22 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetric;
23 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathRouteObjects;
24 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.Response;
25 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.NoPathCase;
26 import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCase;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.General;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.GeneralBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Include;
30 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.IncludeBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.include_.OrderedHops;
32 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.include_.OrderedHopsBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.ordered.constraints.sp.HopType;
34 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.ordered.constraints.sp.HopTypeBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.NodeBuilder;
36 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraintsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
40 import org.opendaylight.yangtools.yang.common.Uint16;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 /**
45  * Class for analyzing the result sent by GNPy.
46  *
47  * @author Ahmed Triki ( ahmed.triki@orange.com )
48  *
49  */
50
51 public class GnpyResult {
52
53     private static final Logger LOG = LoggerFactory.getLogger(GnpyResult.class);
54     private Response response = null;
55     private Map<String, IpAddress> mapNodeRefIp = new HashMap<>();
56
57     public GnpyResult(Result result, GnpyTopoImpl gnpyTopo) throws GnpyException {
58         this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
59         List<Response> responses = new ArrayList<>(result.nonnullResponse().values());
60         if (responses.isEmpty()) {
61             throw new GnpyException("In GnpyResult: the response from GNpy is null!");
62         }
63         LOG.info("The response id is {}; ", responses.get(0).getResponseId());
64         this.response = responses.get(0);
65         analyzeResult();
66     }
67
68     public boolean getPathFeasibility() {
69         boolean isFeasible = false;
70         if (response != null) {
71             if (response.getResponseType() instanceof NoPathCase) {
72                 LOG.info("In GnpyResult: The path is not feasible ");
73             } else if (response.getResponseType() instanceof PathCase) {
74                 isFeasible = true;
75                 LOG.info("In GnpyResult: The path is feasible ");
76             }
77         }
78         return isFeasible;
79     }
80
81     public List<PathRouteObjects> analyzeResult() {
82         List<PathRouteObjects> pathRouteObjectList = null;
83         if (response != null) {
84             if (response.getResponseType() instanceof NoPathCase) {
85                 NoPathCase noPathCase = (NoPathCase) response.getResponseType();
86                 String noPathType = noPathCase.getNoPath().getNoPath();
87                 LOG.info("GNPy: No path - {}", noPathType);
88                 if (((noPathType.equals("NO_FEASIBLE_BAUDRATE_WITH_SPACING"))
89                     && (noPathType.equals("NO_FEASIBLE_MODE"))) && ((noPathType.equals("MODE_NOT_FEASIBLE"))
90                         && (noPathType.equals("NO_SPECTRUM")))) {
91                     Collection<PathMetric> pathMetricList = noPathCase.getNoPath()
92                             .getPathProperties().nonnullPathMetric().values();
93                     LOG.info("GNPy : path is not feasible : {}", noPathType);
94                     for (PathMetric pathMetric : pathMetricList) {
95                         String metricType = pathMetric.getMetricType().getSimpleName();
96                         BigDecimal accumulativeValue = pathMetric.getAccumulativeValue();
97                         LOG.info("Metric type {} // AccumulatriveValue {}", metricType, accumulativeValue);
98                     }
99                 }
100             } else if (response.getResponseType() instanceof PathCase) {
101                 LOG.info("GNPy : path is feasible");
102                 PathCase pathCase = (PathCase) response.getResponseType();
103                 Collection<PathMetric> pathMetricList = pathCase
104                         .getPathProperties().nonnullPathMetric().values();
105                 // Path metrics
106                 for (PathMetric pathMetric : pathMetricList) {
107                     String metricType = pathMetric.getMetricType().getSimpleName();
108                     BigDecimal accumulativeValue = pathMetric.getAccumulativeValue();
109                     LOG.info("Metric type {} // AccumulatriveValue {}", metricType, accumulativeValue);
110                 }
111                 // Path route objects
112                 pathRouteObjectList = pathCase.getPathProperties().getPathRouteObjects();
113                 LOG.info("in GnpyResult: finishing the computation of pathRouteObjectList");
114             }
115         }
116         return pathRouteObjectList;
117     }
118
119     public HardConstraints computeHardConstraintsFromGnpyPath(List<PathRouteObjects> pathRouteObjectList) {
120         HardConstraints hardConstraints = null;
121         // Includes the list of nodes in the GNPy computed path as constraints
122         // for the PCE
123         List<OrderedHops> orderedHopsList = new ArrayList<>();
124         int counter = 0;
125         for (PathRouteObjects pathRouteObjects : pathRouteObjectList) {
126             if (pathRouteObjects.getPathRouteObject().getType() instanceof NumUnnumHop) {
127                 NumUnnumHop numUnnumHop = (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type
128                     .NumUnnumHop) pathRouteObjects.getPathRouteObject().getType();
129                 String nodeIp = numUnnumHop.getNumUnnumHop().getNodeId();
130                 try {
131                     IpAddress nodeIpAddress = new IpAddress(new Ipv4Address(nodeIp));
132                     // find the corresponding node-id (in ord-ntw) corresponding to nodeId (in gnpy response)
133                     String nodeId = findOrdNetworkNodeId(nodeIpAddress);
134                     if (nodeId != null) {
135                         org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017
136                             .ordered.constraints.sp.hop.type.hop.type.Node node = new NodeBuilder().setNodeId(nodeId)
137                             .build();
138                         HopType hopType = new HopTypeBuilder().setHopType(node).build();
139                         OrderedHops orderedHops = new OrderedHopsBuilder()
140                                 .setHopNumber(Uint16.valueOf(counter)).setHopType(hopType)
141                             .build();
142                         orderedHopsList.add(orderedHops);
143                         counter++;
144                     }
145                 } catch (IllegalArgumentException e) {
146                     LOG.debug(" in GnpyResult: the element {} is not a ipv4Address ", nodeIp);
147                 }
148             }
149         }
150         Include include = new IncludeBuilder()
151                 .setOrderedHops(orderedHopsList.stream()
152                         .collect(Collectors.toMap(OrderedHops::key, orderedHops -> orderedHops)))
153                 .build();
154         General general = new GeneralBuilder().setInclude(include).build();
155         hardConstraints = new HardConstraintsBuilder().setCoRoutingOrGeneral(general).build();
156         return hardConstraints;
157     }
158
159     private String findOrdNetworkNodeId(IpAddress nodeIpAddress) {
160         Iterator<Map.Entry<String,IpAddress>> it = this.mapNodeRefIp.entrySet().iterator();
161         while (it.hasNext()) {
162             Entry<String, IpAddress> entry = it.next();
163             if (entry.getValue().equals(nodeIpAddress)) {
164                 return entry.getKey();
165             }
166         }
167         return null;
168     }
169
170     public Response getResponse() {
171         return response;
172     }
173 }