Autonomous impairment aware path computation
[transportpce.git] / pce / src / test / java / org / opendaylight / transportpce / pce / graph / PceGraphTest.java
1 /*
2  * Copyright © 2020 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.graph;
10
11 import static org.junit.Assert.fail;
12
13 import com.google.common.collect.ImmutableMap;
14 import com.google.gson.stream.JsonReader;
15 import java.io.FileReader;
16 import java.io.IOException;
17 import java.io.Reader;
18 import java.nio.charset.StandardCharsets;
19 import java.util.Map;
20 import java.util.Optional;
21 import java.util.Set;
22 import java.util.concurrent.ExecutionException;
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.junit.Assert;
25 import org.junit.Before;
26 import org.junit.Test;
27 import org.mockito.MockitoAnnotations;
28 import org.opendaylight.mdsal.binding.api.DataBroker;
29 import org.opendaylight.mdsal.binding.api.MountPoint;
30 import org.opendaylight.mdsal.binding.api.MountPointService;
31 import org.opendaylight.mdsal.binding.api.WriteTransaction;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.transportpce.common.NetworkUtils;
34 import org.opendaylight.transportpce.common.StringConstants;
35 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
36 import org.opendaylight.transportpce.common.device.DeviceTransactionManagerImpl;
37 import org.opendaylight.transportpce.common.mapping.PortMapping;
38 import org.opendaylight.transportpce.common.mapping.PortMappingImpl;
39 import org.opendaylight.transportpce.common.mapping.PortMappingVersion121;
40 import org.opendaylight.transportpce.common.mapping.PortMappingVersion221;
41 import org.opendaylight.transportpce.common.mapping.PortMappingVersion710;
42 import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
43 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
44 import org.opendaylight.transportpce.common.network.RequestProcessor;
45 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
46 import org.opendaylight.transportpce.pce.networkanalyzer.PceCalculation;
47 import org.opendaylight.transportpce.pce.networkanalyzer.PceLink;
48 import org.opendaylight.transportpce.pce.networkanalyzer.PceNode;
49 //import org.opendaylight.transportpce.pce.networkanalyzer.PceOpticalNode;
50 import org.opendaylight.transportpce.pce.networkanalyzer.PceOtnNode;
51 import org.opendaylight.transportpce.pce.networkanalyzer.PceResult;
52 import org.opendaylight.transportpce.pce.utils.JsonUtil;
53 import org.opendaylight.transportpce.pce.utils.NodeUtils;
54 import org.opendaylight.transportpce.test.AbstractTest;
55 import org.opendaylight.transportpce.test.converter.DataObjectConverter;
56 import org.opendaylight.transportpce.test.converter.JSONDataObjectConverter;
57 import org.opendaylight.transportpce.test.stub.MountPointServiceStub;
58 import org.opendaylight.transportpce.test.stub.MountPointStub;
59 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRequestInput;
60 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.PathComputationRequestInputBuilder;
61 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.path.computation.request.input.ServiceAEndBuilder;
62 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev220808.path.computation.request.input.ServiceZEndBuilder;
63 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.port.PortBuilder;
64 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
65 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev211210.OpenroadmVersionType;
66 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.rev211210.Node1Builder;
67 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.TerminationPoint1Builder;
68 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.XpdrNetworkAttributesBuilder;
69 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmNodeType;
70 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmTpType;
71 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.CoRoutingBuilder;
72 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.co.routing.ServiceIdentifierListBuilder;
73 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.routing.constraints.HardConstraintsBuilder;
74 import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.routing.constraints.SoftConstraintsBuilder;
75 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev191129.ServiceFormat;
76 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.OperationalModeCatalog;
77 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.PceMetric;
78 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.endpoint.sp.RxDirectionBuilder;
79 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.endpoint.sp.TxDirectionBuilder;
80 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.handler.header.ServiceHandlerHeaderBuilder;
81 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
82 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
83 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
84 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
86 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
87 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeBuilder;
88 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
89 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNode;
90 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeBuilder;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeKey;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
93 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
94 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
95 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
96 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
97 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
98 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
99 import org.opendaylight.yangtools.yang.common.QName;
100 import org.opendaylight.yangtools.yang.common.Uint32;
101 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
102 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
103 import org.slf4j.Logger;
104 import org.slf4j.LoggerFactory;
105
106 public class PceGraphTest extends AbstractTest {
107     private static final Logger LOG = LoggerFactory.getLogger(PceGraphTest.class);
108     private Link link1 = null;
109     private Node node = null;
110     private PceLink pceLink1 = null;
111     private PceGraph pceGraph = null;
112     private PceConstraints pceHardConstraints = null;
113     private PceResult rc = null;
114     private Map<NodeId, PceNode> allPceNodes = null;
115     private Map<LinkId, PceLink> allPceLinks = null;
116     private static final String CATALOG_FILE = "src/test/resources/apidocCatalog10_1OptSpecV5_1.json";
117     private static final String MAPPING_FILE = "src/test/resources/topologyData/portMapping2.json";
118     private static OperationalModeCatalog omCatalog;
119     private static org.opendaylight.yang.gen.v1.http.org.opendaylight
120             .transportpce.portmapping.rev220316.Network networkNode;
121     private DataBroker dataBroker;
122     private MountPoint mountPoint;
123     private MountPointService mountPointService;
124     private DeviceTransactionManager deviceTransactionManager;
125     private PortMappingVersion710 portMappingVersion710;
126     private PortMappingVersion221 portMappingVersion22;
127     private PortMappingVersion121 portMappingVersion121;
128     private PortMapping portMapping;
129     private RequestProcessor reqProc;
130     private NetworkTransactionService netTransServ;
131
132     // Test of integration for PceGraph
133
134     @Before
135     public void setUp() throws InterruptedException, ExecutionException {
136         // PortMapping is instantiated to create the mapping of the different nodes in the topology
137         this.dataBroker =  getNewDataBroker();
138         this.mountPoint = new MountPointStub(dataBroker);
139         this.mountPointService = new MountPointServiceStub(mountPoint);
140         this.deviceTransactionManager = new DeviceTransactionManagerImpl(mountPointService, 3000);
141         this.portMappingVersion22 = new PortMappingVersion221(dataBroker, deviceTransactionManager);
142         this.portMappingVersion121 = new PortMappingVersion121(dataBroker, deviceTransactionManager);
143         this.portMappingVersion710 = new PortMappingVersion710(dataBroker, deviceTransactionManager);
144         this.portMapping = new PortMappingImpl(dataBroker, this.portMappingVersion710,
145             this.portMappingVersion22, this.portMappingVersion121);
146         //  The catalog of operational mode needs to be loaded so that Ctalog primitives (CatlogUtils)
147         // can retrieve physical parameters of the nodes of the path
148         DataObjectConverter dataObjectConverter = JSONDataObjectConverter
149             .createWithDataStoreUtil(getDataStoreContextUtil());
150         try (Reader reader = new FileReader(CATALOG_FILE, StandardCharsets.UTF_8)) {
151             NormalizedNode normalizedNode = dataObjectConverter
152                 .transformIntoNormalizedNode(reader).get();
153             omCatalog = (OperationalModeCatalog) getDataStoreContextUtil()
154                 .getBindingDOMCodecServices().fromNormalizedNode(YangInstanceIdentifier
155                     .of(OperationalModeCatalog.QNAME), normalizedNode)
156                 .getValue();
157             @NonNull
158             WriteTransaction newWriteOnlyTransaction = dataBroker.newWriteOnlyTransaction();
159             newWriteOnlyTransaction
160                 .put(LogicalDatastoreType.CONFIGURATION,
161                     InstanceIdentifier.create(OperationalModeCatalog.class),
162                     omCatalog);
163             newWriteOnlyTransaction.commit().get();
164         } catch (IOException e) {
165             LOG.error("Cannot load OpenROADM part of Operational Mode Catalog ", e);
166             fail("Cannot load openROADM operational modes ");
167         }
168         // The mapping corresponding to the topology is directly populated from a file in the Dta Store
169         try (Reader reader = new FileReader(MAPPING_FILE, StandardCharsets.UTF_8)) {
170             NormalizedNode normalizedNode = dataObjectConverter
171                 .transformIntoNormalizedNode(reader).get();
172             networkNode = (org.opendaylight.yang.gen.v1.http.org.opendaylight
173                 .transportpce.portmapping.rev220316.Network) getDataStoreContextUtil()
174                 .getBindingDOMCodecServices().fromNormalizedNode(YangInstanceIdentifier
175                     .of(org.opendaylight.yang.gen.v1.http.org.opendaylight
176                         .transportpce.portmapping.rev220316.Network.QNAME), normalizedNode)
177                 .getValue();
178             @NonNull
179             WriteTransaction newWriteOnlyTransaction = dataBroker.newWriteOnlyTransaction();
180             newWriteOnlyTransaction
181                 .put(LogicalDatastoreType.CONFIGURATION,
182                     InstanceIdentifier.create(org.opendaylight.yang.gen.v1.http.org.opendaylight
183                         .transportpce.portmapping.rev220316.Network.class),
184                     networkNode);
185             newWriteOnlyTransaction.commit().get();
186         } catch (IOException e) {
187             LOG.error("Cannot load OpenROADM part of Operational Mode Catalog ", e);
188             fail("Cannot load openROADM operational modes ");
189         }
190
191         MockitoAnnotations.openMocks(this);
192         // The topology (openROADM-Network and openROADM-topology layers) is loaded from a file
193         JsonReader networkReader = null;
194         JsonReader topoReader = null;
195
196         try {
197             // load openroadm-network
198             Reader gnpyNetwork = new FileReader("src/test/resources/gnpy/gnpy_network.json",
199                     StandardCharsets.UTF_8);
200             networkReader = new JsonReader(gnpyNetwork);
201             Networks networks = (Networks) JsonUtil.getInstance().getDataObjectFromJson(networkReader,
202                     QName.create("urn:ietf:params:xml:ns:yang:ietf-network", "2018-02-26", "networks"));
203             saveOpenRoadmNetwork(networks.getNetwork().values().iterator().next(), NetworkUtils.UNDERLAY_NETWORK_ID);
204             // load openroadm-topology
205             Reader gnpyTopo = new FileReader("src/test/resources/topologyData/or-base-topology.json",
206                     StandardCharsets.UTF_8);
207             topoReader = new JsonReader(gnpyTopo);
208             networks = (Networks) JsonUtil.getInstance().getDataObjectFromJson(topoReader,
209                     QName.create("urn:ietf:params:xml:ns:yang:ietf-network", "2018-02-26", "networks"));
210             saveOpenRoadmNetwork(networks.getNetwork().values().iterator().next(), NetworkUtils.OVERLAY_NETWORK_ID);
211         } catch (IOException | InterruptedException | ExecutionException e) {
212             LOG.error("Cannot init test ", e);
213             fail("Cannot init test ");
214
215         } finally {
216             try {
217                 if (networkReader != null) {
218                     networkReader.close();
219                 }
220                 if (topoReader != null) {
221                     topoReader.close();
222                 }
223             } catch (IOException e) {
224                 LOG.warn("Cannot close reader ", e);
225             }
226         }
227
228         // init PceHardContraints
229         pceHardConstraints = new PceConstraints();
230
231         this.rc = new PceResult();
232         this.reqProc = new RequestProcessor(dataBroker);
233         this.netTransServ = new NetworkTransactionImpl(reqProc);
234
235         LOG.info("The value of the mapping is {}", portMapping);
236
237     }
238
239 //                       TOPOLOGY ON WHICH TEST ARE BASED
240 //           _____                      _____                       _____
241 //          |     | 20dB, 100km,PMD 2  |     | 20dB,100km, PMD 2   |     |
242 //          |  1  |____________________|  2  |_____________________|  5  |
243 //          |     |                    |     |                     |     |
244 //          |_____|                    |_____|                     |_____|
245 //              |___________      10km    |   20dB,100km,PMD32    /   |  100 km
246 //                          |      5dB    |   _________|_________/    |  25 dB
247 //                          |     PMD32 __|__/                      __|__PMD 2.0
248 //        28dB, 100km,PMD 0 |          |     | 25dB,100km, PMD 2   |     |
249 //                          |__________|  3  |_____________________|  4  |
250 //                                     |     |                     |     |
251 //                                     |_____|                     |_____|
252 //
253     @Test
254     public void clacPath100GE() {
255
256         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(100), ServiceFormat.Ethernet,
257             "XPONDER-1", "Node1", "Client-1", "XPONDER-3", "Node3", "Client-1"),
258             netTransServ, pceHardConstraints, null, rc, portMapping);
259         pceCalc.retrievePceNetwork();
260         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
261             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
262             null, rc, StringConstants.SERVICE_TYPE_100GE_T, netTransServ);
263         Assert.assertEquals(pceGraph.calcPath(), true);
264         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
265             Optional.ofNullable(3.0919881995992924));
266     }
267
268     @Test
269     public void clacPathOTUC2() {
270
271         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(200), ServiceFormat.Ethernet,
272             "XPONDER-1", "Node1", "XPDR-NW1-TX", "XPONDER-4", "Node4", "XPDR-NW1-RX"),
273             netTransServ, pceHardConstraints, null, rc, portMapping);
274         pceCalc.retrievePceNetwork();
275         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
276             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
277             null, rc, StringConstants.SERVICE_TYPE_OTUC2, netTransServ);
278         Assert.assertEquals(pceGraph.calcPath(), true);
279         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
280             Optional.ofNullable(1.1559963686478447));
281     }
282
283     @Test
284     public void clacPathOTUC3() {
285
286         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(300), ServiceFormat.Ethernet,
287             "XPONDER-1", "Node1", "XPDR-NW1-TX", "XPONDER-3", "Node3", "XPDR-NW1-RX"),
288             netTransServ, pceHardConstraints, null, rc, portMapping);
289         pceCalc.retrievePceNetwork();
290         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
291             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
292             null, rc, StringConstants.SERVICE_TYPE_OTUC3, netTransServ);
293         Assert.assertEquals(pceGraph.calcPath(), true);
294         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
295             Optional.ofNullable(0.3351048800367167));
296     }
297
298     @Test
299     public void clacUnfeasiblePath400GE() {
300
301         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(400), ServiceFormat.Ethernet,
302             "XPONDER-1", "Node1", "Client-1", "XPONDER-3", "Node3", "Client-1"),
303             netTransServ, pceHardConstraints, null, rc, portMapping);
304         pceCalc.retrievePceNetwork();
305         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
306             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
307             null, rc, StringConstants.SERVICE_TYPE_400GE, netTransServ);
308         Assert.assertEquals(pceGraph.calcPath(), false);
309         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
310             Optional.ofNullable(0.0));
311     }
312
313     @Test
314     public void clacPath400GE() {
315
316         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(400), ServiceFormat.Ethernet,
317             "XPONDER-1", "Node1", "Client-1", "XPONDER-5", "Node5", "Client-1"),
318             netTransServ, pceHardConstraints, null, rc, portMapping);
319         pceCalc.retrievePceNetwork();
320         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
321             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
322             null, rc, StringConstants.SERVICE_TYPE_400GE, netTransServ);
323         Assert.assertEquals(pceGraph.calcPath(), true);
324         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
325             Optional.ofNullable(1.4432381874659086));
326     }
327
328     @Test
329     public void clacPathOTUC4() {
330
331         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(400), ServiceFormat.Ethernet,
332             "XPONDER-1", "Node1", "XPDR-NW1-TX", "XPONDER-5", "Node5", "XPDR-NW1-RX"),
333             netTransServ, pceHardConstraints, null, rc, portMapping);
334         pceCalc.retrievePceNetwork();
335         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
336             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
337             null, rc, StringConstants.SERVICE_TYPE_OTUC4, netTransServ);
338         Assert.assertEquals(pceGraph.calcPath(), true);
339         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
340             Optional.ofNullable(1.4432381874659086));
341     }
342
343     @Test
344     public void clacOpticalTunnelOTUC4() {
345
346         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(400), ServiceFormat.OC,
347             "OpenROADM-1", "Node1", "DEG1-PP-TX", "OpenROADM-5", "Node5", "DEG3-PP-TX"),
348             netTransServ, pceHardConstraints, null, rc, portMapping);
349         pceCalc.retrievePceNetwork();
350         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
351             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
352             null, rc, StringConstants.SERVICE_TYPE_OTUC4, netTransServ);
353         Assert.assertEquals(pceGraph.calcPath(), true);
354         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
355             Optional.ofNullable(0.0));
356     }
357
358     @Test
359     public void clacPath100GEnoPort() {
360
361         PceCalculation pceCalc = new PceCalculation(getPCE2Request(Uint32.valueOf(100), ServiceFormat.Ethernet,
362             "XPONDER-1", "Node1", "Client-1", "XPONDER-3", "Node3", "Client-1"),
363             netTransServ, pceHardConstraints, null, rc, portMapping);
364         pceCalc.retrievePceNetwork();
365         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
366             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
367             null, rc, StringConstants.SERVICE_TYPE_100GE_T, netTransServ);
368         Assert.assertEquals(pceGraph.calcPath(), true);
369         Assert.assertEquals(Optional.ofNullable(pceGraph.getmargin()),
370             Optional.ofNullable(3.0919881995992924));
371     }
372
373     @Test
374     public void clacPathPropagationDelay() {
375         PceCalculation pceCalc = new PceCalculation(getPCE1Request(Uint32.valueOf(100), ServiceFormat.Ethernet,
376             "XPONDER-1", "Node1", "Client-1", "XPONDER-3", "Node3", "Client-1"),
377             netTransServ, pceHardConstraints, null, rc, portMapping);
378         pceCalc.retrievePceNetwork();
379         pceHardConstraints.setPceMetrics(PceMetric.PropagationDelay);
380         pceGraph = new PceGraph(pceCalc.getaendPceNode(), pceCalc.getzendPceNode(),
381             pceCalc.getAllPceNodes(), pceCalc.getAllPceLinks(), pceHardConstraints,
382             null, rc, StringConstants.SERVICE_TYPE_100GE_T, netTransServ);
383         pceGraph.setConstrains(pceHardConstraints, null);
384
385         Assert.assertEquals(pceGraph.calcPath(), true);
386         Assert.assertEquals(Optional.ofNullable(pceGraph.getPathAtoZ().get(2).getLatency()),
387             Optional.ofNullable(1.0));
388         Assert.assertEquals(pceGraph.getReturnStructure().getRate(), 100);
389     }
390
391     @Test(expected = Exception.class)
392     public void clacPath10GE2() {
393         pceGraph = getOtnPceGraph(StringConstants.SERVICE_TYPE_10GE);
394         Assert.assertEquals(pceGraph.calcPath(), false);
395     }
396
397     @Test(expected = Exception.class)
398     public void clacPath1GE() {
399         pceGraph = getOtnPceGraph(StringConstants.SERVICE_TYPE_1GE);
400         Assert.assertEquals(pceGraph.calcPath(), false);
401     }
402
403     private PceGraph getOtnPceGraph(String type) {
404         // Build Link
405         link1 = NodeUtils.createRoadmToRoadm("optical",
406             "optical2",
407             "DEG1-TTP-TX", "DEG1-TTP-RX").build();
408
409         node = NodeUtils.getOTNNodeBuilder(NodeUtils.geSupportingNodes(), OpenroadmTpType.XPONDERNETWORK).build();
410
411         PceOtnNode pceOtnNode = new PceOtnNode(node, OpenroadmNodeType.MUXPDR,
412             new NodeId("optical"), ServiceFormat.OTU.getName(), "serviceType", null);
413         pceOtnNode.validateXponder("optical", "sl");
414         pceOtnNode.validateXponder("not optical", "sl");
415         pceOtnNode.initXndrTps("AZ");
416         pceOtnNode.checkAvailableTribPort();
417         pceOtnNode.checkAvailableTribSlot();
418
419         PceOtnNode pceOtnNode2 = new PceOtnNode(node, OpenroadmNodeType.MUXPDR,
420             new NodeId("optical2"), ServiceFormat.OTU.getName(), "serviceType", null);
421         pceOtnNode2.validateXponder("optical", "sl");
422         pceOtnNode2.validateXponder("not optical", "sl");
423         pceOtnNode2.initXndrTps("AZ");
424         pceOtnNode2.initXndrTps("mode");
425         pceOtnNode2.checkAvailableTribPort();
426         pceOtnNode2.checkAvailableTribSlot();
427
428         pceLink1 = new PceLink(link1, pceOtnNode, pceOtnNode2);
429         pceLink1.setClient("XPONDER-CLIENT");
430
431         pceLink1.getDestId();
432         pceOtnNode.addOutgoingLink(pceLink1);
433
434         // init PceHardContraints
435         pceHardConstraints = new PceConstraints();
436         // pceHardConstraints.setp
437         allPceNodes = Map.of(new NodeId("optical"), pceOtnNode,
438             new NodeId("optical2"), pceOtnNode2);
439         rc = new PceResult();
440         PceGraph otnPceGraph = new PceGraph(pceOtnNode, pceOtnNode2, allPceNodes,
441             allPceLinks, pceHardConstraints,
442             null, rc,
443             type, null);
444
445         return otnPceGraph;
446     }
447
448     private void saveOpenRoadmNetwork(Network network, String networkId)
449             throws InterruptedException, ExecutionException {
450         InstanceIdentifier<Network> nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
451             .child(Network.class, new NetworkKey(new NetworkId(networkId))).build();
452         WriteTransaction dataWriteTransaction = dataBroker.newWriteOnlyTransaction();
453         dataWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier, network);
454         dataWriteTransaction.commit().get();
455     }
456
457     public static Node createNetworkNode(String nodeId, OpenroadmNodeType nodeType) {
458
459         Node1Builder node1Bldr = new Node1Builder()
460             .setOpenroadmVersion(OpenroadmVersionType._221);
461         var node2Bldr = new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
462             .setNodeType(nodeType);
463         SupportingNode supportingNode = new SupportingNodeBuilder()
464             .setNetworkRef(new NetworkId(NetworkUtils.CLLI_NETWORK_ID))
465             .setNodeRef(new NodeId("node1"))
466             .withKey(new SupportingNodeKey(new NetworkId(NetworkUtils.CLLI_NETWORK_ID),
467                 new NodeId("node1")))
468             .build();
469
470         return new NodeBuilder()
471             .setNodeId(new NodeId(nodeId))
472             .withKey(new NodeKey(new NodeId(nodeId)))
473             .setSupportingNode(ImmutableMap.of(supportingNode.key(), supportingNode))
474             .addAugmentation(node1Bldr.build())
475             .addAugmentation(node2Bldr.build())
476             .build();
477     }
478
479     public static TerminationPoint createNetworkTp(String nodeId, String tpId) {
480         var nwTpId = new TpId(tpId);
481         return new TerminationPointBuilder()
482             .setTpId(nwTpId)
483             .withKey(new TerminationPointKey(nwTpId))
484             .addAugmentation(new TerminationPoint1Builder()
485                 .setXpdrNetworkAttributes(new XpdrNetworkAttributesBuilder().setState(State.InService).build())
486                 .build())
487             .build();
488     }
489
490     public static Node createTopologyNode(String nodeId, OpenroadmNodeType nodeType) {
491
492         var node1Bldr = new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Node1Builder()
493             .setXpdrAttributes(null);
494         var node2Bldr = new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
495             .setNodeType(nodeType);
496         SupportingNode supportingNode = new SupportingNodeBuilder()
497             .setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID))
498             .setNodeRef(new NodeId("node1"))
499             .withKey(new SupportingNodeKey(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID),
500                 new NodeId("node1")))
501             .build();
502
503         return new NodeBuilder()
504             .setNodeId(new NodeId(nodeId))
505             .withKey(new NodeKey(new NodeId(nodeId)))
506             .setSupportingNode(ImmutableMap.of(supportingNode.key(), supportingNode))
507             .addAugmentation(node1Bldr.build())
508             .addAugmentation(node2Bldr.build())
509             .build();
510     }
511
512     public static PathComputationRequestInput getPCE1Request(Uint32 rate, ServiceFormat serviceFormat, String aaNodeId,
513                 String aaClliId, String aaPortName, String zzNodeId, String zzClliId, String zzPortName) {
514
515         return new PathComputationRequestInputBuilder()
516             .setServiceName("service1")
517             .setResourceReserve(true)
518             .setPceRoutingMetric(PceMetric.HopCount)
519             .setServiceHandlerHeader(new ServiceHandlerHeaderBuilder()
520                 .setRequestId("request1")
521                 .build())
522             .setServiceAEnd(new ServiceAEndBuilder()
523                 .setServiceFormat(serviceFormat)
524                 .setServiceRate(Uint32.valueOf(100))
525                 .setClli(aaClliId)
526                 .setNodeId(aaNodeId)
527                 .setTxDirection(new TxDirectionBuilder()
528                     .setPort(new PortBuilder()
529                         .setPortDeviceName(aaNodeId)
530                         .setPortType("fixed")
531                         .setPortName(aaPortName)
532                         .setPortRack("Some port-rack")
533                         .setPortShelf("Some port-shelf")
534                         .setPortSlot("Some port-slot")
535                         .setPortSubSlot("Some port-sub-slot")
536                         .build())
537                     .build())
538                 .setRxDirection(new RxDirectionBuilder()
539                     .setPort(new PortBuilder()
540                         .setPortDeviceName(aaNodeId)
541                         .setPortType("fixed")
542                         .setPortName(aaPortName)
543                         .setPortRack("Some port-rack")
544                         .setPortShelf("Some port-shelf")
545                         .setPortSlot("Some port-slot")
546                         .setPortSubSlot("Some port-sub-slot")
547                         .build())
548                     .build())
549                 .build())
550             .setServiceZEnd(new ServiceZEndBuilder()
551                 .setServiceFormat(serviceFormat)
552                 .setServiceRate(Uint32.valueOf(0))
553                 .setClli(zzClliId)
554                 .setNodeId(zzNodeId)
555                 .setTxDirection(new TxDirectionBuilder()
556                     .setPort(new PortBuilder()
557                         .setPortDeviceName(zzNodeId)
558                         .setPortType("fixed")
559                         .setPortName(zzPortName)
560                         .setPortRack("Some port-rack")
561                         .setPortShelf("Some port-shelf")
562                         .setPortSlot("Some port-slot")
563                         .setPortSubSlot("Some port-sub-slot")
564                         .build())
565                     .build())
566                 .setRxDirection(new RxDirectionBuilder()
567                     .setPort(new PortBuilder()
568                         .setPortDeviceName(zzNodeId)
569                         .setPortType("fixed")
570                         .setPortName(zzPortName)
571                         .setPortRack("Some port-rack")
572                         .setPortShelf("Some port-shelf")
573                         .setPortSlot("Some port-slot")
574                         .setPortSubSlot("Some port-sub-slot")
575                         .build())
576                     .build())
577                 .build())
578             .setHardConstraints(new HardConstraintsBuilder()
579                 .setCustomerCode(Set.of("Some customer-code"))
580                 .setCoRouting(new CoRoutingBuilder()
581                     .setServiceIdentifierList(Map.of(
582                         new org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.co
583                                 .routing.ServiceIdentifierListKey("Some existing-service"),
584                         new ServiceIdentifierListBuilder().setServiceIdentifier("Some existing-service").build()))
585                     .build())
586                 .build())
587             .setSoftConstraints(new SoftConstraintsBuilder()
588                 .setCustomerCode(Set.of("Some customer-code"))
589                 .setCoRouting(new CoRoutingBuilder()
590                     .setServiceIdentifierList(Map.of(
591                         new org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.co
592                                 .routing.ServiceIdentifierListKey("Some existing-service"),
593                         new ServiceIdentifierListBuilder().setServiceIdentifier("Some existing-service").build()))
594                     .build())
595                 .build())
596             .build();
597     }
598
599     public static PathComputationRequestInput getPCE2Request(Uint32 rate, ServiceFormat serviceFormat, String aaNodeId,
600         String aaClliId, String aaPortName, String zzNodeId, String zzClliId, String zzPortName) {
601
602         return new PathComputationRequestInputBuilder()
603             .setServiceName("service1")
604             .setResourceReserve(true)
605             .setPceRoutingMetric(PceMetric.HopCount)
606             .setServiceHandlerHeader(new ServiceHandlerHeaderBuilder()
607                 .setRequestId("request1")
608                 .build())
609             .setServiceAEnd(new ServiceAEndBuilder()
610                 .setServiceFormat(serviceFormat)
611                 .setServiceRate(Uint32.valueOf(100))
612                 .setClli(aaClliId)
613                 .setNodeId(aaNodeId)
614                 .setTxDirection(new TxDirectionBuilder()
615                   .build())
616                 .setRxDirection(new RxDirectionBuilder()
617                     .build())
618                 .build())
619             .setServiceZEnd(new ServiceZEndBuilder()
620                 .setServiceFormat(serviceFormat)
621                 .setServiceRate(Uint32.valueOf(0))
622                 .setClli(zzClliId)
623                 .setNodeId(zzNodeId)
624                 .setTxDirection(new TxDirectionBuilder()
625                     .build())
626                 .setRxDirection(new RxDirectionBuilder()
627                     .build())
628                 .build())
629             .setHardConstraints(new HardConstraintsBuilder()
630                 .setCustomerCode(Set.of("Some customer-code"))
631                 .setCoRouting(new CoRoutingBuilder()
632                     .setServiceIdentifierList(Map.of(
633                         new org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.co
634                                 .routing.ServiceIdentifierListKey("Some existing-service"),
635                         new ServiceIdentifierListBuilder().setServiceIdentifier("Some existing-service").build()))
636                     .build())
637                 .build())
638             .setSoftConstraints(new SoftConstraintsBuilder()
639                 .setCustomerCode(Set.of("Some customer-code"))
640                 .setCoRouting(new CoRoutingBuilder()
641                     .setServiceIdentifierList(Map.of(
642                         new org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constraints.rev211210.constraints.co
643                                 .routing.ServiceIdentifierListKey("Some existing-service"),
644                         new ServiceIdentifierListBuilder().setServiceIdentifier("Some existing-service").build()))
645                     .build())
646                 .build())
647                     .build();
648     }
649
650 }