Initial commit for OLM 42/56342/5
authorsvachhani <sv111y@att.com>
Tue, 2 May 2017 03:34:54 +0000 (23:34 -0400)
committerShweta V <sv111y@att.com>
Fri, 5 May 2017 20:59:58 +0000 (20:59 +0000)
It includes implementation of 2 functionalities:
1. PM retrieval by nodeId, resource type, resource Id and granuality.
   This RPC simplifies PM reading which can be used for BER test or
   PM monitoring service
2. Spanloss calculation for links and update spanloss in device's
   OTS interface subtree.

Change-Id: I6cf146e887f85db499d2df62207b2330c99d2e59
Signed-off-by: svachhani <sv111y@att.com>
api/src/main/yang/olm.yang [new file with mode: 0644]
features/pom.xml
features/src/main/features/features.xml
olm/pom.xml [new file with mode: 0644]
olm/src/main/java/org/opendaylight/transportpce/olm/OlmPowerSetupImpl.java [new file with mode: 0644]
olm/src/main/java/org/opendaylight/transportpce/olm/OlmProvider.java [new file with mode: 0644]
olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/OtsPmHolder.java [new file with mode: 0644]
olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/RoadmLinks.java [new file with mode: 0644]
olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/SpanLoss.java [new file with mode: 0644]
olm/src/main/resources/org/opendaylight/blueprint/olm-blueprint.xml [new file with mode: 0644]
pom.xml

diff --git a/api/src/main/yang/olm.yang b/api/src/main/yang/olm.yang
new file mode 100644 (file)
index 0000000..98b9118
--- /dev/null
@@ -0,0 +1,72 @@
+module olm {
+  yang-version 1;
+  namespace "urn:opendaylight:params:xml:ns:yang:olm";
+  prefix "olm";
+
+  revision "2017-4-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;
+      }
+    }
+  }
+}
\ No newline at end of file
index 2f5751c17aea86143605bf3c0a91ea78462d71d5..91f24608dfd982eb1b4df409a1415ba854585fd2 100644 (file)
@@ -191,6 +191,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>transportpce-renderer</artifactId>
       <version>${project.version}</version>
     </dependency>
+   <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>transportpce-olm</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>transportpce-api</artifactId>
index 4b333315511d54f30d0111dfc4ecd6b542195067..4d9c087fac21910bd3ffd0cb7af0a7b50acbe395 100644 (file)
@@ -35,6 +35,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <feature version='${project.version}'>odl-transportpce-ordmodels</feature>
     <bundle>mvn:org.opendaylight.transportpce/transportpce-impl/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.transportpce/transportpce-renderer/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.transportpce/transportpce-olm/{{VERSION}}</bundle>
   </feature>
   <feature name='odl-transportpce-rest' version='${project.version}' description='OpenDaylight :: transportpce :: REST'>
     <feature version="${project.version}">odl-transportpce</feature>
@@ -51,4 +52,4 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <bundle>mvn:org.opendaylight.transportpce/transportpce-cli/{{VERSION}}</bundle>
   </feature>
 
-</features>
+</features>
\ No newline at end of file
diff --git a/olm/pom.xml b/olm/pom.xml
new file mode 100644 (file)
index 0000000..0a21178
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 2016 Orange 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.6.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.transportpce</groupId>
+  <artifactId>transportpce-olm</artifactId>
+  <version>0.1.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>transportpce-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+        <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>transportpce-renderer</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>transportpce-ordmodels</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-topology</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>sal-netconf-connector</artifactId>
+      <version>1.5.0-SNAPSHOT</version>
+    </dependency>
+
+    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/olm/src/main/java/org/opendaylight/transportpce/olm/OlmPowerSetupImpl.java b/olm/src/main/java/org/opendaylight/transportpce/olm/OlmPowerSetupImpl.java
new file mode 100644 (file)
index 0000000..ba2d078
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * 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;
+
+import com.google.common.base.Optional;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+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.spanloss.RoadmLinks;
+import org.opendaylight.transportpce.olm.spanloss.SpanLoss;
+import org.opendaylight.transportpce.renderer.mapping.PortMapping;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.CurrentPmlist;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.current.pm.Measurements;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.currentpmlist.CurrentPm;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmNamesEnum;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
+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.get.pm.output.MeasurementsBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class OlmPowerSetupImpl.
+ */
+public class OlmPowerSetupImpl implements OlmService {
+
+    /** The Constant LOG. */
+    private static final Logger LOG = LoggerFactory.getLogger(OlmPowerSetupImpl.class);
+
+    /** The db. */
+    private final DataBroker db;
+
+    /** The mps. */
+    private final MountPointService mps;
+
+    /**
+     * Instantiates a new olm power setup impl.
+     *
+     * @param db
+     *            the db
+     * @param mps
+     *            the mps
+     */
+    public OlmPowerSetupImpl(DataBroker db, MountPointService mps) {
+        this.db = db;
+        this.mps = mps;
+    }
+
+    /**
+     * This method is the implementation of the 'get-pm' RESTCONF service, which
+     * is one of the external APIs into the olm application.
+     *
+     * <p>
+     * 1. get-pm This operation traverse through current PM list and gets PM for
+     * given NodeId and Resource name
+     *
+     * <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
+     *
+     * @return Result of the request
+     */
+    @Override
+    public Future<RpcResult<GetPmOutput>> getPm(GetPmInput input) {
+        LOG.info("Getting PM Data for NodeId: {} ResouceType: {} ResourceName: {}",
+                input.getNodeId(),input.getResourceType(),input.getResourceName());
+        new PortMapping(db, mps, input.getNodeId());
+        DataBroker deviceDb = PortMapping.getDeviceDataBroker(input.getNodeId(), mps);
+        InstanceIdentifier<CurrentPmlist> currentPmsIID = InstanceIdentifier.create(CurrentPmlist.class);
+        ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
+        Optional<CurrentPmlist> currentPmList;
+        String methodName = "";
+        List<CurrentPm> currentPms = new ArrayList<>();
+        GetPmOutputBuilder pmOutputBuilder = new GetPmOutputBuilder();
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements>
+            measrements = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418
+                .get.pm.output.Measurements>();
+        try {
+            currentPmList = rtx.read(LogicalDatastoreType.OPERATIONAL, currentPmsIID).get();
+            if (currentPmList.isPresent()) {
+                currentPms.addAll(currentPmList.get().getCurrentPm());
+                for (CurrentPm pm : currentPms) {
+                    MeasurementsBuilder measurement = new MeasurementsBuilder();
+                    if (pm.getResource().getResourceType().getType().toString().equals(input.getResourceType())) {
+
+                        switch (pm.getResource().getResourceType().getType()) {
+                            case CircuitPack:
+                                methodName = "getCircuitPackName";
+                                break;
+                            case Connection:
+                                methodName = "getConnectionNumber";
+                                break;
+                            case Degree:
+                                methodName = "getDegreeNumber";
+                                break;
+                            case Interface:
+                                methodName = "getInterfaceName";
+                                break;
+                            case InternalLink:
+                                methodName = "getInternalLinkName";
+                                break;
+                            case PhysicalLink:
+                                methodName = "getPhysicalLinkName";
+                                break;
+                            case Service:
+                                methodName = "getServiceName";
+                                break;
+                            case Shelf:
+                                methodName = "getShelfName";
+                                break;
+                            case SharedRiskGroup:
+                                methodName = "getSrgNumber";
+                                break;
+                            default:
+                                methodName = "getPort";
+                                break;
+                        }
+                        try {
+
+                            String pmResourceId = pm.getResource().getResource().getResource().getImplementedInterface()
+                                .getMethod(methodName).invoke(pm.getResource().getResource().getResource()).toString();
+                            if (pmResourceId.equals(input.getResourceName()) && pm.getGranularity() != null) {
+                                if (pm.getGranularity().getName().equals(input.getGranularity())) {
+                                    for (Measurements measure : pm.getMeasurements()) {
+                                        if (!measure.getMeasurement().getPmParameterName().getType().equals(
+                                            PmNamesEnum.VendorExtension)) {
+                                            measurement.setPmparameterName(measure.getMeasurement().getPmParameterName()
+                                                .getType().toString());
+                                            measurement.setPmparameterValue(measure.getMeasurement()
+                                                .getPmParameterValue().getDecimal64().toString());
+                                            measrements.add(measurement.build());
+                                        }
+                                    }
+                                }
+                            }
+
+                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
+                            | NoSuchMethodException | SecurityException ex) {
+                            LOG.warn("Unable to find PM for NodeID: {} ResourceName: {} ",input.getNodeId(),
+                                    input.getResourceName(),ex);
+                        }
+                    }
+                }
+                if (measrements.size() > 0) {
+                    pmOutputBuilder.setNodeId(input.getNodeId()).setResourceType(input.getResourceType()).setResourceId(
+                        input.getResourceName()).setGranularity(input.getGranularity()).setMeasurements(measrements);
+                }
+
+            } else {
+                LOG.info("Device PM Data is not available");
+            }
+
+        } catch (InterruptedException | ExecutionException ex) {
+            LOG.warn("Unable to get currentPmList for NodeID: {}",input.getNodeId(),ex);
+        }
+        LOG.info("PM Data found successfully for {}-{}",pmOutputBuilder.getNodeId(),pmOutputBuilder.getResourceId());
+        return RpcResultBuilder.success(pmOutputBuilder).buildFuture();
+    }
+
+
+    /**
+     * This method is the implementation of the 'service-power-setup' RESTCONF service, which
+     * is one of the external APIs into the olm application.
+     *
+     * <p>
+     * 1. service-power-setup: This operation performs following steps:
+     *    Step1: Calculate Spanloss on all links which are part of service.
+     *    TODO Step2: Calculate power levels for each Tp-Id
+     *    TODO Step3: Post power values on roadm connections
+     *
+     * <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<org.opendaylight.yangtools.yang.common.RpcResult<ServicePowerSetupOutput>> servicePowerSetup(
+        ServicePowerSetupInput input) {
+        List<RoadmLinks> roadmLinks = new ArrayList<RoadmLinks>();
+        ServicePowerSetupOutputBuilder output = new ServicePowerSetupOutputBuilder();
+        //Finds degree TpID from node and generates a list of links
+        for (int i = 0; i < input.getNodes().size(); i++) {
+            if (input.getNodes().get(i).getDestTp().toLowerCase().contains("deg")) {
+                RoadmLinks rdmLink = new RoadmLinks();
+                rdmLink.setSrcNodeId(input.getNodes().get(i).getNodeId());
+                rdmLink.setSrcTpId(input.getNodes().get(i).getDestTp());
+                rdmLink.setDestNodeId(input.getNodes().get(i + 1).getNodeId());
+                rdmLink.setDestTpid(input.getNodes().get(i + 1).getSrcTp());
+                roadmLinks.add(rdmLink);
+            }
+        }
+        boolean successVal = new SpanLoss(db, mps).getLinkSpanloss(roadmLinks);
+
+        if (successVal) {
+            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/OlmProvider.java b/olm/src/main/java/org/opendaylight/transportpce/olm/OlmProvider.java
new file mode 100644 (file)
index 0000000..6325d33
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.MountPointService;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class OlmProvider.
+ */
+public class OlmProvider {
+
+    /** The Constant LOG. */
+    private static final Logger LOG = LoggerFactory.getLogger(OlmProvider.class);
+
+    /** The data broker. */
+    private final DataBroker dataBroker;
+
+    /** The mount point service. */
+    private final MountPointService mountPointService;
+
+    /** The rpc provider registry. */
+    private final RpcProviderRegistry rpcProviderRegistry;
+
+    /** The get pm registration. */
+    private RpcRegistration<OlmService> olmRPCRegistration;
+
+    /**
+     * Instantiates a new olm provider.
+     *
+     * @param dataBroker
+     *            the data broker
+     * @param mountPointService
+     *            the mount point service
+     * @param rpcProviderRegistry
+     *            the rpc provider registry
+     */
+    public OlmProvider(final DataBroker dataBroker, final MountPointService mountPointService,
+        final RpcProviderRegistry rpcProviderRegistry) {
+        this.dataBroker = dataBroker;
+        this.mountPointService = mountPointService;
+        this.rpcProviderRegistry = rpcProviderRegistry;
+        if (mountPointService == null) {
+            LOG.error("Mount service is null");
+        }
+    }
+
+    /**
+     * Method called when the blueprint container is created.
+     */
+    public void init() {
+        LOG.info("OlmProvider Session Initiated");
+        // Initializing Notification module
+        olmRPCRegistration = rpcProviderRegistry.addRpcImplementation(OlmService.class, new OlmPowerSetupImpl(
+            dataBroker,mountPointService));
+    }
+
+    /**
+     * Method called when the blueprint container is destroyed.
+     */
+    public void close() {
+        LOG.info("RendererProvider Closed");
+        // Clean up the RPC service registration
+        if (olmRPCRegistration != null) {
+            olmRPCRegistration.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/OtsPmHolder.java b/olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/OtsPmHolder.java
new file mode 100644 (file)
index 0000000..50f5560
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.spanloss;
+
+/**
+ * The Class OtsPmHolder.
+ */
+public class OtsPmHolder {
+
+    /** The ots parameter name.*/
+    private String otsParameterName;
+    /** The ots parameter value.*/
+    private Double otsParameterVal;
+
+    /** The ots interface name.*/
+    private String otsInterfaceName;
+
+    public OtsPmHolder(String otsParameterName,Double otsParameterVal,String otsInterfaceName) {
+        this.otsParameterName = otsParameterName;
+        this.otsParameterVal = otsParameterVal;
+        this.otsInterfaceName = otsInterfaceName;
+    }
+
+    public String getOtsParameterName() {
+        return otsParameterName;
+    }
+
+    public void setOtsParameterName(String otsParameterName) {
+        this.otsParameterName = otsParameterName;
+    }
+
+    public Double getOtsParameterVal() {
+        return otsParameterVal;
+    }
+
+    public void setOtsParameterVal(Double otsParameterVal) {
+        this.otsParameterVal = otsParameterVal;
+    }
+
+    public String getOtsInterfaceName() {
+        return otsInterfaceName;
+    }
+
+    public void setOtsInterfaceName(String otsInterfaceName) {
+        this.otsInterfaceName = otsInterfaceName;
+    }
+
+}
diff --git a/olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/RoadmLinks.java b/olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/RoadmLinks.java
new file mode 100644 (file)
index 0000000..d3e0414
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.spanloss;
+/**
+ * The Class RoadmLinks.
+ */
+public class RoadmLinks {
+
+    /** The src node id. */
+    private String srcNodeId;
+
+    /** The src tp id. */
+    private String srcTpId;
+
+    /** The dest node id. */
+    private String destNodeId;
+
+    /** The dest tpid. */
+    private String destTpid;
+
+    /**
+     * Gets the src node id.
+     *
+     * @return the src node id
+     */
+    public String getSrcNodeId() {
+        return srcNodeId;
+    }
+
+    /**
+     * Sets the src node id.
+     *
+     * @param srcNodeId the new src node id
+     */
+    public void setSrcNodeId(String srcNodeId) {
+        this.srcNodeId = srcNodeId;
+    }
+
+    /**
+     * Gets the src tp id.
+     *
+     * @return the src tp id
+     */
+    public String getSrcTpId() {
+        return srcTpId;
+    }
+
+    /**
+     * Sets the src tp id.
+     *
+     * @param srcTpId the new src tp id
+     */
+    public void setSrcTpId(String srcTpId) {
+        this.srcTpId = srcTpId;
+    }
+
+    /**
+     * Gets the dest node id.
+     *
+     * @return the dest node id
+     */
+    public String getDestNodeId() {
+        return destNodeId;
+    }
+
+    /**
+     * Sets the dest node id.
+     *
+     * @param destNodeId the new dest node id
+     */
+    public void setDestNodeId(String destNodeId) {
+        this.destNodeId = destNodeId;
+    }
+
+    /**
+     * Gets the dest tpid.
+     *
+     * @return the dest tpid
+     */
+    public String getDestTpid() {
+        return destTpid;
+    }
+
+    /**
+     * Sets the dest tpid.
+     *
+     * @param destTpid the new dest tpid
+     */
+    public void setDestTpid(String destTpid) {
+        this.destTpid = destTpid;
+    }
+
+}
diff --git a/olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/SpanLoss.java b/olm/src/main/java/org/opendaylight/transportpce/olm/spanloss/SpanLoss.java
new file mode 100644 (file)
index 0000000..c4d25f0
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * 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.spanloss;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+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.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.transportpce.olm.OlmPowerSetupImpl;
+import org.opendaylight.transportpce.renderer.mapping.PortMapping;
+import org.opendaylight.transportpce.renderer.provisiondevice.OpenRoadmInterfaces;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.RatioDB;
+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.optical.transport.interfaces.rev161014.Interface1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.Ots;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.OtsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SpanLoss {
+    private static final Logger LOG = LoggerFactory.getLogger(SpanLoss.class);
+    private final DataBroker db;
+    private final MountPointService mps;
+
+    /**
+     * Instantiates a new span loss.
+     *
+     * @param db
+     *            the db
+     * @param mps
+     *            the mps
+     */
+    public SpanLoss(DataBroker db, MountPointService mps) {
+        this.db = db;
+        this.mps = mps;
+    }
+
+    /**
+     * This method retrieves OTS PM from current PM list by nodeId and TPId:
+     * Steps:
+     *
+     * <p>
+     * 1. Get OTS interface name from port mapping by TPId 2. Call getPm RPC to
+     * get OTS PM
+     *
+     * <p>
+     *
+     * @param nodeId
+     *            Node-id of the NE.
+     * @param tpID
+     *            Termination point Name.
+     * @return reference to OtsPmHolder
+     */
+    public OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
+        GetPmInputBuilder otsPmInputBuilder = new GetPmInputBuilder();
+        Mapping portMapping = new OpenRoadmInterfaces(db, mps, nodeId, tpID).getMapping(nodeId, tpID);
+        if (portMapping != null) {
+            otsPmInputBuilder.setNodeId(nodeId).setResourceType("Interface").setGranularity("15min")
+            .setResourceName(portMapping.getSupportingOts());
+            Future<RpcResult<GetPmOutput>> otsPmOutput = new OlmPowerSetupImpl(db, mps)
+                    .getPm(otsPmInputBuilder.build());
+            if (otsPmOutput != null) {
+                try {
+                    for (Measurements measurement : otsPmOutput.get().getResult().getMeasurements()) {
+                        if (measurement.getPmparameterName().equals(pmName)) {
+                            return new OtsPmHolder(pmName,Double.parseDouble(measurement.getPmparameterValue()),
+                                   portMapping.getSupportingOts());
+                        }
+                    }
+                } catch (NumberFormatException | InterruptedException | ExecutionException e) {
+                    LOG.warn("Unable to get PM for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName, e);
+                }
+            } else {
+                LOG.info("OTS PM not found for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * This method Sets Spanloss on A-End and Z-End OTS interface: Steps:
+     *
+     * <p>
+     * 1. Read existing interface details
+     *
+     * <p>
+     * 2. Set spanloss
+     *
+     * @param nodeId
+     *            nodeId of NE on which spanloss need to be updated
+     * @param interfaceName
+     *            OTS interface for NE on which spanloss is cacluated
+     * @param spanLoss
+     *            calculated spanloss value
+     * @param direction
+     *            for which spanloss is calculated.It can be either Tx or Rx
+     * @return true/false
+     */
+    public boolean setSpanLoss(String nodeId, String interfaceName, BigDecimal spanLoss, String direction) {
+        LOG.info("Setting Spanloss in device for:" + nodeId + " InterfaceName:" + interfaceName);
+        InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
+                .child(Interface.class, new InterfaceKey(interfaceName));
+        Optional<Interface> interfaceObject;
+        try {
+            DataBroker deviceDb = PortMapping.getDeviceDataBroker(nodeId, mps);
+            ReadWriteTransaction rwtx = deviceDb.newReadWriteTransaction();
+            interfaceObject = rwtx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
+            if (interfaceObject.isPresent()) {
+                Interface intf = interfaceObject.get();
+                InterfaceBuilder interfaceBuilder = new InterfaceBuilder(intf);
+                Ots ots = intf.getAugmentation(Interface1.class).getOts();
+                Interface1Builder intf1Builder = new Interface1Builder();
+                OtsBuilder otsBuilder = new OtsBuilder();
+                otsBuilder.setFiberType(ots.getFiberType());
+                if (direction.equals("TX")) {
+                    otsBuilder.setSpanLossTransmit(new RatioDB(spanLoss)).setSpanLossReceive(ots.getSpanLossReceive());
+                } else {
+                    otsBuilder.setSpanLossTransmit(ots.getSpanLossTransmit()).setSpanLossReceive(new RatioDB(spanLoss));
+                }
+                interfaceBuilder.addAugmentation(Interface1.class, intf1Builder.setOts(otsBuilder.build()).build());
+                rwtx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, interfaceBuilder.build());
+                CheckedFuture<Void, TransactionCommitFailedException> submit = rwtx.submit();
+                submit.checkedGet();
+                LOG.info("Spanloss Value update completed successfully");
+                return true;
+            }
+        } catch (InterruptedException | ExecutionException | TransactionCommitFailedException e) {
+            LOG.warn("Unable to set spanloss", e);
+        }
+        return false;
+    }
+
+    /**
+     * This method calculates Spanloss by TranmistPower - Receive Power Steps:
+     *
+     * <p>
+     * 1. Read PM measurement
+     *
+     * <p>
+     * 2. Set Spanloss value for interface
+     *
+     * @param roadmLinks
+     *            reference to list of RoadmLinks
+     * @return true/false
+     */
+    public boolean getLinkSpanloss(List<RoadmLinks> roadmLinks) {
+        LOG.info("Executing GetLinkSpanLoss");
+        BigDecimal spanLoss = new BigDecimal(0);
+        for (int i = 0; i < roadmLinks.size(); i++) {
+            OtsPmHolder srcOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getSrcNodeId(),
+                    roadmLinks.get(i).getSrcTpId(), "OpticalPowerOutput");
+            OtsPmHolder destOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getDestNodeId(),
+                    roadmLinks.get(i).getDestTpid(), "OpticalPowerInput");
+            spanLoss = new BigDecimal(srcOtsPmHoler.getOtsParameterVal() - destOtsPmHoler.getOtsParameterVal())
+                    .setScale(0, RoundingMode.HALF_UP);
+            LOG.info("Spanloss Calculated as :" + spanLoss + "=" + srcOtsPmHoler.getOtsParameterVal() + "-"
+                    + destOtsPmHoler.getOtsParameterVal());
+            if (spanLoss.doubleValue() < 28 && spanLoss.doubleValue() > 0) {
+                if (!setSpanLoss(roadmLinks.get(i).getSrcNodeId(), srcOtsPmHoler.getOtsInterfaceName(), spanLoss,
+                        "TX")) {
+                    LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getSrcNodeId());
+                    return false;
+                }
+                if (!setSpanLoss(roadmLinks.get(i).getDestNodeId(), destOtsPmHoler.getOtsInterfaceName(), spanLoss,
+                        "RX")) {
+                    LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getDestNodeId());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/olm/src/main/resources/org/opendaylight/blueprint/olm-blueprint.xml b/olm/src/main/resources/org/opendaylight/blueprint/olm-blueprint.xml
new file mode 100644 (file)
index 0000000..b8ed336
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 2016 Orange 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
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+  xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+  odl:use-default-for-reference-types="true">
+
+  <reference id="dataBroker"
+    interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
+    odl:type="default" />
+  <reference id="mountPointService"
+    interface="org.opendaylight.controller.md.sal.binding.api.MountPointService" />
+  <reference id="rpcProviderRegistry"
+    interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" />
+  <bean id="provider"
+    class="org.opendaylight.transportpce.olm.OlmProvider"
+    init-method="init" destroy-method="close">
+    <argument ref="dataBroker" />
+    <argument ref="mountPointService" />
+    <argument ref="rpcProviderRegistry" />
+  </bean>
+
+</blueprint>
diff --git a/pom.xml b/pom.xml
index ccd94945b5377fe00416a2cc91411707106fa28c..5aeccea7d34535c0880848407f873b4f9d93c1cf 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -33,6 +33,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <module>ordmodels</module>
     <module>impl</module>
     <module>renderer</module>
+    <module>olm</module>
     <module>karaf</module>
     <module>features</module>
     <module>artifacts</module>