026c041fe93135e3c34efe525a096b6d2f82c6c0
[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      * @param pmName
77      *            PM name which need to be retrieved
78      * @return reference to OtsPmHolder
79      */
80     public OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
81         GetPmInputBuilder otsPmInputBuilder = new GetPmInputBuilder();
82         new PortMapping(db, mps, nodeId);
83         Mapping portMapping = PortMapping.getMapping(nodeId, tpID, db);
84         if (portMapping != null) {
85             otsPmInputBuilder.setNodeId(nodeId).setResourceType("Interface").setGranularity("15min")
86             .setResourceName(portMapping.getSupportingOts());
87             Future<RpcResult<GetPmOutput>> otsPmOutput = new OlmPowerSetupImpl(db, mps)
88                     .getPm(otsPmInputBuilder.build());
89             if (otsPmOutput != null) {
90                 try {
91                     for (Measurements measurement : otsPmOutput.get().getResult().getMeasurements()) {
92                         if (measurement.getPmparameterName().equals(pmName)) {
93                             return new OtsPmHolder(pmName,Double.parseDouble(measurement.getPmparameterValue()),
94                                    portMapping.getSupportingOts());
95                         }
96                     }
97                 } catch (NumberFormatException | InterruptedException | ExecutionException e) {
98                     LOG.warn("Unable to get PM for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName, e);
99                 }
100             } else {
101                 LOG.info("OTS PM not found for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName);
102             }
103         }
104         return null;
105     }
106
107     /**
108      * This method Sets Spanloss on A-End and Z-End OTS interface: Steps:
109      *
110      * <p>
111      * 1. Read existing interface details
112      *
113      * <p>
114      * 2. Set spanloss
115      *
116      * @param nodeId
117      *            nodeId of NE on which spanloss need to be updated
118      * @param interfaceName
119      *            OTS interface for NE on which spanloss is cacluated
120      * @param spanLoss
121      *            calculated spanloss value
122      * @param direction
123      *            for which spanloss is calculated.It can be either Tx or Rx
124      * @return true/false
125      */
126     public boolean setSpanLoss(String nodeId, String interfaceName, BigDecimal spanLoss, String direction) {
127         LOG.info("Setting Spanloss in device for:" + nodeId + " InterfaceName:" + interfaceName);
128         InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
129                 .child(Interface.class, new InterfaceKey(interfaceName));
130         Optional<Interface> interfaceObject;
131         try {
132             DataBroker deviceDb = PortMapping.getDeviceDataBroker(nodeId, mps);
133             ReadWriteTransaction rwtx = deviceDb.newReadWriteTransaction();
134             interfaceObject = rwtx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
135             if (interfaceObject.isPresent()) {
136                 Interface intf = interfaceObject.get();
137                 InterfaceBuilder interfaceBuilder = new InterfaceBuilder(intf);
138                 Ots ots = intf.getAugmentation(Interface1.class).getOts();
139                 Interface1Builder intf1Builder = new Interface1Builder();
140                 OtsBuilder otsBuilder = new OtsBuilder();
141                 otsBuilder.setFiberType(ots.getFiberType());
142                 if (direction.equals("TX")) {
143                     otsBuilder.setSpanLossTransmit(new RatioDB(spanLoss)).setSpanLossReceive(ots.getSpanLossReceive());
144                 } else {
145                     otsBuilder.setSpanLossTransmit(ots.getSpanLossTransmit()).setSpanLossReceive(new RatioDB(spanLoss));
146                 }
147                 interfaceBuilder.addAugmentation(Interface1.class, intf1Builder.setOts(otsBuilder.build()).build());
148                 rwtx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, interfaceBuilder.build());
149                 CheckedFuture<Void, TransactionCommitFailedException> submit = rwtx.submit();
150                 submit.checkedGet();
151                 LOG.info("Spanloss Value update completed successfully");
152                 return true;
153             }
154         } catch (InterruptedException | ExecutionException | TransactionCommitFailedException e) {
155             LOG.warn("Unable to set spanloss", e);
156         }
157         return false;
158     }
159
160     /**
161      * This method calculates Spanloss by TranmistPower - Receive Power Steps:
162      *
163      * <p>
164      * 1. Read PM measurement
165      *
166      * <p>
167      * 2. Set Spanloss value for interface
168      *
169      * @param roadmLinks
170      *            reference to list of RoadmLinks
171      * @return true/false
172      */
173     public boolean getLinkSpanloss(List<RoadmLinks> roadmLinks) {
174         LOG.info("Executing GetLinkSpanLoss");
175         BigDecimal spanLoss = new BigDecimal(0);
176         for (int i = 0; i < roadmLinks.size(); i++) {
177             OtsPmHolder srcOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getSrcNodeId(),
178                     roadmLinks.get(i).getSrcTpId(), "OpticalPowerOutput");
179             OtsPmHolder destOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getDestNodeId(),
180                     roadmLinks.get(i).getDestTpid(), "OpticalPowerInput");
181             spanLoss = new BigDecimal(srcOtsPmHoler.getOtsParameterVal() - destOtsPmHoler.getOtsParameterVal())
182                     .setScale(0, RoundingMode.HALF_UP);
183             LOG.info("Spanloss Calculated as :" + spanLoss + "=" + srcOtsPmHoler.getOtsParameterVal() + "-"
184                     + destOtsPmHoler.getOtsParameterVal());
185             if (spanLoss.doubleValue() < 28 && spanLoss.doubleValue() > 0) {
186                 if (!setSpanLoss(roadmLinks.get(i).getSrcNodeId(), srcOtsPmHoler.getOtsInterfaceName(), spanLoss,
187                         "TX")) {
188                     LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getSrcNodeId());
189                     return false;
190                 }
191                 if (!setSpanLoss(roadmLinks.get(i).getDestNodeId(), destOtsPmHoler.getOtsInterfaceName(), spanLoss,
192                         "RX")) {
193                     LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getDestNodeId());
194                     return false;
195                 }
196             }
197         }
198         return true;
199     }
200 }