Power control commit for OLM 95/58195/6
authorsvachhani <sv111y@att.com>
Thu, 20 Jul 2017 19:17:57 +0000 (15:17 -0400)
committerDhruv Bhardwaj <db929a@att.com>
Thu, 20 Jul 2017 19:45:23 +0000 (19:45 +0000)
It includes implementation of 2 functionalities:
1. Turning up a wave-length: It includes calculating power requirement,
Updating target-output-power and setting power mode for Roadm and
Transponder
2. Turning down a wave-length: It sets interface state to out of status
and updates powers levels

Change-Id: Ie42b6db766d76e13a5ed8763ec263d8d947d47c7
Signed-off-by: Shweta Vachhani <sv111y@att.com>
api/pom.xml
api/src/main/yang/olm.yang
api/src/main/yang/portmapping.yang
features/odl-transportpce-api/pom.xml
olm/src/main/java/org/opendaylight/transportpce/olm/OlmPowerSetupImpl.java
olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmt.java [new file with mode: 0644]
olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/SpanLoss.java
renderer/src/main/java/org/opendaylight/transportpce/renderer/mapping/PortMapping.java
renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterfaces.java
renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/CrossConnect.java

index 410ace450f339f3fdb40f98327a9613e95a2c148..9422d1bf2b6bf6baaccd61cd9609457e1048b52b 100644 (file)
@@ -21,4 +21,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <version>0.2.0-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>transportpce-ordmodels</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
 </project>
index 7eedb4cd3bdc7385dc3c0210f759c72cb4d2939d..bf8a9b37a951c4a251f0db9751dba5007995f061 100644 (file)
-module olm {
-  yang-version 1;
-  namespace "urn:opendaylight:params:xml:ns:yang:olm";
-  prefix "olm";
-
-  revision "2017-04-18" {
-    description "Initial revision of olm model";
-  }
-  rpc get-pm {
-    input{
-      leaf node-id{
-        type string;
-      }
-      leaf resource-type{
-        type string;
-      }
-      leaf resource-name{
-        type string;
-      }
-      leaf granularity{
-        type string;
-      }
-    }
-    output{
-      leaf node-id{
-        type string;
-      }
-      leaf resource-type{
-        type string;
-      }
-      leaf resource-id{
-        type string;
-      }
-      leaf granularity {
-        type string;
-      }
-      list measurements {
-      leaf pmparameter-name{
-        type string;
-      }
-      leaf pmparameter-value {
-        type string;
-        }
-      }
-    }
-  }
-  rpc service-power-setup{
-    input{
-      list nodes{
-        key "node-id";
-        leaf node-id{
-          type string;
-        }
-        leaf src-tp{
-          type string;
-          description "Source termination point ";
-          mandatory true;
-        }
-        leaf dest-tp{
-          type string;
-          description "Destination termination point ";
-           mandatory true;
-        }
-      }
-    }
-    output{
-      leaf result{
-        type string;
-      }
-    }
-  }
-}
+module olm {\r
+  yang-version 1;\r
+  namespace "urn:opendaylight:params:xml:ns:yang:olm";\r
+  prefix "olm";\r
+\r
+ organization\r
+    "transportPCE";\r
+  contact\r
+    "transportPCE committers - ODL";\r
+  description\r
+    "YANG definitions of RPCs supported by OLM.\r
+     Copyright © 2017 AT&T and others.  All rights reserved.\r
+     authors: Dhruv Bhardwaj ( db929a@att.com )\r
+              Shweta Vachhani ( sv111y@att.com )";\r
+\r
+  revision "2017-04-18" {\r
+    description "Initial revision of olm model";\r
+  }\r
+  rpc get-pm {\r
+    input{\r
+      leaf node-id{\r
+        type string;\r
+      }\r
+      leaf resource-type{\r
+        type string;\r
+      }\r
+      leaf resource-name{\r
+        type string;\r
+      }\r
+      leaf granularity{\r
+        type string;\r
+      }\r
+    }\r
+    output{\r
+      leaf node-id{\r
+        type string;\r
+      }\r
+      leaf resource-type{\r
+        type string;\r
+      }\r
+      leaf resource-id{\r
+        type string;\r
+      }\r
+      leaf granularity {\r
+        type string;\r
+      }\r
+      list measurements {\r
+      leaf pmparameter-name{\r
+        type string;\r
+      }\r
+      leaf pmparameter-value {\r
+        type string;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  rpc service-power-setup{\r
+    input{\r
+      leaf wave-number{\r
+        type uint32;\r
+      }\r
+      list nodes{\r
+        ordered-by user;\r
+        leaf node-id{\r
+          type string;\r
+        }\r
+        leaf src-tp{\r
+          type string;\r
+          description "Source termination point ";\r
+          mandatory true;\r
+        }\r
+        leaf dest-tp{\r
+          type string;\r
+          description "Destination termination point ";\r
+           mandatory true;\r
+        }\r
+      }\r
+    }\r
+    output{\r
+      leaf result{\r
+        type string;\r
+      }\r
+    }\r
+  }\r
+  rpc service-power-turndown{\r
+    input{\r
+      leaf wave-number{\r
+        type uint32;\r
+      }\r
+      list nodes{\r
+        ordered-by user;\r
+        leaf node-id{\r
+          type string;\r
+        }\r
+        leaf src-tp{\r
+          type string;\r
+          description "Source termination point ";\r
+          mandatory true;\r
+        }\r
+        leaf dest-tp{\r
+          type string;\r
+          description "Destination termination point ";\r
+           mandatory true;\r
+        }\r
+      }\r
+    }\r
+    output{\r
+      leaf result{\r
+        type string;\r
+      }\r
+    }\r
+  }\r
+}
\ No newline at end of file
index bb935722c1a6b96680583d2f592d3ef6ca8f6530..ee7caa80f1eb2889e7985ed8f8a4089379fcae50 100644 (file)
@@ -1,48 +1,67 @@
-module portmapping {
-  yang-version 1;
-  namespace "urn:opendaylight:params:xml:ns:yang:portmapping";
-  prefix "portmapping";
-
-  revision "2017-02-28" {
-    description "Initial revision of port mapping model";
-  }
-  container network{
-    list nodes{
-      key node-id;
-      leaf node-id{
-        type string;
-        description
-          "Unique identifier for node in the network";
-      }
-      list mapping{
-        description
-          "Mapping for Physical circuit pack/port/parent interfaces
-          corresponding to each logical connection point present in the node.";
-        key logical-connection-point;
-        leaf logical-connection-point{
-          type string;
-        }
-        leaf supporting-circuit-pack-name{
-          type string;
-          description
-          "Circuit pack where the logical connection point is located";
-        }
-        leaf supporting-port{
-          type string;
-          description
-          "Port where the logical connection point is located";
-        }
-        leaf supporting-oms{
-          type string;
-          description
-          "OMS interface provisioned on the port";
-        }
-        leaf supporting-ots{
-          type string;
-          description
-          "OTS interface provisioned on the port";
-        }
-      }
-    }
-  }
-}
+module portmapping {\r
+  yang-version 1;\r
+  namespace "urn:opendaylight:params:xml:ns:yang:portmapping";\r
+  prefix "portmapping";\r
+\r
+  import org-openroadm-common-types {\r
+    prefix org-openroadm-common-types;\r
+  }\r
+\r
+ organization\r
+    "transportPCE";\r
+  contact\r
+    "transportPCE committers - ODL";\r
+  description\r
+    "YANG definitions of RPCs supported by OLM.\r
+     Copyright © 2017 AT&T and others.  All rights reserved.\r
+     authors: Dhruv Bhardwaj ( db929a@att.com )\r
+              Shweta Vachhani ( sv111y@att.com )";\r
+\r
+  revision "2017-2-28" {\r
+    description "Initial revision of port mapping model";\r
+  }\r
+  container network{\r
+    list nodes{\r
+      key node-id;\r
+      leaf node-id{\r
+        type string;\r
+        description\r
+          "Unique identifier for node in the network";\r
+      }\r
+      leaf node-type{\r
+        type org-openroadm-common-types:node-types;\r
+        description\r
+          "Identifier for node-type e.g Roadm, xponder";\r
+      }\r
+      list mapping{\r
+        description\r
+          "Mapping for Physical circuit pack/port/parent interfaces\r
+          corresponding to each logical connection point present in the node.";\r
+        key logical-connection-point;\r
+        leaf logical-connection-point{\r
+          type string;\r
+        }\r
+        leaf supporting-circuit-pack-name{\r
+          type string;\r
+          description\r
+          "Circuit pack where the logical connection point is located";\r
+        }\r
+        leaf supporting-port{\r
+          type string;\r
+          description\r
+          "Port where the logical connection point is located";\r
+        }\r
+        leaf supporting-oms{\r
+          type string;\r
+          description\r
+          "OMS interface provisioned on the port";\r
+        }\r
+        leaf supporting-ots{\r
+          type string;\r
+          description\r
+          "OTS interface provisioned on the port";\r
+        }\r
+      }\r
+    }\r
+  }\r
+}
\ No newline at end of file
index 707e4b660675918f01152becdffc23b946ed2240..16a1b3a86971f3a75e1387b77639c8f20f5df60e 100644 (file)
@@ -48,5 +48,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>transportpce-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>transportpce-ordmodels</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 </project>
index ba2d07814d1f46630c154b7dff1720f284a96854..9a82ad5efe47884eca550ab7038b44d0e4f006d8 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.transportpce.olm.power.PowerMgmt;
 import org.opendaylight.transportpce.olm.spanloss.RoadmLinks;
 import org.opendaylight.transportpce.olm.spanloss.SpanLoss;
 import org.opendaylight.transportpce.renderer.mapping.PortMapping;
@@ -33,6 +34,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev1
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.MeasurementsBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -218,16 +222,47 @@ public class OlmPowerSetupImpl implements OlmService {
                 roadmLinks.add(rdmLink);
             }
         }
-        boolean successVal = new SpanLoss(db, mps).getLinkSpanloss(roadmLinks);
+        boolean successValSpanCalculation = new SpanLoss(db, mps).getLinkSpanloss(roadmLinks);
+        boolean successValPowerCalculation = new PowerMgmt(db,mps).setPower(input);
 
-        if (successVal) {
+        if (successValSpanCalculation && successValPowerCalculation) {
             output.setResult("Success");
         } else {
             output.setResult("Failed");
         }
 
         return RpcResultBuilder.success(output).buildFuture();
-
     }
 
+
+    /**
+     * This method is the implementation of the 'service-power-trundown' RESTCONF service, which
+     * is one of the external APIs into the olm application.
+     *
+     * <p>
+     * 1. service-power-turndown: This operation performs following steps:
+     *    Step1: For each TP within Node sets interface outofservice .
+     *    Step2: For each roam-connection sets power to -60dbm
+     *    Step3: Turns power mode off
+     *
+     * <p>
+     * The signature for this method was generated by yang tools from the
+     * renderer API model.
+     *
+     * @param input
+     *            Input parameter from the olm yang model
+     *            Input will contain nodeId and termination point
+     *
+     * @return Result of the request
+     */
+    @Override
+    public  Future<RpcResult<ServicePowerTurndownOutput>> servicePowerTurndown(ServicePowerTurndownInput input) {
+        ServicePowerTurndownOutputBuilder output = new ServicePowerTurndownOutputBuilder();
+        if (new PowerMgmt(db,mps).powerTurnDown(input)) {
+            output.setResult("Success");
+        } else {
+            output.setResult("Failed");
+        }
+        return RpcResultBuilder.success(output).buildFuture();
+    }
 }
\ No newline at end of file
diff --git a/olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmt.java b/olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmt.java
new file mode 100644 (file)
index 0000000..789d2fb
--- /dev/null
@@ -0,0 +1,539 @@
+/*
+ * Copyright © 2017 AT&T 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.olm.power;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.MountPoint;
+import org.opendaylight.controller.md.sal.binding.api.MountPointService;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaces;
+import org.opendaylight.transportpce.renderer.provisiondevice.CrossConnect;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.PowerDBm;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev161014.AdminStates;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.och.container.OchBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.Network;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PowerMgmt {
+    private static final Logger LOG = LoggerFactory.getLogger(PowerMgmt.class);
+    private final DataBroker db;
+    private final MountPointService mps;
+    public static final InstanceIdentifier<Topology> NETCONF_TOPO_IID =
+            InstanceIdentifier
+                    .create(NetworkTopology.class)
+                    .child(Topology.class,
+                            new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+
+    public PowerMgmt(DataBroker db, MountPointService mps) {
+        this.db = db;
+        this.mps = mps;
+    }
+
+    /**
+     * This methods measures power requirement for turning up a WL
+     * from the Spanloss at OTS transmit direction and update
+     * roadm-connection target-output-power.
+     *
+     * @param input
+     *            Input parameter from the olm servicePowerSetup rpc
+     *
+     * @return true/false based on status of operation.
+     */
+    public Boolean setPower(ServicePowerSetupInput input) {
+        LOG.info("Olm-setPower initiated");
+        for (int i = 0; i < input.getNodes().size(); i++) {
+            String nodeId = input.getNodes().get(i).getNodeId();
+            String srcTpId =  input.getNodes().get(i).getSrcTp();
+            String destTpId = input.getNodes().get(i).getDestTp();
+            DataBroker deviceDb = getDeviceDataBroker(nodeId , mps);
+            Nodes inputNode = getNode(nodeId, mps, db);
+            LOG.info("Getting data from input node {}",inputNode.getNodeType());
+            LOG.info("Getting mapping data for node is {}",inputNode.getMapping().stream().filter(o -> o.getKey()
+                            .equals(new MappingKey(destTpId))).findFirst().toString());
+            // If node type is transponder
+            if (inputNode.getNodeType() != null && inputNode.getNodeType().equals(NodeTypes.Xpdr)) {
+                // If its A-End transponder
+                if (destTpId.toLowerCase().contains("network")) {
+                    java.util.Optional<Mapping> mappingObject = inputNode.getMapping().stream().filter(o -> o.getKey()
+                            .equals(new MappingKey(destTpId))).findFirst();
+                    if (mappingObject.isPresent()) {
+                        Map<String, Double> txPowerRangeMap = getXponderPowerRange(nodeId, mappingObject.get()
+                                .getSupportingCircuitPackName(),
+                                mappingObject.get().getSupportingPort(),deviceDb);
+                        if (!txPowerRangeMap.isEmpty()) {
+                            LOG.info("Transponder range exists for nodeId: {}", nodeId);
+                            String srgId =  input.getNodes().get(i + 1).getSrcTp();
+                            String nextNodeId = input.getNodes().get(i + 1).getNodeId();
+                            DataBroker deviceDbSRG = getDeviceDataBroker(nextNodeId , mps);
+                            Map<String, Double> rxSRGPowerRangeMap = getSRGRxPowerRange(nextNodeId, srgId, deviceDbSRG);
+                            Double powerValue = new Double(0);
+                            if (!rxSRGPowerRangeMap.isEmpty()) {
+                                LOG.info("SRG Rx Power range exists for nodeId: {}", nodeId);
+                                if (txPowerRangeMap.get("MaxTx").doubleValue()
+                                        <= rxSRGPowerRangeMap.get("MaxRx").doubleValue()) {
+                                    powerValue = txPowerRangeMap.get("MaxTx").doubleValue();
+                                } else if (rxSRGPowerRangeMap.get("MaxRx").doubleValue()
+                                        < txPowerRangeMap.get("MaxTx").doubleValue()) {
+                                    powerValue = rxSRGPowerRangeMap.get("MaxRx").doubleValue();
+                                }
+                                LOG.info("Calculated Transponder Power value is {}" , powerValue);
+                                if (setTransponderPower(nodeId, destTpId, destTpId + "-" + input.getWaveNumber(),
+                                        new BigDecimal(powerValue), deviceDb)) {
+                                    LOG.info("Transponder OCH connection: {} power updated ",
+                                            destTpId + "-" + input.getWaveNumber());
+                                    try {
+                                        LOG.info("Now going in sleep mode");
+                                        Thread.sleep(180000);
+                                    } catch (InterruptedException e) {
+                                        LOG.info("Transponder warmup failed for OCH connection: {}",
+                                              destTpId + "-" + input.getWaveNumber(), e);
+                                    }
+                                } else {
+                                    LOG.info("Transponder OCH connection: {} power update failed ",
+                                           destTpId + "-" + input.getWaveNumber());
+                                }
+                            } else {
+                                LOG.info("SRG Power Range not found");
+                            }
+                        } else {
+                            LOG.info("Tranponder range not available seting to default "
+                                    + "power for nodeId: {}", nodeId);
+                            if (setTransponderPower(nodeId, destTpId, destTpId + "-" + input.getWaveNumber(),
+                                    new BigDecimal(-5), deviceDb)) {
+                                LOG.info("Transponder OCH connection: {} power updated ",
+                                        destTpId + "-" + input.getWaveNumber());
+                                try {
+                                    Thread.sleep(180000);
+                                } catch (InterruptedException e) {
+                                    // TODO Auto-generated catch block
+                                    LOG.info("Transponder warmup failed for OCH connection: {}",
+                                            destTpId + "-" + input.getWaveNumber(), e);
+                                }
+                            } else {
+                                LOG.info("Transponder OCH connection: {} power update failed ",
+                                         destTpId + "-" + input.getWaveNumber());
+                            }
+                        }
+                    } else {
+                        LOG.info("Mapping object not found for nodeId: {}", nodeId);
+                        return false;
+                    }
+                } else {
+                    LOG.info("{} is a drop node. Net power settings needed", nodeId);
+                }
+            } else if (inputNode.getNodeType() != null && inputNode.getNodeType().equals(NodeTypes.Rdm)) {
+            // If Degree is transmitting end then set power
+                if (destTpId.toLowerCase().contains("deg")) {
+                    java.util.Optional<Mapping> mappingObject = inputNode.getMapping().stream().filter(o -> o.getKey()
+                            .equals(new MappingKey(destTpId))).findFirst();
+                    Mapping portMapping = mappingObject.get();
+                    if (portMapping != null && deviceDb != null) {
+                        BigDecimal spanLossTx = new OpenRoadmInterfaces(db, mps, nodeId, destTpId)
+                                .getInterface(portMapping.getSupportingOts()).getAugmentation(Interface1.class).getOts()
+                                .getSpanLossTransmit().getValue();
+                        Double powerValue = Math.min(spanLossTx.doubleValue() - 9 , 2);
+                        CrossConnect roadmCrossConnect = new CrossConnect(deviceDb, srcTpId
+                               + "-" + destTpId + "-" + input.getWaveNumber());
+                        try {
+                            Boolean setXconnPowerSuccessVal = roadmCrossConnect.setPowerLevel(OpticalControlMode.Power,
+                                    new PowerDBm(BigDecimal.valueOf(powerValue)));
+                            if (setXconnPowerSuccessVal) {
+                                LOG.info("Roadm-connection: {} updated ");
+                                //TODO - commented code because one vendor is not supporting
+                                //GainLoss with target-output-power
+                                Thread.sleep(20000);
+                                roadmCrossConnect.setPowerLevel(OpticalControlMode.GainLoss,
+                                        new PowerDBm(BigDecimal.valueOf(powerValue)));
+                            } else {
+                                LOG.info("Set Power failed for Roadm-connection: {} on Node: {}",
+                                        srcTpId + "-" + destTpId + "-" + input.getWaveNumber(), nodeId);
+                                return false;
+                            }
+                        } catch (InterruptedException e) {
+                            LOG.error("Olm-setPower wait failed {}",e);
+                            return false;
+                        }
+                    }
+                  // If Drop node leave node is power mode
+                } else if (destTpId.toLowerCase().contains("srg")) {
+                    LOG.info("Setting power at drop node");
+                    CrossConnect roadmDropCrossConnect = new CrossConnect(deviceDb, srcTpId + "-"
+                            + destTpId + "-" + input.getWaveNumber());
+                    roadmDropCrossConnect.setPowerLevel(OpticalControlMode.Power, null);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * This methods turns down power a WL by performing
+     * following steps:
+     *
+     * <p>
+     * 1. Pull interfaces used in service and change
+     * status to outOfService
+     *
+     * <p>
+     * 2. For each of the ROADM node set target-output-power
+     * to -60dbm, wait for 20 seconds, turn power mode to off
+     *
+     * <p>
+     * 3. Turn down power in Z to A direction and A to Z
+     *
+     * @param input
+     *            Input parameter from the olm servicePowerTurndown rpc
+     *
+     * @return true/false based on status of operation
+     */
+    public Boolean powerTurnDown(ServicePowerTurndownInput input) {
+        LOG.info("Olm-powerTurnDown initiated");
+        /**Starting with last element into the list Z -> A for
+          turning down A -> Z **/
+        for (int i = input.getNodes().size() - 1; i >= 0; i--) {
+            String nodeId = input.getNodes().get(i).getNodeId();
+            String srcTpId =  input.getNodes().get(i).getSrcTp();
+            String destTpId = input.getNodes().get(i).getDestTp();
+            Long wlNumber = input.getWaveNumber();
+            DataBroker deviceDb = getDeviceDataBroker(nodeId , mps);
+            if (!setInterfaceOutOfService(nodeId, srcTpId,
+                    srcTpId + "-" + wlNumber, deviceDb)) {
+                LOG.warn("Out of service status update failed for interface {} ",
+                       srcTpId + "-" + wlNumber);
+                return false;
+            }
+            if (!setInterfaceOutOfService(nodeId, destTpId,
+                    destTpId + "-" + wlNumber, deviceDb)) {
+                LOG.warn("Out of service status update failed for interface {} ",
+                       destTpId + "-" + wlNumber);
+                return false;
+            }
+            CrossConnect roadmCrossConnect = new CrossConnect(deviceDb, srcTpId
+                    + "-" + destTpId + "-" + wlNumber);
+            if (destTpId.toLowerCase().contains("srg")) {
+                roadmCrossConnect.setPowerLevel(OpticalControlMode.Off, null);
+            } else if (destTpId.toLowerCase().contains("deg")) {
+                try {
+                    if (!roadmCrossConnect.setPowerLevel(OpticalControlMode.Power,
+                            new PowerDBm(new BigDecimal(-60)))) {
+                        LOG.warn("Power down failed for Roadm-connection: {}", srcTpId
+                                + "-" + destTpId + "-" + wlNumber);
+                        return false;
+                    }
+                    Thread.sleep(20000);
+                    if (!roadmCrossConnect.setPowerLevel(OpticalControlMode.Off,
+                            null)) {
+                        LOG.warn("Setting power-control mode off failed for Roadm-connection: {}",
+                                srcTpId + "-" + destTpId + "-" + wlNumber);
+                        return false;
+                    }
+                } catch (InterruptedException e) {
+                    // TODO Auto-generated catch block
+                    LOG.error("Olm-powerTurnDown wait failed {}",e);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * This method updates interface administrative state to
+     * outOfService.
+     *
+     * @param nodeId
+     *            Unique identifier for the mounted netconf- node
+     * @param tpId
+     *            Termination point of mounted netconf - node
+     * @param interfaceName
+     *            Name of interface which needs status update
+     * @param deviceDb
+     *            Reference to device data broker
+     * @return true/false based on status of operation
+     */
+    public Boolean setInterfaceOutOfService(String nodeId, String tpId,
+            String interfaceName, DataBroker deviceDb) {
+        InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier
+                .create(OrgOpenroadmDevice.class)
+                .child(Interface.class, new InterfaceKey(interfaceName));
+        Interface nodeInterface = new OpenRoadmInterfaces(db, mps, nodeId, tpId)
+                .getInterface(interfaceName);
+        InterfaceBuilder intfBuilder = new InterfaceBuilder(nodeInterface);
+        intfBuilder.setAdministrativeState(AdminStates.OutOfService);
+        final WriteTransaction writeTransaction = deviceDb.newWriteOnlyTransaction();
+        writeTransaction.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, intfBuilder.build());
+        final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
+        try {
+            submit.checkedGet();
+            LOG.info("Successfully posted interface {}" , interfaceName);
+            return true;
+        } catch (TransactionCommitFailedException ex) {
+            LOG.warn("Failed to post {} ", interfaceName ,ex);
+            return false;
+        }
+    }
+
+    /**
+     * This static method returns the DataBroker for a netconf node.
+     *
+     * @param nodeId
+     *            Unique identifier for the mounted netconf- node
+     * @param mps
+     *            Reference to mount service
+     * @return Databroker for the given device
+     */
+    public static DataBroker getDeviceDataBroker(String nodeId, MountPointService mps) {
+        MountPoint netconfNode = getDeviceMountPoint(nodeId, mps);
+        if (netconfNode != null) {
+            DataBroker netconfNodeDataBroker = netconfNode.getService(DataBroker.class).get();
+            return netconfNodeDataBroker;
+        } else {
+            LOG.info("Device Data broker not found for :" + nodeId);
+            return null;
+        }
+    }
+
+    /**
+     * This static method returns the Mountpoint for a netconf node.
+     *
+     * @param nodeId
+     *            Unique identifier for the mounted netconf- node
+     * @param mps
+     *            Reference to mount service
+     * @return MountPoint for the given device
+     */
+    public static MountPoint getDeviceMountPoint(String nodeId, MountPointService mps) {
+        final Optional<MountPoint> netconfNodeOptional = mps.getMountPoint(NETCONF_TOPO_IID
+                .child(Node.class, new NodeKey(new NodeId(nodeId))));
+        // Get mount point for specified device
+        if (netconfNodeOptional.isPresent()) {
+            MountPoint netconfNode = netconfNodeOptional.get();
+            return netconfNode;
+        } else {
+            LOG.info("Mount Point not found for :" + nodeId);
+            return null;
+        }
+
+    }
+
+    /**
+     * This static method returns the DataBroker for a netconf node.
+     *
+     * @param nodeId
+     *            Unique identifier for the mounted netconf- node
+     * @param mps
+     *            Reference to mount service
+     * @param db
+     *            Databroker
+     * @return Nodes from portMapping for given nodeId
+     */
+    public static Nodes getNode(String nodeId, MountPointService mps, DataBroker db) {
+        InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class)
+                .child(Nodes.class, new NodesKey(nodeId));
+        ReadOnlyTransaction readTransaction = db.newReadOnlyTransaction();
+        Optional<Nodes> nodeObject;
+        try {
+            nodeObject = readTransaction.read(LogicalDatastoreType.CONFIGURATION, nodesIID).get();
+            if (nodeObject.isPresent()) {
+                LOG.info("Found Node in Portmapping for nodeId {}", nodeObject.get().getNodeId());
+                return nodeObject.get();
+            } else {
+                LOG.info("Could not find Portmapping for nodeId {}", nodeId);
+                return null;
+            }
+        } catch (InterruptedException | ExecutionException ex) {
+            LOG.info("Unable to read Portmapping for nodeId {}", nodeId, ex);
+        }
+        return null;
+    }
+
+    /**
+     * This method provides Transponder transmit power range.
+     *
+     * @param nodeId
+     *            Unique identifier for the mounted netconf- node
+     * @param circuitPackName
+     *            Transponder circuitPack name
+     * @param portName
+     *            Transponder port name
+     * @param deviceDb
+     *            Databroker for the given device
+     * @return HashMap holding Min and Max transmit power for given port
+     */
+    public Map<String, Double> getXponderPowerRange(String nodeId, String circuitPackName, String portName,
+            DataBroker deviceDb) {
+        InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
+                CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class, new PortsKey(portName));
+        ReadOnlyTransaction readTransaction = deviceDb.newReadOnlyTransaction();
+        Map<String, Double> powerRangeMap = new HashMap<String, Double>();
+        try {
+            LOG.info("Fetching logical Connection Point value for port " + portName + " at circuit pack "
+                + circuitPackName);
+            Optional<Ports> portObject = readTransaction.read(LogicalDatastoreType.OPERATIONAL, portIID).get();
+            if (portObject.isPresent()) {
+                Ports port = portObject.get();
+                if (port.getTransponderPort() != null) {
+                    powerRangeMap.put("MaxTx", port.getTransponderPort().getPortPowerCapabilityMaxTx()
+                            .getValue().doubleValue());
+                    powerRangeMap.put("MinTx", port.getTransponderPort().getPortPowerCapabilityMinTx()
+                            .getValue().doubleValue());
+                } else {
+                    LOG.warn("Logical Connection Point value missing for " + circuitPackName + " " + port
+                        .getPortName());
+                }
+            }
+        } catch (InterruptedException | ExecutionException ex) {
+            LOG.warn("Read failed for Logical Connection Point value missing for " + circuitPackName + " "
+                + portName,ex);
+            return powerRangeMap;
+        }
+        return powerRangeMap;
+    }
+
+    /**
+     * This method provides Transponder transmit power range.
+     *
+     * @param nodeId
+     *            Unique identifier for the mounted netconf- node
+     * @param srgId
+     *            SRG Id connected to transponder
+     * @param deviceDb
+     *            Databroker for the given device
+     * @return HashMap holding Min and Max transmit power for given port
+     */
+    public Map<String, Double> getSRGRxPowerRange(String nodeId, String srgId, DataBroker deviceDb) {
+        Map<String, Double> powerRangeMap = new HashMap<String, Double>();
+        LOG.info("Coming inside Xpdr power range");
+        java.util.Optional<Mapping> mappingSRGObject = getNode(nodeId, mps, db).getMapping()
+                .stream().filter(o -> o.getKey()
+                .equals(new MappingKey(srgId))).findFirst();
+        if (mappingSRGObject.isPresent()) {
+            LOG.info("Mapping object exists.");
+            String circuitPackName = mappingSRGObject.get().getSupportingCircuitPackName();
+            String portName = mappingSRGObject.get().getSupportingPort();
+            InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
+                    .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
+                    .child(Ports.class, new PortsKey(portName));
+            try {
+                LOG.info("Fetching logical Connection Point value for port " + portName + " at circuit pack "
+                    + circuitPackName + portIID);
+                ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
+                Optional<Ports> portObject = rtx.read(LogicalDatastoreType.OPERATIONAL, portIID).get();
+                if (portObject.isPresent()) {
+                    Ports port = portObject.get();
+                    if (port.getRoadmPort() != null) {
+                        LOG.info("Port found on the node ID");
+                        powerRangeMap.put("MinRx", port.getRoadmPort()
+                                .getPortPowerCapabilityMinRx().getValue().doubleValue());
+                        powerRangeMap.put("MaxRx", port.getRoadmPort()
+                                .getPortPowerCapabilityMaxRx().getValue().doubleValue());
+                        return powerRangeMap;
+                    } else {
+                        LOG.warn("Roadm ports power value is missing for " + circuitPackName + " " + port
+                            .getPortName());
+                    }
+                } else {
+                    LOG.info("Port not found");
+                }
+            } catch (InterruptedException | ExecutionException ex) {
+                LOG.warn("Read failed for Logical Connection Point value missing for " + circuitPackName + " "
+                    + portName,ex);
+            }
+        } else {
+            LOG.info("Port mapping not found for nodeId: {} and srgId: {} ",
+                    nodeId, srgId);
+        }
+        return powerRangeMap;
+
+    }
+
+    /**
+     * This method retrieves transponder OCH interface and
+     * sets power.
+     *
+     * @param nodeId
+     *            Unique identifier for the mounted netconf- node
+     * @param tpId
+     *            Termination port for transponder connected to SRG
+     * @param interfaceName
+     *            OCH interface name carrying WL
+     * @param txPower
+     *            Calculated transmit power
+     * @param deviceDb
+     *            Databroker for the given device
+     * @return true/false based on status of operation
+     */
+    public boolean setTransponderPower(String nodeId, String tpId, String interfaceName, BigDecimal txPower,
+            DataBroker deviceDb) {
+        LOG.info("Setting target-power for transponder nodeId: {} InterfaceName: {}",
+                nodeId, interfaceName);
+        InterfaceBuilder ochInterfaceBuilder = new InterfaceBuilder(
+                new OpenRoadmInterfaces(db, mps, nodeId, tpId)
+                   .getInterface(interfaceName));
+        OchBuilder ochBuilder = new OchBuilder(ochInterfaceBuilder
+                .getAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.optical
+                        .channel.interfaces.rev161014.Interface1.class).getOch());
+        ochBuilder.setTransmitPower(new PowerDBm(txPower));
+        ochInterfaceBuilder.addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.optical
+                .channel.interfaces.rev161014.Interface1.class,
+                new Interface1Builder().setOch(ochBuilder.build()).build());
+        ReadWriteTransaction rwtx = deviceDb.newReadWriteTransaction();
+        InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
+                .child(Interface.class, new InterfaceKey(interfaceName));
+        rwtx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, ochInterfaceBuilder.build());
+        CheckedFuture<Void, TransactionCommitFailedException> submit = rwtx.submit();
+        try {
+            submit.checkedGet();
+            LOG.info("Power update is submitted");
+            return true;
+        } catch (TransactionCommitFailedException e) {
+            LOG.info("Setting transponder power failed {}" ,e);
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
index f7c314cc9499662e7da51a2bfd563dde2aa933ad..026c041fe93135e3c34efe525a096b6d2f82c6c0 100644 (file)
@@ -73,6 +73,8 @@ public class SpanLoss {
      *            Node-id of the NE.
      * @param tpID
      *            Termination point Name.
+     * @param pmName
+     *            PM name which need to be retrieved
      * @return reference to OtsPmHolder
      */
     public OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
@@ -195,4 +197,4 @@ public class SpanLoss {
         }
         return true;
     }
-}
+}
\ No newline at end of file
index 9ff32a24c28528b79eae4a66abd35f05541f55c5..ec4a3bd694ab71c3a786c1bce36a91c7c70ef4f4 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaces;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
@@ -104,6 +105,7 @@ public class PortMapping {
         DataBroker deviceDb = getDeviceDataBroker(nodeId, mps);
         List<Mapping> portMapList = new ArrayList<>();
         Info deviceInfo;
+        Integer nodeType = 1;
         if (deviceDb != null) {
             deviceInfo = getDeviceInfo(deviceDb);
             if (deviceInfo != null) {
@@ -111,7 +113,7 @@ public class PortMapping {
                     LOG.info("Node type mandatory field is missing");
                     return false;
                 }
-                Integer nodeType = deviceInfo.getNodeType().getIntValue();
+                nodeType = deviceInfo.getNodeType().getIntValue();
                 // Create Mapping for Roadm Node
                 if (nodeType == 1) {
                     // Get TTP port mapping
@@ -144,7 +146,7 @@ public class PortMapping {
             LOG.info("Unable to get Data broker for node " + nodeId);
             return false;
         }
-        return postPortMapping(deviceInfo, portMapList);
+        return postPortMapping(deviceInfo, portMapList, nodeType);
     }
 
     /**
@@ -539,12 +541,13 @@ public class PortMapping {
      *
      * @return Result true/false based on status of operation.
      */
-    private boolean postPortMapping(Info deviceInfo, List<Mapping> portMapList) {
+    private boolean postPortMapping(Info deviceInfo, List<Mapping> portMapList, Integer nodeType) {
 
-        List<Nodes> nodesList = new ArrayList<>();
         NodesBuilder nodesBldr = new NodesBuilder();
         nodesBldr.setKey(new NodesKey(deviceInfo.getNodeId())).setNodeId(deviceInfo.getNodeId());
+        nodesBldr.setNodeType(NodeTypes.forValue(nodeType));
         nodesBldr.setMapping(portMapList);
+        List<Nodes> nodesList = new ArrayList<>();
         nodesList.add(nodesBldr.build());
         NetworkBuilder nwBldr = new NetworkBuilder();
         nwBldr.setNodes(nodesList);
index 78838cad6b7c4707219c340635a550bc666263c1..a23d84e24e84e8bfef40a247626680eedc6e8b23 100644 (file)
@@ -133,7 +133,7 @@ public class OpenRoadmInterfaces {
         InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
             Interface.class, new InterfaceKey(interfaceName));
         try {
-            Optional<Interface> interfaceObject = rtx.read(LogicalDatastoreType.OPERATIONAL, interfacesIID).get();
+            Optional<Interface> interfaceObject = rtx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
             if (interfaceObject.isPresent()) {
                 return interfaceObject.get();
             } else {
index 94404c1336bc1f63035afb203e1ccccc9e988f1e..af220f7bbd05757e206c205acd0dbd8a32198c75 100644 (file)
@@ -226,7 +226,7 @@ public class CrossConnect {
                 try {
                     submit.checkedGet();
                     LOG.info("Roadm connection power level successfully set ");
-                    return false;
+                    return true;
                 } catch (TransactionCommitFailedException ex) {
                     LOG.info("Failed to post {} ", rdmConnBldr.build(), ex);
                     return false;
@@ -289,4 +289,4 @@ public class CrossConnect {
         }
         return null;
     }
-}
+}
\ No newline at end of file