2 * Copyright © 2017 AT&T and others. All rights reserved.
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
9 package org.opendaylight.transportpce.common.mapping;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import java.util.ArrayList;
13 import java.util.Comparator;
14 import java.util.HashMap;
15 import java.util.List;
17 import java.util.Map.Entry;
18 import java.util.Optional;
20 import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.TimeoutException;
23 import java.util.stream.Collectors;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
27 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
30 import org.opendaylight.transportpce.common.Timeouts;
31 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
32 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
33 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
34 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.CircuitPack;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.Port;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.degree.ConnectionPorts;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Degree;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.DegreeKey;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Info;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Protocols;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.port.Interfaces;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.InterfaceType;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpenROADMOpticalMultiplex;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalTransport;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.Protocols1;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.Lldp;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.lldp.PortConfig;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.Network;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.NetworkBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegree;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegreeBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegreeKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
74 public class PortMappingImpl implements PortMapping {
76 private static final Logger LOG = LoggerFactory.getLogger(PortMappingImpl.class);
78 private final DataBroker dataBroker;
79 private final DeviceTransactionManager deviceTransactionManager;
80 private final OpenRoadmInterfaces openRoadmInterfaces;
82 public PortMappingImpl(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
83 OpenRoadmInterfaces openRoadmInterfaces) {
84 this.dataBroker = dataBroker;
85 this.deviceTransactionManager = deviceTransactionManager;
86 this.openRoadmInterfaces = openRoadmInterfaces;
90 public boolean createMappingData(String nodeId) {
92 LOG.info("Create Mapping Data for node {}", nodeId);
93 List<Mapping> portMapList = new ArrayList<>();
94 InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
95 Optional<Info> deviceInfoOptional = this.deviceTransactionManager.getDataFromDevice(nodeId,
96 LogicalDatastoreType.OPERATIONAL, infoIID, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
99 if (deviceInfoOptional.isPresent()) {
100 deviceInfo = deviceInfoOptional.get();
102 LOG.warn("Device info subtree is absent for {}", nodeId);
105 if (deviceInfo.getNodeType() == null) {
106 LOG.error("Node type field is missing"); // TODO make mandatory in yang
109 switch (deviceInfo.getNodeType()) {
112 // Get TTP port mapping
113 if (!createTtpPortMapping(nodeId, deviceInfo, portMapList)) {
114 // return false if mapping creation for TTP's failed
115 LOG.warn("Unable to create mapping for TTP's on node {}", nodeId);
119 // Get PP port mapping
120 if (!createPpPortMapping(nodeId, deviceInfo, portMapList)) {
121 // return false if mapping creation for PP's failed
122 LOG.warn("Unable to create mapping for PP's on node {}", nodeId);
127 if (!createXpdrPortMapping(nodeId, portMapList)) {
128 LOG.warn("Unable to create mapping for Xponder on node {}", nodeId);
133 LOG.error("Unable to create mapping for node {} : unknown nodetype ", nodeId);
137 return postPortMapping(deviceInfo, portMapList, deviceInfo.getNodeType().getIntValue(), null);
141 * This private method gets the list of external ports on a degree. For each
142 * port in the degree, it does a get on port subtree with
143 * circuit-pack-name/port-name as key in order to get the logical connection
144 * point name corresponding to it.
147 * Info subtree read from the device
149 * Reference to the list containing the mapping to be pushed to
152 * @return true/false based on status of operation
154 private boolean createTtpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
155 // Creating mapping data for degree TTP's
157 List<Degree> degrees = getDegrees(nodeId, deviceInfo);
158 List<ConnectionPorts> degreeConPorts = getDegreePorts(degrees);
159 Map<String, String> interfaceList = getEthInterfaceList(nodeId);
160 List<CpToDegree> cpToDegreeList = getCpToDegreeList(degrees, nodeId, interfaceList);
161 LOG.info("Map looks like this {}",interfaceList);
163 postPortMapping(deviceInfo, null, deviceInfo.getNodeType().getIntValue(), cpToDegreeList);
165 // Getting circuit-pack-name/port-name corresponding to TTP's
166 for (ConnectionPorts cp : degreeConPorts) {
167 String circuitPackName = cp.getCircuitPackName();
168 String portName = cp.getPortName().toString();
169 InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
170 CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class, new PortsKey(portName));
172 LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}", portName,
174 Optional<Ports> portObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
175 LogicalDatastoreType.OPERATIONAL, portIID, Timeouts.DEVICE_READ_TIMEOUT,
176 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
177 if (portObject.isPresent()) {
178 Ports port = portObject.get();
179 if (port.getLogicalConnectionPoint() != null) {
180 LOG.info("Logical Connection Point for {} {} is {}", circuitPackName, portName, port
181 .getLogicalConnectionPoint());
182 portMapList.add(createMappingObject(nodeId, port, circuitPackName, port
183 .getLogicalConnectionPoint()));
185 LOG.warn("Logical Connection Point value is missing for {} {}", circuitPackName, port
189 LOG.warn("Port {} is not present in node {} in circuit pack {}!", portName, nodeId, circuitPackName);
190 continue; // TODO continue or return true?
196 private List<Degree> getDegrees(String deviceId, Info ordmInfo) {
197 List<Degree> degrees = new ArrayList<>();
200 // Get value for max degree from info subtree, required for iteration
201 // if not present assume to be 20 (temporary)
202 if (ordmInfo.getMaxDegrees() != null) {
203 maxDegree = ordmInfo.getMaxDegrees();
208 for (int degreeCounter = 1; degreeCounter <= maxDegree; degreeCounter++) {
209 LOG.info("Getting Connection ports for Degree Number {}", degreeCounter);
210 InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
211 Degree.class, new DegreeKey(degreeCounter));
212 Optional<Degree> ordmDegreeObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
213 LogicalDatastoreType.CONFIGURATION, deviceIID, Timeouts.DEVICE_READ_TIMEOUT,
214 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
215 if (ordmDegreeObject.isPresent()) {
216 degrees.add(ordmDegreeObject.get());
218 LOG.info("Device has {} degree", degreeCounter - 1);
226 * This private method gets the list of circuit packs on an Srg. For each
227 * circuit pack on an Srg, it does a get on circuit-pack subtree with
228 * circuit-pack-name as key in order to get the list of ports. It then
229 * iterates over the list of ports to get ports with port-qual as
230 * roadm-external. It appends a TX,RX,TXRX to the logical connection point
231 * name based on the direction of the port.
236 * Info subtree read from the device
238 * Reference to the list containing the mapping to be pushed to
241 * @return true/false based on status of operation
244 private boolean createPpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
245 // Creating mapping data for SRG's PP
246 HashMap<Integer, List<
247 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> srgCps = getSrgCps(
249 Set<Map.Entry<Integer, List<
250 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>>> circuitPacks = srgCps
252 for (Entry<Integer, List<
253 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> entry : circuitPacks) {
254 Integer srgIndex = entry.getKey();
255 for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks cp : entry
257 String circuitPackName = cp.getCircuitPackName();
258 InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
259 CircuitPacks.class, new CircuitPacksKey(circuitPackName));
260 Optional<CircuitPacks> circuitPackObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
261 LogicalDatastoreType.OPERATIONAL, cpIID, Timeouts.DEVICE_READ_TIMEOUT,
262 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
264 if (!circuitPackObject.isPresent() || (circuitPackObject.get().getPorts() == null)) {
265 LOG.warn("{} : Circuit pack {} not found or without ports.", nodeId, circuitPackName);
266 continue; // TODO continue or return false?
268 CircuitPacks circuitPack = circuitPackObject.get();
269 for (Ports port : circuitPack.getPorts()) {
270 if (port.getLogicalConnectionPoint() != null) {
271 String logicalConnectionPoint = getLogicalConnectionPort(port, srgIndex);
272 LOG.info("{} : Logical Connection Point for {} {} is {}", nodeId, circuitPackName, port
273 .getPortName(), logicalConnectionPoint);
274 portMapList.add(createMappingObject(nodeId, port, circuitPackName, logicalConnectionPoint));
275 } else if (Port.PortQual.RoadmInternal.equals(port.getPortQual())) {
276 LOG.info("Port is internal, skipping Logical Connection Point missing for {} {}",
277 circuitPackName, port.getPortName());
278 } else if (port.getLogicalConnectionPoint() == null) {
279 LOG.info("Value missing, Skipping Logical Connection Point missing for {} {}", circuitPackName,
289 * This method does a get operation on shared risk group subtree of the
290 * netconf device's config datastore and returns a list of all circuit packs
291 * objects that are part of srgs. It is required to do a selective get on
292 * all the circuit packs that contain add/drop ports of interest.
297 * Info subtree from the device
298 * @return List of circuit packs object belonging to- shared risk group
301 private HashMap<Integer, List<
302 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> getSrgCps(String deviceId,
304 HashMap<Integer, List<
305 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> cpPerSrg =
308 // Get value for max Srg from info subtree, required for iteration
309 // if not present assume to be 20 (temporary)
310 if (ordmInfo.getMaxSrgs() != null) {
311 maxSrg = ordmInfo.getMaxSrgs();
315 for (int srgCounter = 1; srgCounter <= maxSrg; srgCounter++) {
316 List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> srgCps =
318 LOG.info("Getting Circuitpacks for Srg Number {}", srgCounter);
319 InstanceIdentifier<SharedRiskGroup> srgIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
320 SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
321 Optional<SharedRiskGroup> ordmSrgObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
322 LogicalDatastoreType.CONFIGURATION, srgIID, Timeouts.DEVICE_READ_TIMEOUT,
323 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
324 if (ordmSrgObject.isPresent()) {
325 srgCps.addAll(ordmSrgObject.get().getCircuitPacks());
326 cpPerSrg.put(ordmSrgObject.get().getSrgNumber(), srgCps);
329 LOG.info("Device {} has {} Srg", deviceId, cpPerSrg.size());
334 * This private method gets the list of circuit packs on a xponder. For each
335 * circuit pack on a Xponder, it does a get on circuit-pack subtree with
336 * circuit-pack-name as key in order to get the list of ports. It then
337 * iterates over the list of ports to get ports with port-qual as
338 * xpdr-network/xpdr-client. The line and client ports are saved as:
349 * Reference to the list containing the mapping to be pushed to
352 * @return true/false based on status of operation
354 private boolean createXpdrPortMapping(String nodeId, List<Mapping> portMapList) {
355 // Creating for Xponder Line and Client Ports
356 InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
357 Optional<OrgOpenroadmDevice> deviceObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
358 LogicalDatastoreType.OPERATIONAL, deviceIID, Timeouts.DEVICE_READ_TIMEOUT,
359 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
361 // Variable to keep track of number of line ports
363 // Variable to keep track of number of client ports
365 if (!deviceObject.isPresent() || (deviceObject.get().getCircuitPacks() == null)) {
366 LOG.warn("Circuit Packs are not present for {}", nodeId);
367 return false; // TODO return false or continue?
370 List<CircuitPacks> circuitPackList = deviceObject.get().getCircuitPacks();
371 circuitPackList.sort(Comparator.comparing(CircuitPack::getCircuitPackName));
373 for (CircuitPacks cp : circuitPackList) {
374 String circuitPackName = cp.getCircuitPackName();
375 if (cp.getPorts() == null) {
376 LOG.warn("Ports were not found for circuit pack: {}", circuitPackName);
379 for (Ports port : cp.getPorts()) {
380 if (Port.PortQual.XpdrNetwork.equals(port.getPortQual())) {
381 portMapList.add(createMappingObject(nodeId, port, circuitPackName,
382 "XPDR1-" + OpenRoadmInterfacesImpl.NETWORK_TOKEN + line));
383 //String lcp = port.getLogicalConnectionPoint();
384 //String regex = "XPDR[0-9]+-NETWORK[0-9]+";
385 //checkLogicalConnectionPoint(regex, lcp, nodeId, portMapList, circuitPackName, port, "NETWORK", line);
387 } else if (Port.PortQual.XpdrClient.equals(port.getPortQual())) {
388 portMapList.add(createMappingObject(nodeId, port, circuitPackName,
389 "XPDR1-" + OpenRoadmInterfacesImpl.CLIENT_TOKEN + client));
390 //String lcp = port.getLogicalConnectionPoint();
391 //String regex = "XPDR[0-9]+-CLIENT[0-9]+";
392 //checkLogicalConnectionPoint(regex, lcp, nodeId, portMapList, circuitPackName, port, "CLIENT", client);
395 LOG.warn("Port type {} not supported", port.getPortQual());
402 private void checkLogicalConnectionPoint(String regex, String logicalConnectionPoint, String nodeId, List<
403 Mapping> portMapList, String circuitPackName, Ports port, String portQual, int index) {
404 if (logicalConnectionPoint.matches(regex)) {
405 Mapping map = createMappingObject(nodeId, port, circuitPackName, logicalConnectionPoint);
406 if (portMapList.stream().filter(mapping -> mapping.getLogicalConnectionPoint().equals(
407 logicalConnectionPoint)).count() > 0) {
408 LOG.warn("{} : logical connection point {} on {} {} already used. Port can not be used", nodeId,
409 logicalConnectionPoint, circuitPackName, port.getPortName());
411 portMapList.add(map);
412 LOG.info("{} : logical connection point for {} {} is {}", nodeId, circuitPackName, port.getPortName(),
413 logicalConnectionPoint);
415 } else if (logicalConnectionPoint.isEmpty()) {
416 String lcp = "XPDR0-" + portQual + index;
417 Mapping map = createMappingObject(nodeId, port, circuitPackName, lcp);
418 if (portMapList.contains(map)) {
419 LOG.warn("{} : can not assign logical connection point {} to port {} of circuit pack {}. "
420 + "Name is already used", nodeId, lcp, port.getPortName(), circuitPackName);
422 portMapList.add(createMappingObject(nodeId, port, circuitPackName, lcp));
423 LOG.info("{} : no logical connection port on {} {}. Assigning {}.", nodeId, circuitPackName, port
424 .getPortName(), lcp);
427 LOG.warn("{} : logical connection point {} on {} {} does not respect OrgOpenRoadm recommendation. Port can "
428 + "not be used.", nodeId, logicalConnectionPoint, circuitPackName, port.getPortName());
433 * This private method builds the mapping object to be pushed in MD-SAL in
434 * order to save port mapping. In case of TTP ports, it also saves the
435 * OTS,OMS interfaces provisioned on the port.
438 * Reference to device's port subtree object.
439 * @param circuitPackName
440 * Name of cp where port exists.
441 * @param logicalConnectionPoint
442 * logical name of the port.
444 * @return true/false based on status of operation
447 private Mapping createMappingObject(String nodeId, Ports port, String circuitPackName,
448 String logicalConnectionPoint) {
449 MappingBuilder mpBldr = new MappingBuilder();
450 mpBldr.withKey(new MappingKey(logicalConnectionPoint)).setLogicalConnectionPoint(logicalConnectionPoint)
451 .setSupportingCircuitPackName(circuitPackName).setSupportingPort(port.getPortName());
453 // Get OMS and OTS interface provisioned on the TTP's
454 if (logicalConnectionPoint.contains(OpenRoadmInterfacesImpl.TTP_TOKEN) && (port.getInterfaces() != null)) {
455 for (Interfaces interfaces : port.getInterfaces()) {
457 Optional<Interface> openRoadmInterface = this.openRoadmInterfaces.getInterface(nodeId, interfaces
458 .getInterfaceName());
459 if (openRoadmInterface.isPresent()) {
460 Class<? extends InterfaceType> interfaceType = openRoadmInterface.get().getType();
461 // Check if interface type is OMS or OTS
462 if (interfaceType.equals(OpenROADMOpticalMultiplex.class)) {
463 mpBldr.setSupportingOms(interfaces.getInterfaceName());
465 if (interfaceType.equals(OpticalTransport.class)) {
466 mpBldr.setSupportingOts(interfaces.getInterfaceName());
469 LOG.warn("Interface {} from node {} was null!", interfaces.getInterfaceName(), nodeId);
471 } catch (OpenRoadmInterfaceException ex) {
472 LOG.warn("Error while getting interface {} from node {}!", interfaces.getInterfaceName(), nodeId,
477 return mpBldr.build();
480 private CpToDegree createCpToDegreeObject(String circuitPackName, String degreeNumber, String nodeId,
481 Map<String, String> interfaceList) {
482 String interfaceName = null;
483 if (interfaceList.get(circuitPackName) != null) {
484 interfaceName = interfaceList.get(circuitPackName);
486 return new CpToDegreeBuilder().withKey(new CpToDegreeKey(circuitPackName)).setCircuitPackName(circuitPackName)
487 .setDegreeNumber(new Long(degreeNumber)).setInterfaceName(interfaceName).build();
490 private static List<ConnectionPorts> getDegreePorts(List<Degree> degrees) {
491 return degrees.stream().filter(degree -> degree.getConnectionPorts() != null).flatMap(degree -> degree
492 .getConnectionPorts().stream()).collect(Collectors.toList());
495 private List<CpToDegree> getCpToDegreeList(List<Degree> degrees, String nodeId,
496 Map<String, String> interfaceList) {
497 List<CpToDegree> cpToDegreeList = new ArrayList<>();
498 for (Degree degree : degrees) {
499 if (degree.getCircuitPacks() != null) {
500 LOG.info("Inside CP to degree list");
501 cpToDegreeList.addAll(degree.getCircuitPacks().stream()
502 .map(cp -> createCpToDegreeObject(cp.getCircuitPackName() ,
503 degree.getDegreeNumber().toString(), nodeId ,interfaceList))
504 .collect(Collectors.toList()));
507 return cpToDegreeList;
511 * This method for ports the portMapping corresponding to the
512 * portmapping.yang file to the MD-SAL datastore.
515 * 1. Supporting circuit pack 2. Supporting port 3. Supporting OMS interface
519 * Info subtree from the device.
521 * Reference to the list containing the mapping to be pushed to
524 * @return Result true/false based on status of operation.
526 private boolean postPortMapping(Info deviceInfo, List<Mapping> portMapList, Integer nodeType, List<
527 CpToDegree> cp2DegreeList) {
528 NodesBuilder nodesBldr = new NodesBuilder();
529 nodesBldr.withKey(new NodesKey(deviceInfo.getNodeId())).setNodeId(deviceInfo.getNodeId());
530 nodesBldr.setNodeType(NodeTypes.forValue(nodeType));
532 if (portMapList != null) {
533 nodesBldr.setMapping(portMapList);
535 if (cp2DegreeList != null) {
536 nodesBldr.setCpToDegree(cp2DegreeList);
539 List<Nodes> nodesList = new ArrayList<>();
540 nodesList.add(nodesBldr.build());
542 NetworkBuilder nwBldr = new NetworkBuilder();
543 nwBldr.setNodes(nodesList);
545 final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
546 InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
547 Network network = nwBldr.build();
548 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, network);
549 CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
554 } catch (TransactionCommitFailedException e) {
555 LOG.warn("Failed to post {}", network, e);
561 public Mapping getMapping(String nodeId, String logicalConnPoint) {
564 * Getting physical mapping corresponding to logical connection point
566 InstanceIdentifier<Mapping> portMappingIID = InstanceIdentifier.builder(Network.class).child(Nodes.class,
567 new NodesKey(nodeId)).child(Mapping.class, new MappingKey(logicalConnPoint)).build();
568 try (ReadOnlyTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
569 Optional<Mapping> mapObject = readTx.read(LogicalDatastoreType.CONFIGURATION, portMappingIID).get()
571 if (mapObject.isPresent()) {
572 Mapping mapping = mapObject.get();
573 LOG.info("Found mapping for the logical port {}. Mapping: {}", logicalConnPoint, mapping.toString());
576 LOG.warn("Could not find mapping for logical connection point {} for nodeId {}", logicalConnPoint,
579 } catch (InterruptedException | ExecutionException ex) {
580 LOG.error("Unable to read mapping for logical connection point : {} for nodeId {}", logicalConnPoint,
586 private static String getLogicalConnectionPort(Ports port, int srgCounter) {
587 String logicalConnectionPoint = null;
588 if (port.getLogicalConnectionPoint() != null) {
589 switch (port.getPortDirection()) {
591 // Port direction is transmit
592 if (!port.getLogicalConnectionPoint().contains("SRG")) {
593 logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint() + "-TX";
595 logicalConnectionPoint = port.getLogicalConnectionPoint() + "-TX";
599 // Port direction is receive
600 if (!port.getLogicalConnectionPoint().contains("SRG")) {
601 logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint() + "-RX";
603 logicalConnectionPoint = port.getLogicalConnectionPoint() + "-RX";
607 // port is bidirectional
608 if (!port.getLogicalConnectionPoint().contains("SRG")) {
609 logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint();
611 logicalConnectionPoint = port.getLogicalConnectionPoint();
613 if (!port.getLogicalConnectionPoint().endsWith("-TXRX")) {
614 logicalConnectionPoint = logicalConnectionPoint.concat("-TXRX");
618 // Unsupported Port direction
619 LOG.error("Unsupported port direction for port {} {}", port, port.getPortDirection());
620 return null; // TODO return false or continue?
622 return logicalConnectionPoint;
624 LOG.warn("Unsupported port direction for port {} - {} - LogicalConnectionPoint is null", port, port
625 .getPortDirection());
626 return null; // TODO return false or continue?
630 public void deleteMappingData(String nodeId) {
631 LOG.info("Deleting Mapping Data corresponding at node '{}'", nodeId);
632 WriteTransaction rw = this.dataBroker.newWriteOnlyTransaction();
633 InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class).child(Nodes.class, new NodesKey(
635 rw.delete(LogicalDatastoreType.CONFIGURATION, nodesIID);
637 rw.submit().get(1, TimeUnit.SECONDS);
638 LOG.info("Port mapping removal for node '{}'", nodeId);
639 } catch (InterruptedException | ExecutionException | TimeoutException e) {
640 LOG.error("Error for removing port mapping infos for node '{}'", nodeId);
646 public boolean updateMapping(String nodeId, Mapping oldMapping) {
647 LOG.info("Updating Mapping Data {} for node {}", oldMapping, nodeId);
648 InstanceIdentifier<Ports> portIId = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
649 CircuitPacks.class, new CircuitPacksKey(oldMapping.getSupportingCircuitPackName())).child(Ports.class,
650 new PortsKey(oldMapping.getSupportingPort()));
651 if (oldMapping != null && nodeId != null) {
653 Optional<Ports> portObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
654 LogicalDatastoreType.OPERATIONAL, portIId, Timeouts.DEVICE_READ_TIMEOUT,
655 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
656 if (portObject.isPresent()) {
657 Ports port = portObject.get();
658 Mapping newMapping = createMappingObject(nodeId, port, oldMapping.getSupportingCircuitPackName(),
659 oldMapping.getLogicalConnectionPoint());
661 final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
662 InstanceIdentifier<Mapping> mapIID = InstanceIdentifier.create(Network.class).child(Nodes.class,
663 new NodesKey(nodeId)).child(Mapping.class, new MappingKey(oldMapping
664 .getLogicalConnectionPoint()));
665 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, mapIID, newMapping);
666 CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
671 } catch (TransactionCommitFailedException e) {
672 LOG.error("Transaction Commit Error updating Mapping {} for node {}", oldMapping
673 .getLogicalConnectionPoint(), nodeId, e);
677 LOG.error("Impossible to update mapping");
683 private Map<String, String> getEthInterfaceList(String nodeId) {
684 LOG.info("It is calling get ethernet interface");
685 Map<String, String> cpToInterfaceMap = new HashMap<>();
686 InstanceIdentifier<Lldp> lldpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
687 .child(Protocols.class).augmentation(Protocols1.class).child(Lldp.class);
688 Optional<Lldp> lldpObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
689 LogicalDatastoreType.OPERATIONAL, lldpIID, Timeouts.DEVICE_READ_TIMEOUT,
690 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
691 if (lldpObject.isPresent() && (lldpObject.get().getPortConfig() != null)) {
692 for (PortConfig portConfig : lldpObject.get().getPortConfig()) {
693 if (portConfig.getAdminStatus().equals(PortConfig.AdminStatus.Txandrx)) {
694 InstanceIdentifier<Interface> interfaceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
695 .child(Interface.class, new InterfaceKey(portConfig.getIfName()));
696 Optional<Interface> interfaceObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
697 LogicalDatastoreType.OPERATIONAL, interfaceIID, Timeouts.DEVICE_READ_TIMEOUT,
698 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
699 if (interfaceObject.isPresent() && (interfaceObject.get().getSupportingCircuitPackName() != null)) {
700 String supportingCircuitPackName = interfaceObject.get().getSupportingCircuitPackName();
701 cpToInterfaceMap.put(supportingCircuitPackName, portConfig.getIfName());
702 InstanceIdentifier<CircuitPacks> circuitPacksIID = InstanceIdentifier.create(OrgOpenroadmDevice
703 .class).child(CircuitPacks.class, new CircuitPacksKey(supportingCircuitPackName));
704 Optional<CircuitPacks> circuitPackObject = this.deviceTransactionManager.getDataFromDevice(
705 nodeId, LogicalDatastoreType.OPERATIONAL, circuitPacksIID, Timeouts
706 .DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
707 if (circuitPackObject.isPresent() && (circuitPackObject.get().getParentCircuitPack() != null)) {
708 cpToInterfaceMap.put(circuitPackObject.get().getParentCircuitPack().getCircuitPackName() ,
709 portConfig.getIfName());
715 LOG.warn("Couldnt find port config under LLDP for Node : {}", nodeId);
717 LOG.info("Processiong is done.. now returning..");
718 return cpToInterfaceMap;