cc78a78f869b3a1c52af5a981265542b627596ec
[transportpce.git] / pce / src / test / java / org / opendaylight / transportpce / pce / gnpy / GnpyUtilitiesImplTest.java
1 /*
2  * Copyright © 2020 Orange Labs, 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 package org.opendaylight.transportpce.pce.gnpy;
9
10
11 import static org.junit.jupiter.api.Assertions.assertFalse;
12 import static org.junit.jupiter.api.Assertions.assertNotNull;
13 import static org.junit.jupiter.api.Assertions.assertNull;
14 import static org.junit.jupiter.api.Assertions.fail;
15
16 import com.google.gson.stream.JsonReader;
17 import java.io.FileNotFoundException;
18 import java.io.FileReader;
19 import java.io.IOException;
20 import java.io.Reader;
21 import java.net.URI;
22 import java.nio.charset.StandardCharsets;
23 import java.util.Map;
24 import java.util.concurrent.ExecutionException;
25 import org.glassfish.grizzly.http.server.HttpServer;
26 import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
27 import org.glassfish.jersey.server.ResourceConfig;
28 import org.junit.jupiter.api.AfterAll;
29 import org.junit.jupiter.api.BeforeAll;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Test;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.transportpce.common.NetworkUtils;
34 import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
35 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
36 import org.opendaylight.transportpce.pce.constraints.PceConstraintsCalc;
37 import org.opendaylight.transportpce.pce.gnpy.consumer.GnpyConsumer;
38 import org.opendaylight.transportpce.pce.gnpy.consumer.GnpyConsumerImpl;
39 import org.opendaylight.transportpce.pce.gnpy.consumer.GnpyStub;
40 import org.opendaylight.transportpce.pce.utils.JsonUtil;
41 import org.opendaylight.transportpce.pce.utils.PceTestData;
42 import org.opendaylight.transportpce.test.AbstractTest;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirectionBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirectionBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
46 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZKey;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToA;
49 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToABuilder;
50 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToAKey;
51 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.Resource;
52 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.ResourceBuilder;
53 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPoint;
54 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPointBuilder;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.opendaylight.yangtools.yang.common.QName;
61 import org.opendaylight.yangtools.yang.common.Uint32;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65 public class GnpyUtilitiesImplTest extends AbstractTest {
66
67     private static final Logger LOG = LoggerFactory.getLogger(GnpyUtilitiesImplTest.class);
68     private GnpyUtilitiesImpl gnpyUtilitiesImpl;
69     private NetworkTransactionImpl networkTransaction;
70     private static HttpServer httpServer;
71     private GnpyConsumer gnpyConsumer;
72
73     public GnpyUtilitiesImplTest() throws IOException {
74         networkTransaction = new NetworkTransactionImpl(getDataBroker());
75         JsonReader networkReader = null;
76         JsonReader topoReader = null;
77
78         try {
79             // load openroadm-network
80             Reader gnpyNetwork = new FileReader("src/test/resources/gnpy/gnpy_network.json",
81                     StandardCharsets.UTF_8);
82
83             networkReader = new JsonReader(gnpyNetwork);
84             Networks networks = (Networks) JsonUtil.getInstance().getDataObjectFromJson(networkReader,
85                     QName.create("urn:ietf:params:xml:ns:yang:ietf-network", "2018-02-26", "networks"));
86             saveOpenRoadmNetwork(networks.getNetwork().values().iterator().next(), NetworkUtils.UNDERLAY_NETWORK_ID);
87             // load openroadm-topology
88             Reader gnpyTopo = new FileReader("src/test/resources/gnpy/gnpy_topology.json",
89                     StandardCharsets.UTF_8);
90             topoReader = new JsonReader(gnpyTopo);
91             networks = (Networks) JsonUtil.getInstance().getDataObjectFromJson(topoReader,
92                     QName.create("urn:ietf:params:xml:ns:yang:ietf-network", "2018-02-26", "networks"));
93             saveOpenRoadmNetwork(networks.getNetwork().values().iterator().next(), NetworkUtils.OVERLAY_NETWORK_ID);
94         } catch (FileNotFoundException | InterruptedException | ExecutionException e) {
95             LOG.error("Cannot init test ", e);
96             fail("Cannot init test ");
97
98         } finally {
99             try {
100                 if (networkReader != null) {
101                     networkReader.close();
102                 }
103                 if (topoReader != null) {
104                     topoReader.close();
105                 }
106             } catch (IOException e) {
107                 LOG.warn("Cannot close reader ", e);
108             }
109         }
110
111     }
112
113     @BeforeEach
114     void initConsumer() {
115         gnpyConsumer = new GnpyConsumerImpl("http://localhost:9998", "mylogin", "mypassword",
116                 getDataStoreContextUtil().getBindingDOMCodecServices());
117     }
118
119     @BeforeAll
120     static void init() {
121         // here we cannot use JerseyTest as we already extends AbstractTest
122         final ResourceConfig rc = new ResourceConfig(GnpyStub.class);
123         httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create("http://localhost:9998"), rc);
124     }
125
126     @AfterAll
127     static void tearDown() {
128         httpServer.shutdownNow();
129     }
130
131     private void saveOpenRoadmNetwork(Network network, String networkId)
132             throws InterruptedException, ExecutionException {
133         InstanceIdentifier<Network> nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
134                 .child(Network.class, new NetworkKey(new NetworkId(networkId))).build();
135         networkTransaction.put(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier, network);
136         networkTransaction.commit().get();
137     }
138
139     @Test
140     void askNewPathFromGnpyNullResultTest() throws Exception {
141         gnpyUtilitiesImpl = new GnpyUtilitiesImpl(networkTransaction,
142                 PceTestData.getGnpyPCERequest("XPONDER-1", "XPONDER-2"),
143                 gnpyConsumer);
144         assertNull(gnpyUtilitiesImpl.askNewPathFromGnpy(null), "No hard constraints should be available");
145     }
146
147     @Test
148     void askNewPathFromGnpyTest() throws Exception {
149         gnpyUtilitiesImpl = new GnpyUtilitiesImpl(networkTransaction,
150                 PceTestData.getGnpyPCERequest("XPONDER-3", "XPONDER-4"),
151                 gnpyConsumer);
152         PceConstraintsCalc constraints = new PceConstraintsCalc(PceTestData.getPCE_simpletopology_test1_request(),
153                 networkTransaction);
154         PceConstraints pceHardConstraints = constraints.getPceHardConstraints();
155         assertNotNull(gnpyUtilitiesImpl.askNewPathFromGnpy(pceHardConstraints), "Hard constraints should be available");
156     }
157
158     @Test
159     void verifyComputationByGnpyTest() throws Exception {
160         // build AtoZ
161         AToZDirectionBuilder atoZDirectionBldr = buildAtZ();
162         // build ZtoA
163         ZToADirectionBuilder ztoADirectionBldr = buildZtoA();
164
165         gnpyUtilitiesImpl = new GnpyUtilitiesImpl(networkTransaction,
166                 PceTestData.getGnpyPCERequest("XPONDER-1", "XPONDER-2"),
167                 gnpyConsumer);
168         PceConstraintsCalc constraints = new PceConstraintsCalc(PceTestData.getPCE_simpletopology_test1_request(),
169                 networkTransaction);
170         PceConstraints pceHardConstraints = constraints.getPceHardConstraints();
171         boolean result = gnpyUtilitiesImpl.verifyComputationByGnpy(atoZDirectionBldr.build(),
172                 ztoADirectionBldr.build(),
173                 pceHardConstraints);
174         assertFalse(result, "Gnpy Computation should be false");
175     }
176
177     private AToZDirectionBuilder buildAtZ() {
178         AToZKey clientKey = new AToZKey("key");
179         TerminationPoint stp = new TerminationPointBuilder()
180                 .setTpId("tpName").setTpNodeId("xname")
181                 .build();
182         Resource clientResource = new ResourceBuilder().setResource(stp).build();
183         AToZ firstResource = new AToZBuilder().setId("tpName").withKey(clientKey).setResource(clientResource).build();
184         return new AToZDirectionBuilder()
185                 .setRate(Uint32.valueOf(100))
186                 .setAToZ(Map.of(firstResource.key(),firstResource))
187                 .setAToZWavelengthNumber(Uint32.valueOf(0));
188     }
189
190     private ZToADirectionBuilder buildZtoA() {
191         ZToAKey clientKey = new ZToAKey("key");
192         TerminationPoint stp = new TerminationPointBuilder()
193                 .setTpId("tpName").setTpNodeId("xname")
194                 .build();
195         Resource clientResource = new ResourceBuilder().setResource(stp).build();
196         ZToA firstResource = new ZToABuilder().setId("tpName").withKey(clientKey).setResource(clientResource).build();
197         return new ZToADirectionBuilder()
198                 .setRate(Uint32.valueOf(100))
199                 .setZToA(Map.of(firstResource.key(),firstResource))
200                 .setZToAWavelengthNumber(Uint32.valueOf(0));
201     }
202 }