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;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
26 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
29 import org.opendaylight.transportpce.common.Timeouts;
30 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
31 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
32 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
33 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.CircuitPack;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.Port;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.degree.ConnectionPorts;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Degree;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.DegreeKey;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Info;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Protocols;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.port.Interfaces;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.InterfaceType;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpenROADMOpticalMultiplex;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalTransport;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.Protocols1;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.Lldp;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.lldp.PortConfig;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.Network;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.NetworkBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegree;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegreeBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegreeKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
73 public class PortMappingImpl implements PortMapping {
75 private static final Logger LOG = LoggerFactory.getLogger(PortMappingImpl.class);
77 private final DataBroker dataBroker;
78 private final DeviceTransactionManager deviceTransactionManager;
79 private final OpenRoadmInterfaces openRoadmInterfaces;
81 public PortMappingImpl(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
82 OpenRoadmInterfaces openRoadmInterfaces) {
83 this.dataBroker = dataBroker;
84 this.deviceTransactionManager = deviceTransactionManager;
85 this.openRoadmInterfaces = openRoadmInterfaces;
89 public boolean createMappingData(String nodeId) {
91 LOG.info("Create Mapping Data for node {}", nodeId);
92 List<Mapping> portMapList = new ArrayList<>();
93 InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
94 Optional<Info> deviceInfoOptional = this.deviceTransactionManager.getDataFromDevice(nodeId,
95 LogicalDatastoreType.OPERATIONAL, infoIID, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
98 if (deviceInfoOptional.isPresent()) {
99 deviceInfo = deviceInfoOptional.get();
101 LOG.warn("Device info subtree is absent for {}", nodeId);
104 if (deviceInfo.getNodeType() == null) {
105 LOG.error("Node type field is missing"); // TODO make mandatory in yang
108 switch (deviceInfo.getNodeType()) {
111 // Get TTP port mapping
112 if (!createTtpPortMapping(nodeId, deviceInfo, portMapList)) {
113 // return false if mapping creation for TTP's failed
114 LOG.warn("Unable to create mapping for TTP's on node {}", nodeId);
118 // Get PP port mapping
119 if (!createPpPortMapping(nodeId, deviceInfo, portMapList)) {
120 // return false if mapping creation for PP's failed
121 LOG.warn("Unable to create mapping for PP's on node {}", nodeId);
126 if (!createXpdrPortMapping(nodeId, portMapList)) {
127 LOG.warn("Unable to create mapping for Xponder on node {}", nodeId);
132 LOG.error("Unable to create mapping for node {} : unknown nodetype ", nodeId);
136 return postPortMapping(deviceInfo, portMapList, deviceInfo.getNodeType().getIntValue(), null);
140 * This private method gets the list of external ports on a degree. For each
141 * port in the degree, it does a get on port subtree with
142 * circuit-pack-name/port-name as key in order to get the logical connection
143 * point name corresponding to it.
146 * Info subtree read from the device
148 * Reference to the list containing the mapping to be pushed to
151 * @return true/false based on status of operation
153 private boolean createTtpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
154 // Creating mapping data for degree TTP's
156 List<Degree> degrees = getDegrees(nodeId, deviceInfo);
157 List<ConnectionPorts> degreeConPorts = getDegreePorts(degrees);
158 Map<String, String> interfaceList = getEthInterfaceList(nodeId);
159 List<CpToDegree> cpToDegreeList = getCpToDegreeList(degrees, nodeId, interfaceList);
160 LOG.info("Map looks like this {}",interfaceList);
162 postPortMapping(deviceInfo, null, deviceInfo.getNodeType().getIntValue(), cpToDegreeList);
164 // Getting circuit-pack-name/port-name corresponding to TTP's
165 for (ConnectionPorts cp : degreeConPorts) {
166 String circuitPackName = cp.getCircuitPackName();
167 String portName = cp.getPortName().toString();
168 InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
169 CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class, new PortsKey(portName));
171 LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}", portName,
173 Optional<Ports> portObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
174 LogicalDatastoreType.OPERATIONAL, portIID, Timeouts.DEVICE_READ_TIMEOUT,
175 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
176 if (portObject.isPresent()) {
177 Ports port = portObject.get();
178 if (port.getLogicalConnectionPoint() != null) {
179 LOG.info("Logical Connection Point for {} {} is {}", circuitPackName, portName, port
180 .getLogicalConnectionPoint());
181 portMapList.add(createMappingObject(nodeId, port, circuitPackName, port
182 .getLogicalConnectionPoint()));
184 LOG.warn("Logical Connection Point value is missing for {} {}", circuitPackName, port
188 LOG.warn("Port {} is not present in node {} in circuit pack {}!", portName, nodeId, circuitPackName);
189 continue; // TODO continue or return true?
195 private List<Degree> getDegrees(String deviceId, Info ordmInfo) {
196 List<Degree> degrees = new ArrayList<>();
199 // Get value for max degree from info subtree, required for iteration
200 // if not present assume to be 20 (temporary)
201 if (ordmInfo.getMaxDegrees() != null) {
202 maxDegree = ordmInfo.getMaxDegrees();
207 for (int degreeCounter = 1; degreeCounter <= maxDegree; degreeCounter++) {
208 LOG.info("Getting Connection ports for Degree Number {}", degreeCounter);
209 InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
210 Degree.class, new DegreeKey(degreeCounter));
211 Optional<Degree> ordmDegreeObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
212 LogicalDatastoreType.CONFIGURATION, deviceIID, Timeouts.DEVICE_READ_TIMEOUT,
213 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
214 if (ordmDegreeObject.isPresent()) {
215 degrees.add(ordmDegreeObject.get());
217 LOG.info("Device has {} degree", degreeCounter - 1);
225 * This private method gets the list of circuit packs on an Srg. For each
226 * circuit pack on an Srg, it does a get on circuit-pack subtree with
227 * circuit-pack-name as key in order to get the list of ports. It then
228 * iterates over the list of ports to get ports with port-qual as
229 * roadm-external. It appends a TX,RX,TXRX to the logical connection point
230 * name based on the direction of the port.
235 * Info subtree read from the device
237 * Reference to the list containing the mapping to be pushed to
240 * @return true/false based on status of operation
243 private boolean createPpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
244 // Creating mapping data for SRG's PP
245 HashMap<Integer, List<
246 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> srgCps = getSrgCps(
248 Set<Map.Entry<Integer, List<
249 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>>> circuitPacks = srgCps
251 for (Entry<Integer, List<
252 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> entry : circuitPacks) {
253 Integer srgIndex = entry.getKey();
254 for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks cp : entry
256 String circuitPackName = cp.getCircuitPackName();
257 InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
258 CircuitPacks.class, new CircuitPacksKey(circuitPackName));
259 Optional<CircuitPacks> circuitPackObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
260 LogicalDatastoreType.OPERATIONAL, cpIID, Timeouts.DEVICE_READ_TIMEOUT,
261 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
263 if (!circuitPackObject.isPresent() || (circuitPackObject.get().getPorts() == null)) {
264 LOG.warn("{} : Circuit pack {} not found or without ports.", nodeId, circuitPackName);
265 continue; // TODO continue or return false?
267 CircuitPacks circuitPack = circuitPackObject.get();
268 for (Ports port : circuitPack.getPorts()) {
269 if (port.getLogicalConnectionPoint() != null) {
270 String logicalConnectionPoint = getLogicalConnectionPort(port, srgIndex);
271 LOG.info("{} : Logical Connection Point for {} {} is {}", nodeId, circuitPackName, port
272 .getPortName(), logicalConnectionPoint);
273 portMapList.add(createMappingObject(nodeId, port, circuitPackName, logicalConnectionPoint));
274 } else if (Port.PortQual.RoadmInternal.equals(port.getPortQual())) {
275 LOG.info("Port is internal, skipping Logical Connection Point missing for {} {}",
276 circuitPackName, port.getPortName());
277 } else if (port.getLogicalConnectionPoint() == null) {
278 LOG.info("Value missing, Skipping Logical Connection Point missing for {} {}", circuitPackName,
288 * This method does a get operation on shared risk group subtree of the
289 * netconf device's config datastore and returns a list of all circuit packs
290 * objects that are part of srgs. It is required to do a selective get on
291 * all the circuit packs that contain add/drop ports of interest.
296 * Info subtree from the device
297 * @return List of circuit packs object belonging to- shared risk group
300 private HashMap<Integer, List<
301 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> getSrgCps(String deviceId,
303 HashMap<Integer, List<
304 org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> cpPerSrg =
307 // Get value for max Srg from info subtree, required for iteration
308 // if not present assume to be 20 (temporary)
309 if (ordmInfo.getMaxSrgs() != null) {
310 maxSrg = ordmInfo.getMaxSrgs();
314 for (int srgCounter = 1; srgCounter <= maxSrg; srgCounter++) {
315 List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> srgCps =
317 LOG.info("Getting Circuitpacks for Srg Number {}", srgCounter);
318 InstanceIdentifier<SharedRiskGroup> srgIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
319 SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
320 Optional<SharedRiskGroup> ordmSrgObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
321 LogicalDatastoreType.CONFIGURATION, srgIID, Timeouts.DEVICE_READ_TIMEOUT,
322 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
323 if (ordmSrgObject.isPresent()) {
324 srgCps.addAll(ordmSrgObject.get().getCircuitPacks());
325 cpPerSrg.put(ordmSrgObject.get().getSrgNumber(), srgCps);
328 LOG.info("Device {} has {} Srg", deviceId, cpPerSrg.size());
333 * This private method gets the list of circuit packs on a xponder. For each
334 * circuit pack on a Xponder, it does a get on circuit-pack subtree with
335 * circuit-pack-name as key in order to get the list of ports. It then
336 * iterates over the list of ports to get ports with port-qual as
337 * xpdr-network/xpdr-client. The line and client ports are saved as:
348 * Reference to the list containing the mapping to be pushed to
351 * @return true/false based on status of operation
353 private boolean createXpdrPortMapping(String nodeId, List<Mapping> portMapList) {
354 // Creating for Xponder Line and Client Ports
355 InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
356 Optional<OrgOpenroadmDevice> deviceObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
357 LogicalDatastoreType.OPERATIONAL, deviceIID, Timeouts.DEVICE_READ_TIMEOUT,
358 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
360 // Variable to keep track of number of line ports
362 // Variable to keep track of number of client ports
364 if (!deviceObject.isPresent() || (deviceObject.get().getCircuitPacks() == null)) {
365 LOG.warn("Circuit Packs are not present for {}", nodeId);
366 return false; // TODO return false or continue?
369 List<CircuitPacks> circuitPackList = deviceObject.get().getCircuitPacks();
370 circuitPackList.sort(Comparator.comparing(CircuitPack::getCircuitPackName));
372 for (CircuitPacks cp : circuitPackList) {
373 String circuitPackName = cp.getCircuitPackName();
374 if (cp.getPorts() == null) {
375 LOG.warn("Ports were not found for circuit pack: {}", circuitPackName);
378 for (Ports port : cp.getPorts()) {
379 if (Port.PortQual.XpdrNetwork.equals(port.getPortQual())) {
380 portMapList.add(createMappingObject(nodeId, port, circuitPackName,
381 "XPDR1-" + OpenRoadmInterfacesImpl.NETWORK_TOKEN + line));
382 //String lcp = port.getLogicalConnectionPoint();
383 //String regex = "XPDR[0-9]+-NETWORK[0-9]+";
384 //checkLogicalConnectionPoint(regex, lcp, nodeId, portMapList, circuitPackName, port, "NETWORK", line);
386 } else if (Port.PortQual.XpdrClient.equals(port.getPortQual())) {
387 portMapList.add(createMappingObject(nodeId, port, circuitPackName,
388 "XPDR1-" + OpenRoadmInterfacesImpl.CLIENT_TOKEN + client));
389 //String lcp = port.getLogicalConnectionPoint();
390 //String regex = "XPDR[0-9]+-CLIENT[0-9]+";
391 //checkLogicalConnectionPoint(regex, lcp, nodeId, portMapList, circuitPackName, port, "CLIENT", client);
394 LOG.warn("Port type {} not supported", port.getPortQual());
401 private void checkLogicalConnectionPoint(String regex, String logicalConnectionPoint, String nodeId, List<
402 Mapping> portMapList, String circuitPackName, Ports port, String portQual, int index) {
403 if (logicalConnectionPoint.matches(regex)) {
404 Mapping map = createMappingObject(nodeId, port, circuitPackName, logicalConnectionPoint);
405 if (portMapList.stream().filter(mapping -> mapping.getLogicalConnectionPoint().equals(
406 logicalConnectionPoint)).count() > 0) {
407 LOG.warn("{} : logical connection point {} on {} {} already used. Port can not be used", nodeId,
408 logicalConnectionPoint, circuitPackName, port.getPortName());
410 portMapList.add(map);
411 LOG.info("{} : logical connection point for {} {} is {}", nodeId, circuitPackName, port.getPortName(),
412 logicalConnectionPoint);
414 } else if (logicalConnectionPoint.isEmpty()) {
415 String lcp = "XPDR0-" + portQual + index;
416 Mapping map = createMappingObject(nodeId, port, circuitPackName, lcp);
417 if (portMapList.contains(map)) {
418 LOG.warn("{} : can not assign logical connection point {} to port {} of circuit pack {}. "
419 + "Name is already used", nodeId, lcp, port.getPortName(), circuitPackName);
421 portMapList.add(createMappingObject(nodeId, port, circuitPackName, lcp));
422 LOG.info("{} : no logical connection port on {} {}. Assigning {}.", nodeId, circuitPackName, port
423 .getPortName(), lcp);
426 LOG.warn("{} : logical connection point {} on {} {} does not respect OrgOpenRoadm recommendation. Port can "
427 + "not be used.", nodeId, logicalConnectionPoint, circuitPackName, port.getPortName());
432 * This private method builds the mapping object to be pushed in MD-SAL in
433 * order to save port mapping. In case of TTP ports, it also saves the
434 * OTS,OMS interfaces provisioned on the port.
437 * Reference to device's port subtree object.
438 * @param circuitPackName
439 * Name of cp where port exists.
440 * @param logicalConnectionPoint
441 * logical name of the port.
443 * @return true/false based on status of operation
446 private Mapping createMappingObject(String nodeId, Ports port, String circuitPackName,
447 String logicalConnectionPoint) {
448 MappingBuilder mpBldr = new MappingBuilder();
449 mpBldr.withKey(new MappingKey(logicalConnectionPoint)).setLogicalConnectionPoint(logicalConnectionPoint)
450 .setSupportingCircuitPackName(circuitPackName).setSupportingPort(port.getPortName());
452 // Get OMS and OTS interface provisioned on the TTP's
453 if (logicalConnectionPoint.contains(OpenRoadmInterfacesImpl.TTP_TOKEN) && (port.getInterfaces() != null)) {
454 for (Interfaces interfaces : port.getInterfaces()) {
456 Optional<Interface> openRoadmInterface = this.openRoadmInterfaces.getInterface(nodeId, interfaces
457 .getInterfaceName());
458 if (openRoadmInterface.isPresent()) {
459 Class<? extends InterfaceType> interfaceType = openRoadmInterface.get().getType();
460 // Check if interface type is OMS or OTS
461 if (interfaceType.equals(OpenROADMOpticalMultiplex.class)) {
462 mpBldr.setSupportingOms(interfaces.getInterfaceName());
464 if (interfaceType.equals(OpticalTransport.class)) {
465 mpBldr.setSupportingOts(interfaces.getInterfaceName());
468 LOG.warn("Interface {} from node {} was null!", interfaces.getInterfaceName(), nodeId);
470 } catch (OpenRoadmInterfaceException ex) {
471 LOG.warn("Error while getting interface {} from node {}!", interfaces.getInterfaceName(), nodeId,
476 return mpBldr.build();
479 private CpToDegree createCpToDegreeObject(String circuitPackName, String degreeNumber, String nodeId,
480 Map<String, String> interfaceList) {
481 String interfaceName = null;
482 if (interfaceList.get(circuitPackName) != null) {
483 interfaceName = interfaceList.get(circuitPackName);
485 return new CpToDegreeBuilder().withKey(new CpToDegreeKey(circuitPackName)).setCircuitPackName(circuitPackName)
486 .setDegreeNumber(new Long(degreeNumber)).setInterfaceName(interfaceName).build();
489 private static List<ConnectionPorts> getDegreePorts(List<Degree> degrees) {
490 return degrees.stream().filter(degree -> degree.getConnectionPorts() != null).flatMap(degree -> degree
491 .getConnectionPorts().stream()).collect(Collectors.toList());
494 private List<CpToDegree> getCpToDegreeList(List<Degree> degrees, String nodeId,
495 Map<String, String> interfaceList) {
496 List<CpToDegree> cpToDegreeList = new ArrayList<>();
497 for (Degree degree : degrees) {
498 if (degree.getCircuitPacks() != null) {
499 LOG.info("Inside CP to degree list");
500 cpToDegreeList.addAll(degree.getCircuitPacks().stream()
501 .map(cp -> createCpToDegreeObject(cp.getCircuitPackName() ,
502 degree.getDegreeNumber().toString(), nodeId ,interfaceList))
503 .collect(Collectors.toList()));
506 return cpToDegreeList;
510 * This method for ports the portMapping corresponding to the
511 * portmapping.yang file to the MD-SAL datastore.
514 * 1. Supporting circuit pack 2. Supporting port 3. Supporting OMS interface
518 * Info subtree from the device.
520 * Reference to the list containing the mapping to be pushed to
523 * @return Result true/false based on status of operation.
525 private boolean postPortMapping(Info deviceInfo, List<Mapping> portMapList, Integer nodeType, List<
526 CpToDegree> cp2DegreeList) {
527 NodesBuilder nodesBldr = new NodesBuilder();
528 nodesBldr.withKey(new NodesKey(deviceInfo.getNodeId())).setNodeId(deviceInfo.getNodeId());
529 nodesBldr.setNodeType(NodeTypes.forValue(nodeType));
531 if (portMapList != null) {
532 nodesBldr.setMapping(portMapList);
534 if (cp2DegreeList != null) {
535 nodesBldr.setCpToDegree(cp2DegreeList);
538 List<Nodes> nodesList = new ArrayList<>();
539 nodesList.add(nodesBldr.build());
541 NetworkBuilder nwBldr = new NetworkBuilder();
542 nwBldr.setNodes(nodesList);
544 final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
545 InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
546 Network network = nwBldr.build();
547 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, network);
548 CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
553 } catch (TransactionCommitFailedException e) {
554 LOG.warn("Failed to post {}", network, e);
560 public Mapping getMapping(String nodeId, String logicalConnPoint) {
563 * Getting physical mapping corresponding to logical connection point
565 InstanceIdentifier<Mapping> portMappingIID = InstanceIdentifier.builder(Network.class).child(Nodes.class,
566 new NodesKey(nodeId)).child(Mapping.class, new MappingKey(logicalConnPoint)).build();
567 try (ReadOnlyTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
568 Optional<Mapping> mapObject = readTx.read(LogicalDatastoreType.CONFIGURATION, portMappingIID).get()
570 if (mapObject.isPresent()) {
571 Mapping mapping = mapObject.get();
572 LOG.info("Found mapping for the logical port {}. Mapping: {}", logicalConnPoint, mapping.toString());
575 LOG.warn("Could not find mapping for logical connection point {} for nodeId {}", logicalConnPoint,
578 } catch (InterruptedException | ExecutionException ex) {
579 LOG.error("Unable to read mapping for logical connection point : {} for nodeId {}", logicalConnPoint,
585 private static String getLogicalConnectionPort(Ports port, int srgCounter) {
586 String logicalConnectionPoint = null;
587 if (port.getLogicalConnectionPoint() != null) {
588 switch (port.getPortDirection()) {
590 // Port direction is transmit
591 if (!port.getLogicalConnectionPoint().contains("SRG")) {
592 logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint() + "-TX";
594 logicalConnectionPoint = port.getLogicalConnectionPoint() + "-TX";
598 // Port direction is receive
599 if (!port.getLogicalConnectionPoint().contains("SRG")) {
600 logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint() + "-RX";
602 logicalConnectionPoint = port.getLogicalConnectionPoint() + "-RX";
606 // port is bidirectional
607 if (!port.getLogicalConnectionPoint().contains("SRG")) {
608 logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint();
610 logicalConnectionPoint = port.getLogicalConnectionPoint();
612 if (!port.getLogicalConnectionPoint().endsWith("-TXRX")) {
613 logicalConnectionPoint = logicalConnectionPoint.concat("-TXRX");
617 // Unsupported Port direction
618 LOG.error("Unsupported port direction for port {} {}", port, port.getPortDirection());
619 return null; // TODO return false or continue?
621 return logicalConnectionPoint;
623 LOG.warn("Unsupported port direction for port {} - {} - LogicalConnectionPoint is null", port, port
624 .getPortDirection());
625 return null; // TODO return false or continue?
629 public void deleteMappingData(String nodeId) {
630 LOG.info("Deleting Mapping Data corresponding at node '{}'", nodeId);
631 WriteTransaction rw = this.dataBroker.newWriteOnlyTransaction();
632 InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class).child(Nodes.class, new NodesKey(
634 rw.delete(LogicalDatastoreType.CONFIGURATION, nodesIID);
636 rw.submit().get(1, TimeUnit.SECONDS);
637 LOG.info("Port mapping removal for node '{}'", nodeId);
638 } catch (InterruptedException | ExecutionException | TimeoutException e) {
639 LOG.error("Error for removing port mapping infos for node '{}'", nodeId);
645 public boolean updateMapping(String nodeId, Mapping oldMapping) {
646 InstanceIdentifier<Ports> portIId = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
647 CircuitPacks.class, new CircuitPacksKey(oldMapping.getSupportingCircuitPackName())).child(Ports.class,
648 new PortsKey(oldMapping.getSupportingPort()));
649 if (oldMapping != null && nodeId != null) {
651 Optional<Ports> portObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
652 LogicalDatastoreType.OPERATIONAL, portIId, Timeouts.DEVICE_READ_TIMEOUT,
653 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
654 if (portObject.isPresent()) {
655 Ports port = portObject.get();
656 Mapping newMapping = createMappingObject(nodeId, port, oldMapping.getSupportingCircuitPackName(),
657 oldMapping.getLogicalConnectionPoint());
659 final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
660 InstanceIdentifier<Mapping> mapIID = InstanceIdentifier.create(Network.class).child(Nodes.class,
661 new NodesKey(nodeId)).child(Mapping.class, new MappingKey(oldMapping
662 .getLogicalConnectionPoint()));
663 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, mapIID, newMapping);
664 CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
669 } catch (TransactionCommitFailedException e) {
670 LOG.error("Transaction Commit Error updating Mapping {} for node {}", oldMapping
671 .getLogicalConnectionPoint(), nodeId, e);
675 LOG.error("Impossible to update mapping");
681 private Map<String, String> getEthInterfaceList(String nodeId) {
682 LOG.info("It is calling get ethernet interface");
683 Map<String, String> cpToInterfaceMap = new HashMap<>();
684 InstanceIdentifier<Lldp> lldpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
685 .child(Protocols.class).augmentation(Protocols1.class).child(Lldp.class);
686 Optional<Lldp> lldpObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
687 LogicalDatastoreType.OPERATIONAL, lldpIID, Timeouts.DEVICE_READ_TIMEOUT,
688 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
689 if (lldpObject.isPresent() && (lldpObject.get().getPortConfig() != null)) {
690 for (PortConfig portConfig : lldpObject.get().getPortConfig()) {
691 if (portConfig.getAdminStatus().equals(PortConfig.AdminStatus.Txandrx)) {
692 InstanceIdentifier<Interface> interfaceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
693 .child(Interface.class, new InterfaceKey(portConfig.getIfName()));
694 Optional<Interface> interfaceObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
695 LogicalDatastoreType.OPERATIONAL, interfaceIID, Timeouts.DEVICE_READ_TIMEOUT,
696 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
697 if (interfaceObject.isPresent() && (interfaceObject.get().getSupportingCircuitPackName() != null)) {
698 String supportingCircuitPackName = interfaceObject.get().getSupportingCircuitPackName();
699 cpToInterfaceMap.put(supportingCircuitPackName, portConfig.getIfName());
700 InstanceIdentifier<CircuitPacks> circuitPacksIID = InstanceIdentifier.create(OrgOpenroadmDevice
701 .class).child(CircuitPacks.class, new CircuitPacksKey(supportingCircuitPackName));
702 Optional<CircuitPacks> circuitPackObject = this.deviceTransactionManager.getDataFromDevice(
703 nodeId, LogicalDatastoreType.OPERATIONAL, circuitPacksIID, Timeouts
704 .DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
705 if (circuitPackObject.isPresent() && (circuitPackObject.get().getParentCircuitPack() != null)) {
706 cpToInterfaceMap.put(circuitPackObject.get().getParentCircuitPack().getCircuitPackName() ,
707 portConfig.getIfName());
713 LOG.warn("Couldnt find port config under LLDP for Node : {}", nodeId);
715 LOG.info("Processiong is done.. now returning..");
716 return cpToInterfaceMap;