Initial commit for OLM
[transportpce.git] / olm / src / main / java / org / opendaylight / transportpce / olm / spanloss / SpanLoss.java
1 /*
2  * Copyright © 2017 AT&T and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.transportpce.olm.spanloss;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.CheckedFuture;
12
13 import java.math.BigDecimal;
14 import java.math.RoundingMode;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Future;
18
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.transportpce.olm.OlmPowerSetupImpl;
25 import org.opendaylight.transportpce.renderer.mapping.PortMapping;
26 import org.opendaylight.transportpce.renderer.provisiondevice.OpenRoadmInterfaces;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.RatioDB;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1Builder;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.Ots;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.OtsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.RpcResult;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class SpanLoss {
46     private static final Logger LOG = LoggerFactory.getLogger(SpanLoss.class);
47     private final DataBroker db;
48     private final MountPointService mps;
49
50     /**
51      * Instantiates a new span loss.
52      *
53      * @param db
54      *            the db
55      * @param mps
56      *            the mps
57      */
58     public SpanLoss(DataBroker db, MountPointService mps) {
59         this.db = db;
60         this.mps = mps;
61     }
62
63     /**
64      * This method retrieves OTS PM from current PM list by nodeId and TPId:
65      * Steps:
66      *
67      * <p>
68      * 1. Get OTS interface name from port mapping by TPId 2. Call getPm RPC to
69      * get OTS PM
70      *
71      * <p>
72      *
73      * @param nodeId
74      *            Node-id of the NE.
75      * @param tpID
76      *            Termination point Name.
77      * @return reference to OtsPmHolder
78      */
79     public OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
80         GetPmInputBuilder otsPmInputBuilder = new GetPmInputBuilder();
81         Mapping portMapping = new OpenRoadmInterfaces(db, mps, nodeId, tpID).getMapping(nodeId, tpID);
82         if (portMapping != null) {
83             otsPmInputBuilder.setNodeId(nodeId).setResourceType("Interface").setGranularity("15min")
84             .setResourceName(portMapping.getSupportingOts());
85             Future<RpcResult<GetPmOutput>> otsPmOutput = new OlmPowerSetupImpl(db, mps)
86                     .getPm(otsPmInputBuilder.build());
87             if (otsPmOutput != null) {
88                 try {
89                     for (Measurements measurement : otsPmOutput.get().getResult().getMeasurements()) {
90                         if (measurement.getPmparameterName().equals(pmName)) {
91                             return new OtsPmHolder(pmName,Double.parseDouble(measurement.getPmparameterValue()),
92                                    portMapping.getSupportingOts());
93                         }
94                     }
95                 } catch (NumberFormatException | InterruptedException | ExecutionException e) {
96                     LOG.warn("Unable to get PM for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName, e);
97                 }
98             } else {
99                 LOG.info("OTS PM not found for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName);
100             }
101         }
102         return null;
103     }
104
105     /**
106      * This method Sets Spanloss on A-End and Z-End OTS interface: Steps:
107      *
108      * <p>
109      * 1. Read existing interface details
110      *
111      * <p>
112      * 2. Set spanloss
113      *
114      * @param nodeId
115      *            nodeId of NE on which spanloss need to be updated
116      * @param interfaceName
117      *            OTS interface for NE on which spanloss is cacluated
118      * @param spanLoss
119      *            calculated spanloss value
120      * @param direction
121      *            for which spanloss is calculated.It can be either Tx or Rx
122      * @return true/false
123      */
124     public boolean setSpanLoss(String nodeId, String interfaceName, BigDecimal spanLoss, String direction) {
125         LOG.info("Setting Spanloss in device for:" + nodeId + " InterfaceName:" + interfaceName);
126         InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
127                 .child(Interface.class, new InterfaceKey(interfaceName));
128         Optional<Interface> interfaceObject;
129         try {
130             DataBroker deviceDb = PortMapping.getDeviceDataBroker(nodeId, mps);
131             ReadWriteTransaction rwtx = deviceDb.newReadWriteTransaction();
132             interfaceObject = rwtx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
133             if (interfaceObject.isPresent()) {
134                 Interface intf = interfaceObject.get();
135                 InterfaceBuilder interfaceBuilder = new InterfaceBuilder(intf);
136                 Ots ots = intf.getAugmentation(Interface1.class).getOts();
137                 Interface1Builder intf1Builder = new Interface1Builder();
138                 OtsBuilder otsBuilder = new OtsBuilder();
139                 otsBuilder.setFiberType(ots.getFiberType());
140                 if (direction.equals("TX")) {
141                     otsBuilder.setSpanLossTransmit(new RatioDB(spanLoss)).setSpanLossReceive(ots.getSpanLossReceive());
142                 } else {
143                     otsBuilder.setSpanLossTransmit(ots.getSpanLossTransmit()).setSpanLossReceive(new RatioDB(spanLoss));
144                 }
145                 interfaceBuilder.addAugmentation(Interface1.class, intf1Builder.setOts(otsBuilder.build()).build());
146                 rwtx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, interfaceBuilder.build());
147                 CheckedFuture<Void, TransactionCommitFailedException> submit = rwtx.submit();
148                 submit.checkedGet();
149                 LOG.info("Spanloss Value update completed successfully");
150                 return true;
151             }
152         } catch (InterruptedException | ExecutionException | TransactionCommitFailedException e) {
153             LOG.warn("Unable to set spanloss", e);
154         }
155         return false;
156     }
157
158     /**
159      * This method calculates Spanloss by TranmistPower - Receive Power Steps:
160      *
161      * <p>
162      * 1. Read PM measurement
163      *
164      * <p>
165      * 2. Set Spanloss value for interface
166      *
167      * @param roadmLinks
168      *            reference to list of RoadmLinks
169      * @return true/false
170      */
171     public boolean getLinkSpanloss(List<RoadmLinks> roadmLinks) {
172         LOG.info("Executing GetLinkSpanLoss");
173         BigDecimal spanLoss = new BigDecimal(0);
174         for (int i = 0; i < roadmLinks.size(); i++) {
175             OtsPmHolder srcOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getSrcNodeId(),
176                     roadmLinks.get(i).getSrcTpId(), "OpticalPowerOutput");
177             OtsPmHolder destOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getDestNodeId(),
178                     roadmLinks.get(i).getDestTpid(), "OpticalPowerInput");
179             spanLoss = new BigDecimal(srcOtsPmHoler.getOtsParameterVal() - destOtsPmHoler.getOtsParameterVal())
180                     .setScale(0, RoundingMode.HALF_UP);
181             LOG.info("Spanloss Calculated as :" + spanLoss + "=" + srcOtsPmHoler.getOtsParameterVal() + "-"
182                     + destOtsPmHoler.getOtsParameterVal());
183             if (spanLoss.doubleValue() < 28 && spanLoss.doubleValue() > 0) {
184                 if (!setSpanLoss(roadmLinks.get(i).getSrcNodeId(), srcOtsPmHoler.getOtsInterfaceName(), spanLoss,
185                         "TX")) {
186                     LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getSrcNodeId());
187                     return false;
188                 }
189                 if (!setSpanLoss(roadmLinks.get(i).getDestNodeId(), destOtsPmHoler.getOtsInterfaceName(), spanLoss,
190                         "RX")) {
191                     LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getDestNodeId());
192                     return false;
193                 }
194             }
195         }
196         return true;
197     }
198 }