From 33f02861873bc037807d40ad5f9946d87983f76b Mon Sep 17 00:00:00 2001 From: Martial COULIBALY Date: Fri, 20 Oct 2017 11:04:26 +0200 Subject: [PATCH] Stubpce Update (FakePCE implementation) This implementation is only for test purposes and allows to load PCE topology from xml file. This commit includes : - Add java package 'org.opendaylight.transportpce.stubpce.topology' which implements java classes for getting topology elements from xml file and build path descriptions List. - This file 'fakepce.xml' must be in src/main/resources to be loaded in target/classes and must also follow 'SuperNode' model (cf fakepce.xml). - change 'leaf node-id' in case termination-point in model yang transportpce-pathDescription by 'leaf tp-node-id' to not interfere with 'leaf node-id' in case node. - Add PathDescriptionList in stubpce yang model to stored all possible paths in datastore. - update servicehandler dependency - move stubpce and stubrenderer to tests folder - add dependency 'Version update to 1.6 of the service-path model'. Change-Id: I29391cc098706c261d109f8f1860bbfd78012c69 Signed-off-by: Martial COULIBALY Signed-off-by: Olivier RENAIS (cherry picked from commit 730925ab6a616aef3cc2f5b8b190774fa5708407) --- ...ansportpce-pathDescription@2017-04-26.yang | 2 +- .../transportpce-service-path@2017-04-26.yang | 21 + tests/stubpce/pom.xml | 46 + .../stubpce/CheckCoherencyHardSoft.java | 55 + .../transportpce/stubpce/CompliancyCheck.java | 17 +- .../stubpce/LoggingFuturesCallBack.java | 41 + .../transportpce/stubpce/MyEndpoint.java | 59 + .../transportpce/stubpce/SendingPceRPCs.java | 1055 +++++++++++++---- .../stubpce/StubpceCompliancyCheck.java | 102 ++ .../stubpce/StubpceTxRxCheck.java | 195 +++ .../transportpce/stubpce/TpNodeTp.java | 152 +++ .../stubpce/impl/StubpceImpl.java | 648 ++++++++-- .../stubpce/impl/StubpceProvider.java | 22 +- .../stubpce/topology/InterNodePath.java | 554 +++++++++ .../topology/LogicalConnectionPoint.java | 68 ++ .../stubpce/topology/Network.java | 92 ++ .../stubpce/topology/NodeLinkNode.java | 117 ++ .../stubpce/topology/NodePath.java | 357 ++++++ .../transportpce/stubpce/topology/Path.java | 72 ++ .../topology/PathDescriptionsOrdered.java | 56 + .../stubpce/topology/Resource.java | 115 ++ .../stubpce/topology/RoadmToRoadm.java | 68 ++ .../stubpce/topology/SuperNode.java | 125 ++ .../stubpce/topology/SuperNodePath.java | 731 ++++++++++++ .../stubpce/topology/Topology.java | 111 ++ tests/stubpce/src/main/resources/fakepce.xml | 198 ++++ .../blueprint/Stubpce-blueprint.xml | 18 +- 27 files changed, 4760 insertions(+), 337 deletions(-) create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CheckCoherencyHardSoft.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/LoggingFuturesCallBack.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/MyEndpoint.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceCompliancyCheck.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceTxRxCheck.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/TpNodeTp.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/InterNodePath.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/LogicalConnectionPoint.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Network.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodeLinkNode.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodePath.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Path.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/PathDescriptionsOrdered.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Resource.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/RoadmToRoadm.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNode.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNodePath.java create mode 100644 tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Topology.java create mode 100644 tests/stubpce/src/main/resources/fakepce.xml diff --git a/api/src/main/yang/service_path/transportpce-pathDescription@2017-04-26.yang b/api/src/main/yang/service_path/transportpce-pathDescription@2017-04-26.yang index d9d4de0aa..dff1bd49b 100644 --- a/api/src/main/yang/service_path/transportpce-pathDescription@2017-04-26.yang +++ b/api/src/main/yang/service_path/transportpce-pathDescription@2017-04-26.yang @@ -60,7 +60,7 @@ module transportpce-pathDescription { leaf tp-id { type string; //to be clarified with topology model } - leaf node-id { + leaf tp-node-id { type string; //to be clarified with topology model } } diff --git a/api/src/main/yang/service_path/transportpce-service-path@2017-04-26.yang b/api/src/main/yang/service_path/transportpce-service-path@2017-04-26.yang index dd517b4b0..41022a306 100644 --- a/api/src/main/yang/service_path/transportpce-service-path@2017-04-26.yang +++ b/api/src/main/yang/service_path/transportpce-service-path@2017-04-26.yang @@ -140,6 +140,27 @@ module transportpce-servicepath { uses transportpce-common-service-path-types:service-path; } } + + grouping stubpce-path-description { + leaf path-name { + type string; + description + "Identifier for the pathDescription to be created in + the ROADM network, e.g., CLFI, CLCI, etc."; + mandatory true; + } + uses transportpce-pathDescription:path-description; + } + + container path-description-list { + description + "List of pathDescription. Can only be created, deleted, modified, etc. using special RPCs."; + list pathDescriptions { + key "path-name"; + uses stubpce-path-description; + } + } + notification service-path-rpc-result { description "This Notification indicates result of service RPC"; diff --git a/tests/stubpce/pom.xml b/tests/stubpce/pom.xml index 48ae3cfa0..f4e5341b4 100644 --- a/tests/stubpce/pom.xml +++ b/tests/stubpce/pom.xml @@ -26,6 +26,21 @@ Author: Martial Coulibaly on behalf of Orange 0.2.0-SNAPSHOT bundle + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/main/resources + + + + + + ${project.groupId} @@ -50,5 +65,36 @@ Author: Martial Coulibaly on behalf of Orange mockito-core test + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + com.fasterxml.woodstox + woodstox-core + 5.0.3 + + + org.codehaus.woodstox + stax2-api + diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CheckCoherencyHardSoft.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CheckCoherencyHardSoft.java new file mode 100644 index 000000000..bae514fb1 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CheckCoherencyHardSoft.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce; + +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraints; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraints; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class to check coherency between hard and soft constraints. + * @author Martial Coulibaly on + * behalf of Orange + * + */ +public class CheckCoherencyHardSoft { + /** Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(CheckCoherencyHardSoft.class); + /** Hard Constraints. */ + private HardConstraints hard; + /** Soft Constraints. */ + private SoftConstraints soft; + + public CheckCoherencyHardSoft(HardConstraints hard, SoftConstraints soft) { + this.hard = hard; + this.soft = soft; + } + + /** + * function to check coherency between hard and soft constraints. + * @return true if coherent + * false else + */ + public boolean check() { + boolean result = false; + if (hard != null && soft != null) { + /** + * Check coherency with hard/soft constraints + * hard/soft include/exclude coherency + * + */ + } else { + LOG.info("HardConstraints or/and SoftConstraints is null !"); + result = true; + } + return result; + } + +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java index 12d2b0dee..ccbc5ea24 100644 --- a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java @@ -9,20 +9,21 @@ package org.opendaylight.transportpce.stubpce; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Class to check RPCs Compliancy. + * * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange * */ public class CompliancyCheck { - /* Logging. */ + /** Logging. */ private static final Logger LOG = LoggerFactory.getLogger(CompliancyCheck.class); - /* Response message from procedure. */ + /** Response message from procedure. */ private String message; private PathComputationRequestInput input; @@ -31,7 +32,7 @@ public class CompliancyCheck { input = prcInput; } - /* + /** * Check if a String is not * null and not equal to ''. * @@ -48,6 +49,14 @@ public class CompliancyCheck { } + /** + * check if service name + * or ServiceHandlerHeader + * is set in RPC request. + * + * @return true if settings is ok, + * false if not + */ public Boolean check() { Boolean result = true; if (input != null) { diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/LoggingFuturesCallBack.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/LoggingFuturesCallBack.java new file mode 100644 index 000000000..7738ceb51 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/LoggingFuturesCallBack.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce; + +import com.google.common.util.concurrent.FutureCallback; +import org.slf4j.Logger; + +/** + * Class to log future logging from datastore actions (write, modify, delete..). + * @author Martial Coulibaly on + * bealf of Orange + */ +public class LoggingFuturesCallBack implements FutureCallback { + + private Logger log; + private String message; + + public LoggingFuturesCallBack(String message, Logger log) { + this.message = message; + this.log = log; + } + + @Override + public void onFailure(Throwable ex) { + log.warn(message, ex); + + } + + @Override + public void onSuccess(V arg0) { + log.info("Success! {} ", arg0); + + } + +} \ No newline at end of file diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/MyEndpoint.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/MyEndpoint.java new file mode 100644 index 000000000..87758df52 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/MyEndpoint.java @@ -0,0 +1,59 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce; + +import java.util.Map; + +/** + * Enum class to identify ServiceAEnd and serviceZEnd. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +enum MyEndpoint { + SERVICEAEND(1), + SERVICEZEND(2); + + int value; + private static final Map VALUE_MAP; + + MyEndpoint(int value) { + this.value = value; + } + + static { + final com.google.common.collect.ImmutableMap.Builder b = + com.google.common.collect.ImmutableMap.builder(); + for (MyEndpoint enumItem : MyEndpoint.values()) { + b.put(enumItem.value, enumItem); + } + + VALUE_MAP = b.build(); + } + + /** + * Get integer value. + * + * @return integer value. + */ + public int getIntValue() { + return value; + } + + /** + * Get Endpoint value. + * + * @param valueArg + * Integer to identify Enum + * @return corresponding ServiceFormat item + */ + public static MyEndpoint forValue(int valueArg) { + return VALUE_MAP.get(valueArg); + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java index 0ad88a6e5..ad867bde6 100644 --- a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java @@ -9,26 +9,52 @@ package org.opendaylight.transportpce.stubpce; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; + import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.transportpce.stubpce.topology.PathDescriptionsOrdered; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.Resource; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node; -import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.NodeBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.General; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Diversity; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Exclude; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraints; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraints; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.handler.header.ServiceHandlerHeaderBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.ServiceAEnd; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.ServiceZEnd; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveInput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionList; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathList; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptions; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePaths; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,223 +63,793 @@ import org.slf4j.LoggerFactory; * PCE requests : * - path-computation-request * - cancel-resource-reserve. - * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * @author Martial Coulibaly on behalf of Orange * */ public class SendingPceRPCs { - - /* Logging. */ + /** Logging. */ private static final Logger LOG = LoggerFactory.getLogger(SendingPceRPCs.class); - /* define procedure success (or not ). */ private Boolean success; - /* define type of request
- * true pathcomputation
- * false cancelresourcereserve .*/ - private AToZDirection atozdirection; - private ZToADirection ztoadirection; + private PathComputationRequestInput input; + private CancelResourceReserveInput cancelInput; private PathDescriptionBuilder pathDescription; - + private DataBroker db; + private String error; + private final ListeningExecutorService executor; + private List servicePathList; public SendingPceRPCs() { success = true; - atozdirection = null; - ztoadirection = null; setPathDescription(null); + setError(""); + executor = null; + setServicePathList(new ArrayList()); + } + + public SendingPceRPCs(PathComputationRequestInput input,DataBroker databroker,ListeningExecutorService executor) { + success = true; + setPathDescription(null); + setInput(input); + setCancelInput(null); + setDb(databroker); + setError(""); + servicePathList = readServicePathList(); + this.executor = executor; + } + + public SendingPceRPCs(CancelResourceReserveInput input,DataBroker databroker,ListeningExecutorService executor) { + success = true; + setPathDescription(null); + setInput(null); + setCancelInput(input); + setDb(databroker); + setError(""); + servicePathList = readServicePathList(); + this.executor = executor; + } + + /** + * Compare AEnd and ZEnd resource Node to + * AEnd and ZEnd String. + * + * @param pathAend AEnd resource Node + * @param pathZend ZEnd resource Node + * @param inputAend AEnd String Node + * @param inputZend ZEnd String Node + * @return Boolean result true if equal, false if not + */ + private Boolean comp(Resource pathAend, Resource pathZend, String inputAend, String inputZend) { + Boolean result = false; + if (pathAend != null && pathZend != null && inputAend != null && inputZend != null) { + if (pathAend instanceof Node && pathZend instanceof Node) { + Node aend = (Node) pathAend; + Node zend = (Node) pathZend; + if (aend.getNodeId().compareToIgnoreCase(inputAend) == 0) { + if (zend.getNodeId().compareToIgnoreCase(inputZend) == 0) { + result = true; + } + } + } + } + return result; + } + + /** + * Compare two resource. + * + * @param res1 first resource + * @param res2 second resource + * @return Boolean result true if equal, false if not + */ + private Boolean egalResource(Resource res1, Resource res2) { + LOG.info("comparing resource ..."); + Boolean result = false; + LOG.info(res1.getClass().getName() + " - " + res2.getClass().getName()); + if (res1.getClass().getName().compareToIgnoreCase(res2.getClass().getName()) == 0) { + if (res1 instanceof Node && res2 instanceof Node) { + Node node1 = (Node)res1; + Node node2 = (Node)res2; + if (node1.getNodeId().compareTo(node2.getNodeId()) == 0) { + result = true; + } + } + if (res1 instanceof TerminationPoint && res2 instanceof TerminationPoint) { + TerminationPoint tp1 = (TerminationPoint)res1; + TerminationPoint tp2 = (TerminationPoint)res2; + if (tp1.getTpNodeId().compareTo(tp2.getTpNodeId()) == 0) { + if (tp1.getTpId().compareTo(tp2.getTpId()) == 0) { + result = true; + } + } + } + if (res1 instanceof Link && res2 instanceof Link) { + Link link1 = (Link)res1; + Link link2 = (Link)res2; + if (link1.getLinkId().compareTo(link2.getLinkId()) == 0) { + result = true; + } + + } + } + return result; + } + + /** + * compare two AtoZDirection. + * + * @param atoz1 first AToZDirection + * @param atoz2 second AToZDirection + * @return Boolean result true if equal, false if not + */ + private Boolean egalAtoZDirection(AToZDirection atoz1, AToZDirection atoz2) { + LOG.info("comparing AtoZDirection ..."); + Boolean result = true; + if (atoz1.getAToZ().size() == atoz2.getAToZ().size()) { + int index = 0; + int size = atoz1.getAToZ().size(); + LOG.info("size : " + size); + String id1 = null; + String id2 = null; + while (index < size) { + id1 = atoz1.getAToZ().get(index).getId(); + LOG.info("id : " + id1); + Resource res1 = atoz1.getAToZ().get(index).getResource().getResource(); + LOG.info("res1 : " + res1.toString()); + Resource res2 = null; + if (id1 != null) { + Boolean trouve = false; + for (int loop = 0;loop < size;loop++) { + id2 = atoz2.getAToZ().get(loop).getId(); + if (id2 != null && id2.compareTo(id1) == 0) { + res2 = atoz2.getAToZ().get(loop).getResource().getResource(); + LOG.info("res2 : " + res2.toString()); + trouve = true; + break; + } + } + if (trouve) { + if (!egalResource(res1, res2)) { + result = false; + break; + } + } + } else { + result = false; + break; + } + index++; + } + } else { + LOG.info("AToZDirection size is not equal !"); + result = false; + } + return result; + } + + /** + * compare two ZtoZDirection. + * + * @param ztoa1 first ZToZDirection + * @param ztoa2 second ZToZDirection + * @return Boolean result true if equal, false if not + */ + private Boolean egalZtoADirection(ZToADirection ztoa1, ZToADirection ztoa2) { + LOG.info("comparing ZtoADirection ..."); + Boolean result = true; + if (ztoa1.getZToA().size() == ztoa2.getZToA().size()) { + int index = 0; + int size = ztoa1.getZToA().size(); + LOG.info("size : " + size); + String id1 = null; + String id2 = null; + while (index < size) { + id1 = ztoa1.getZToA().get(index).getId(); + LOG.info("id : " + id1); + Resource res1 = ztoa1.getZToA().get(index).getResource().getResource(); + LOG.info("res1 : " + res1.toString()); + Resource res2 = null; + if (id1 != null) { + Boolean trouve = false; + for (int loop = 0;loop < size;loop++) { + id2 = ztoa2.getZToA().get(loop).getId(); + if (id2 != null && id2.compareTo(id1) == 0) { + res2 = ztoa2.getZToA().get(loop).getResource().getResource(); + LOG.info("res2 : " + res2.toString()); + trouve = true; + break; + } + } + if (trouve) { + if (!egalResource(res1, res2)) { + result = false; + break; + } + } + } else { + result = false; + break; + } + index++; + } + } else { + result = false; + } + return result; + } + + /** + * Test if resources Nodes + * not include in PathDescriptions. + * + * @param path PathDescriptions + * @param nodes Nodes List + * @return Boolean result true if found, false if not + */ + private Boolean excludeNode(PathDescriptions path, List nodes) { + LOG.info("Testing exclude Nodes ..."); + Boolean result = false; + if (path != null && !nodes.isEmpty()) { + List list = path.getAToZDirection().getAToZ(); + if (!list.isEmpty()) { + int index = 0; + boolean found = false; + while (index < list.size() && !found) { + Resource res = list.get(index).getResource().getResource(); + if (res != null && res instanceof Node) { + Node node = (Node) res; + for (String exclude : nodes) { + if (exclude.compareToIgnoreCase(node.getNodeId()) == 0) { + LOG.info("Node not excluded !"); + found = true; + break; + } + } + } + index++; + } + if (!found) { + result = true; + } + } + } else { + LOG.info("exclude parameters not corrrect !"); + } + return result; + } + + /** + * check if existing services not + * in pathDescriptions. + * + * + * @param existingService existing service list + * @param path PathDescriptions + * @param choice 0:Nodes, 1:Clli, 2:Srlg + * @return Boolean result true if found, false if not + */ + private Boolean diversityService(List existingService, PathDescriptions path, int choice) { + LOG.info("Testing diversity ..."); + Boolean result = false; + if (path != null && choice >= 0 && !existingService.isEmpty()) { + int index = 0; + while (index < existingService.size()) { + String tmp = existingService.get(index); + if (tmp != null) { + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service + .types.rev170426.service.path.PathDescription pathDesc = null; + if (servicePathList != null && !servicePathList.isEmpty()) { + for (ServicePaths service : servicePathList) { + if (service.getServicePathName().compareTo(tmp) == 0) { + LOG.info("Existing Service '" + tmp + "' found in ServicePathList ..."); + pathDesc = service.getPathDescription(); + } + } + } + if (pathDesc != null) { + switch (choice) { + case 0: //Nodes + LOG.info("Checking Node existing-service-applicability ..."); + if (!egalAtoZDirection(path.getAToZDirection(), pathDesc.getAToZDirection())) { + result = true; + break; + } + break; + case 1: //Clli + LOG.info("Checking clli existing-service-applicability ..."); + break; + + case 2: //Srlg + LOG.info("Checking srlg existing-service-applicability ..."); + + break; + default: + break; + } + } else { + LOG.info("Existing Service '" + tmp + "' not found in ServicePathList !"); + result = true; + } + if (!result) { + break; + } + } + index++; + } + } else { + LOG.info("Diversity parameters not coherent !"); + } + return result; + } + + /** + * test if pathDescription + * already exists in ServicePathList. + * + * @param path PathDescriptions + * @return Boolean result + */ + private Boolean testPathDescription(PathDescriptions path) { + LOG.info("Testing pathDescription ..."); + Boolean result = false; + if (path != null) { + LOG.info("retrieving path from servicePath List ..."); + try { + if (!servicePathList.isEmpty()) { + LOG.info("ServicePathList not empty, contains " + servicePathList.size() + " paths."); + for (ServicePaths service : servicePathList) { + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service + .types.rev170426.service.path.PathDescription tmp = service.getPathDescription(); + if (tmp != null) { + if (path.getAToZDirection() != null && tmp.getAToZDirection() != null + && egalAtoZDirection(path.getAToZDirection(), tmp.getAToZDirection())) { + if (path.getZToADirection() != null && tmp.getZToADirection() != null + && egalZtoADirection(path.getZToADirection(), tmp.getZToADirection())) { + result = true; + LOG.info("Path already present in servicePath List"); + break; + } else { + LOG.info("ZtoADirection not equal or one of ZtoADirection is null!"); + break; + } + } else { + LOG.info("AtoZDirection not equal !"); + break; + } + + } + } + } else { + LOG.info("ServicePathList is empty"); + } + } catch (NullPointerException e) { + LOG.error("ServicePathList is empty"); + } + } else { + LOG.info("PathDescriptions is null !"); + result = true; + } + LOG.info("testPathDescription result : " + result); + return result; + } + + /** + * function to retrieve Paths based on + * AEnd and ZEnd. + * + * @param aendNodeId Aend Node Id + * @param zendNodeId Zend Node Id + * @return result PathDescriptions List + */ + private List retrievePath(String aendNodeId, String zendNodeId) { + List result = new ArrayList(); + List paths = readPathDescriptionList(); + if (!paths.isEmpty() && aendNodeId != null && zendNodeId != null) { + LOG.info("retrieving paths from pathDescription List for " + aendNodeId + " / " + zendNodeId); + for (PathDescriptions tmp : paths) { + Resource pathAend = null; + Resource pathZend = null; + String id = null; + if (tmp != null) { + LOG.info("Getting Aend & ZEnd from path '" + tmp.getPathName() + "'..."); + int index = 0; + int size = tmp.getAToZDirection().getAToZ().size(); + while (index < size) { + id = tmp.getAToZDirection().getAToZ().get(index).getId(); + if (id.compareToIgnoreCase("1") == 0) { + Resource resource = tmp.getAToZDirection().getAToZ().get(index).getResource() + .getResource(); + LOG.info(resource.getClass().toString() + " : " + resource.toString()); + pathAend = resource; + break; + } + index++; + } + index = 0; + while (index < size) { + id = tmp.getZToADirection().getZToA().get(index).getId(); + if (id.compareToIgnoreCase("1") == 0) { + Resource resource = tmp.getZToADirection().getZToA().get(index).getResource() + .getResource(); + LOG.info(resource.toString()); + pathZend = resource; + break; + } + index++; + } + if (pathAend != null && pathZend != null) { + LOG.info("pathAend : " + pathAend + " - pathZend: " + pathZend); + LOG.info("aendNodeId : " + aendNodeId + " - zendNodeId : " + zendNodeId); + if (comp(pathAend, pathZend, aendNodeId, zendNodeId)) { + LOG.info("PathDescription found !"); + result.add(tmp); + } + } + } + } + } + return result; + } + + + /** + * found Pathdescriptions with + * name containing an expression. + * + * @param pathdescr PathDescriptions List + * @param contain String expression + * @return PathDescriptionsOrdered List + */ + private SortedSet foundpath(List pathdescr, String contain) { + SortedSet result = new TreeSet(); + ListIterator it = pathdescr.listIterator(); + int odr = 0; + while (it.hasNext()) { + PathDescriptions path = it.next(); + String name = path.getPathName(); + LOG.info("path : " + name); + if (name != null && name.contains(contain)) { + LOG.info(" path gets : " + name); + String [] split = name.split("_"); + if (split.length == 3) { + odr = Integer.parseInt(split[2]); + result.add(new PathDescriptionsOrdered(path, odr)); + } + } + } + return result; + } + + /** + * order PathDescriptions List + * with first, ordered direct links + * and secondly ordered indirect + * links. + * + * @param pathdescr PathDescriptions List + * @return PathDescriptions List ordered + */ + private List orderPathdescriptionsList(List pathdescr) { + SortedSet direct = new TreeSet(); + SortedSet indirect = new TreeSet(); + List result = new ArrayList(); + int size = pathdescr.size(); + if (size > 0) { + LOG.info("getting direct path first ..."); + direct = foundpath(pathdescr, "_direct_"); + LOG.info("getting indirect path first ..."); + indirect = foundpath(pathdescr, "_indirect_"); + } + if (direct.size() > 0) { + Iterator itset = direct.iterator(); + while (itset.hasNext()) { + result.add(itset.next().getPathDescriptions()); + } + if (indirect.size() > 0) { + Iterator itset2 = indirect.iterator(); + while (itset2.hasNext()) { + result.add(itset2.next().getPathDescriptions()); + } + } + + } else if (indirect.size() > 0) { + Iterator itset2 = indirect.iterator(); + while (itset2.hasNext()) { + result.add(itset2.next().getPathDescriptions()); + } + } + if (result.size() == pathdescr.size()) { + return result; + } else { + return null; + } + } + + public ListenableFuture cancelResourceReserve() { + LOG.info("In cancelResourceReserve request ..."); + setSuccess(false); + return executor.submit(new Callable() { + @Override + public Boolean call() throws Exception { + Boolean output = false; + if (cancelInput != null) { + Boolean found = false; + String name = cancelInput.getServiceName(); + if (name != null && !servicePathList.isEmpty()) { + for (ServicePaths service : servicePathList) { + if (name.compareTo(service.getServicePathName()) == 0) { + LOG.info("ServicePaths found in ServicePathList !!!"); + found = true; + break; + } + } + if (found) { + LOG.info("removing servicePaths from datastore ..."); + if (writeOrDeleteServicePathList(name,1)) { + LOG.info("Service deleted !"); + setSuccess(true); + output = true; + } else { + LOG.info("service deletion failed !"); + } + } + } else { + LOG.info("serviceName is null or servicePathList is empty !"); + } + } else { + LOG.info("cancelresourcereserveinput parameter not valid !"); + } + return output; + } + }); + } + + public ListenableFuture pathComputation() { + LOG.info("In pathComputation request ..."); + setSuccess(false); + return executor.submit(new Callable() { + @Override + public Boolean call() throws Exception { + Boolean output = false; + List pathsList = new ArrayList(); + PathDescriptions path = null; + int index ; + Boolean constraints = false; + if (input != null) { + HardConstraints inputHard = input.getHardConstraints(); + SoftConstraints inputSoft = input.getSoftConstraints(); + if (inputHard != null || inputSoft != null) { + constraints = true; + } + path = null; + pathsList = retrievePath(input.getServiceAEnd().getNodeId(), input.getServiceZEnd() + .getNodeId()); + index = 0; + output = false; + /** get pathList ordered. */ + pathsList = orderPathdescriptionsList(pathsList); + if (!pathsList.isEmpty()) { + LOG.info(pathsList.size() + " Paths get from Pathdescription List"); + index = 0; + output = false; + while (index < pathsList.size()) { + path = pathsList.get(index); + LOG.info("path n°" + index + " gets : '" + path.getPathName() + "'!"); + if (constraints) { + LOG.info("Calculating path with constraints ..."); + if (inputHard.getCoRoutingOrGeneral() instanceof General) { + General general = (General)inputHard.getCoRoutingOrGeneral(); + if (general != null) { + Diversity diversity = general.getDiversity(); + if (diversity != null) { + LOG.info("Getting diversity ..."); + List existingService = diversity.getExistingService(); + if (existingService.size() > 0) { + LOG.info("Getting existing service applicability ..."); + int choice = -1; + if (choice < 0 + && diversity.getExistingServiceApplicability().isNode()) { + LOG.info("existing-service-applicability : Node"); + choice = 0; + } + if (choice < 0 + && diversity.getExistingServiceApplicability().isClli()) { + LOG.info("existing-service-applicability : Clli"); + choice = 1; + } + if (choice < 0 + && diversity.getExistingServiceApplicability().isSrlg()) { + LOG.info("existing-service-applicability : Srlg"); + choice = 2; + } + if (!diversityService(existingService, path, choice)) { + error = "existing service applicability not satisfied"; + LOG.info(error); + path = null; + } + } + } + Exclude exclude = general.getExclude(); + if (exclude != null) { + LOG.info("Getting exclude ..."); + if (!excludeNode(path, exclude.getNodeId())) { + error = "Exclude node constraints not satisfied !"; + LOG.info(error); + path = null; + } + } + } + } + } + if (!testPathDescription(path)) { + LOG.info("Process finish !"); + output = true; + break; + } + index++; + } + } else { + LOG.info("failed to retrieve path from PathDescription List !"); + } + } else { + LOG.info("pathComputationRequestInput parameter not valid !"); + } + if (path != null) { + LOG.info("Path ok !"); + pathDescription = new PathDescriptionBuilder() + .setAToZDirection(path.getAToZDirection()) + .setZToADirection(path.getZToADirection()); + if (input.isResourceReserve()) { + LOG.info("reserving pce resource ..."); + setPathDescription(pathDescription); + if (writeOrDeleteServicePathList(input.getServiceName(), 0)) { + LOG.info("write ServicePaths to datastore"); + setSuccess(true); + } else { + LOG.error("writing ServicePaths to datastore failed ! "); + } + } else { + LOG.info("no pce resource reserve !"); + setSuccess(true); + } + } + return output; + } + }); } - public void cancelResourceReserve() { - LOG.info("Wait for 10s til beginning the PCE cancelResourceReserve request"); + + /** + * get all ServicePaths in ServicePathlist. + * + * @return ServicePaths List + */ + private List readServicePathList() { + LOG.info("Reading ServicePathList ..."); + List result = null; + ReadOnlyTransaction readTx = db.newReadOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class); + Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid); + Optional optional = Optional.absent(); try { - Thread.sleep(10000); //sleep for 10s - } catch (InterruptedException e) { - LOG.error(e.toString()); + optional = Futures.getChecked(future, ExecutionException.class, 60, TimeUnit.SECONDS); + } catch (ExecutionException e) { + LOG.error("Reading service failed:", e); + } + if (optional.isPresent()) { + LOG.info("ServicePath List present !"); + result = optional.get().getServicePaths(); } - LOG.info("cancelResourceReserve ..."); + return result; } - public void pathComputation() { - LOG.info("Wait for 10s til beginning the PCE pathComputation request"); + + private List readPathDescriptionList() { + LOG.info("Reading PathDescriptionsList ..."); + List result = null; + ReadOnlyTransaction readTx = db.newReadOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(PathDescriptionList.class); + Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid); + Optional optional = Optional.absent(); try { - Thread.sleep(10000); //sleep for 10s - } catch (InterruptedException e) { - LOG.error(e.toString()); + optional = Futures.getChecked(future, ExecutionException.class, 60, TimeUnit.SECONDS); + } catch (ExecutionException e) { + LOG.error("Reading service failed:", e); + } + if (optional.isPresent()) { + LOG.info("ServicePath List present !"); + result = optional.get().getPathDescriptions(); + } + return result; + + } + + /** + * Write or Delete ServicePaths + * for ServicePathList. + * + * @param serviceName Service Name + * @param choice 0 : write or 1 : delete + * @return Boolean result true if deleted, false if not + */ + private Boolean writeOrDeleteServicePathList(String serviceName, int choice) { + Boolean result = null; + if (serviceName != null && serviceName.compareTo(" ") != 0 && choice >= 0 && choice < 2) { + LOG.info("WriteOrDeleting '" + serviceName + "' ServicePaths"); + WriteTransaction writeTx = db.newWriteOnlyTransaction(); + result = true; + String action = null; + InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class) + .child(ServicePaths.class,new ServicePathsKey(serviceName)); + Future future = null; + switch (choice) { + case 0: /** Write. */ + LOG.info("Writing '" + serviceName + "' Service"); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service + .path.PathDescriptionBuilder path = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c + ._interface.service.types.rev170426.service.path.PathDescriptionBuilder(); + if (pathDescription != null) { + if (pathDescription.getAToZDirection() != null) { + path.setAToZDirection(pathDescription.getAToZDirection()); + } + if (pathDescription.getZToADirection() != null) { + path.setZToADirection(pathDescription.getZToADirection()); + } + LOG.info("pathdescription gets"); + } + ServiceAEnd aend = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c + ._interface.service.types.rev170426.service.path.ServiceAEndBuilder(input.getServiceAEnd()) + .build(); + ServiceZEnd zend = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c + ._interface.service.types.rev170426.service.path.ServiceZEndBuilder(input.getServiceZEnd()) + .build(); + ServicePaths service = new ServicePathsBuilder() + .setServicePathName(serviceName) + .setServiceHandlerHeader(new ServiceHandlerHeaderBuilder() + .setRequestId(input.getServiceHandlerHeader().getRequestId()).build()) + .setServiceAEnd(aend) + .setServiceZEnd(zend) + .setHardConstraints(input.getHardConstraints()) + .setSoftConstraints(input.getSoftConstraints()) + .setPathDescription(path.build()) + .build(); + LOG.info("Servicepath build"); + writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service); + action = "write"; + //CheckedFuture future = transaction.submit(); + future = writeTx.submit(); + try { + LOG.info("Sending '" + action + "' command to datastore !"); + Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Failed to " + action + " service from Service List"); + result = false; + } + break; + + case 1: /** Delete */ + LOG.info("Deleting '" + serviceName + "' Service"); + writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid); + action = "delete"; + future = writeTx.submit(); + try { + LOG.info("Sending '" + action + "' command to datastore !"); + Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Failed to " + action + " service from Service List"); + result = false; + } + break; + + default: + LOG.info("No choice found"); + break; + + } + + } else { + LOG.info("Parameters not correct !"); } - LOG.info("PathComputation ..."); - buildAToZ(); - buildZToA(); - - setPathDescription(new PathDescriptionBuilder() - .setAToZDirection(atozdirection) - .setZToADirection(ztoadirection)); - } - - public void buildAToZ() { - Link atoB = new LinkBuilder() - .setLinkId("AtoB") - .build(); - Link btoZ = new LinkBuilder() - .setLinkId("BtoZ") - .build(); - - Node roadmA = new NodeBuilder() - .setNodeId("RoadmA") - .build(); - Node roadmB = new NodeBuilder() - .setNodeId("RoadmB") - .build(); - Node roadmZ = new NodeBuilder() - .setNodeId("RoadmZ") - .build(); - - /*A -> Z*/ - /*RoadmA*/ - AToZKey roadmAKey = new AToZKey("RoadmA"); - Resource roadmAResource = new ResourceBuilder() - .setResource(roadmA) - .build(); - AToZ atoz = new AToZBuilder() - .setId("RoadmA") - .setKey(roadmAKey) - .setResource(roadmAResource) - .build(); - /*Link AtoB*/ - AToZKey atoBKey = new AToZKey("AtoB"); - Resource atozResource = new ResourceBuilder() - .setResource(atoB) - .build(); - AToZ atob = new AToZBuilder() - .setId("AtoB") - .setKey(atoBKey) - .setResource(atozResource) - .build(); - /*RoadmB*/ - AToZKey roadmBKey = new AToZKey("RoadmB"); - Resource roadmBResource = new ResourceBuilder() - .setResource(roadmB) - .build(); - AToZ roadmb = new AToZBuilder() - .setId("RoadmB") - .setKey(roadmBKey) - .setResource(roadmBResource) - .build(); - /*Link BtoZ*/ - AToZKey btoZKey = new AToZKey("BtoZ"); - Resource botzResource = new ResourceBuilder() - .setResource(btoZ) - .build(); - AToZ btoz = new AToZBuilder() - .setId("BtoZ") - .setKey(btoZKey) - .setResource(botzResource) - .build(); - /*RoadmZ*/ - AToZKey roadmZKey = new AToZKey("RoadmZ"); - Resource roadmZResource = new ResourceBuilder() - .setResource(roadmZ) - .build(); - AToZ roadmz = new AToZBuilder() - .setId("RoadmZ") - .setKey(roadmZKey) - .setResource(roadmZResource) - .build(); - - List atozList = new ArrayList(); - atozList.add(atoz); - atozList.add(atob); - atozList.add(roadmb); - atozList.add(btoz); - atozList.add(roadmz); - - atozdirection = new AToZDirectionBuilder() - .setRate((long)100) - .setAToZWavelengthNumber((long)200) - .setAToZ(atozList) - .build(); - } - - public void buildZToA() { - - Link btoA = new LinkBuilder() - .setLinkId("BtoA") - .build(); - Link ztoB = new LinkBuilder() - .setLinkId("ZtoB") - .build(); - - Node roadmA = new NodeBuilder() - .setNodeId("RoadmA") - .build(); - Node roadmB = new NodeBuilder() - .setNodeId("RoadmB") - .build(); - Node roadmZ = new NodeBuilder() - .setNodeId("RoadmZ") - .build(); - - /*Z -> A*/ - /*RoadmZ*/ - ZToAKey roadmZKey = new ZToAKey("RoadmZ"); - Resource roadmZResource = new ResourceBuilder() - .setResource(roadmZ) - .build(); - ZToA ztoa = new ZToABuilder() - .setId("RoadmZ") - .setKey(roadmZKey) - .setResource(roadmZResource) - .build(); - /*Link ZtoB*/ - ZToAKey ztoBKey = new ZToAKey("ZtoB"); - Resource ztoBResource = new ResourceBuilder() - .setResource(ztoB) - .build(); - ZToA ztob = new ZToABuilder() - .setId("ZtoB") - .setKey(ztoBKey) - .setResource(ztoBResource) - .build(); - /*RoadmB*/ - ZToAKey roadmBKey = new ZToAKey("RoadmB"); - Resource roadmBResource = new ResourceBuilder() - .setResource(roadmB) - .build(); - ZToA roadmb = new ZToABuilder() - .setId("RoadmB") - .setKey(roadmBKey) - .setResource(roadmBResource) - .build(); - /*Link BtoA*/ - ZToAKey btoAKey = new ZToAKey("BtoA"); - Resource btoAResource = new ResourceBuilder() - .setResource(btoA) - .build(); - ZToA btoa = new ZToABuilder() - .setId("BtoA") - .setKey(btoAKey) - .setResource(btoAResource) - .build(); - /* RoadmA*/ - ZToAKey roadmAKey = new ZToAKey("RoadmA"); - Resource roadmAResource = new ResourceBuilder() - .setResource(roadmA) - .build(); - ZToA roadma = new ZToABuilder() - .setId("RoadmA") - .setKey(roadmAKey) - .setResource(roadmAResource) - .build(); - - List ztoaList = new ArrayList(); - ztoaList.add(ztoa); - ztoaList.add(ztob); - ztoaList.add(roadmb); - ztoaList.add(btoa); - ztoaList.add(roadma); - - ztoadirection = new ZToADirectionBuilder() - .setRate((long)100) - .setZToAWavelengthNumber((long)100) - .setZToA(ztoaList) - .build(); + return result; } public PathDescriptionBuilder getPathDescription() { @@ -272,4 +868,43 @@ public class SendingPceRPCs { this.success = success; } + public PathComputationRequestInput getInput() { + return input; + } + + public void setInput(PathComputationRequestInput input) { + this.input = input; + } + + public CancelResourceReserveInput getCancelInput() { + return cancelInput; + } + + public void setCancelInput(CancelResourceReserveInput input) { + this.cancelInput = input; + } + + public DataBroker getDb() { + return db; + } + + public void setDb(DataBroker db) { + this.db = db; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public List getServicePathList() { + return servicePathList; + } + + public void setServicePathList(List servicePathList) { + this.servicePathList = servicePathList; + } } diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceCompliancyCheck.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceCompliancyCheck.java new file mode 100644 index 000000000..7353d9647 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceCompliancyCheck.java @@ -0,0 +1,102 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce; + +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ConnectionType; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.handler.header.ServiceHandlerHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class for checking service sdnc-request-header compliancy. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class StubpceCompliancyCheck { + /** Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(StubpceCompliancyCheck.class); + /** SdncRequestHeader. */ + private ServiceHandlerHeader serviceHandlerHeader; + /** Service Name. */ + private String serviceName; + /** Type of connection : service / infrastructure / roadm-line. */ + private ConnectionType conType; + /** Response message from procedure. */ + private String message; + + + public StubpceCompliancyCheck(String serviceName,ServiceHandlerHeader serviceHandlerHeader) { + this.serviceName = serviceName; + this.serviceHandlerHeader = serviceHandlerHeader; + this.setMessage(""); + } + + /** + * Check if a String is not null and not equal to void. + * + * @param value + * String value + * @return true if String ok false if not + */ + public Boolean checkString(String value) { + Boolean result = false; + if (value != null && value.compareTo("") != 0) { + result = true; + } + return result; + + } + + /** + * Check Compliancy of Service request. + * + * @param contype + * Boolean to check connection Type + * @param servicehandler + * Boolean to check sndcRequestHeader + * + * @return true if String ok false if not + */ + public Boolean check(Boolean contype, Boolean servicehandler) { + Boolean result = true; + if (!checkString(serviceName)) { + result = false; + message = "Service Name is not set"; + LOG.debug(message); + } else if (contype && conType == null) { + result = false; + message = "Service ConnectionType is not set"; + LOG.debug(message); + } + if (servicehandler) { + if (serviceHandlerHeader != null) { + String requestId = serviceHandlerHeader.getRequestId(); + if (!checkString(requestId)) { + result = false; + message = "Service serviceHandlerHeader 'request-id' is not set"; + LOG.debug(message); + } + } else { + result = false; + message = "Service serviceHandlerHeader is not set "; + LOG.debug(message); + } + } + return result; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceTxRxCheck.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceTxRxCheck.java new file mode 100644 index 000000000..a30190073 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceTxRxCheck.java @@ -0,0 +1,195 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce; + +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceFormat; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.lgx.Lgx; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.port.Port; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServiceEndpointSp; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.RxDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.TxDirection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class for checking missing info on Tx/Rx for A/Z end. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + */ +public class StubpceTxRxCheck { + /** Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(StubpceTxRxCheck.class); + /** ServiceEndpoint. */ + private ServiceEndpointSp serviceEnd; + /** Response message from procedure. */ + private String message; + /** type serviceEndpoint : serviceAEnd / serviceZEnd. */ + private String service = null; + + /** + * ServicehandlerTxRxCheck class constructor. + * + * @param endPoint + * ServiceEndpoint + * @param value + * Integer to define ServiceAEND/ZEND + */ + public StubpceTxRxCheck(ServiceEndpointSp endPoint, int value) { + this.serviceEnd = endPoint; + this.setMessage(""); + if (value > 0) { + service = MyEndpoint.forValue(value).name(); + } + } + + /** + * Check if a String is not null and not equal to ''. + * + * @param value + * String value + * @return true if String ok false if not + */ + public Boolean checkString(String value) { + Boolean result = false; + if (value != null && value.compareTo("") != 0) { + result = true; + } + return result; + + } + + /** + * check if Port info is compliant. + * + * @param port + * port info + * @return true if String ok false if not + */ + public Boolean checkPort(Port port) { + Boolean result = false; + if (port != null) { + String portDeviceName = port.getPortDeviceName(); + String portType = port.getPortType(); + String portName = port.getPortName(); + String portRack = port.getPortRack(); + String portShelf = port.getPortShelf(); + + if (checkString(portDeviceName) && checkString(portType) && checkString(portName) && checkString(portRack) + && checkString(portShelf)) { + result = true; + } + } + return result; + + } + + /** + * Check if lgx info is compliant. + * + * @param lgx + * lgx info + * @return true if String ok false if not + */ + public Boolean checkLgx(Lgx lgx) { + Boolean result = false; + if (lgx != null) { + String lgxDeviceName = lgx.getLgxDeviceName(); + String lgxPortName = lgx.getLgxPortName(); + String lgxPortRack = lgx.getLgxPortRack(); + String lgxPortShelf = lgx.getLgxPortShelf(); + if (checkString(lgxDeviceName) && checkString(lgxPortName) && checkString(lgxPortRack) + && checkString(lgxPortShelf)) { + result = true; + } + } + return result; + } + + /** + * Check if Tx/Rx Direction complaincy info. + * + * @param txDirection + * TxDirection + * @param rxDirection + * RxDirection + * + * @return true if check is ok false else + */ + public boolean checkTxOrRxInfo(TxDirection txDirection, RxDirection rxDirection) { + Boolean result = true; + if (txDirection != null) { + if (!checkPort(txDirection.getPort())) { + result = false; + message = "Service TxDirection Port is not correctly set"; + } else if (rxDirection != null) { + if (!checkPort(rxDirection.getPort())) { + result = false; + message = "Service RxDirection Port is not correctly set"; + } + } else { + result = false; + message = "Service RxDirection is not correctly set"; + } + } else { + result = false; + message = "Service TxDirection is not correctly set"; + } + return result; + } + + /** + * Check Compliancy of Service TxRx info. + * + * @return true if String ok false if not + */ + public Boolean check() { + Boolean result = true; + if (serviceEnd != null) { + Long serviceRate = serviceEnd.getServiceRate(); + ServiceFormat serviceformat = serviceEnd.getServiceFormat(); + String clli = serviceEnd.getClli(); + if (serviceRate != null && serviceRate <= 0) { + result = false; + message = "Service " + service + " rate is not set"; + LOG.info(message); + } else if (serviceformat == null) { + result = false; + message = "Service " + service + " format is not set"; + LOG.info(message); + } else if (!checkString(clli)) { + result = false; + message = "Service" + service + " clli format is not set"; + LOG.info(message); + } else { + if (!checkTxOrRxInfo(serviceEnd.getTxDirection(), serviceEnd.getRxDirection())) { + result = false; + } + } + } else { + result = false; + message = service + " is not set"; + LOG.info(message); + } + return result; + + } + + public static void main(String[] args) { + + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/TpNodeTp.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/TpNodeTp.java new file mode 100644 index 000000000..ebb2ac6b9 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/TpNodeTp.java @@ -0,0 +1,152 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce; + +import java.util.ArrayList; +import java.util.List; + +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint; + +/** + * Class to create structure + * TerminationPoint + * Node + * TerminationPoint. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +public class TpNodeTp { + private TerminationPoint tpOut; + private TerminationPoint tpIn; + private Node node; + private List resources; + private List atoz; + private List ztoa; + private List ids; + + /** + * TpNodeTp Constructor. + * + * @param in TerminationPoint input + * @param out TerminationPoint output + * @param node Node Id + */ + public TpNodeTp(TerminationPoint in, TerminationPoint out, Node node) { + this.tpOut = out; + this.tpIn = in; + this.node = node; + resources = new ArrayList(); + atoz = new ArrayList(); + ztoa = new ArrayList(); + ids = new ArrayList(); + + } + + /** + * create resource List. + */ + public void createListResource() { + ids.clear(); + resources.clear(); + atoz.clear(); + ztoa.clear(); + + resources.add(new ResourceBuilder().setResource(tpIn).build()); + ids.add(tpIn.getTpNodeId().concat("-").concat(tpIn.getTpId())); + resources.add(new ResourceBuilder().setResource(node).build()); + ids.add(node.getNodeId()); + resources.add(new ResourceBuilder().setResource(tpOut).build()); + ids.add(tpOut.getTpNodeId().concat("-").concat(tpOut.getTpId())); + } + + /** + * Create an hop in AtoZList. + * @param odr hop number + */ + public void createAToZListHop(int odr) { + AToZ hop = null; + AToZKey atozKey = null; + createListResource(); + for (Resource resource : resources) { + atozKey = new AToZKey(Integer.toString(odr)); + resource = new ResourceBuilder().setResource(resource.getResource()).build(); + hop = new AToZBuilder() + .setKey(atozKey) + .setResource(resource) + .build(); + atoz.add(hop); + odr++; + } + } + + /** + * Create an hop in ZtoAList. + * @param odr hop number + */ + public void createZToAListHop(int odr) { + ZToA hop = null; + ZToAKey ztoaKey = null; + createListResource(); + for (Resource resource : resources) { + ztoaKey = new ZToAKey(Integer.toString(odr)); + resource = new ResourceBuilder().setResource(resource.getResource()).build(); + hop = new ZToABuilder() + .setKey(ztoaKey) + .setResource(resource) + .build(); + ztoa.add(hop); + odr++; + } + } + + public TpNodeTp reverse() { + return new TpNodeTp(tpOut, tpIn, node); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("[ "); + result.append("tpIn : " + tpIn.getTpId()); + result.append(" - Node : " + node.getNodeId()); + result.append(" - tpOut : " + tpOut.getTpId()); + result.append(" ]"); + return result.toString(); + + } + + public List getAToZ() { + return atoz; + } + + public List getZToA() { + return ztoa; + } + + public Node getNode() { + return node; + } + + public TerminationPoint getTpIn() { + return tpIn; + } + + public TerminationPoint getTpOut() { + return tpOut; + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java index 41ac6e991..89d3404f7 100644 --- a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java @@ -6,166 +6,598 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.transportpce.stubpce.impl; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; + +import java.util.Iterator; +import java.util.SortedSet; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; import java.util.concurrent.Future; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; -import org.opendaylight.transportpce.stubpce.CompliancyCheck; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.transportpce.stubpce.CheckCoherencyHardSoft; import org.opendaylight.transportpce.stubpce.SendingPceRPCs; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveInput; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutput; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutputBuilder; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutput; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutputBuilder; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResult; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResultBuilder; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.rpc.result.PathDescription; +import org.opendaylight.transportpce.stubpce.StubpceCompliancyCheck; +import org.opendaylight.transportpce.stubpce.StubpceTxRxCheck; +import org.opendaylight.transportpce.stubpce.topology.PathDescriptionsOrdered; +import org.opendaylight.transportpce.stubpce.topology.SuperNodePath; +import org.opendaylight.transportpce.stubpce.topology.Topology; import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceList; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.Services; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesKey; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServicePathNotificationTypes; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveInput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveOutput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionList; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionListBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteInput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathList; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathListBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathRpcResult; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathRpcResultBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathService; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptions; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePaths; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.rpc.result.PathDescription; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** - * Class to implement - * StubpceService - * StubpceListener. - * - * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange - * + * Class to implement StubpceService StubpceListener. + * @author Martial Coulibaly on + * behalf of Orange */ -public class StubpceImpl implements StubpceService { - - /* Logging. */ +public class StubpceImpl implements TransportpceServicepathService { + /** Logging. */ private static final Logger LOG = LoggerFactory.getLogger(StubpceImpl.class); - - private CompliancyCheck compliancyCheck; - /* send notification. */ + /** Permit to access database. */ + private DataBroker db; + /** check service sdnc-request-header compliancy. */ + private StubpceCompliancyCheck compliancyCheck; + /** check missing info on Tx/Rx for A/Z end. */ + private StubpceTxRxCheck txrxCheck; + /** check coherency between hard and soft constraints. */ + private CheckCoherencyHardSoft checkCoherencyHardSoft; private NotificationPublishService notificationPublishService; private ServicePathRpcResult notification; + private PathDescriptionBuilder pathDescriptionBuilder; + private SendingPceRPCs sendingPCE; + private final ListeningExecutorService executor = MoreExecutors + .listeningDecorator(Executors.newFixedThreadPool(10)); - public StubpceImpl(NotificationPublishService notificationPublishService) { + public StubpceImpl(NotificationPublishService notificationPublishService, DataBroker databroker) { this.notificationPublishService = notificationPublishService; + this.db = databroker; + pathDescriptionBuilder = null; + if (initializePathDescriptionList(databroker)) { + fillPathDesciptionList(); + } + initializeServicePathList(databroker); + /*if (initializeServicePathList(databroker)) { + fillServicePathList(); + }*/ } @Override public Future> cancelResourceReserve(CancelResourceReserveInput input) { LOG.info("RPC cancelResourceReserve request received"); String message = ""; + String responseCode = ""; + ConfigurationResponseCommonBuilder configurationResponseCommon = null; + String serviceName = input.getServiceName(); + LOG.info("serviceName : " + serviceName); + if (serviceName != null) { + sendingPCE = new SendingPceRPCs(input,db,executor); + FutureCallback pceCallback = new FutureCallback() { + String message = ""; + ServicePathRpcResult notification = null; - notification = new ServicePathRpcResultBuilder() - .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve) - .setServiceName(input.getServiceName()) - .setStatus(RpcStatusEx.Pending) - .setStatusMessage("Service compliant, submitting cancelResourceReserve Request ...") - .build(); - try { - notificationPublishService.putNotification(notification); - } catch (InterruptedException e) { - LOG.info("notification offer rejected : " + e); - } + @Override + public void onFailure(Throwable arg0) { + LOG.error(arg0.toString()); + LOG.error("Cancel resource failed !"); + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed) + .setStatusMessage("Cancel resource request failed : " + arg0.getMessage()).build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + } + + @Override + public void onSuccess(Boolean response) { + LOG.info("response : " + response); + if (response) { + message = "Resource cancelled !"; + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful) + .setStatusMessage(message) + .build(); + } else { + message = sendingPCE.getError(); + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve) + .setServiceName("") + .setStatus(RpcStatusEx.Failed).setStatusMessage(message) + .build(); + message = "Cancel request failed !"; + } + LOG.info(notification.toString()); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + LOG.info(message); + } + }; + ListenableFuture pce = sendingPCE.cancelResourceReserve(); + Futures.addCallback(pce, pceCallback, executor); + LOG.info("Cancel Resource Request in progress ..."); + configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("No") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseMessage("Service compliant, Cancel resource request in progress...") + .setResponseCode("200"); + + CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon.build()); - SendingPceRPCs sendingPCE = new SendingPceRPCs(); - sendingPCE.cancelResourceReserve(); - if (sendingPCE.getSuccess()) { - message = "ResourceReserve cancelled ! "; + return RpcResultBuilder.success(output.build()).buildFuture(); } else { - message = "Cancelling ResourceReserve failed ! "; + message = "serviceName / requestId is not correct !"; + responseCode = "500"; + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed) + .setStatusMessage(message).build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } } - LOG.info(message); - ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder(); - configurationResponseCommon - .setAckFinalIndicator("Yes") - .setRequestId(input.getServiceHandlerHeader().getRequestId()) - .setResponseCode("200") - .setResponseMessage("") - .setResponseMessage(message); - CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder(); - output - .setConfigurationResponseCommon(configurationResponseCommon.build()); + configurationResponseCommon = new ConfigurationResponseCommonBuilder(); + configurationResponseCommon.setAckFinalIndicator("Yes") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseMessage(message) + .setResponseCode(responseCode).build(); + CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder(); + output.setConfigurationResponseCommon(configurationResponseCommon.build()); return RpcResultBuilder.success(output.build()).buildFuture(); } - @Override public Future> pathComputationRequest(PathComputationRequestInput input) { LOG.info("RPC pathcomputation request received"); String message = ""; - PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder(); - ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder(); + String responseCode = ""; + boolean coherencyHardSoft = false; + boolean commonId = true; + ConfigurationResponseCommonBuilder configurationResponseCommon = null; + compliancyCheck = new StubpceCompliancyCheck(input.getServiceName(), input.getServiceHandlerHeader()); + if (compliancyCheck.check(false, true)) { + LOG.info("Service compliant !"); + /** + * If compliant, service-request parameters are verified in order to + * check if there is no missing parameter that prevents calculating + * a path and implement a service. + */ + LOG.info("checking Tx/Rx Info for AEnd ..."); + txrxCheck = new StubpceTxRxCheck(input.getServiceAEnd(), 1); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for AEnd checked !"); + LOG.info("checking Tx/Rx Info for ZEnd ..."); + txrxCheck = new StubpceTxRxCheck(input.getServiceZEnd(), 2); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for ZEnd checked !"); + /** + * If OK, common-id is verified in order to see if there is + * no routing policy provided. If yes, the routing + * constraints of the policy are recovered and coherency + * with hard/soft constraints provided in the input of the + * RPC. + */ + if (input.getHardConstraints() != null || input.getSoftConstraints() != null) { + LOG.info("Constraints specified !"); + checkCoherencyHardSoft = new CheckCoherencyHardSoft(input.getHardConstraints(), + input.getSoftConstraints()); + if (checkCoherencyHardSoft.check()) { + LOG.info("hard/soft constraints coherent !"); + coherencyHardSoft = true; + } else { + LOG.info("hard/soft constraints are not coherent !"); + message = "hard/soft constraints are not coherent !"; + responseCode = "500"; + } + } else { + commonId = false; + } + if (!commonId || (commonId && coherencyHardSoft)) { + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, submitting pathComputation Request ...").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendingPCE = new SendingPceRPCs(input,db,executor); + FutureCallback pceCallback = new FutureCallback() { + String message = ""; + ServicePathRpcResult notification = null; - compliancyCheck = new CompliancyCheck(input); - if (!compliancyCheck.check()) { - configurationResponseCommon - .setAckFinalIndicator("Yes") - .setRequestId(input.getServiceHandlerHeader().getRequestId()) - .setResponseCode("Path not calculated") - .setResponseMessage(compliancyCheck.getMessage()); + @Override + public void onFailure(Throwable arg0) { + LOG.error("Failure message : " + arg0.toString()); + LOG.error("Path calculation failed !"); + notification = new ServicePathRpcResultBuilder() + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed) + .setStatusMessage("PCR Request failed : " + arg0.getMessage()).build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + } - output - .setConfigurationResponseCommon(configurationResponseCommon.build()) - .setResponseParameters(null); + @Override + public void onSuccess(Boolean response) { + LOG.info("response : " + response); + if (response) { + message = "Path Computated !"; + ServicePathRpcResultBuilder tmp = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful) + .setStatusMessage(message); + pathDescriptionBuilder = sendingPCE.getPathDescription(); + if (pathDescriptionBuilder != null) { + PathDescription pathDescription = new org.opendaylight.yang.gen.v1.http.org + .transportpce.b.c._interface.servicepath.rev170426.service.path + .rpc.result.PathDescriptionBuilder() + .setAToZDirection(pathDescriptionBuilder.getAToZDirection()) + .setZToADirection(pathDescriptionBuilder.getZToADirection()) + .build(); + tmp.setPathDescription(pathDescription); + } + notification = tmp.build(); + } else { + message = sendingPCE.getError(); + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) + .setServiceName("") + .setStatus(RpcStatusEx.Failed).setStatusMessage(message) + .build(); + message = "Path not calculated!"; + } + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + LOG.info(message); + } + }; + ListenableFuture pce = sendingPCE.pathComputation(); + Futures.addCallback(pce, pceCallback, executor); + LOG.info("PathComputation Request in progress ..."); + configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("No") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseMessage("Service compliant, Path calculating in progress...") + .setResponseCode("200"); - return RpcResultBuilder.success(output.build()).buildFuture(); - } - notification = new ServicePathRpcResultBuilder() - .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) - .setServiceName(input.getServiceName()) - .setStatus(RpcStatusEx.Pending) - .setStatusMessage("Service compliant, submitting pathComputation Request ...") - .build(); - try { - notificationPublishService.putNotification(notification); - } catch (InterruptedException e) { - LOG.info("notification offer rejected : " + e); - } + PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon.build()); + return RpcResultBuilder.success(output.build()).buildFuture(); + } - SendingPceRPCs sendingPCE = new SendingPceRPCs(); - sendingPCE.pathComputation(); - if (sendingPCE.getSuccess()) { - message = "Path Computated !"; - ServicePathRpcResultBuilder tmp = new ServicePathRpcResultBuilder() - .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) - .setServiceName(input.getServiceName()) - .setStatus(RpcStatusEx.Successful) - .setStatusMessage(message); - PathDescriptionBuilder path = sendingPCE.getPathDescription(); - if (path != null) { - PathDescription pathDescription = new org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce - .stubpce.rev170426.service.path.rpc.result.PathDescriptionBuilder() - .setAToZDirection(path.getAToZDirection()) - .setZToADirection(path.getZToADirection()) - .build(); - tmp.setPathDescription(pathDescription); + } else { + message = txrxCheck.getMessage(); + responseCode = "500"; + } + } else { + message = txrxCheck.getMessage(); + responseCode = "500"; } - notification = tmp.build(); + } else { + message = compliancyCheck.getMessage(); + responseCode = "500"; + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed) + .setStatusMessage("Service not compliant : " + message).build(); try { notificationPublishService.putNotification(notification); } catch (InterruptedException e) { LOG.info("notification offer rejected : " + e); } - } else { - message = "Path Computating failed !"; } - LOG.info(message); - configurationResponseCommon - .setAckFinalIndicator("Yes") - .setRequestId(input.getServiceHandlerHeader().getRequestId()) - .setResponseCode("200") - .setResponseMessage(message); - - output - .setConfigurationResponseCommon(configurationResponseCommon.build()); + configurationResponseCommon = new ConfigurationResponseCommonBuilder(); + configurationResponseCommon.setAckFinalIndicator("Yes") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseMessage(message) + .setResponseCode(responseCode).build(); + PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder(); + output.setConfigurationResponseCommon(configurationResponseCommon.build()); return RpcResultBuilder.success(output.build()).buildFuture(); } + + /** + * Initialize PathDescriptionList Structure on DataStore. + * + * @param DataBroker + * Access DataStore + */ + private boolean initializePathDescriptionList(DataBroker db) { + Boolean result = true; + LOG.info("Preparing to initialize the PathDescription List"); + WriteTransaction transaction = db.newWriteOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(PathDescriptionList.class); + PathDescriptionList pathDescriptionList = new PathDescriptionListBuilder().build(); + transaction.put(LogicalDatastoreType.OPERATIONAL, iid, pathDescriptionList); + Future future = transaction.submit(); + try { + Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Failed to create PathDescription List"); + result = false; + } + return result; + } + + /** + * Initialize ServicePathList Structure on DataStore. + * + * @param DataBroker + * Access DataStore + * @return true if ok, false else + */ + private boolean initializeServicePathList(DataBroker db) { + Boolean result = true; + LOG.info("Preparing to initialize the ServicePathList registry"); + WriteTransaction transaction = db.newWriteOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class); + ServicePathList servicePathList = new ServicePathListBuilder().build(); + transaction.put(LogicalDatastoreType.OPERATIONAL, iid, servicePathList); + Future future = transaction.submit(); + try { + Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Failed to create ServicePathList List : " + e.toString()); + result = false; + } + return result; + } + + /** + * fill PathDescriptionList + * with direct paths and + * indirect paths. + */ + private void fillPathDesciptionList() { + LOG.info("filling PathDescription List..."); + Topology topo = new Topology(); + topo.start(); + LOG.info("Network : " + topo.getNetwork()); + SuperNodePath superNodePath = new SuperNodePath(topo.getNetwork()); + String aend = "NodeA"; + String zend = "NodeZ"; + superNodePath.run(aend, zend); + fill(superNodePath.getDirectPathDesc(aend, zend, superNodePath.getPaths())); + fill(superNodePath.getIndirectPathDesc(aend, zend, superNodePath.getPaths())); + } + + /** + * fill datastore with + * Pathdescriptions List. + * + * @param sortedSet PathDescriptionsOrdered List + */ + private void fill(SortedSet sortedSet) { + InstanceIdentifier iid; + WriteTransaction writeTx; + Future future; + if (!sortedSet.isEmpty()) { + Iterator it = sortedSet.iterator(); + while (it.hasNext()) { + PathDescriptions pathDesc = it.next().getPathDescriptions(); + if (pathDesc != null) { + iid = InstanceIdentifier.create(PathDescriptionList.class) + .child(PathDescriptions.class, new PathDescriptionsKey(pathDesc.getPathName())); + writeTx = db.newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, pathDesc); + future = writeTx.submit(); + try { + Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Failed to write PathDescriptions to PathDescriptionsList : " + e.toString()); + } + } else { + LOG.error("PathDescriptions gets is null !"); + } + } + } else { + LOG.info("PathDescriptions List is empty !"); + } + } + + /** + * read Service from ServiceList DataStore. + * + * @param serviceName + * Name of Service + * + * @return Services + */ + @SuppressWarnings("unused") + private Services readServiceList(String serviceName) { + Services result = null; + ReadOnlyTransaction readTx = db.newReadOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(ServiceList.class).child(Services.class, + new ServicesKey(serviceName)); + Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid); + Optional optional = Optional.absent(); + try { + optional = Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Reading service failed:", e); + } + if (optional.isPresent()) { + LOG.debug("Service '" + serviceName + "' present !"); + result = new ServicesBuilder(optional.get()).build(); + } + return result; + } + + /** + * read ServicePath Service from ServicePathList DataStore. + * + * @param serviceName + * Name of ServicePath + * + * @return Services + */ + @SuppressWarnings("unused") + private ServicePaths readServicePathList(String serviceName) { + ServicePaths result = null; + ReadOnlyTransaction readTx = db.newReadOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class) + .child(ServicePaths.class, new ServicePathsKey(serviceName)); + Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid); + Optional optional = Optional.absent(); + try { + optional = Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Reading service failed:", e); + } + if (optional.isPresent()) { + LOG.debug("Service '" + serviceName + "' present !"); + result = new ServicePathsBuilder(optional.get()).build(); + } + return result; + } + + /** + * read PathDescription information from PathDescriptionList. + * + * @param pathName + * Name of PathDescription + * + * @return PathDescriptions + */ + @SuppressWarnings("unused") + private PathDescriptions readPathDescriptionList(String pathName) { + PathDescriptions result = null; + ReadOnlyTransaction readTx = db.newReadOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(PathDescriptionList.class) + .child(PathDescriptions.class, new PathDescriptionsKey(pathName)); + Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid); + Optional optional = Optional.absent(); + try { + optional = Futures.getChecked(future, ExecutionException.class); + } catch (ExecutionException e) { + LOG.error("Reading service failed:", e); + } + if (optional.isPresent()) { + LOG.debug("PathDescritions '" + pathName + "' present !"); + result = new PathDescriptionsBuilder(optional.get()).build(); + } + return result; + } + + /** + * register ServicePath Service to ServicePathList with PathDescription + * information. + * + * @param input + * PathComputationRequestInput + * @return String operations result, null if ok or not otherwise + */ + @SuppressWarnings("unused") + private String writeServicePathList(PathComputationRequestInput input) { + String serviceName = input.getServiceName(); + LOG.debug("Write ServicePath '" + serviceName + "' Service"); + String result = null; + LOG.debug("Writing '" + serviceName + "' ServicePath"); + InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class) + .child(ServicePaths.class, new ServicePathsKey(serviceName)); + + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service + .path.PathDescriptionBuilder path = new org.opendaylight.yang.gen.v1.http.org.transportpce + .b.c._interface.service.types.rev170426.service.path.PathDescriptionBuilder(); + path.setAToZDirection(pathDescriptionBuilder.getAToZDirection()); + path.setZToADirection(pathDescriptionBuilder.getZToADirection()); + ServicePaths service = new ServicePathsBuilder().setServicePathName(input.getServiceName()) + .setSoftConstraints(input.getSoftConstraints()).setHardConstraints(input.getHardConstraints()) + .setPathDescription(path.build()).build(); + WriteTransaction writeTx = db.newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service); + Future future = writeTx.submit(); + try { + Futures.getChecked(future, ExecutionException.class); + result = null; + } catch (ExecutionException e) { + LOG.error("Failed to write service to Service List"); + result = "Failed to write service to Service List"; + } + return result; + } + + public PathDescriptionBuilder getPathDescriptionBuilder() { + return pathDescriptionBuilder; + } + + public void setPathDescriptionBuilder(PathDescriptionBuilder pathDescriptionBuilder) { + this.pathDescriptionBuilder = pathDescriptionBuilder; + } + + @Override + public Future> serviceImplementationRequest( + ServiceImplementationRequestInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> serviceDelete(ServiceDeleteInput input) { + // TODO Auto-generated method stub + return null; + } } diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java index 0b1fe228e..9ef48f373 100644 --- a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java @@ -9,12 +9,13 @@ package org.opendaylight.transportpce.stubpce.impl; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; import org.opendaylight.controller.md.sal.binding.api.NotificationService; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceListener; -import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathListener; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathService; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,23 +23,24 @@ import org.slf4j.LoggerFactory; /** * Class to register * Stubpce Service and Notification. - * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * @author Martial Coulibaly on behalf of Orange * */ public class StubpceProvider { private static final Logger LOG = LoggerFactory.getLogger(StubpceProvider.class); private final RpcProviderRegistry rpcRegistry; private final NotificationPublishService notificationPublishService; + private final DataBroker dataBroker; - private BindingAwareBroker.RpcRegistration rpcRegistration; - private ListenerRegistration stubPcelistenerRegistration; + private BindingAwareBroker.RpcRegistration rpcRegistration; + private ListenerRegistration stubPcelistenerRegistration; - public StubpceProvider(RpcProviderRegistry rpcProviderRegistry, - NotificationService notificationService, - NotificationPublishService notificationPublishService) { + public StubpceProvider(RpcProviderRegistry rpcProviderRegistry,final DataBroker dataBroker, + NotificationService notificationService, NotificationPublishService notificationPublishService) { this.rpcRegistry = rpcProviderRegistry; this.notificationPublishService = notificationPublishService; + this.dataBroker = dataBroker; } /** @@ -46,8 +48,8 @@ public class StubpceProvider { */ public void init() { LOG.info("StubpceProvider Session Initiated"); - final StubpceImpl consumer = new StubpceImpl(notificationPublishService); - rpcRegistration = rpcRegistry.addRpcImplementation(StubpceService.class, consumer); + final StubpceImpl consumer = new StubpceImpl(notificationPublishService,dataBroker); + rpcRegistration = rpcRegistry.addRpcImplementation(TransportpceServicepathService.class, consumer); } /** diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/InterNodePath.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/InterNodePath.java new file mode 100644 index 000000000..b1bd4239a --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/InterNodePath.java @@ -0,0 +1,554 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.stubpce.topology; + +import com.google.common.collect.Lists; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +import org.opendaylight.transportpce.stubpce.TpNodeTp; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * class to build all path between superNode elements + * ( XPDR and ROADM). + * + * @author Martial Coulibaly on + * behalf of Orange + */ + +public class InterNodePath { + /** Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(InterNodePath.class); + private SuperNode superNode; + private List nodepaths; + private List atoz; + private List ztoa; + + /** + * InterNodePath constructor. + * + * @param supernode Supernode + */ + public InterNodePath(SuperNode supernode) { + setSuperNode(supernode); + setNodepaths(new ArrayList()); + setAtoz(new ArrayList()); + setZtoa(new ArrayList()); + } + + /** + * build AToZdirection. + * + * @param paths Path List + */ + private void getAToZDirection(List paths) { + int order = 0; + AToZDirectionBuilder atozDirection = new AToZDirectionBuilder(); + List atozList = new ArrayList(); + TpNodeTp tpNodeTp; + for (Path path : paths) { + tpNodeTp = path.getTpNodeTp(); + tpNodeTp.createAToZListHop(order); + for (AToZ atoz : tpNodeTp.getAToZ()) { + atozList.add(atoz); + order++; + } + Link link = path.getLink(); + AToZKey atozKey = new AToZKey(Integer.toString(order)); + Resource resource = new ResourceBuilder().setResource(link).build(); + AToZ hop = new AToZBuilder().setId(atozKey.getId()).setKey(atozKey).setResource(resource).build(); + atozList.add(hop); + order++; + } + atozDirection.setRate((long) 100).setAToZWavelengthNumber((long) 200).setAToZ(atozList); + atoz.add(atozDirection.build()); + } + + /** + * build ZToAdirection. + * + * @param paths Path List + */ + private void getZToADirection(List paths) { + int order = 0; + ZToADirectionBuilder ztoaDirection = new ZToADirectionBuilder(); + List ztoaList = new ArrayList(); + TpNodeTp tpNodeTp; + for (Path path : paths) { + tpNodeTp = path.getTpNodeTp(); + tpNodeTp.createZToAListHop(order); + for (ZToA ztoa : tpNodeTp.getZToA()) { + ztoaList.add(ztoa); + order++; + } + Link link = path.getLink(); + ZToAKey ztoaKey = new ZToAKey(Integer.toString(order)); + Resource resource = new ResourceBuilder().setResource(link).build(); + ZToA hop = new ZToABuilder().setId(ztoaKey.getId()).setKey(ztoaKey).setResource(resource).build(); + ztoaList.add(hop); + order++; + } + ztoaDirection.setRate((long) 100).setZToAWavelengthNumber((long) 200).setZToA(ztoaList); + ztoa.add(ztoaDirection.build()); + } + + /** + * Build direction path + * for all Supernode elements. + * + * @param skip Boolean to specify an ROADM without XPDR + * @param nodeId Supernode element nodeId + * @param zend Supernode path ZEnd nodeId + */ + public void build(Boolean skip, String nodeId,String zend) { + LOG.info("Building direction ..."); + if (skip) { + buildDegToDeg(false); + buildDegToDeg(true); + } else { + boolean reverse = false; + if (nodeId.contains(zend)) { + reverse = true; + } + NodePath xpdr = null; + NodePath srg = null; + NodePath deg1 = null; + NodePath deg2 = null; + for (NodePath node : nodepaths) { + //LOG.info(node.toString()); + String id = node.getNodeId(); + if (id.contains("XPDR")) { + xpdr = node; + } + if (id.contains("SRG")) { + srg = node; + } + if (id.contains("DEG1")) { + deg1 = node; + } + if (id.contains("DEG2")) { + deg2 = node; + } + } + buildXpdrToSrgToDeg(xpdr,srg,deg1,deg2,reverse); + buildDegToSrgToXpdr(xpdr,srg,deg1,deg2,reverse); + } + } + + /** + * build direction path for + * Supernode element DEG1, DEG2. + * + * @param twotoOne boolean to determine direction + */ + private void buildDegToDeg(boolean twotoOne) { + LOG.info("buildDegToDeg ..."); + NodePath deg1 = null; + NodePath deg2 = null; + for (NodePath node : nodepaths) { + //LOG.info(node.toString()); + String nodeId = node.getNodeId(); + if (nodeId.contains("DEG1")) { + deg1 = node; + } + if (nodeId.contains("DEG2")) { + deg2 = node; + } + } + if (deg1 != null && deg2 != null) { + List result = new ArrayList(); + NodePath deb = deg1; + NodePath end = deg2; + if (twotoOne) { + deb = deg2; + end = deg1; + } + for (Path deg1Path : deb.getPath()) { + TpNodeTp tmpdeg = deg1Path.getTpNodeTp(); + if (tmpdeg.getTpIn().getTpId().contains("TTP")) { + result.clear(); + result.addAll(Lists.newArrayList(deg1Path)); + if (!twotoOne) { + getAToZDirection(result); + } else { + getZToADirection(result); + } + } + } + for (Path deg2Path : end.getPath()) { + TpNodeTp tmpdeg = deg2Path.getTpNodeTp(); + if (tmpdeg.getTpIn().getTpId().contains("CTP")) { + result.clear(); + result.addAll(Lists.newArrayList(deg2Path)); + if (!twotoOne) { + getAToZDirection(result); + } else { + getZToADirection(result); + } + } + } + } else { + LOG.info("deg1 or/and deg2 is null !"); + } + } + + /** + build direction from + *Degree to SRG to XPDR + *in Supernode elements. + * + *@param xpdr NodePath XPDR + *@param srg NodePath SRG + *@param deg NodePath Degree + *@param reverse boolean to determine the direction + */ + private void buildDeg(NodePath xpdr,NodePath srg,NodePath deg, Boolean reverse) { + List result = new ArrayList(); + for (Path degPath : deg.getPath()) { + TpNodeTp tmpdeg = degPath.getTpNodeTp(); + if (tmpdeg.getTpIn().getTpId().contains("TTP")) { + for (Path srgPath : srg.getPath()) { + TpNodeTp tmpsrg = srgPath.getTpNodeTp(); + if (tmpsrg.getTpIn().getTpId().contains("CP")) { + for (Path xpdrPath : xpdr.getPath()) { + TpNodeTp tmpxpdr = xpdrPath.getTpNodeTp(); + if (tmpxpdr.getTpIn().getTpId().contains("NETWORK")) { + result.clear(); + result.addAll(Lists.newArrayList(degPath,srgPath,xpdrPath)); + if (reverse) { + getAToZDirection(result); + } else { + getZToADirection(result); + } + } + } + } + } + } + } + } + + /** + *build direction from + *DEG1 / DEG2 to SRG to XPDR + *in Supernode elements. + * + *@param xpdr NodePath XPDR + *@param srg NodePath SRG + *@param deg1 NodePath Degree 1 + *@param deg2 NodePath Degree 2 + *@param reverse boolean to determine the direction + */ + private void buildDegToSrgToXpdr(NodePath xpdr,NodePath srg,NodePath deg1,NodePath deg2,boolean reverse) { + LOG.info("buildDegToSrgToXpr ..."); + if (xpdr != null && srg != null && deg1 != null && deg2 != null) { + buildDeg(xpdr, srg, deg1, reverse); + buildDeg(xpdr, srg, deg2, reverse); + } else { + LOG.info("xpdr, deg or/and srg is null !"); + } + } + + /** + *build direction from + *XPDR to SRG to DEG + *in Supernode elements. + * + *@param xpdr NodePath XPDR + *@param srg NodePath SRG + *@param deg1 NodePath Degree 1 + *@param deg2 NodePath Degree 2 + *@param reverse boolean to determine the direction + */ + private void buildXpdrToSrgToDeg(NodePath xpdr,NodePath srg,NodePath deg1,NodePath deg2,boolean reverse) { + LOG.info("buildXpdrToSrgToDeg ..."); + if (xpdr != null && srg != null && deg1 != null && deg2 != null) { + List result = new ArrayList(); + for (Path xpdrPath : xpdr.getPath()) { + TpNodeTp tmpxpdr = xpdrPath.getTpNodeTp(); + if (tmpxpdr.getTpIn().getTpId().contains("CLIENT")) { + for (Path srgPath : srg.getPath()) { + TpNodeTp tmp = srgPath.getTpNodeTp(); + Link srglink = srgPath.getLink(); + if (tmp.getTpIn().getTpId().contains("PP")) { + for (Path deg1Path : deg1.getPath()) { + TpNodeTp tmpdeg = deg1Path.getTpNodeTp(); + if (tmpdeg.getTpIn().getTpId().contains("CTP") + && srglink.getLinkId().contains("DEG1")) { + result.clear(); + result.addAll(Lists.newArrayList(xpdrPath,srgPath,deg1Path)); + if (reverse) { + getZToADirection(result); + } else { + getAToZDirection(result); + } + } + } + for (Path deg2Path : deg2.getPath()) { + TpNodeTp tmpdeg = deg2Path.getTpNodeTp(); + if (tmpdeg.getTpIn().getTpId().contains("CTP") + && srglink.getLinkId().contains("DEG2")) { + result.clear(); + result.addAll(Lists.newArrayList(xpdrPath,srgPath,deg2Path)); + if (reverse) { + getZToADirection(result); + } else { + getAToZDirection(result); + } + } + } + } + } + } + } + } else { + LOG.info("xpdr, deg or/and srg is null !"); + } + } + + /** + * get all AToZdirection containing + * a list of AToZ end by + * a String. + * + * @param endBy String + * @param atozDirection AToZdirection List + * @param index Integer to determine if it for last Link(1) or last TerminationPoint(2) + * @return AToZDirection List + */ + public List getAToZDirectionEndBy(String endBy, List atozDirection, int index) { + List result = new ArrayList(); + for (AToZDirection tmp : atozDirection) { + List atozList = tmp.getAToZ(); + int size = atozList.size(); + if (size > 2) { + String id = Integer.toString(size - index); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription + .rev170426.pce.resource.resource.Resource res = null; + for (AToZ atoz : atozList) { + if (atoz.getId().compareTo(id) == 0) { + res = atoz.getResource().getResource(); + if (res != null) { + + switch (index) { + case 1: //last link + if (res instanceof Link) { + Link tp = (Link) res; + if (tp != null && tp.getLinkId().contains(endBy)) { + result.add(tmp); + } + } + break; + + case 2: //last tp + if (res instanceof TerminationPoint) { + TerminationPoint tp = (TerminationPoint) res; + if (tp != null && tp.getTpId().contains(endBy)) { + result.add(tmp); + } + } + break; + + default : + break; + } + } + } + } + } else { + LOG.info("firstnodeTpId is null !"); + } + } + LOG.info("getAToZDirectionEndBy result size : " + result.size() + "\n " + result.toString()); + return result; + } + + /** + * replace or remove in + * Link in AToZ list + * containing in AToZdirection. + * + * @param endBy String + * @param beginBy String + * @param atozLink name of ROAMDTOROAMD link + * @param atozDirection AToZdirection List + * @param remove boolean to determine if removing or not + * @return AToZDirection List + */ + public List replaceOrRemoveAToZDirectionEndLink(String endBy,String beginBy,String atozLink, + List atozDirection, boolean remove) { + List result = new ArrayList(); + List tmp = new ArrayList(); + if (remove) { + tmp = getAToZDirectionEndBy(endBy, atozDirection, 1); + if (!tmp.isEmpty()) { + tmp = getAToZDirectionBeginBy(beginBy, tmp); + } + } else { + tmp = getAToZDirectionEndBy(endBy, atozDirection,2); + } + if (!tmp.isEmpty()) { + for (AToZDirection atozdir : tmp) { + List atozList = atozdir.getAToZ(); + int size = atozList.size(); + if (size > 0) { + String id = Integer.toString(size - 1); + for (ListIterator it = atozList.listIterator(); it.hasNext();) { + AToZ atoz = it.next(); + if (atoz.getId().compareTo(id) == 0) { + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription + .rev170426.pce.resource.resource.Resource res = atoz.getResource().getResource(); + if (res != null && res instanceof Link) { + Link link = new LinkBuilder() + .setLinkId(atozLink) + .build(); + AToZKey atozKey = new AToZKey(atoz.getKey()); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .pathdescription.rev170426.pce.resource.Resource resource = new ResourceBuilder() + .setResource(link).build(); + AToZ hop = new AToZBuilder().setId(atozKey.getId()).setKey(atozKey) + .setResource(resource).build(); + it.remove(); + if (!remove) { + it.add(hop); + } + result.add(atozdir); + } + } + } + } + } + } else { + LOG.info("getAToZDirectionEndBy size " + tmp.size()); + } + return result; + } + + /** + *get all AToZdirection containing + * a list of AToZ begin by + * a String. + * + * @param beginBy String + * @param atozDirection AToZdirection List + * @return AToZDirection List + */ + public List getAToZDirectionBeginBy(String beginBy, List atozDirection) { + List result = new ArrayList(); + for (AToZDirection tmp : atozDirection) { + List atozList = tmp.getAToZ(); + int size = atozList.size(); + if (size > 0) { + String id = Integer.toString(0); + for (AToZ atoz : atozList) { + if (atoz.getId().compareTo(id) == 0) { + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription + .rev170426.pce.resource.resource.Resource res = atoz.getResource().getResource(); + if (res != null && res instanceof TerminationPoint) { + TerminationPoint tp = (TerminationPoint) res; + if (tp != null && tp.getTpId().contains(beginBy)) { + LOG.info("tmp : " + tmp.toString()); + result.add(tmp); + } + } + } + } + } + } + LOG.info("result size : " + result.size()); + return result; + } + + /** + * first launch process to + * build/fill NodePath + * And after that, start building + * direction between Supernode + * elements. + * + * @param zend path zend Supernode nodeId + */ + public void buildPath(String zend) { + if (superNode != null) { + for (org.opendaylight.transportpce.stubpce.topology.Resource res : superNode.getResources()) { + NodePath path = new NodePath(res, superNode.getSuperNodeId(), superNode.isXpdrSrgAbsent()); + path.fill(); + nodepaths.add(path); + } + LOG.info("nodepaths size : " + nodepaths.size()); + build(superNode.isXpdrSrgAbsent(),superNode.getSuperNodeId(), zend); + } + } + + public static void main(String[] args) { + Topology topo = new Topology(); + topo.start(); + Network net = topo.getNetwork(); + if (net != null) { + SuperNode res = net.getSuperNodes().get(0); + String zend = "NodeZ"; + LOG.info(res.getSuperNodeId().toString()); + InterNodePath path = new InterNodePath(res); + path.buildPath(zend); + } + } + + public SuperNode getSuperNode() { + return superNode; + } + + public void setSuperNode(SuperNode superNode) { + this.superNode = superNode; + } + + public List getAtoz() { + return atoz; + } + + public void setAtoz(List atoz) { + this.atoz = atoz; + } + + public List getZtoa() { + return ztoa; + } + + public void setZtoa(List ztoa) { + this.ztoa = ztoa; + } + + public List getNodepaths() { + return nodepaths; + } + + public void setNodepaths(List nodepaths) { + this.nodepaths = nodepaths; + } + +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/LogicalConnectionPoint.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/LogicalConnectionPoint.java new file mode 100644 index 000000000..45da247f1 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/LogicalConnectionPoint.java @@ -0,0 +1,68 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + + +/** + * class to build Logical + * Connection Point. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +@JacksonXmlRootElement(localName = "logical-connection-point") +public class LogicalConnectionPoint { + @JacksonXmlProperty(localName = "tp-id") + private String tpId; + @JacksonXmlProperty(localName = "node-id") + private String nodeId; + + public LogicalConnectionPoint(@JacksonXmlProperty(localName = "tp-id") final String tpId, + @JacksonXmlProperty(localName = "node-id") final String nodeId) { + this.setTpId(tpId); + this.setNodeId(nodeId); + } + + public String getTpId() { + return tpId; + } + + public void setTpId(String tpId) { + this.tpId = tpId; + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + @Override + public String toString() { + java.lang.String name = "["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + if (tpId != null) { + builder.append("tpId="); + builder.append(tpId); + builder.append(", "); + } + if (nodeId != null) { + builder.append("nodeId="); + builder.append(nodeId); + } + return builder.append(']').toString(); + + } + +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Network.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Network.java new file mode 100644 index 000000000..1849cba84 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Network.java @@ -0,0 +1,92 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +import java.util.List; + +/** + * Class to create topology + * structure according to the idea of + * SuperNode. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +@JacksonXmlRootElement(localName = "network") +public class Network { + /** SuperNode List.*/ + @JacksonXmlElementWrapper(localName = "super-nodes") + @JacksonXmlProperty(localName = "super-node") + private List superNodes; + /** Links between Supernodes. */ + @JacksonXmlProperty(localName = "roadm-to-roadm") + private RoadmToRoadm roadmToroadm; + + /** + * Network constructor. + * + * @param nodes Supernode list + * @param links roadmtoroadm links + */ + public Network( + @JacksonXmlProperty(localName = "Nsupernode") final List nodes, + @JacksonXmlProperty(localName = "roadm-to-roadm") final RoadmToRoadm links) { + setSuperNodes(nodes); + setRoadmToroadm(links); + } + + public List getSuperNodes() { + return superNodes; + } + + public void setSuperNodes(List superNodes) { + this.superNodes = superNodes; + } + + + public RoadmToRoadm getRoadmToroadm() { + return roadmToroadm; + } + + public void setRoadmToroadm(RoadmToRoadm roadmToroadm) { + this.roadmToroadm = roadmToroadm; + } + + @Override + public String toString() { + int index; + int size; + java.lang.String name = "Network ["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + index = 0; + size = superNodes.size(); + builder.append("SuperNodes ["); + if (size > 0) { + for (SuperNode tmp : superNodes) { + builder.append(tmp.toString()); + index++; + if (index < size) { + builder.append(", "); + } + } + } + builder.append("]"); + if (roadmToroadm != null) { + builder.append(", roadmToroadm="); + builder.append(roadmToroadm.toString()); + } + return builder.append(']').toString(); + + } + +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodeLinkNode.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodeLinkNode.java new file mode 100644 index 000000000..07faa034d --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodeLinkNode.java @@ -0,0 +1,117 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import java.util.List; + +/** + * Class to create structure + * NodeToLinkToNode. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +public class NodeLinkNode { + /** aend first endpoint. */ + private String aend; + /** zend second endpoint. */ + private String zend; + /** atoz link. */ + private List atozLink; + /** ztoa link. */ + private List ztoaLink; + /** direct boolean to specify direct path. */ + private Boolean direct; + + /** + * NodeLinkNode Constructor. + * + * @param aend first endpoint + * @param zend second endpoint + * @param link1 atoz link + * @param link2 ztoa link + * @param direct boolean to specify direct path + */ + public NodeLinkNode(String aend, String zend, List link1, List link2,Boolean direct) { + setAend(aend); + setZend(zend); + setAtozLink(link1); + setZtoaLink(link2); + setDirect(direct); + } + + public Boolean getDirect() { + return direct; + } + + public void setDirect(Boolean direct) { + this.direct = direct; + } + + public String getAend() { + return aend; + } + + public void setAend(String aend) { + this.aend = aend; + } + + public String getZend() { + return zend; + } + + public void setZend(String zend) { + this.zend = zend; + } + + @Override + public String toString() { + java.lang.String name = "NodeLinkNode ["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + if (aend != null) { + builder.append("aend="); + builder.append(aend); + builder.append(", "); + } + if (atozLink != null) { + builder.append("atozLink="); + builder.append(atozLink); + builder.append(", "); + } + if (ztoaLink != null) { + builder.append("ztoaLink="); + builder.append(ztoaLink); + builder.append(", "); + } + if (zend != null) { + builder.append("zend="); + builder.append(zend); + builder.append(", "); + } + builder.append(", direct="); + builder.append(direct); + return builder.append(']').toString(); + } + + public List getAtozLink() { + return atozLink; + } + + public void setAtozLink(List atozLink) { + this.atozLink = atozLink; + } + + public List getZtoaLink() { + return ztoaLink; + } + + public void setZtoaLink(List ztoaLink) { + this.ztoaLink = ztoaLink; + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodePath.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodePath.java new file mode 100644 index 000000000..634c27958 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodePath.java @@ -0,0 +1,357 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.opendaylight.transportpce.stubpce.TpNodeTp; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.NodeBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPointBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * build all path with one resource + * from Supernode. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +public class NodePath { + /** Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(NodePath.class); + /** element of Supernode. */ + private org.opendaylight.transportpce.stubpce.topology.Resource resource; + /** TpNodeTp list. */ + private List tpNodeTps; + /** Link list. */ + private List links; + /** SuperNode element nodeId. */ + private String nodeId; + /** Supernode Id. */ + private String superNodeId; + /** boolean to determine if Supernode contains an XPDR. */ + private boolean isXpdrSrgAbsent; + /** Path List. */ + private List path; + + /** + *NodePath constructor. + * + * @param res element of Supernode + * @param superNodeId supernode Id + * @param isXpdrSrgAbsent boolean to determine if Supernode contains an XPDR + */ + public NodePath(org.opendaylight.transportpce.stubpce.topology.Resource res, + String superNodeId, boolean isXpdrSrgAbsent) { + setResource(res); + setNodeId(res.getNodeId()); + setSuperNodeId(superNodeId); + setXpdrSrgAbsent(isXpdrSrgAbsent); + setLinks(new ArrayList()); + setTpNodeTps(new ArrayList()); + setPath(new ArrayList()); + } + + @Override + public String toString() { + java.lang.String name = "NodePath ["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + if (nodeId != null) { + builder.append("nodeId= "); + builder.append(nodeId); + builder.append(", "); + } + if (path.size() > 0) { + builder.append("Paths ["); + builder.append(path.toString()); + builder.append(" ]"); + } + return builder.append(']').toString(); + } + + /** + *get all resources (links, + *logicalConnectionpoints, nodeId) + *from Supernode element. + */ + public void fill() { + Boolean xpdr = false; + if (resource != null) { + String nodeid = resource.getNodeId(); + List resLinks = resource.getLinks(); + List resLcps = resource.getLcps(); + for (String tmp : resLinks) { + Link link = new LinkBuilder() + .setLinkId(tmp) + .build(); + links.add(link); + } + if (nodeid.contains("XPDR")) { + LOG.info("building xpdr resource ..."); + xpdr = true; + buildXpdrTopo(nodeid,resLinks,resLcps,xpdr); + links.add(new LinkBuilder() + .setLinkId("TAIL-LINKS") + .build()); + } + if (nodeid.contains("SRG")) { + LOG.info("building SRG resource ..."); + buildSRGTopo(nodeid, resLinks, resLcps); + } + if (nodeid.contains("DEG")) { + LOG.info("building DEG resource ..."); + xpdr = false; + buildXpdrTopo(nodeid,resLinks,resLcps,xpdr); + links.add(new LinkBuilder() + .setLinkId("EXTERNAL-LINKS") + .build()); + } + } + createDirection(); + } + + /** + * reverse a TpNodeTp + * List. + * + * @return TpNodeTp list + */ + private List reverseTpNodetpList() { + List result = new ArrayList(); + for (TpNodeTp tpNodetp : tpNodeTps) { + TpNodeTp tmp = tpNodetp.reverse(); + result.add(tmp); + } + return result; + } + + /** + *create list of Path + *(TpNodeTp/Link). + */ + private void createDirection() { + /** create direction */ + LOG.info("creating direction ..."); + Path resourcePath = null; + List direction = new ArrayList(); + for (Link link : links) { + String linkId = link.getLinkId(); + LOG.info("LinkId : " + linkId); + if (!isXpdrSrgAbsent) { + if (StringUtils.countMatches(link.getLinkId(), "ROADM") < 2) { + if ((linkId.contains("XPDR") && linkId.startsWith("ROADM")) + || ((linkId.startsWith("DEG") && linkId.contains("SRG"))) + || (nodeId.contains("XPDR") && linkId.contains("TAIL-LINKS"))) { + LOG.info("reversing TpNodetp list for link '" + linkId + "'"); + direction = reverseTpNodetpList(); + } else { + direction = tpNodeTps; + } + } else { + LOG.info("link is deg to deg link !"); + } + } else { + if (StringUtils.countMatches(link.getLinkId(), "ROADM") == 2) { + direction = reverseTpNodetpList(); + } else { + direction = tpNodeTps; + } + } + if (tpNodeTps.size() > 0) { + for (TpNodeTp tpNodeTp : direction) { + resourcePath = new Path(tpNodeTp, link); + LOG.info(resourcePath.toString()); + path.add(resourcePath); + } + } else { + LOG.info("tpNodeTps is empty !"); + } + } + } + + /** + * build a list of + * Termination Point in + * XPDR or DEG + * ordered in AToZdirection + * on a Supernode (XPDR to SRG) + * (ROADMA-DEG to ROADMZ-DEG). + * + * @param xpdr determine if it is an XPDR or not + * @param resLcps list of LogicalConnectionPoint + * @return String list of TerminationPoints + */ + private List getOrderedTps(boolean xpdr, List resLcps) { + List result = new ArrayList(); + if (xpdr) { + for (LogicalConnectionPoint lcp : resLcps) { + String tmp = lcp.getTpId(); + if (tmp.contains("CLIENT")) { + result.add(0, tmp); + } else if (tmp.contains("NETWORK")) { + result.add(1, tmp); + } + } + } else { + for (LogicalConnectionPoint lcp : resLcps) { + String tmp = lcp.getTpId(); + if (tmp.contains("CTP")) { + result.add(0, tmp); + } else if (tmp.contains("TTP")) { + result.add(1, tmp); + } + } + } + return result; + } + + /** + * build TpNodeTp + * structure in an + * XPDR. + * + * @param nodeid XPDR Id + * @param resLinks list of links + * @param resLcps list of LogicalConnectionPoints + * @param xpdr determine if it is an XPDR or not + */ + private void buildXpdrTopo(String nodeid, List resLinks, List resLcps, + boolean xpdr) { + /** build TpNodetp .*/ + TerminationPointBuilder in = null; + TerminationPointBuilder out = null; + List lcps = getOrderedTps(xpdr,resLcps); + if (lcps.size() == 2) { + in = new TerminationPointBuilder() + .setTpNodeId(nodeid) + .setTpId(lcps.get(0)); + out = new TerminationPointBuilder() + .setTpNodeId(nodeid) + .setTpId(lcps.get(1)); + } else { + LOG.info("lcps size not equal to 2"); + + } + Node node = new NodeBuilder() + .setNodeId(nodeid) + .build(); + TpNodeTp tmp = new TpNodeTp(in.build(), out.build(), node); + tpNodeTps.add(tmp); + } + + /** + * build TpNodeTp + * structure in an + * SGR. + * + * @param nodeid SRG nodeId + * @param resLinks list of links + * @param resLcps list of LogicalConnectionPoints + */ + private void buildSRGTopo(String nodeid, List resLinks,List resLcps) { + /** build TpNodetp .*/ + Node node = new NodeBuilder() + .setNodeId(nodeid) + .build(); + TerminationPoint out = new TerminationPointBuilder() + .setTpNodeId(nodeid) + .setTpId("SRG1-CP-TXRX") + .build(); + + for (LogicalConnectionPoint lcp : resLcps) { + if (lcp.getTpId().compareTo("SRG1-CP-TXRX") != 0) { + TerminationPoint in = new TerminationPointBuilder() + .setTpNodeId(nodeid) + .setTpId(lcp.getTpId()) + .build(); + tpNodeTps.add(new TpNodeTp(in, out, node)); + } + } + } + + public static void main(String[] args) { + Topology topo = new Topology(); + topo.start(); + Network net = topo.getNetwork(); + if (net != null) { + SuperNode superNode = net.getSuperNodes().get(0); + LOG.info("SuperNode : " + superNode.getSuperNodeId()); + for (org.opendaylight.transportpce.stubpce.topology.Resource res : + superNode.getResources()) { + LOG.info(res.toString()); + NodePath path = new NodePath(res, superNode.getSuperNodeId(), superNode.isXpdrSrgAbsent()); + path.fill(); + } + } + } + + public org.opendaylight.transportpce.stubpce.topology.Resource getResource() { + return resource; + } + + public void setResource(org.opendaylight.transportpce.stubpce.topology.Resource resource) { + this.resource = resource; + } + + public List getTpNodeTps() { + return tpNodeTps; + } + + public void setTpNodeTps(List tpNodeTps) { + this.tpNodeTps = tpNodeTps; + } + + public List getLinks() { + return links; + } + + public void setLinks(List links) { + this.links = links; + } + + public List getPath() { + return path; + } + + public void setPath(List path) { + this.path = path; + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getSuperNodeId() { + return superNodeId; + } + + public void setSuperNodeId(String superNodeId) { + this.superNodeId = superNodeId; + } + + public boolean isXpdrSrgAbsent() { + return isXpdrSrgAbsent; + } + + public void setXpdrSrgAbsent(boolean isXpdrSrgAbsent) { + this.isXpdrSrgAbsent = isXpdrSrgAbsent; + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Path.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Path.java new file mode 100644 index 000000000..6de05e91f --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Path.java @@ -0,0 +1,72 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import org.opendaylight.transportpce.stubpce.TpNodeTp; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link; + +/** + * Class to create structure + * TpNodeTp and link. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +public class Path { + /** TpNodeTp. */ + private TpNodeTp tpNodeTp; + /** Link at TpNodeTp. */ + private Link link; + + /** + *Path constructor. + * + * @param tpnodetp TpNodeTp + * @param link link at the end of TpNodeTp + */ + public Path(TpNodeTp tpnodetp, Link link) { + setTpNodeTp(tpnodetp); + setLink(link); + } + + public Path(TpNodeTp tpNodeTp) { + setTpNodeTp(tpNodeTp); + } + + public TpNodeTp getTpNodeTp() { + return tpNodeTp; + } + + public void setTpNodeTp(TpNodeTp tpNodeTp) { + this.tpNodeTp = tpNodeTp; + } + + public Link getLink() { + return link; + } + + public void setLink(Link link) { + this.link = link; + } + + @Override + public String toString() { + java.lang.String name = "Path ["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + if (tpNodeTp != null) { + builder.append("tpNodeTp= "); + builder.append(tpNodeTp); + builder.append(", "); + } + if (link != null) { + builder.append(link); + } + return builder.append(']').toString(); + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/PathDescriptionsOrdered.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/PathDescriptionsOrdered.java new file mode 100644 index 000000000..c31c55ee5 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/PathDescriptionsOrdered.java @@ -0,0 +1,56 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptions; + +/** + * class to create structure + * of PathDescriptions + * ordered. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +public class PathDescriptionsOrdered implements Comparable { + private PathDescriptions pathDescriptions; + private int ord; + + /** + * PathDescriptionsOrdered constructor. + * + * @param paths PathDescriptions + * @param order Integer + */ + public PathDescriptionsOrdered(PathDescriptions paths, int order) { + setPathDescriptions(paths); + setOrd(order); + } + + @Override + public int compareTo(PathDescriptionsOrdered paths) { + return this.ord - paths.getOrd(); + } + + public PathDescriptions getPathDescriptions() { + return pathDescriptions; + } + + public void setPathDescriptions(PathDescriptions pathDescriptions) { + this.pathDescriptions = pathDescriptions; + } + + public int getOrd() { + return ord; + } + + public void setOrd(int ord) { + this.ord = ord; + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Resource.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Resource.java new file mode 100644 index 000000000..141cae4c8 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Resource.java @@ -0,0 +1,115 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +import java.util.List; + + +/** + * Class to create structure of + * Supernode element. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +@JacksonXmlRootElement(localName = "resource") +public class Resource { + /** element nodeId. */ + @JacksonXmlProperty(localName = "node-id") + private String nodeId; + /** list of element links. */ + @JacksonXmlElementWrapper(localName = "links") + @JacksonXmlProperty(localName = "link") + private List links; + /** list of element LogicalConnectionPoint. */ + @JacksonXmlElementWrapper(localName = "logical-connection-points") + @JacksonXmlProperty(localName = "logical-connection-point") + private List lcps; + + + /** + * Resource constructor. + * + * @param nodeId element nodeId + * @param links list of element links + * @param lcps list of element LogicalConnectionPoint + */ + public Resource(@JacksonXmlProperty(localName = "node-id") final String nodeId, + @JacksonXmlProperty(localName = "Reslinks") final List links, + @JacksonXmlProperty(localName = "Reslcps") final List lcps) { + this.setNodeId(nodeId); + this.setLinks(links); + this.setLpcs(lcps); + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public List getLinks() { + return links; + } + + public void setLinks(List links) { + this.links = links; + } + + public List getLcps() { + return lcps; + } + + public void setLpcs(List lcps) { + this.lcps = lcps; + } + + @Override + public String toString() { + int index; + int size; + java.lang.String name = "Resource ["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + if (nodeId != null) { + builder.append("nodeId="); + builder.append(nodeId); + } + index = 0; + size = lcps.size(); + builder.append(", LogicalConnectionPoints ["); + for (LogicalConnectionPoint tmp : lcps) { + builder.append(tmp.toString()); + index++; + if (index < size) { + builder.append(", "); + } + } + builder.append("]"); + index = 0; + size = links.size(); + builder.append(", links ["); + for (String tmp : links) { + builder.append(tmp); + index++; + if (index < size) { + builder.append(", "); + } + } + builder.append("]"); + return builder.append(']').toString(); + + } + +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/RoadmToRoadm.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/RoadmToRoadm.java new file mode 100644 index 000000000..2699d339b --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/RoadmToRoadm.java @@ -0,0 +1,68 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +import java.util.List; + + +/** + * Class to create list of links + * between Supernode. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +@JacksonXmlRootElement(localName = "roadm-to-roadm") +public class RoadmToRoadm { + /** List of links. */ + @JacksonXmlElementWrapper(localName = "links") + @JacksonXmlProperty(localName = "link") + private List links; + + /** + * RoadmToRoadm structure. + * + * @param links list of links + */ + public RoadmToRoadm(@JacksonXmlProperty(localName = "Rlinks") final List links) { + setLinks(links); + } + + public List getLinks() { + return links; + } + + public void setLinks(List links) { + this.links = links; + } + + @Override + public String toString() { + int index; + int size; + java.lang.String name = "RoadmToRoadm ["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + index = 0; + size = links.size(); + builder.append("Links ["); + for (String tmp : links) { + builder.append(tmp.toString()); + index++; + if (index < size) { + builder.append(", "); + } + } + builder.append("]"); + return builder.append(']').toString(); + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNode.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNode.java new file mode 100644 index 000000000..fcf825ab5 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNode.java @@ -0,0 +1,125 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +import java.util.ArrayList; +import java.util.List; + + +/** + * class to create Supernode + * structure. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +@JacksonXmlRootElement(localName = "super-node") +public class SuperNode { + /** Supernode Id. */ + @JacksonXmlProperty(localName = "super-node-id") + private String superNodeId; + /** list of elements cotaining in Supernode. */ + @JacksonXmlElementWrapper(localName = "resources") + @JacksonXmlProperty(localName = "resource") + private List resources; + + /** + * SuperNode constructor. + * + * @param supernodeid superNode Id + * @param resources List of Supernode elements + */ + public SuperNode(@JacksonXmlProperty(localName = "super-node-id") final String supernodeid, + @JacksonXmlProperty(localName = "Spresource") final List resources) { + setSuperNodeId(supernodeid); + setResources(resources); + } + + /** + * SuperNode constructor. + * + * @param supernodeid supernode Id + */ + public SuperNode(String supernodeid) { + setSuperNodeId(supernodeid); + setResources(new ArrayList()); + } + + /** + *Test if Supernode contains + *an XPDR. + * @return true if XPDR present, false else + */ + public boolean isXpdrSrgAbsent() { + boolean result = true; + int present = 0; + if (resources.size() > 0) { + for (Resource resource : resources) { + String nodeId = resource.getNodeId(); + if (nodeId != null) { + if (nodeId.contains("XPDR")) { + present++; + } + if (nodeId.contains("SRG")) { + present++; + } + } + } + } + if (present == 2) { + result = false; + } + return result; + } + + public List getResources() { + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public String getSuperNodeId() { + return superNodeId; + } + + public void setSuperNodeId(String superNodeId) { + this.superNodeId = superNodeId; + } + + @Override + public String toString() { + int index; + int size; + java.lang.String name = "SuperNode ["; + java.lang.StringBuilder builder = new java.lang.StringBuilder(name); + if (superNodeId != null) { + builder.append("superNodeId="); + builder.append(superNodeId); + } + index = 0; + size = resources.size(); + builder.append(", Resources ["); + for (Resource tmp : resources) { + builder.append(tmp.toString()); + index++; + if (index < size) { + builder.append(", "); + } + } + builder.append("]"); + return builder.append(']').toString(); + } + +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNodePath.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNodePath.java new file mode 100644 index 000000000..732f31888 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNodePath.java @@ -0,0 +1,731 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import com.google.common.collect.Lists; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Class to build Path between + * two Supernode. + * + * @author Martial Coulibaly on + * behalf of Orange + */ +public class SuperNodePath { + /** Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(SuperNodePath.class); + /** List of NodeLinkNode. */ + private List paths; + /** Supernode topology. */ + private Network network; + + /** + * SuperNodePath constructor. + * + * @param network Supernode topology + */ + public SuperNodePath(Network network) { + setPaths(new ArrayList()); + this.network = network; + } + + /** + * test if Supernode is an + * extremity of path to build. + * + * @param end extremity node Id + * @param supernodes Supernodes list to build path + * @return true if link extremity, false else + */ + private Boolean endNode(String end, List supernodes) { + Boolean result = false; + if (end != null && end.compareTo(" ") != 0) { + for (String node : supernodes) { + if (node.compareTo(end) == 0) { + result = true; + break; + } + } + } + return result; + } + + /** + * get Supernode + * with supernode Id. + * + * @param nodeId supernode id to get + * @return SuperNode supernode gets + */ + public SuperNode getSuperNode(String nodeId) { + SuperNode result = null; + if (network != null) { + for (SuperNode tmp : network.getSuperNodes()) { + if (tmp.getSuperNodeId().compareTo(nodeId) == 0) { + result = tmp; + break; + } + } + } + return result; + } + + /** + *find links between + *two Supernodes. + * + * @param aend begin extremity + * @param zend end extremity + * @param links Roadm to Roadm links + * @param direct determine if link is direct or not + * @return String list of links name + */ + private List findLinks(String aend, String zend, List links, boolean direct) { + List result = new ArrayList(); + if (links.size() > 0) { + aend = aend.replace("Node", "ROADM"); + zend = zend.replace("Node", "ROADM"); + String atozlink = null; + String ztoalink = null; + for (String tmp : links) { + if (tmp.contains(aend) + && tmp.contains(zend)) { + LOG.info("direct path found for : " + aend + " / " + zend); + if (tmp.startsWith(aend)) { + atozlink = tmp; + } + if (tmp.startsWith(zend)) { + ztoalink = tmp; + } + if (atozlink != null && ztoalink != null) { + result.add(atozlink.concat("/").concat(ztoalink)); + atozlink = null; + ztoalink = null; + } + } + } + } else { + LOG.info("no roadm-to-roadm links !"); + } + return result; + } + + /** + *find next Supernode hop. + * + * @param link roadm to roadm link + * @param aend begin supernode + * @param node list of supernode id + * @return String supernodeId next hop + */ + private String findHop(String link, String aend, List node) { + String result = null; + aend = aend.replace("Node", "ROADM"); + for (String tmp : node) { + tmp = tmp.replace("Node", "ROADM"); + if (tmp.compareTo(aend) != 0) { + if (link.contains(aend) && link.contains(tmp)) { + LOG.info("hop : " + tmp); + result = tmp; + } + } + } + return result; + } + + /** + *get all Supernode in + *topology. + * + * @return String list of Supernode Id + */ + private List getSuperNodeId() { + List result = new ArrayList(); + if (network.getSuperNodes().size() > 0) { + for (SuperNode tmp : network.getSuperNodes()) { + result.add(tmp.getSuperNodeId()); + } + } + return result; + } + + /** + * get all roadm to roadm + * links in topology. + * + * @return String list of roadm to roadm links + */ + private List getRoadmLinks() { + List result = new ArrayList(); + if (network.getRoadmToroadm().getLinks().size() > 0) { + for (String tmp : network.getRoadmToroadm().getLinks()) { + result.add(tmp); + } + } + return result; + } + + /** + * create NodeLinkNode + * structure. + * + * @param links String list of roadm to roadm links + * @param aend beginning Supernode + * @param zend ending Supernode + * @param direct determine if link is direct or not + */ + private void fill(List links,String aend, String zend, boolean direct) { + String term = "indirect"; + if (direct) { + term = "direct"; + } + if (!links.isEmpty()) { + List atoz = new ArrayList(); + List ztoa = new ArrayList(); + for (String tmp : links) { + String [] split = tmp.split("/"); + if (split.length == 2) { + atoz.add(split[0]); + ztoa.add(split[1]); + } + } + if (!atoz.isEmpty() && atoz.size() == ztoa.size()) { + NodeLinkNode node = new NodeLinkNode(aend, zend, atoz,ztoa,direct); + paths.add(node); + } + + } else { + LOG.info(term + " links not found !"); + } + } + + /** + * launch SupernodePath process + * to build NodeLinkNode. + * + * @param aend beginning extremity path + * @param zend ending extremity path + */ + public void run(String aend, String zend) { + if (network != null) { + List supernodes = getSuperNodeId(); + List roadmLinks = getRoadmLinks(); + if (aend != null && zend != null) { + int size = supernodes.size(); + String hop = null; + List links = null; + if (size > 0) { + if (endNode(aend, supernodes) && endNode(zend, supernodes)) { + LOG.info("Getting direct links ..."); + links = new ArrayList(); + links = findLinks(aend,zend,roadmLinks,true); + fill(links, aend, zend, true); + LOG.info("Getting indirect links .."); + links = new ArrayList(); + for (String tmp : roadmLinks) { + hop = findHop(tmp, aend, supernodes); + if (hop != null) { + if (hop.compareTo(zend.replace("Node", "ROADM")) != 0) { + LOG.info("next hop found : " + hop); + links.addAll(findLinks(aend,hop,roadmLinks,false)); + links.addAll(findLinks(hop,zend,roadmLinks,false)); + } else { + break; + } + } + } + fill(links, aend, zend, false); + } else { + LOG.info("aend or/and zend not exists !"); + } + } + } else { + LOG.info("aend or/and is null !"); + } + } else { + LOG.info("network is null !!"); + } + } + + /** + * modify all AToZ Id + * in AToZ List containing + * in AToZdirection. + * + * @param order beginning order + * @param atozDirection AToZdirection List + * @return AToZdirection List + */ + public List modifyOrder(int order, List atozDirection) { + List result = new ArrayList(); + for (AToZDirection tmp : atozDirection) { + List atozList = tmp.getAToZ(); + int size = atozList.size(); + if (size > 0) { + for (ListIterator it = atozList.listIterator(); it.hasNext();) { + AToZ atoz = it.next(); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription + .rev170426.pce.resource.resource.Resource res = atoz.getResource().getResource(); + int tmpkey = order + Integer.parseInt(atoz.getKey().getId()); + AToZKey atozKey = new AToZKey(Integer.toString(tmpkey)); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .pathdescription.rev170426.pce.resource.Resource resource = new ResourceBuilder() + .setResource(res).build(); + AToZ hop = new AToZBuilder().setId(atozKey.getId()).setKey(atozKey).setResource(resource).build(); + it.remove(); + it.add(hop); + tmpkey++; + } + result.add(tmp); + } + } + return result; + } + + /** + * merge two AToZdirection List. + * + * @param cleanInterA first AToZdirection List + * @param cleanInterZ second AToZdirection List + * @param first boolean to determine if it is the first time merge is done + * @return AToZDirection List + */ + public List merge(List cleanInterA, List cleanInterZ, + boolean first) { + List result = new ArrayList(); + if (!cleanInterA.isEmpty()) { + int order = cleanInterA.get(0).getAToZ().size(); + if (order > 0) { + List modify = modifyOrder(order, cleanInterZ); + if (!modify.isEmpty()) { + for (AToZDirection tmp : cleanInterA) { + List atozList = new ArrayList(tmp.getAToZ()); + for (AToZDirection add : modify) { + ListIterator it = atozList.listIterator(); + /** on va a la fin de la liste */ + while (it.hasNext()) { + it.next(); + } + List addList = add.getAToZ(); + for (AToZ atoz : addList) { + it.add(atoz); + } + AToZDirectionBuilder newDirection = new AToZDirectionBuilder(); + newDirection.setRate((long) 100).setAToZWavelengthNumber((long) 200).setAToZ(atozList); + result.add(newDirection.build()); + atozList = new ArrayList(tmp.getAToZ()); + } + } + } else { + LOG.info("modify List is empty ! "); + } + } else { + LOG.info("order is not superior to 0"); + } + } else { + if (first && !cleanInterZ.isEmpty()) { + LOG.info("first merge so result is a copy of second AToZDirection List !"); + result = new ArrayList(cleanInterZ); + } else { + LOG.info("cleanInterA is empty !"); + } + } + return result; + } + + /** + * gets Degree number + * for roadm links. + * + * @param atozLink atoz roadm link + * @param ztoaLink ztoa roadm link + * @return String list of degree + */ + public List getDeg(String atozLink, String ztoaLink) { + List result = new ArrayList(); + if (atozLink != null && ztoaLink != null) { + String [] split = atozLink.split("-", 4); + if (split.length == 4) { + result = Lists.newArrayList(split[1],split[3]); + } + } else { + LOG.info("atozlink and/or ztoalink is null !"); + } + return result; + } + + /** + * reverse link name + * (ROADMA-DEG1-ROADMZ-DEG2 + * to + * ROADMZ-DEG2-ROADMA-DEG1). + * + * @param linkId Link name + * @return String link name reversed + */ + public String reverseLinkId(String linkId) { + StringBuilder builder = new StringBuilder(); + String [] split = linkId.split("-"); + int size = split.length; + switch (size) { + case 3: + if (linkId.contains("XPDR")) { + if (linkId.startsWith("XPDR")) { + builder.append(split[1]).append("-") + .append(split[2]).append("-") + .append(split[0]); + } else { + builder.append(split[2]).append("-") + .append(split[0]).append("-") + .append(split[1]); + } + } + break; + + case 4: + builder.append(split[2]).append("-") + .append(split[3]).append("-") + .append(split[0]).append("-") + .append(split[1]); + break; + + default: + break; + } + return builder.toString(); + } + + /** + * convert AToAdirection to + * ZToAdirection. + * + * @param atozDirection AToZdirection to convert + * @return ZToAdirection + */ + public ZToADirection convertToZtoaDirection(AToZDirection atozDirection) { + ZToADirectionBuilder ztoaDirection = new ZToADirectionBuilder(); + if (atozDirection != null) { + List atozList = atozDirection.getAToZ(); + List ztoaList = new ArrayList(); + if (!atozList.isEmpty()) { + List reverse = Lists.reverse(atozList); + /** Building path. */ + ZToAKey ztoaKey = null; + Resource resource = null; + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription + .rev170426.pce.resource.resource.Resource resLink = null; + ZToA hop = null; + int odr = 0; + for (AToZ atoz : reverse) { + ztoaKey = new ZToAKey(Integer.toString(odr)); + resLink = atoz.getResource().getResource(); + if (resLink != null) { + if (resLink instanceof Link) { + Link link = (Link) resLink; + String newLinkId = reverseLinkId(link.getLinkId()); + if (newLinkId != null) { + resource = new ResourceBuilder().setResource( + new LinkBuilder() + .setLinkId(newLinkId) + .build() + ).build(); + } + + } else { + resource = new ResourceBuilder().setResource(resLink).build(); + } + } + if (resource != null) { + hop = new ZToABuilder() + .setKey(ztoaKey) + .setResource(resource) + .build(); + ztoaList.add(hop); + odr++; + } else { + LOG.info("resource is null "); + } + } + if (!ztoaList.isEmpty()) { + ztoaDirection.setRate((long) 100).setZToAWavelengthNumber((long) 200).setZToA(ztoaList); + } else { + LOG.info("ztoaList is empty !"); + } + } + } + return ztoaDirection.build(); + } + + /** + *build Pathdescritions ordered List + *to be loaded in Pathdescriptions + *datastore. + * + * @param atozDirection AToZdirection List + * @param term direct ou indirect + * @return PathDescriptionsOrdered List + */ + private SortedSet buildPathDescription(List atozDirection, String term) { + SortedSet result = new TreeSet(); + PathDescriptionsBuilder pathDescr = new PathDescriptionsBuilder(); + int size = atozDirection.size(); + if (!atozDirection.isEmpty()) { + LOG.info("result list AToZDirection size : " + atozDirection.size()); + List ztoadirList = new ArrayList(); + for (AToZDirection atozdir : atozDirection) { + ZToADirection ztodir = convertToZtoaDirection(atozdir); + if (ztodir != null) { + ztoadirList.add(ztodir); + } + } + if (!ztoadirList.isEmpty() && size == ztoadirList.size()) { + LOG.info("building PathDescriptions ..."); + int index = 1; + String pathName = null; + for (int indexPath = 0 ; indexPath < size ; indexPath++) { + pathName = term.concat(Integer.toString(index)); + LOG.info("pathName : " + pathName); + pathDescr.setAToZDirection(atozDirection.get(indexPath)) + .setZToADirection(ztoadirList.get(indexPath)).setPathName(pathName); + LOG.info(pathDescr.build().toString()); + result.add(new PathDescriptionsOrdered(pathDescr.build(),index)); + index++; + } + } else { + LOG.info("Something wrong happen during atodir conversion..."); + } + + } else { + LOG.info("atozDirection is empty"); + } + return result; + } + + /** + * gets link extremity. + * + * @param link link + * @return Supernode List of extremities + */ + public List getSuperNodeEndLink(String link) { + List result = new ArrayList(); + if (link != null) { + String [] split = link.split("-"); + if (split.length == 4) { + String aend = split[0].replaceAll("ROADM", "Node"); + String zend = split[2].replaceAll("ROADM", "Node"); + if (aend != null && zend != null) { + LOG.info("getting super node for : " + aend + " and " + zend); + SuperNode aendSp = getSuperNode(aend); + SuperNode zendSp = getSuperNode(zend); + if (aendSp != null && zendSp != null) { + result.add(aendSp); + result.add(zendSp); + } + } + } + } + return result; + } + + /** + * build all direct paths. + * + * @param aend beginning extremity path + * @param zend ending extremity path + * @param paths NodeLinkNode list paths + * @return PathDescriptionsOrdered List of direct paths + */ + public SortedSet getDirectPathDesc(String aend, String zend,List paths) { + List atozdirectionPaths = new ArrayList(); + SortedSet result = new TreeSet(); + SuperNode aendSp = getSuperNode(aend); + SuperNode zendSp = getSuperNode(zend); + if (!paths.isEmpty()) { + for (NodeLinkNode tmp : paths) { + if (tmp.getDirect()) { + LOG.info("Direct NodeLinkNode : " + tmp.toString()); + String atozLink = null; + String ztoaLink = null; + atozLink = tmp.getAtozLink().get(0); + ztoaLink = tmp.getZtoaLink().get(0); + if (atozLink != null && ztoaLink != null) { + LOG.info("atozlink : " + atozLink); + LOG.info("ztoalink : " + ztoaLink); + InterNodePath interAend = new InterNodePath(aendSp); + interAend.buildPath(zend); + InterNodePath interZend = new InterNodePath(zendSp); + interZend.buildPath(zend); + List deg = getDeg(atozLink,ztoaLink); + LOG.info("deg : " + deg.toString()); + if (deg.size() == 2) { + List cleanInterA = + interAend.replaceOrRemoveAToZDirectionEndLink(deg.get(0),"",atozLink, + interAend.getAtoz(),false); + List cleanInterZ = + interZend.replaceOrRemoveAToZDirectionEndLink("TAIL-LINKS",deg.get(1),"", + interZend.getAtoz(),true); + if (!cleanInterA.isEmpty() && !cleanInterZ.isEmpty()) { + atozdirectionPaths.addAll(merge(cleanInterA,cleanInterZ,false)); + } else { + LOG.info("cleanInterA ad/or cleanInterZ is empty !"); + } + } else { + LOG.info("deg size is not correct, must be 2 ! "); + } + } else { + LOG.info("atozlink and / or ztoalink is null"); + } + } + } + + } else { + LOG.info("List of direct path is empty !"); + } + if (!atozdirectionPaths.isEmpty()) { + LOG.info("result size : " + result.size()); + result = buildPathDescription(atozdirectionPaths,aend.concat("To").concat(zend).concat("_direct_")); + } else { + LOG.info("result is empty"); + } + return result; + } + + /** + * build all indirect paths. + * + * @param aend beginning extremity path + * @param zend ending extremity path + * @param paths NodeLinkNode list paths + * @return PathDescriptionsOrdered List of indirect paths + */ + public SortedSet getIndirectPathDesc(String aend, String zend,List paths) { + List atozdirectionPaths = new ArrayList(); + SortedSet result = new TreeSet(); + SuperNode aendSp = getSuperNode(aend); + SuperNode zendSp = getSuperNode(zend); + if (!paths.isEmpty()) { + for (NodeLinkNode tmp : paths) { + if (!tmp.getDirect()) { + LOG.info("Indirect NodeLinkNode : " + tmp.toString()); + int size = tmp.getAtozLink().size(); + /** must be two for now just one hop. */ + LOG.info("number of links : " + size); + boolean first = true; + if (size == 2) { + List atozLinks = tmp.getAtozLink(); + List ztoaLinks = tmp.getZtoaLink(); + if (!atozLinks.isEmpty() && !ztoaLinks.isEmpty()) { + LOG.info("atozlink : " + atozLinks.toString()); + LOG.info("ztoalink : " + ztoaLinks.toString()); + int loop = 0; + while (loop < 2) { + List hop = getSuperNodeEndLink(atozLinks.get(loop)); + if (!hop.isEmpty() && hop.size() == 2) { + aendSp = hop.get(0); + zendSp = hop.get(1); + InterNodePath interAend = new InterNodePath(aendSp); + interAend.buildPath(zend); + LOG.info("interAend : " + interAend.getAtoz().toString()); + InterNodePath interZend = new InterNodePath(zendSp); + interZend.buildPath(zend); + LOG.info("interZend : " + interZend.getAtoz().toString()); + List deg1 = getDeg(atozLinks.get(loop),ztoaLinks.get(loop)); + LOG.info("deg1 : " + deg1.toString()); + if (!deg1.isEmpty() && deg1.size() == 2) { + List cleanInterA = null; + List cleanInterZ = null; + if (zendSp.getSuperNodeId().compareTo(zend) == 0) { + cleanInterA = interAend.replaceOrRemoveAToZDirectionEndLink(deg1.get(0), + "",atozLinks.get(loop),interAend.getAtoz(),false); + LOG.info("next hop is zend"); + cleanInterZ = interZend.replaceOrRemoveAToZDirectionEndLink("TAIL-LINKS", + deg1.get(1),"",interZend.getAtoz(),true); + } else if (loop < 1) { + cleanInterA = interAend.replaceOrRemoveAToZDirectionEndLink(deg1.get(0), + "",atozLinks.get(loop),interAend.getAtoz(),false); + cleanInterZ = interZend.getAToZDirectionEndBy(deg1.get(1), + interZend.getAtoz(), 1); + } + if (!cleanInterA.isEmpty() && !cleanInterZ.isEmpty()) { + atozdirectionPaths = merge(atozdirectionPaths,cleanInterA,first); + atozdirectionPaths = merge(atozdirectionPaths, cleanInterZ,false); + first = false; + } else { + LOG.info("cleanInterA ad/or cleanInterZ is empty !"); + break; + } + } + } else { + LOG.info("Hop list is empty"); + } + loop++; + } + } + } else { + LOG.info("Link size is not supported , must be two !"); + } + } + } + } else { + LOG.info("List of indirect path is empty !"); + } + if (!atozdirectionPaths.isEmpty()) { + LOG.info("result size : " + result.size()); + result = buildPathDescription(atozdirectionPaths,aend.concat("To").concat(zend).concat("_indirect_")); + } else { + LOG.info("result is empty"); + } + return result; + } + + public static void main(String[] args) { + Topology topo = new Topology(); + topo.start(); + SuperNodePath path = new SuperNodePath(topo.getNetwork()); + String aend = "NodeA"; + String zend = "NodeZ"; + path.run(aend, zend); + path.getDirectPathDesc(aend, zend, path.getPaths()); + path.getIndirectPathDesc(aend, zend, path.getPaths()); + } + + public List getPaths() { + return paths; + } + + public void setPaths(List paths) { + this.paths = paths; + } +} diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Topology.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Topology.java new file mode 100644 index 000000000..72fd5dd58 --- /dev/null +++ b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Topology.java @@ -0,0 +1,111 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubpce.topology; + +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class to build Supernode + * topology (fakepce.xml file has to be + * in src/main/ressources folder + * to be loaded in taget/classes). + * + * + * @author Martial Coulibaly on + * behalf of Orange + */ +public class Topology { + /** Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(Topology.class); + /** file must be in src/main/resources in order to be in + * target/classes after compilation. + */ + + /** Structure of Supernode topology. */ + private Network network; + public BundleContext bcontext; + /** String to get Supernode topolgy info freom xml file. */ + private String xml = null; + + /** + * load fakepce.xml file + * and convert the informations + * in Network structure. + * + */ + public void start() { + setNetwork(null); + XmlMapper xmlMapper = new XmlMapper(); + try { + InputStream is = FrameworkUtil.getBundle(Topology.class).getBundleContext() + .getBundle().getEntry("/fakepce.xml").openStream(); + /*File file = new File("target/classes/fakepce.xml"); + InputStream is = new FileInputStream(file);*/ + xml = inputStreamToString(is); + if (xml != null) { + setNetwork(xmlMapper.readValue(xml, Network.class)); + LOG.info("Network : " + network.toString()); + } else { + LOG.info("String xml is null"); + } + } catch (IOException e) { + LOG.error("The file fakepce.xml not found", e); + } + } + + /** + * get xml file + * content. + * + * @param is InputStream + * @return String xml file content + * @throws IOException exception raised + */ + private String inputStreamToString(InputStream is) throws IOException { + StringBuilder sb = new StringBuilder(); + String line; + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + while ((line = br.readLine()) != null) { + sb.append(line); + } + br.close(); + return sb.toString(); + } + + public static void main(String[] args) { + Topology topo = new Topology(); + topo.start(); + } + + public Network getNetwork() { + return network; + } + + public void setNetwork(Network network) { + this.network = network; + } + + public void setBcontext(BundleContext bcontext) { + this.bcontext = bcontext; + } + + public BundleContext getBcontext() { + return this.bcontext; + } +} diff --git a/tests/stubpce/src/main/resources/fakepce.xml b/tests/stubpce/src/main/resources/fakepce.xml new file mode 100644 index 000000000..2d4433a58 --- /dev/null +++ b/tests/stubpce/src/main/resources/fakepce.xml @@ -0,0 +1,198 @@ + + + + + ROADMA-DEG1-ROADMB-DEG1 + ROADMA-DEG2-ROADMZ-DEG2 + ROADMZ-DEG1-ROADMB-DEG1 + ROADMZ-DEG2-ROADMA-DEG2 + ROADMB-DEG1-ROADMA-DEG1 + ROADMB-DEG2-ROADMZ-DEG1 + + + + + NodeA + + + XPDRA + + XPDRA-ROADMA-SRG1 + + + + CLIENT1 + XPDRA + + + NETWORK1 + XPDRA + + + + + ROADMA-SRG1 + + ROADMA-SRG1-XPDRA + SRG1-CP-DEG1-CP + SRG1-CP-DEG2-CP + + + + SRG1-PP1 + ROADMA-SRG1 + + + SRG1-PP2 + ROADMA-SRG1 + + + + + ROADMA-DEG1 + + ROADMA-DEG1-ROADMA-DEG2 + DEG1-CP-SRG1-CP + + + + DEG1-CTP-TXRX + ROADMA-DEG1 + + + DEG1-TTP-TXRX + ROADMA-DEG1 + + + + + ROADMA-DEG2 + + ROADMA-DEG2-ROADMA-DEG1 + DEG2-CP-SRG1-CP + + + + DEG2-CTP-TXRX + ROADMA-DEG2 + + + DEG2-TTP-TXRX + ROADMA-DEG2 + + + + + + + NodeB + + + ROADMB-DEG1 + + ROADMB-DEG1-ROADMB-DEG2 + + + + DEG1-CTP-TXRX + ROADMB-DEG1 + + + DEG1-TTP-TXRX + ROADMB-DEG1 + + + + + ROADMB-DEG2 + + ROADMB-DEG2-ROADMB-DEG1 + + + + DEG2-CTP-TXRX + ROADMB-DEG2 + + + DEG2-TTP-TXRX + ROADMB-DEG2 + + + + + + + NodeZ + + + XPDRC + + XPDRC-ROADMZ-SRG1 + + + + CLIENT1 + XPDRC + + + NETWORK1 + XPDRC + + + + + ROADMZ-SRG1 + + ROADMZ-SRG1-XPDRC + SRG1-CP-DEG1-CP + SRG1-CP-DEG2-CP + + + + SRG1-PP1 + ROADMZ-SRG1 + + + SRG1-PP2 + ROADMZ-SRG1 + + + + + ROADMA-DEG1 + + ROADMZ-DEG1-ROADMZ-DEG2 + DEG1-CP-SRG1-CP + + + + DEG1-CTP-TXRX + ROADMA-DEG1 + + + DEG1-TTP-TXRX + ROADMA-DEG1 + + + + + ROADMZ-DEG2 + + ROADMZ-DEG2-ROADMZ-DEG1 + DEG2-CP-SRG1-CP + + + + DEG2-CTP-TXRX + ROADMZ-DEG2 + + + DEG2-TTP-TXRX + ROADMZ-DEG2 + + + + + + + diff --git a/tests/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml b/tests/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml index c585e88cf..30a4f3a94 100644 --- a/tests/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml +++ b/tests/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml @@ -14,22 +14,32 @@ Author: Martial Coulibaly on behalf of Orange odl:use-default-for-reference-types="true"> + interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/> + interface="org.opendaylight.controller.md.sal.binding.api.NotificationService" + odl:type="default" /> + + - + + + + + + -- 2.36.6