f7c314cc9499662e7da51a2bfd563dde2aa933ad
[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.yang.gen.v1.http.org.openroadm.common.types.rev161014.RatioDB;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1Builder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.Ots;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.OtsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.opendaylight.yangtools.yang.common.RpcResult;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 public class SpanLoss {
45     private static final Logger LOG = LoggerFactory.getLogger(SpanLoss.class);
46     private final DataBroker db;
47     private final MountPointService mps;
48
49     /**
50      * Instantiates a new span loss.
51      *
52      * @param db
53      *            the db
54      * @param mps
55      *            the mps
56      */
57     public SpanLoss(DataBroker db, MountPointService mps) {
58         this.db = db;
59         this.mps = mps;
60     }
61
62     /**
63      * This method retrieves OTS PM from current PM list by nodeId and TPId:
64      * Steps:
65      *
66      * <p>
67      * 1. Get OTS interface name from port mapping by TPId 2. Call getPm RPC to
68      * get OTS PM
69      *
70      * <p>
71      *
72      * @param nodeId
73      *            Node-id of the NE.
74      * @param tpID
75      *            Termination point Name.
76      * @return reference to OtsPmHolder
77      */
78     public OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
79         GetPmInputBuilder otsPmInputBuilder = new GetPmInputBuilder();
80         new PortMapping(db, mps, nodeId);
81         Mapping portMapping = PortMapping.getMapping(nodeId, tpID, db);
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 }