--- /dev/null
+.. _transportpce-tox-guide:
+
+TransportPCE tox Guide
+======================
+
+What is tox?
+------------
+
+`Tox` is a tool written in Python to ease tests automation and dependencies management.
+It provides a command line tool that run tests inside a `Python virtual environment <https://docs.python.org/3/glossary.html#term-virtual-environment>`_.
+
+This means that it will not modify your local system settings or package and executable files.
+Instead, it uses a hidden folder (`.tox`) to install the required Python dependencies via pip
+(`the package installer for Python <https://pip.pypa.io/>`_) before running tests.
+
+You can find more details about tox at https://github.com/tox-dev/tox .
+`Tox` is often used as a front-end to Continuous Integration servers.
+
+For instance, `Linux Foundation globaljjb <https://globaljjbdocstest.readthedocs.io/en/latest/jjb/lf-python-jobs.html#tox-verify>`_
+provides a gerrit-tox-verify profile.
+This profile is `used by TransportPCE <https://git.opendaylight.org/gerrit/c/releng/builder/+/78656>`_
+in OpenDaylight Jenkins CI.
+
+`Tox` configuration and behavior is very portable across GNU+Linux distributions
+and others UNIX-like systems or environments.
+
+Once tox installed in a local environment with
+for example the following command on Debian based systems::
+
+ $ sudo apt-get install tox
+
+or on Red Hat based systems::
+
+ $ sudo yum install python-tox
+
+the same test suite than the CI can be run locally by simply calling the tox command
+from the project git clone local folder::
+
+ $ tox
+
+Tox configuration
+-----------------
+
+`Tox` configuration is written in the `tox.ini` file at the root folder of the Git project.
+Please read `tox official documentation <https://tox.readthedocs.io/>`_ for more details.
+For tox users, the most important parameter in the `[tox]` section is `envlist`.
+It specifies which profiles to run by default (i.e. when tox is called without the option `-e`).
+The option `-e` overrides this parameter and allows to choose which profiles to run.
+For example::
+
+ $ tox -e gitlint
+
+will only run the `gitlint` profile.
+And::
+
+ $ tox -e gitlint,checkbashisms
+
+will run the `gitlint` and `checkbashisms` profiles.
+
+Profiles configuration are described in the `[testenv]` section.
+Each profile specificities are usually configured in a subsection, for example the
+subsection `[testenv:gitlint]` for the configuration of `Gitlint <https://jorisroovers.com/gitlint/>`_.
+
+Docs profiles
+-------------
+
+The `docs` profile itself is used to generate from the sources the HTML documentation of the project.
+This docuementation can be found in `docs/_build/html/`
+once the following command has been run locally::
+
+ $ tox -e docs
+
+The sources are written in the reStructuredText format a.k.a. RST and are located in the `docs/` folder.
+
+`Sphinx` can also be used to check the validity of the URLs present in the sources
+with the `docs-linkcheck` profile::
+
+ $ tox -e docs-linkcheck
+
+False positives can be declared in the sphinx configuration file (usually `docs/conf.py`).
+Both `docs` and `docs-linkcheck` profiles are run in the CI.
+
+A third profile called `spelling` and based on `Sphinx` and `PyEnchant <https://pyenchant.github.io/pyenchant/>`_
+can also be used as a spellchecker.
+
+.. note::
+
+ All docs profiles call the sphinx Python package.
+ Documentation and more details can be found at `sphinx home page <https://www.sphinx-doc.org/>`_ .
+ Web page templates are inherited from the Python dependency `lfdocs-conf` delared in `docs/requirements.txt`.
+
+Linter profiles
+---------------
+
+A few linter are also provided from tox profiles.
+Some are even performed in the CI.
+
+* `gitlint`. Check that the last commit message is well formatted.
+* `pylint`. Lint Python tests scripts
+* `autopep8`. Autoformat Python tests scripts according to PEP8 standard rules.
+* `pyang`. Lint YANG files.
+* `pyangformat`. Autoformat YANG files.
+* `checkbashisms`. Detect bashisms in shell scripts.
+
+
+Pre-commit profiles
+-------------------
+
+`Pre-commit <https://pre-commit.com/>`_ is another wrapper for linters that relies on `Git Hooks <https://githooks.com/>`_.
+It is particularly useful to address common programming issues such as
+triming trailing whitespaces or removing tabs.
+
+`Pre-commit` configuration can be found in the `.pre-commit-config.yaml` file
+at the Git project root.
+`Pre-commit` hooks, like any other Git hooks, are run automatically when the
+command `'git commit'` is called. This avoids forgetting running linters.
+Although, `pre-commit` can also be called directly from its shell command.
+This is what is currently performed in TransportPCE CI.
+
+The `pre-commit` profile allows to call `pre-commit` inside tox virtualenv
+without installing the `pre-commit` package in the local system,
+what is pretty convenient::
+
+ $ tox -e pre-commit
+
+This is also true to install/uninstall the corresponding Git hooks in your
+Git folder thanks to the profiles `pre-commit-install`
+and `pre-commit-uninstall`::
+
+ $ tox -e pre-commit-install
+
+and::
+
+ $ tox -e pre-commit-uninstall
+
+Functional tests profiles
+-------------------------
+
+TransportPCE functional tests are Python scripts that allow to perform blackbox testing on a
+controller instance.
+They do not need tox to be performed locally and can be called directly from the shell or with
+a launcher such as `nosetests <https://nose.readthedocs.io/>`_
+(often available in Linux distributions packages under the name `python-nose`).
+Currently, they require the presence of `Honeynode simulators <https://gitlab.com/Orange-OpenSource/lfn/odl/honeynode-simulator>`_
+and the modification of the controller default OLM timers to speed-up the tests.
+They are also supposed to be called within the tests folder::
+
+ $ cd tests/
+
+These tests have been spread over several directories in `tranportpce_tests/`.
+These directories are mostly named upon OpenROADM device versions.
+Tests scripts files names are also numbered so that they are performed in a certain order.
+To ease their integration in tox, a script `launch_tests.sh` can be used to call them.
+For example, the following command::
+
+ $ ./launch_tests.sh pce
+
+will call by default all the tests in the folder `tests/transportpce_tests/pce` with `nose`.
+And the command::
+
+ $ ./launch_tests.sh 1.2.1 portmapping
+
+is equivalent to::
+
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test01_portmapping.py
+
+Several tests can be listed in the arguments. For example::
+
+ $ ./launch_tests.sh 1.2.1 portmapping topology
+
+is equivalent to::
+
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test01_portmapping.py
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test03_topology.py
+
+Also, some shell environment variables can be used to modify their default behavior.
+For example the commands::
+
+ $ export LAUNCHER="python3"
+ $ ./launch_tests.sh 2.2.1
+
+are equivalent to::
+
+ $ python3 transportpce_tests/2.2.1/test01_portmapping.py
+
+And::
+
+ $ export LAUNCHER="nosetests"
+ $ export USE_LIGHTY="True"
+ $ ./launch_tests.sh 7.1
+
+are equivalent to::
+
+ $ nosetests transportpce_tests/2.2.1/test01_portmapping.py
+
+but will ask tests script to use the controller `lighty.io <https://lighty.io/>`_
+build instead of Karaf.
+
+These variables are also understood inside tox virtualenv thanks to the `passenv` parameter
+configured in `tox.ini`.
+
+Tox TransportPCE functional tests support is split into several tox profiles.
+Strictly spoken, only the following profiles perform functional tests as described above:
+
+* `testsPCE`. To evaluate the Path Computation behavior.
+* `tests121`. To evaluate the support of OpenROADM devices version 1.2.1 .
+* `tests221`. To evaluate the support of OpenROADM devices version 2.2.1 .
+* `tests71`. To evaluate the support of OpenROADM devices version 7.1 .
+* `tests_hybrid`. To evaluate the controller behavior in a mixed environment with several versions of OpenROADM devices.
+* `gnpy`. To evaluate the controller behavior when used in conjunction with `GNPy <https://github.com/Telecominfraproject/oopt-gnpy>`_. Requires `docker <https://www.docker.com/>`_.
+* `nbinotifications`. To evaluate the controller north-bound interface notifications support. Requires `docker <https://www.docker.com/>`_.
+
+Each of these profiles depend on the `buildcontroller` profile, which is simply
+there to build the controller from sources and adapt OLM default timers.
+They can also depend on `sims121` or `sims221` or `sims71` profiles to download
+simulators of OpenROADM devices when needed.
+
+The `depend` parameter in `tox.ini` allows tox to establish the most efficient
+tests order strategy when calling tox without the `-e` option.
+This is particularly important when the parallelized mode is enabled.
+If tox is called locally with the option `-e`, profiles not specified to this
+option but listed in the `depends` parameters are simply ignored.
+This means you have to specify manually the `buildcontroller` or `simsXXX`
+profiles if the controller was not build yet or the sims were not downloaded.
+For example::
+
+ $ tox -e buildcontroller,sims121,tests121
+
+will build the controller and download simulators before running every functional
+tests for OpenROADM devices 1.2.1.
+Once that done, you only need to list the others sims versions profiles before
+lauching hybrid tests::
+
+ $ tox -e sims221,sims71,tests_hybrid
+
+Also the same way arguments can be passed to the `launch_tests.sh` script,
+tests names can be passed as argument when calling the corresponding tox profiles.
+
+For example:
+
+ $ tox -e tests121 portmapping
+
+will launch by default the following command inside tox virtual environment::
+
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test01_portmapping.py
+
+And::
+
+ $ tox -e tests121 "portmapping topology"
+
+will perform::
+
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test01_portmapping.py
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test03_topology.py
+
+Note the necessity to use quotes here when listing several test names.
+If you need to test the portmapping behavior for every OpenROADM devices versions::
+
+ $ tox -e tests121,tests221,tests71 portmapping
+
+will perform::
+
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test01_portmapping.py
+ $ nosetests --with-xunit transportpce_tests/2.2.1/test01_portmapping.py
+ $ nosetests --with-xunit transportpce_tests/7.1/test01_portmapping.py
+
+Idem for OLM with only OpenROADM devices versions 1.2.1 and 2.2.1 ::
+
+ $ tox -e tests121,tests221 olm
+
+will perform::
+
+ $ nosetests --with-xunit transportpce_tests/1.2.1/test05_olm.py
+ $ nosetests --with-xunit transportpce_tests/2.2.1/test08_olm.py
+
+Profiles parrallelization
+-------------------------
+
+Tox profiles execution can be parallelized.
+CI behavior can be configured from the `releng/builder` repository.
+This is `the current configuration <https://git.opendaylight.org/gerrit/c/releng/builder/+/96557>`_
+in TransportPCE CI.
+
+Locally, tox jobs are not parallelized by default.
+You have to use the `-p` option to specify the level of concurrency::
+
+ $ tox -p
+
+or::
+
+ $ tox -p auto
+
+or::
+
+ $ tox -p 2
+
+The default parameter "auto" is based on the number of CPU cores,
+which is a bad idea for TransportPCE functional tests.
+Their most critical ressource is RAM, mostly because of the need
+to launch several simulators very greedy in memory.
+Unfortunately, "auto" is historically the only option available
+in OpenDaylight CI configuration.
+To palliate this problem, `tox.ini` current configuration uses the `depends` parameter
+to artifically chain tests profiles and limit to only 2 the number of controller instances
+run in parallel.
+
+Also, the default display will change from the classical sequence mode.
+You need to use the option `-o` to get it back (with the notable difference
+that displayed messages are now mixed between tests profiles).
+This is the default configuration in the CI::
+
+ $ tox -o -p 2
+
+Running different tests in parallel also creates concurrency access problems
+to others ressources than RAM, mostly the ports to listen to, and the log files.
+To this sake, lighty.io and karaf build configuration have been customized to change
+thier listening ports and log files from shell environment variables.
+This environment variables are also understood by Python tests scripts and tox.
+
+You can take a look at the following Gerrit changes for more details
+
+https://git.opendaylight.org/gerrit/q/topic:%2522parallel%2522+project:transportpce
+
+And particularly at
+
+https://git.opendaylight.org/gerrit/c/transportpce/+/96696
+
+and
+
+https://git.opendaylight.org/gerrit/c/transportpce/+/96662
+
+and
+
+https://git.opendaylight.org/gerrit/c/transportpce/+/96663
+
+In a nutshell, TransportPCE CI uses tox and parrallelization to perform functional tests.
+And if your computer environment has enough RAM and CPU cores,
+it is perfectly possible to run the same way several functional tests concurrently on it.
+For example, the following command will test the portmapping behavior
+for every OpenROADM devices supported versions::
+
+ $ tox -p 3 -e buildcontroller,sims121,sims221,sims71,tests121,tests221,tests71 portmapping
*/
package org.opendaylight.transportpce.olm.power;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.math.BigDecimal;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.Nodes;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode;
import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes;
import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@SuppressFBWarnings("DM_CONVERT_CASE")
public class PowerMgmtImpl implements PowerMgmt {
private static final Logger LOG = LoggerFactory.getLogger(PowerMgmtImpl.class);
private final DataBroker db;
private final DeviceTransactionManager deviceTransactionManager;
private static final BigDecimal DEFAULT_TPDR_PWR_100G = new BigDecimal(-5);
private static final BigDecimal DEFAULT_TPDR_PWR_400G = new BigDecimal(0);
-
+ private static final String INTERFACE_NOT_PRESENT = "Interface {} on node {} is not present!";
public PowerMgmtImpl(DataBroker db, OpenRoadmInterfaces openRoadmInterfaces,
CrossConnect crossConnect, DeviceTransactionManager deviceTransactionManager) {
* @return true/false based on status of operation.
*/
//TODO Need to Case Optical Power mode/NodeType in case of 2.2 devices
- //@SuppressFBwarnings("DM_CONVERT_CASE")
public Boolean setPower(ServicePowerSetupInput input) {
LOG.info("Olm-setPower initiated for input {}", input);
- int lowerSpectralSlotNumber = input.getLowerSpectralSlotNumber().intValue();
- int higherSpectralSlotNumber = input.getHigherSpectralSlotNumber().intValue();
String spectralSlotName = String.join(GridConstant.SPECTRAL_SLOT_SEPARATOR,
- String.valueOf(lowerSpectralSlotNumber),
- String.valueOf(higherSpectralSlotNumber));
+ input.getLowerSpectralSlotNumber().toString(),
+ input.getHigherSpectralSlotNumber().toString());
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();
Optional<Nodes> inputNodeOptional = OlmUtils.getNode(nodeId, this.db);
- // If node type is transponder
- if (inputNodeOptional.isPresent()
- && (inputNodeOptional.get().getNodeInfo().getNodeType() != null)
- && inputNodeOptional.get().getNodeInfo().getNodeType().equals(NodeTypes.Xpdr)
- && destTpId != null) {
+ if (inputNodeOptional.isEmpty()
+ || inputNodeOptional.get().getNodeInfo().getNodeType() == null) {
+ LOG.error("OLM-PowerMgmtImpl : Error node type cannot be retrieved for node {}", nodeId);
+ continue;
+ }
+ Nodes inputNode = inputNodeOptional.get();
+ OpenroadmNodeVersion openroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion();
- Nodes inputNode = inputNodeOptional.get();
- OpenroadmNodeVersion openroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion();
- LOG.info("Getting data from input node {}", inputNode.getNodeInfo().getNodeType());
- LOG.info("Getting mapping data for node is {}",
+ switch (inputNode.getNodeInfo().getNodeType()) {
+ case Xpdr:
+ if (destTpId == null) {
+ continue;
+ }
+ LOG.info("Getting data from input node {}", inputNode.getNodeInfo().getNodeType());
+ LOG.info("Getting mapping data for node is {}",
inputNode.nonnullMapping().values().stream().filter(o -> o.key()
.equals(new MappingKey(destTpId))).findFirst().toString());
- // If its A-End transponder
- if (destTpId.toLowerCase().contains("network")) {
- java.util.Optional<Mapping> mappingObject = inputNode.nonnullMapping()
- .values().stream().filter(o -> o.key()
- .equals(new MappingKey(destTpId))).findFirst();
- boolean setTpdrPowerResult;
- if (mappingObject.isPresent()) {
- String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
- String portName = mappingObject.get().getSupportingPort();
- Map<String, Double> txPowerRangeMap = new HashMap<>();
- switch (openroadmVersion.getIntValue()) {
- case 1:
- txPowerRangeMap = PowerMgmtVersion121.getXponderPowerRange(circuitPackName, portName,
- nodeId, deviceTransactionManager);
- break;
- case 2:
- txPowerRangeMap = PowerMgmtVersion221.getXponderPowerRange(circuitPackName, portName,
- nodeId, deviceTransactionManager);
- break;
- case 3:
- txPowerRangeMap = PowerMgmtVersion710.getXponderPowerRange(circuitPackName, portName,
- nodeId, deviceTransactionManager);
- break;
- default:
- LOG.error("Unrecognized OpenRoadm version");
- }
- if (!txPowerRangeMap.isEmpty()) {
- LOG.info("Transponder range exists for nodeId: {}", nodeId);
- OpenroadmNodeVersion rdmOpenroadmVersion = openroadmVersion;
- String srgId = input.getNodes().get(i + 1).getSrcTp();
- String nextNodeId = input.getNodes().get(i + 1).getNodeId();
- Optional<Nodes> inputNextOptional = OlmUtils.getNode(nextNodeId, this.db);
- if (inputNextOptional.isPresent()) {
- rdmOpenroadmVersion = inputNextOptional.get()
- .getNodeInfo().getOpenroadmVersion();
- }
- Map<String, Double> rxSRGPowerRangeMap = new HashMap<>();
- Optional<Mapping> mappingObjectSRG = OlmUtils.getNode(nextNodeId, db)
- .flatMap(node -> node.nonnullMapping().values()
- .stream().filter(o -> o.key()
- .equals(new MappingKey(srgId))).findFirst());
+ // If its not A-End transponder
+ if (!destTpId.toUpperCase(Locale.getDefault()).contains("NETWORK")) {
+ LOG.info("{} is a drop node. Net power settings needed", nodeId);
+ continue;
+ }
- if (mappingObjectSRG.isPresent()) {
- switch (rdmOpenroadmVersion.getIntValue()) {
- case 1:
- rxSRGPowerRangeMap = PowerMgmtVersion121.getSRGRxPowerRange(nextNodeId, srgId,
- deviceTransactionManager, mappingObjectSRG.get()
- .getSupportingCircuitPackName(),
- mappingObjectSRG.get().getSupportingPort());
- break;
- case 2:
- rxSRGPowerRangeMap = PowerMgmtVersion221.getSRGRxPowerRange(nextNodeId, srgId,
- deviceTransactionManager, mappingObjectSRG.get()
- .getSupportingCircuitPackName(),
- mappingObjectSRG.get().getSupportingPort());
- break;
- case 3:
- rxSRGPowerRangeMap = PowerMgmtVersion710.getSRGRxPowerRange(nextNodeId, srgId,
- deviceTransactionManager, mappingObjectSRG.get()
- .getSupportingCircuitPackName(),
- mappingObjectSRG.get().getSupportingPort());
- break;
- default:
- LOG.error("Unrecognized OpenRoadm version");
- return false;
- }
- }
- double powerValue = 0;
- if (!rxSRGPowerRangeMap.isEmpty()) {
- LOG.info("SRG Rx Power range exists for nodeId: {}", nodeId);
- if (txPowerRangeMap.get("MaxTx")
- <= rxSRGPowerRangeMap.get("MaxRx")) {
- powerValue = txPowerRangeMap.get("MaxTx");
- } else if (rxSRGPowerRangeMap.get("MaxRx")
- < txPowerRangeMap.get("MaxTx")) {
- powerValue = rxSRGPowerRangeMap.get("MaxRx");
- }
- LOG.info("Calculated Transponder Power value is {}" , powerValue);
- String interfaceName = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
- destTpId, spectralSlotName);
- if (callSetTransponderPower(nodeId, interfaceName, new BigDecimal(powerValue),
- openroadmVersion)) {
- LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
- try {
- LOG.info("Now going in sleep mode");
- Thread.sleep(OlmUtils.OLM_TIMER_1);
- } catch (InterruptedException e) {
- LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
- }
- } else {
- LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
- }
- } else {
- LOG.info("SRG Power Range not found, setting the Transponder range to default");
- String interfaceName = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
- destTpId, spectralSlotName);
- if (openroadmVersion.getIntValue() == 3) {
- setTpdrPowerResult = callSetTransponderPower(nodeId, interfaceName,
- DEFAULT_TPDR_PWR_400G, openroadmVersion);
- } else {
- setTpdrPowerResult = callSetTransponderPower(nodeId, interfaceName,
- DEFAULT_TPDR_PWR_100G, openroadmVersion);
- }
- if (setTpdrPowerResult) {
- LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
- try {
- Thread.sleep(OlmUtils.OLM_TIMER_1);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
- }
- } else {
- LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
- }
- }
- } else {
- LOG.info("Tranponder range not available setting to default power for nodeId: {}", nodeId);
- String interfaceName = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
- destTpId, spectralSlotName);
- if (openroadmVersion.getIntValue() == 3) {
- setTpdrPowerResult = callSetTransponderPower(nodeId, interfaceName,
- DEFAULT_TPDR_PWR_400G, openroadmVersion);
- } else {
- setTpdrPowerResult = callSetTransponderPower(nodeId, interfaceName,
- DEFAULT_TPDR_PWR_100G, openroadmVersion);
- }
- if (setTpdrPowerResult) {
- LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
- try {
- Thread.sleep(OlmUtils.OLM_TIMER_1);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
- }
- } else {
- LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
- }
- }
- } else {
- LOG.info("Mapping object not found for nodeId: {}", nodeId);
+ BigDecimal powerVal = getXpdrPowerValue(
+ inputNode, destTpId, nodeId, openroadmVersion.getIntValue(),
+ input.getNodes().get(i + 1).getSrcTp(), input.getNodes().get(i + 1).getNodeId());
+ if (powerVal == null) {
return false;
}
- } else {
- LOG.info("{} is a drop node. Net power settings needed", nodeId);
- }
- } else if (inputNodeOptional.isPresent()
- && (inputNodeOptional.get().getNodeInfo().getNodeType() != null)
- && inputNodeOptional.get().getNodeInfo().getNodeType().equals(NodeTypes.Rdm)) {
- // If Degree is transmitting end then set power
- Nodes inputNode = inputNodeOptional.get();
- OpenroadmNodeVersion openroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion();
- LOG.info("This is a roadm {} device", openroadmVersion.getName());
- String connectionNumber = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,srcTpId, destTpId,
- spectralSlotName);
- LOG.info("Connection number is {}", connectionNumber);
- if (destTpId.toLowerCase().contains("deg")) {
+
+ String interfaceName = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
+ destTpId, spectralSlotName);
+ if (!callSetTransponderPower(nodeId, interfaceName, powerVal, openroadmVersion)) {
+ LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
+ continue;
+ }
+ LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
+ try {
+ LOG.info("Now going in sleep mode");
+ Thread.sleep(OlmUtils.OLM_TIMER_1);
+ } catch (InterruptedException e) {
+ LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
+ // FIXME shouldn't it be LOG.warn or LOG.error?
+ // or maybe this try/catch block can simply be removed
+ }
+ break;
+ case Rdm:
+ LOG.info("This is a roadm {} device", openroadmVersion.getName());
+ String connectionNumber = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
+ input.getNodes().get(i).getSrcTp(), destTpId, spectralSlotName);
+ LOG.info("Connection number is {}", connectionNumber);
+
+ // If Drop node leave node is power mode
+ if (destTpId.toUpperCase(Locale.getDefault()).contains("SRG")) {
+ LOG.info("Setting power at drop node");
+ crossConnect.setPowerLevel(nodeId, OpticalControlMode.Power.getName(), null, connectionNumber);
+ continue;
+ }
+ if (!destTpId.toUpperCase(Locale.getDefault()).contains("DEG")) {
+ continue;
+ }
+ // If Degree is transmitting end then set power
Optional<Mapping> mappingObjectOptional = inputNode.nonnullMapping()
.values().stream().filter(o -> o.key()
.equals(new MappingKey(destTpId))).findFirst();
- if (mappingObjectOptional.isPresent()) {
- BigDecimal spanLossTx = null;
- LOG.info("Dest point is Degree {}", mappingObjectOptional.get());
- Mapping portMapping = mappingObjectOptional.get();
- // debut reprise
- if (openroadmVersion.getIntValue() == 1) {
- Optional<Interface> interfaceOpt;
- try {
- interfaceOpt =
- this.openRoadmInterfaces.getInterface(nodeId, portMapping.getSupportingOts());
- } catch (OpenRoadmInterfaceException ex) {
- LOG.error("Failed to get interface {} from node {}!", portMapping.getSupportingOts(),
- nodeId, ex);
- return false;
- } catch (IllegalArgumentException ex) {
- LOG.error("Failed to get non existing interface {} from node {}!",
- portMapping.getSupportingOts(), nodeId);
- return false;
- }
- if (interfaceOpt.isPresent()) {
- if (interfaceOpt.get().augmentation(Interface1.class).getOts()
- .getSpanLossTransmit() != null) {
- spanLossTx = interfaceOpt.get().augmentation(Interface1.class).getOts()
- .getSpanLossTransmit().getValue();
- LOG.info("Spanloss TX is {}", spanLossTx);
- } else {
- LOG.error("interface {} has no spanloss value", interfaceOpt.get().getName());
- }
- } else {
- LOG.error("Interface {} on node {} is not present!", portMapping.getSupportingOts(),
- nodeId);
- return false;
- }
- } else if (openroadmVersion.getIntValue() == 2) {
- Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp
- .Interface> interfaceOpt;
- try {
- interfaceOpt =
- this.openRoadmInterfaces.getInterface(nodeId, portMapping.getSupportingOts());
- } catch (OpenRoadmInterfaceException ex) {
- LOG.error("Failed to get interface {} from node {}!", portMapping.getSupportingOts(),
- nodeId, ex);
- return false;
- } catch (IllegalArgumentException ex) {
- LOG.error("Failed to get non existing interface {} from node {}!",
- portMapping.getSupportingOts(), nodeId);
- return false;
- }
- if (interfaceOpt.isPresent()) {
- if (interfaceOpt.get().augmentation(org.opendaylight.yang.gen.v1.http.org
- .openroadm.optical.transport.interfaces.rev181019.Interface1.class).getOts()
- .getSpanLossTransmit() != null) {
- spanLossTx = interfaceOpt.get().augmentation(org.opendaylight.yang.gen.v1.http.org
- .openroadm.optical.transport.interfaces.rev181019.Interface1.class).getOts()
- .getSpanLossTransmit().getValue();
- LOG.info("Spanloss TX is {}", spanLossTx);
- } else {
- LOG.error("interface {} has no spanloss value", interfaceOpt.get().getName());
- }
- } else {
- LOG.error("Interface {} on node {} is not present!", portMapping.getSupportingOts(),
- nodeId);
- return false;
- }
- }
+ if (mappingObjectOptional.isEmpty()) {
+ continue;
+ }
+ // TODO can it be return false rather than continue?
+ // in that case, mappingObjectOptional could be moved inside method getSpanLossTx()
+ LOG.info("Dest point is Degree {}", mappingObjectOptional.get());
+ BigDecimal spanLossTx = getSpanLossTx(mappingObjectOptional.get().getSupportingOts(),
+ destTpId, nodeId, openroadmVersion.getIntValue());
- if (spanLossTx == null || spanLossTx.intValue() <= 0 || spanLossTx.intValue() > 28) {
- LOG.error(
- "Power Value is null: spanLossTx null or out of openROADM range ]0,28] {}", spanLossTx);
+ LOG.info("Spanloss TX is {}", spanLossTx);
+ if (spanLossTx == null || spanLossTx.intValue() <= 0 || spanLossTx.intValue() > 28) {
+ LOG.error("Power Value is null: spanLossTx null or out of openROADM range ]0,28] {}",
+ spanLossTx);
+ return false;
+ }
+ BigDecimal powerValue = getRdmPowerValue(spanLossTx, input);
+ try {
+ if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Power.getName(), powerValue,
+ connectionNumber)) {
+ LOG.info("Set Power failed for Roadm-connection: {} on Node: {}",
+ connectionNumber, nodeId);
+ // FIXME shouldn't it be LOG.error
return false;
}
- BigDecimal powerValue = spanLossTx.subtract(BigDecimal.valueOf(9));
- powerValue = powerValue.min(BigDecimal.valueOf(2));
- //we work at constant power spectral density (50 GHz channel width @-20dBm=37.5GHz)
- // 87.5 GHz channel width @-20dBm=75GHz
- if (input.getWidth() != null && GridConstant.WIDTH_80.equals(input.getWidth().getValue())) {
- powerValue = powerValue.add(BigDecimal.valueOf(3));
- }
- LOG.info("Power Value is {}", powerValue);
- try {
- Boolean setXconnPowerSuccessVal = crossConnect.setPowerLevel(nodeId,
- OpticalControlMode.Power.getName(), powerValue, connectionNumber);
- LOG.info("Success Value is {}", setXconnPowerSuccessVal);
- if (setXconnPowerSuccessVal) {
- LOG.info("Roadm-connection: {} updated ", connectionNumber);
- Thread.sleep(OlmUtils.OLM_TIMER_2);
- crossConnect.setPowerLevel(nodeId, OpticalControlMode.GainLoss.getName(), powerValue,
- connectionNumber);
- //TODO make this timer value configurable via OSGi blueprint
- // although the value recommended by the white paper is 20 seconds.
- // At least one vendor product needs 60 seconds
- // because it is not supporting GainLoss with target-output-power.
- } else {
- LOG.info("Set Power failed for Roadm-connection: {} on Node: {}", connectionNumber,
- nodeId);
- return false;
- }
- } catch (InterruptedException e) {
- LOG.error("Olm-setPower wait failed :", e);
- return false;
+ LOG.info("Roadm-connection: {} updated ", connectionNumber);
+ Thread.sleep(OlmUtils.OLM_TIMER_2);
+ // TODO make this timer value configurable via OSGi blueprint
+ // although the value recommended by the white paper is 20 seconds.
+ // At least one vendor product needs 60 seconds
+ // because it is not supporting GainLoss with target-output-power.
+
+ if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.GainLoss.getName(), powerValue,
+ connectionNumber)) {
+ LOG.warn("Setting power-control mode off failed for Roadm-connection: {}",
+ connectionNumber);
+ // FIXME no return false in that case?
}
+ } 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.setPowerLevel(nodeId, OpticalControlMode.Power.getName(), null, connectionNumber);
- }
- } else {
- LOG.error("OLM-PowerMgmtImpl : Error with node type for node {}", nodeId);
+ break;
+ default :
+ LOG.error("OLM-PowerMgmtImpl : Error with node type for node {}", nodeId);
+ break;
}
}
return true;
}
+ private Map<String, Double> getTxPowerRangeMap(Nodes inputNode, String destTpId, String nodeId,
+ Integer openroadmVersion) {
+
+ Optional<Mapping> mappingObject = inputNode.nonnullMapping().values().stream()
+ .filter(o -> o.key().equals(new MappingKey(destTpId))).findFirst();
+ if (mappingObject.isEmpty()) {
+ LOG.info("Mapping object not found for nodeId: {}", nodeId);
+ // FIXME shouldn't it be LOG.error ?
+ return null;
+ // return null here means return false in setPower()
+ // TODO Align protections with getSRGRxPowerRangeMap
+ }
+
+ String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
+ String portName = mappingObject.get().getSupportingPort();
+ switch (openroadmVersion) {
+ case 1:
+ return PowerMgmtVersion121.getXponderPowerRange(circuitPackName, portName,
+ nodeId, deviceTransactionManager);
+ case 2:
+ return PowerMgmtVersion221.getXponderPowerRange(circuitPackName, portName,
+ nodeId, deviceTransactionManager);
+ case 3:
+ return PowerMgmtVersion710.getXponderPowerRange(circuitPackName, portName,
+ nodeId, deviceTransactionManager);
+ default:
+ LOG.error("Unrecognized OpenRoadm version");
+ return new HashMap<>();
+ // FIXME shouldn't it lead to a return false in setPower()?
+ }
+ }
+
+
+ private Map<String, Double> getSRGRxPowerRangeMap(String srgId, String nodeId, Integer openroadmVersion) {
+
+ Optional<Nodes> inputNode = OlmUtils.getNode(nodeId, this.db);
+ int rdmOpenroadmVersion =
+ inputNode.isPresent()
+ ? inputNode.get().getNodeInfo().getOpenroadmVersion().getIntValue()
+ : openroadmVersion;
+ Optional<Mapping> mappingObject = inputNode
+ .flatMap(node -> node.nonnullMapping().values().stream()
+ .filter(o -> o.key().equals(new MappingKey(srgId))).findFirst());
+
+ if (mappingObject.isEmpty()) {
+ return new HashMap<>();
+ // FIXME shouldn't it lead to a return false in setPower() ?
+ }
+
+ String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
+ String portName = mappingObject.get().getSupportingPort();
+ switch (rdmOpenroadmVersion) {
+ case 1:
+ return PowerMgmtVersion121.getSRGRxPowerRange(nodeId, srgId,
+ deviceTransactionManager, circuitPackName, portName);
+ case 2:
+ return PowerMgmtVersion221.getSRGRxPowerRange(nodeId, srgId,
+ deviceTransactionManager, circuitPackName, portName);
+ case 3:
+ return PowerMgmtVersion710.getSRGRxPowerRange(nodeId, srgId,
+ deviceTransactionManager, circuitPackName, portName);
+ default:
+ LOG.error("Unrecognized OpenRoadm version");
+ return null;
+ //return null here means return false in setPower()
+ // TODO Align protections with getTxPowerRangeMap
+ }
+ }
+
+ private BigDecimal getSpanLossTx(String supportingOts, String destTpId, String nodeId, Integer openroadmVersion) {
+ try {
+ switch (openroadmVersion) {
+ case 1:
+ Optional<Interface> interfaceOpt =
+ this.openRoadmInterfaces.getInterface(nodeId, supportingOts);
+ if (interfaceOpt.isEmpty()) {
+ LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
+ return null;
+ }
+ if (interfaceOpt.get().augmentation(Interface1.class).getOts()
+ .getSpanLossTransmit() == null) {
+ LOG.error("interface {} has no spanloss value", interfaceOpt.get().getName());
+ return null;
+ }
+ return interfaceOpt.get()
+ .augmentation(Interface1.class)
+ .getOts().getSpanLossTransmit().getValue();
+ case 2:
+ Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+ .interfaces.grp.Interface> interfaceOpt1 =
+ this.openRoadmInterfaces.getInterface(nodeId, supportingOts);
+ if (interfaceOpt1.isEmpty()) {
+ LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
+ return null;
+ }
+ if (interfaceOpt1.get().augmentation(org.opendaylight.yang.gen.v1.http.org
+ .openroadm.optical.transport.interfaces.rev181019.Interface1.class).getOts()
+ .getSpanLossTransmit() == null) {
+ LOG.error("interface {} has no spanloss value", interfaceOpt1.get().getName());
+ return null;
+ }
+ return interfaceOpt1.get()
+ .augmentation(org.opendaylight.yang.gen.v1.http.org
+ .openroadm.optical.transport.interfaces.rev181019.Interface1.class)
+ .getOts().getSpanLossTransmit().getValue();
+ // TODO no case 3 ?
+ default:
+ return null;
+ }
+ } catch (OpenRoadmInterfaceException ex) {
+ LOG.error("Failed to get interface {} from node {}!",
+ supportingOts, nodeId, ex);
+ return null;
+ } catch (IllegalArgumentException ex) {
+ LOG.error("Failed to get non existing interface {} from node {}!",
+ supportingOts, nodeId);
+ return null;
+ }
+ }
+
+ private BigDecimal getXpdrPowerValue(Nodes inputNode, String destTpId, String nodeId, Integer openroadmVersion,
+ String srgId, String nextNodeId) {
+
+ Map<String, Double> txPowerRangeMap = getTxPowerRangeMap(inputNode, destTpId, nodeId, openroadmVersion);
+ if (txPowerRangeMap == null) {
+ return null;
+ // return null here means return false in setPower()
+ }
+ BigDecimal powerVal =
+ openroadmVersion == 3 ? DEFAULT_TPDR_PWR_400G : DEFAULT_TPDR_PWR_100G;
+ if (txPowerRangeMap.isEmpty()) {
+ LOG.info("Tranponder range not available setting to default power for nodeId: {}", nodeId);
+ return powerVal;
+ }
+
+ Map<String, Double> rxSRGPowerRangeMap = getSRGRxPowerRangeMap(srgId, nextNodeId, openroadmVersion);
+ if (rxSRGPowerRangeMap == null) {
+ return null;
+ // return null here means return false in setPower()
+ // TODO empty txPowerRangeMap + null rxSRGPowerRangeMap is allowed
+ // => confirm this behavior is OK
+ }
+ if (rxSRGPowerRangeMap.isEmpty()) {
+ LOG.info("SRG Power Range not found, setting the Transponder range to default");
+ return powerVal;
+ }
+
+ powerVal = new BigDecimal(txPowerRangeMap.get("MaxTx"))
+ .min(new BigDecimal(rxSRGPowerRangeMap.get("MaxRx")));
+ LOG.info("Calculated Transponder Power value is {}" , powerVal);
+ return powerVal;
+ }
+
+
+ private BigDecimal getRdmPowerValue(BigDecimal spanLossTx, ServicePowerSetupInput input) {
+ BigDecimal powerValue = spanLossTx.subtract(BigDecimal.valueOf(9)).min(BigDecimal.valueOf(2));
+ // we work at constant power spectral density (50 GHz channel width @-20dBm=37.5GHz)
+ // 87.5 GHz channel width @-20dBm=75GHz
+ if (input.getWidth() != null) {
+ BigDecimal gridSize = input.getWidth().getValue();
+ LOG.debug("Input Gridsize is {}",gridSize);
+ if (gridSize.equals(GridConstant.WIDTH_80)) {
+ powerValue = powerValue.add(BigDecimal.valueOf(3));
+ }
+ // TODO no default or warning for unsupported grid sizes ?
+ }
+ // FIXME compliancy with OpenROADM MSA and approximations used
+ // cf JIRA ticket https://jira.opendaylight.org/browse/TRNSPRTPCE-494
+ LOG.info("Power Value is {}", powerValue);
+ return powerValue;
+ }
+
/**
* This methods turns down power a WL by performing
* following steps:
LOG.info("Olm-powerTurnDown initiated for input {}", input);
/*Starting with last element into the list Z -> A for
turning down A -> Z */
- int lowerSpectralSlotNumber = input.getLowerSpectralSlotNumber().intValue();
- int higherSpectralSlotNumber = input.getHigherSpectralSlotNumber().intValue();
String spectralSlotName = String.join(GridConstant.SPECTRAL_SLOT_SEPARATOR,
- String.valueOf(lowerSpectralSlotNumber),
- String.valueOf(higherSpectralSlotNumber));
+ input.getLowerSpectralSlotNumber().toString(),
+ input.getHigherSpectralSlotNumber().toString());
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();
- String connectionNumber = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,srcTpId, destTpId,
- spectralSlotName);
- if (destTpId.toLowerCase().contains("srg")) {
- crossConnect.setPowerLevel(nodeId, OpticalControlMode.Off.getName(), null, connectionNumber);
- } else if (destTpId.toLowerCase().contains("deg")) {
- try {
+ String connectionNumber = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
+ input.getNodes().get(i).getSrcTp(), destTpId, spectralSlotName);
+ try {
+ if (destTpId.toUpperCase(Locale.getDefault()).contains("DEG")) {
if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Power.getName(), new BigDecimal(-60),
connectionNumber)) {
LOG.warn("Power down failed for Roadm-connection: {}", connectionNumber);
return false;
}
Thread.sleep(OlmUtils.OLM_TIMER_2);
- if (! crossConnect.setPowerLevel(nodeId, OpticalControlMode.Off.getName(), null,
- connectionNumber)) {
+ if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Off.getName(), null, connectionNumber)) {
LOG.warn("Setting power-control mode off failed for Roadm-connection: {}", connectionNumber);
return false;
}
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- LOG.error("Olm-powerTurnDown wait failed: ",e);
- return false;
+ } else if (destTpId.toUpperCase(Locale.getDefault()).contains("SRG")) {
+ if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Off.getName(), null, connectionNumber)) {
+ LOG.warn("Setting power-control mode off failed for Roadm-connection: {}", connectionNumber);
+ // FIXME a return false would allow sync with DEG case but makes current Unit tests fail
+ }
}
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ LOG.error("Olm-powerTurnDown wait failed: ",e);
+ return false;
}
}
return true;
}
- /*
- * This method does an edit-config on roadm connection subtree for a given
- * connection number in order to set power level for use by the optical
- * power control.
- *
- * @param inputNode
- * PortMapping network node.
- * @param destTpId
- * Destination termination point.
- * @param srgId
- * SRG Id to which network port is connected to.
- * @param nextNodeId
- * Next roadm connect.
- * @param waveLength
- * WaveLength number part of request
- * @return true/false based on status of operation.
- */
- /*private boolean setTransponderPowerTx(Nodes inputNode, String destTpId, String srgId,
- String nextNodeId, Long waveLength) {
- Map<String, Double> txPowerRangeMap = null;
- Map<String, Double> rxSRGPowerRangeMap = null;
- OpenroadmVersion openroadmVersion;
- Optional<Mapping> mappingObject = inputNode.getMapping().stream().filter(o -> o.key()
- .equals(new MappingKey(destTpId))).findFirst();
- String nodeId = inputNode.getNodeId();
- if (mappingObject.isPresent()) {
- String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
- String portName = mappingObject.get().getSupportingPort();
- openroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion();
- if (openroadmVersion.getIntValue() == 1) {
- txPowerRangeMap = PowerMgmtVersion121.getXponderPowerRange(circuitPackName, portName,
- nodeId, deviceTransactionManager);
- } else if (openroadmVersion.getIntValue() == 2) {
- txPowerRangeMap = PowerMgmtVersion221.getXponderPowerRange(circuitPackName, portName,
- nodeId, deviceTransactionManager);
- }
- LOG.info("Transponder power range is fine");
- if (!txPowerRangeMap.isEmpty()) {
- LOG.info("Transponder power range is not null {}, {}", nextNodeId,srgId);
- //Transponder range is not empty then check SRG Range
-
- Optional<Mapping> mappingObjectSRG = OlmUtils.getNode(nextNodeId, db)
- .flatMap(node -> node.getMapping()
- .stream().filter(o -> o.key()
- .equals(new MappingKey(srgId))).findFirst());
- if (mappingObjectSRG.isPresent()) {
- LOG.info("Transponder range exists for nodeId: {}", nodeId);
- if (openroadmVersion.getIntValue() == 1) {
- rxSRGPowerRangeMap = PowerMgmtVersion121.getSRGRxPowerRange(nextNodeId, srgId,
- deviceTransactionManager, mappingObjectSRG.get().getSupportingCircuitPackName(),
- mappingObjectSRG.get().getSupportingPort());
- } else if (openroadmVersion.getIntValue() == 2) {
- rxSRGPowerRangeMap = PowerMgmtVersion221.getSRGRxPowerRange(nextNodeId, srgId,
- deviceTransactionManager, mappingObjectSRG.get().getSupportingCircuitPackName(),
- mappingObjectSRG.get().getSupportingPort());
- }
- }
- double powerValue = 0;
- if (!rxSRGPowerRangeMap.isEmpty()) {
- LOG.debug("SRG Rx Power range exists for nodeId: {}", nodeId);
- if (txPowerRangeMap.get("MaxTx")
- <= rxSRGPowerRangeMap.get("MaxRx")) {
- powerValue = txPowerRangeMap.get("MaxTx");
- } else if (rxSRGPowerRangeMap.get("MaxRx")
- < txPowerRangeMap.get("MaxTx")) {
- powerValue = rxSRGPowerRangeMap.get("MaxRx");
- }
- LOG.debug("Calculated Transponder Power value is {}" , powerValue);
- String interfaceName = destTpId + "-" + waveLength;
- if (callSetTransponderPower(nodeId,interfaceName,new BigDecimal(powerValue),
- openroadmVersion)) {
- LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
- try {
- LOG.info("Now going in sleep mode");
- Thread.sleep(90000);
- return true;
- } catch (InterruptedException e) {
- LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
- return false;
- }
- } else {
- LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
- return false;
- }
- } else {
- LOG.info("Transponder Range exists but SRG Power Range not found");
- return false;
- }
- } else {
- LOG.info("Tranponder range not available seting to default power for nodeId: {}", nodeId);
- String interfaceName = destTpId + "-" + waveLength;
- if (callSetTransponderPower(nodeId,interfaceName,new BigDecimal(-5),
- openroadmVersion)) {
- LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
- try {
- Thread.sleep(OlmUtils.OLM_TIMER_1);
- return true;
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
- return false;
- }
- } else {
- LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
- return false;
- }
- }
- } else {
- LOG.info("Mapping object not found for nodeId: {}", nodeId);
- return false;
- }
- }*/
-
/**
* This method retrieves transponder OCH interface and
* sets power.
*/
private boolean callSetTransponderPower(String nodeId, String interfaceName, BigDecimal txPower,
OpenroadmNodeVersion openroadmVersion) {
+
boolean powerSetupResult = false;
try {
switch (openroadmVersion.getIntValue()) {
case 1:
- Optional<Interface> interfaceOptional121;
- interfaceOptional121 = openRoadmInterfaces.getInterface(nodeId, interfaceName);
- if (!interfaceOptional121.isPresent()) {
- LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
+ Optional<Interface> interfaceOptional121 =
+ openRoadmInterfaces.getInterface(nodeId, interfaceName);
+ if (interfaceOptional121.isEmpty()) {
+ LOG.error(INTERFACE_NOT_PRESENT, interfaceName, nodeId);
return false;
}
powerSetupResult = PowerMgmtVersion121.setTransponderPower(nodeId, interfaceName,
- txPower, deviceTransactionManager, interfaceOptional121.get());
+ txPower, deviceTransactionManager, interfaceOptional121.get());
break;
case 2:
Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp
- .Interface> interfaceOptional221;
- interfaceOptional221 = openRoadmInterfaces.getInterface(nodeId, interfaceName);
- if (!interfaceOptional221.isPresent()) {
- LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
+ .Interface> interfaceOptional221 =
+ openRoadmInterfaces.getInterface(nodeId, interfaceName);
+ if (interfaceOptional221.isEmpty()) {
+ LOG.error(INTERFACE_NOT_PRESENT, interfaceName, nodeId);
return false;
}
powerSetupResult = PowerMgmtVersion221.setTransponderPower(nodeId, interfaceName,
- txPower, deviceTransactionManager, interfaceOptional221.get());
+ txPower, deviceTransactionManager, interfaceOptional221.get());
break;
case 3:
Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp
- .Interface> interfaceOptional710;
- interfaceOptional710 = openRoadmInterfaces.getInterface(nodeId, interfaceName);
- if (!interfaceOptional710.isPresent()) {
- LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
+ .Interface> interfaceOptional710 =
+ openRoadmInterfaces.getInterface(nodeId, interfaceName);
+ if (interfaceOptional710.isEmpty()) {
+ LOG.error(INTERFACE_NOT_PRESENT, interfaceName, nodeId);
return false;
}
powerSetupResult = PowerMgmtVersion710.setTransponderPower(nodeId, interfaceName,
LOG.error("Failed to get interface {} from node {}!", interfaceName, nodeId, ex);
return false;
}
- if (powerSetupResult) {
- LOG.debug("Transponder power set up completed successfully for nodeId {} and interface {}",
- nodeId,interfaceName);
- } else {
+ if (!powerSetupResult) {
LOG.debug("Transponder power setup failed for nodeId {} on interface {}",
nodeId, interfaceName);
- }
- return powerSetupResult;
- }
-
- /*
- * This method retrieves transponder OCH interface and
- * sets power.
- *
- * @param nodeId
- * Unique identifier for the mounted netconf- node
- * @param interfaceName
- * OCH interface name carrying WL
- * @param openroadmVersion
- * Version of openRoadm device software
- * @param wavelength
- * Wavelength Number *
- * @return true/false based on status of operation
- */
- /*private boolean callSetRoadmPowerTx(String nodeId, String interfaceName,
- OpenroadmVersion openroadmVersion,
- Long wavelength, String connectionNumber) {
- if (interfaceName == null) {
- crossConnect.setPowerLevel(nodeId,
- OpticalControlMode.Power , null,connectionNumber);
- return true;
- }
- try {
- if (openroadmVersion.getIntValue() == 1) {
- Optional<Interface> interfaceOpt;
- interfaceOpt = openRoadmInterfaces.getInterface(nodeId, interfaceName);
- if (interfaceOpt.isPresent()) {
- BigDecimal spanLossTx = interfaceOpt.get().augmentation(Interface1.class).getOts()
- .getSpanLossTransmit().getValue();
- LOG.debug("Spanloss TX is {}", spanLossTx);
- BigDecimal powerValue = BigDecimal.valueOf(Math.min(spanLossTx.doubleValue() - 9, 2));
- LOG.debug("Power Value is {}", powerValue);
- Boolean setXconnPowerSuccessVal = crossConnect.setPowerLevel(nodeId,
- OpticalControlMode.Power, powerValue,connectionNumber);
- if (setXconnPowerSuccessVal) {
- LOG.info("Roadm-connection: {} updated ");
- //TODO - commented code because one vendor is not supporting
- //GainLoss with target-output-power
- Thread.sleep(OlmUtils.OLM_TIMER_2);
- crossConnect.setPowerLevel(nodeId,
- OpticalControlMode.GainLoss, powerValue,connectionNumber);
- return true;
- } else {
- LOG.info("Set Power failed for Roadm-connection: {} on Node: {}", connectionNumber, nodeId);
- return false;
- }
- } else {
- LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
- return false;
- }
- } else if (openroadmVersion.getIntValue() == 2) {
- Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces
- .grp.Interface> interfaceOpt;
- interfaceOpt = openRoadmInterfaces.getInterface(nodeId, interfaceName);
- if (interfaceOpt.isPresent()) {
- BigDecimal spanLossTx = interfaceOpt.get().augmentation(org.opendaylight.yang.gen.v1.http
- .org.openroadm.optical.transport.interfaces.rev181019.Interface1.class).getOts()
- .getSpanLossTransmit().getValue();
- LOG.debug("Spanloss TX is {}", spanLossTx);
- BigDecimal powerValue = BigDecimal.valueOf(Math.min(spanLossTx.doubleValue() - 9, 2));
- LOG.debug("Power Value is {}", powerValue);
- Boolean setXconnPowerSuccessVal = crossConnect.setPowerLevel(nodeId,
- OpticalControlMode.Power, powerValue,connectionNumber);
- if (setXconnPowerSuccessVal) {
- LOG.info("Roadm-connection: {} updated ");
- //TODO - commented code because one vendor is not supporting
- //GainLoss with target-output-power
- Thread.sleep(OlmUtils.OLM_TIMER_2);
- crossConnect.setPowerLevel(nodeId,
- OpticalControlMode.GainLoss, powerValue,connectionNumber);
- return true;
- } else {
- LOG.info("Set Power failed for Roadm-connection: {} on Node: {}", connectionNumber, nodeId);
- return false;
- }
- }
- }
- } catch (OpenRoadmInterfaceException | InterruptedException ex) {
- LOG.error("Error during power setup on Roadm nodeId: {} for connection: {}", nodeId, connectionNumber, ex);
return false;
}
- return false;
- }*/
+ LOG.debug("Transponder power set up completed successfully for nodeId {} and interface {}",
+ nodeId,interfaceName);
+ return true;
+ }
}