From c3511abce385a49a96caced1520cd4ee8a5ceac9 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 5 May 2017 20:33:05 +0300 Subject: [PATCH] Code refactoring and added new checks 1. Divided code into subclasses 2. Before deleting the interface now method checks if: --interface exists --if yes, then change admin state to out of service --if change of state successful then delete 3. Before creating interface now the method checks if: --if interface with same name in service exists then donot create new --if exists but state not in service then create new --if does not exist then create new interface with state in service 4. Before deleting a cross connect check if it exists, if not then do not proceed. 5. Created new class CrossConnect.java with methods: --getCrossConnect() --postCrossConnect() --deleteCrossConnect() --setPowerLevel() --getConnectionPortTrail() 6. Created new class OpenRoadmInerface.java with methods/attributes common to all interface irrespective to their type: --getIntfBuilder() --postInterface() --getInterface() --deleteInterface() 7. Added child classes OpenRoadmOdu4Interface.java, OpenRoadmOchInterface.java,OpenRoadmOtu4Interface.java 8. Added check for nodeType mandatory field. 9. Added checks for null value in data change notification when a device is disconnected. Change-Id: Id775e36a8db0d14a11147e23414df4b07d1d6910 Signed-off-by: Dhruv Bhardwaj --- .../renderer/RendererNotificationsImpl.java | 32 +- .../renderer/mapping/PortMapping.java | 91 +++--- .../OpenRoadmInterfaces.java | 209 ++++++++++++ .../OpenRoadmOchInterface.java | 61 ++++ .../OpenRoadmOdu4Interface.java | 32 ++ .../OpenRoadmOtu4Interface.java | 33 ++ .../provisiondevice/CrossConnect.java | 292 +++++++++++++++++ .../provisiondevice/DeviceRenderer.java | 206 +++++------- .../provisiondevice/OpenRoadmInterfaces.java | 298 ------------------ 9 files changed, 752 insertions(+), 502 deletions(-) create mode 100644 renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterfaces.java create mode 100644 renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOchInterface.java create mode 100644 renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOdu4Interface.java create mode 100644 renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOtu4Interface.java create mode 100644 renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/CrossConnect.java delete mode 100644 renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/OpenRoadmInterfaces.java diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/RendererNotificationsImpl.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/RendererNotificationsImpl.java index 451c1a64a..6c1388840 100644 --- a/renderer/src/main/java/org/opendaylight/transportpce/renderer/RendererNotificationsImpl.java +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/RendererNotificationsImpl.java @@ -16,7 +16,6 @@ import com.google.common.cache.LoadingCache; import java.util.Collection; import java.util.List; import java.util.Set; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.stream.Collectors; @@ -60,7 +59,6 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -99,19 +97,11 @@ public class RendererNotificationsImpl implements DataTreeChangeListener { } private void registerNotificationListener(final NodeId nodeId) { - final Optional mountPoint; - try { - // Get mount point for specified device - mountPoint = mountService.getMountPoint(mountIds.get(nodeId.getValue())); - if (!mountPoint.isPresent()) { - LOG.error("Mount point for node {} doesn't exist", nodeId.getValue()); - } - } catch (ExecutionException e) { - throw new IllegalArgumentException(e); - } + + MountPoint mountPoint = PortMapping.getDeviceMountPoint(nodeId.getValue(), mountService); // Register notification service - final Optional notificationService = mountPoint.get().getService( + final Optional notificationService = mountPoint.getService( NotificationService.class); if (!notificationService.isPresent()) { LOG.error("Failed to get RpcService for node {}", nodeId.getValue()); @@ -157,10 +147,11 @@ public class RendererNotificationsImpl implements DataTreeChangeListener { // Listening to NETCONF datastream final String streamName = "NETCONF"; - final Optional service = mountPoint.get().getService(RpcConsumerRegistry.class); + final Optional service = mountPoint.getService(RpcConsumerRegistry.class); if (!service.isPresent()) { LOG.error("Failed to get RpcService for node {}", nodeId.getValue()); } + final NotificationsService rpcService = service.get().getRpcService(NotificationsService.class); final CreateSubscriptionInputBuilder createSubscriptionInputBuilder = new CreateSubscriptionInputBuilder(); createSubscriptionInputBuilder.setStream(new StreamNameType(streamName)); @@ -183,11 +174,14 @@ public class RendererNotificationsImpl implements DataTreeChangeListener { for (DataTreeModification change : changes) { DataObjectModification rootNode = change.getRootNode(); - String nodeId = rootNode.getDataAfter().getKey().getNodeId().getValue(); - NetconfNode nnode = Preconditions.checkNotNull(rootNode.getDataAfter().getAugmentation(NetconfNode.class), - "Node not connected via Netconf protocol"); + NetconfNode nnode = null; + String nodeId = new String(); + if (rootNode.getDataAfter() != null) { + nnode = Preconditions.checkNotNull(rootNode.getDataAfter().getAugmentation(NetconfNode.class), + "Node not connected via Netconf protocol"); + nodeId = rootNode.getDataAfter().getKey().getNodeId().getValue(); + } if (nnode != null) { - if (rootNode.getModificationType() == ModificationType.WRITE) { LOG.info("Node added " + nodeId); @@ -230,4 +224,4 @@ public class RendererNotificationsImpl implements DataTreeChangeListener { } } } -} +} \ No newline at end of file diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/mapping/PortMapping.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/mapping/PortMapping.java index 7945cf4ed..9ff32a24c 100644 --- a/renderer/src/main/java/org/opendaylight/transportpce/renderer/mapping/PortMapping.java +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/mapping/PortMapping.java @@ -22,13 +22,12 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaces; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.degree.ConnectionPorts; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Degree; import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.DegreeKey; @@ -101,13 +100,17 @@ public class PortMapping { */ public boolean createMappingData() { - LOG.info(" Create Mapping Data for node " + nodeId); + LOG.info("Create Mapping Data for node " + nodeId); DataBroker deviceDb = getDeviceDataBroker(nodeId, mps); - Info deviceInfo = getDeviceInfo(deviceDb); List portMapList = new ArrayList<>(); - + Info deviceInfo; if (deviceDb != null) { + deviceInfo = getDeviceInfo(deviceDb); if (deviceInfo != null) { + if (deviceInfo.getNodeType() == null) { + LOG.info("Node type mandatory field is missing"); + return false; + } Integer nodeType = deviceInfo.getNodeType().getIntValue(); // Create Mapping for Roadm Node if (nodeType == 1) { @@ -133,12 +136,12 @@ public class PortMapping { } } } else { - LOG.info(" Device info subtree is absent for " + nodeId); + LOG.info("Device info subtree is absent for " + nodeId); return false; } } else { - LOG.info(" Unable to get Data broker for node " + nodeId); + LOG.info("Unable to get Data broker for node " + nodeId); return false; } return postPortMapping(deviceInfo, portMapList); @@ -191,7 +194,7 @@ public class PortMapping { } } catch (InterruptedException | ExecutionException ex) { LOG.warn("Read failed for Logical Connection Point value missing for " + circuitPackName + " " - + portName); + + portName,ex); return false; } } @@ -273,7 +276,7 @@ public class PortMapping { } } catch (InterruptedException | ExecutionException ex) { - LOG.warn("Read failed for " + circuitPackName); + LOG.warn("Read failed for " + circuitPackName,ex); return false; } } @@ -338,7 +341,7 @@ public class PortMapping { } } catch (InterruptedException | ExecutionException ex) { - LOG.warn("Read failed for CircuitPacks of " + nodeId); + LOG.warn("Read failed for CircuitPacks of " + nodeId,ex); return false; } return true; @@ -370,8 +373,8 @@ public class PortMapping { // Get OMS and OTS interface provisioned on the TTP's if (logicalConnectionPoint.contains("TTP") && port.getInterfaces() != null) { for (Interfaces interfaces : port.getInterfaces()) { - Class interfaceType = getInterfaceType(deviceDb, interfaces - .getInterfaceName()); + Class interfaceType = new OpenRoadmInterfaces(db, mps, nodeId, + logicalConnectionPoint).getInterface(interfaces.getInterfaceName()).getType(); // Check if interface type is OMS or OTS if (interfaceType.equals(OpenROADMOpticalMultiplex.class)) { String omsInterfaceName = interfaces.getInterfaceName(); @@ -386,37 +389,6 @@ public class PortMapping { return mpBldr.build(); } - /** - * This private does a get on the interface subtree of the device with the - * interface name as the key and return the class corresponding to the - * interface type. - * - * @param interfaceName - * Name of the interface - * @param deviceDb - * Reference to device's databroker. - * - * @return true/false based on status of operation - */ - - private Class getInterfaceType(DataBroker deviceDb, String interfaceName) { - ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction(); - InstanceIdentifier interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child( - Interface.class, new InterfaceKey(interfaceName)); - try { - Optional interfaceObject = rtx.read(LogicalDatastoreType.OPERATIONAL, interfacesIID).get(); - if (interfaceObject.isPresent()) { - return interfaceObject.get().getType(); - } else { - LOG.info("Interface subtree is not present for " + interfaceName); - } - } catch (InterruptedException | ExecutionException ex) { - LOG.info("Read failed on interface subtree for"); - return null; - } - return null; - } - /** * This method does a get operation on info subtree of the netconf device's * configuration datastore and returns info object.It is required to get @@ -438,7 +410,7 @@ public class PortMapping { LOG.info("Info subtree is not present"); } } catch (InterruptedException | ExecutionException ex) { - LOG.info("Read failed on info subtree for"); + LOG.info("Read failed on info subtree ",ex); return null; } return null; @@ -485,7 +457,7 @@ public class PortMapping { break; } } catch (InterruptedException | ExecutionException ex) { - LOG.info("Failed to read degree " + degreeCounter); + LOG.info("Failed to read degree " + degreeCounter,ex); break; } @@ -535,14 +507,14 @@ public class PortMapping { srgCps.addAll( new ArrayList(ordmSrgObject.get().getCircuitPacks())); + .CircuitPacks>(ordmSrgObject.get().getCircuitPacks())); } else { LOG.info("Device has " + (srgCounter - 1) + " Srg"); break; } } catch (InterruptedException | ExecutionException ex) { - LOG.warn("Failed to read Srg " + srgCounter); + LOG.warn("Failed to read Srg " + srgCounter,ex); break; } srgCounter++; @@ -635,7 +607,7 @@ public class PortMapping { } } catch (InterruptedException | ExecutionException ex) { LOG.info("Unable to read mapping for logical connection point : " + logicalConnPoint + " for nodeId " - + nodeId); + + nodeId,ex); } return null; } @@ -650,20 +622,31 @@ public class PortMapping { * @return Databroker for the given device */ public static DataBroker getDeviceDataBroker(String nodeId, MountPointService mps) { + MountPoint netconfNode = getDeviceMountPoint(nodeId, mps); + if (netconfNode != null) { + DataBroker netconfNodeDataBroker = netconfNode.getService(DataBroker.class).get(); + return netconfNodeDataBroker; + } else { + LOG.info("Device Data broker not found for :" + nodeId); + return null; + } + } + + public static MountPoint getDeviceMountPoint(String nodeId, MountPointService mps) { InstanceIdentifier netconfNodeIID = InstanceIdentifier.builder(NetworkTopology.class).child( Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))).child(Node.class, new NodeKey(new NodeId(nodeId))).build(); - // Get the mount point for the specified node + // Get mount point for specified device final Optional netconfNodeOptional = mps.getMountPoint(netconfNodeIID); if (netconfNodeOptional.isPresent()) { MountPoint netconfNode = netconfNodeOptional.get(); - // Get the DataBroker for the mounted node - DataBroker netconfNodeDataBroker = netconfNode.getService(DataBroker.class).get(); - return netconfNodeDataBroker; + return netconfNode; } else { - LOG.info("Device Data broker not found for :" + nodeId); + LOG.info("Mount Point not found for :" + nodeId); + return null; } - return null; + } + } \ No newline at end of file diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterfaces.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterfaces.java new file mode 100644 index 000000000..78838cad6 --- /dev/null +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmInterfaces.java @@ -0,0 +1,209 @@ +/* + * Copyright © 2017 AT&T and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.renderer.openroadminterface; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; + +import java.util.concurrent.ExecutionException; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.transportpce.renderer.mapping.PortMapping; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice; +import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev161014.AdminStates; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OpenRoadmInterfaces { + + protected final DataBroker db; + protected final DataBroker netconfNodeDataBroker; + protected final String nodeId; + protected final Mapping portMap; + protected final String logicalConnPoint; + private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmInterfaces.class); + + public OpenRoadmInterfaces(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint) { + this.db = db; + this.logicalConnPoint = logicalConnPoint; + this.nodeId = nodeId; + this.portMap = PortMapping.getMapping(nodeId, logicalConnPoint, db); + netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps); + } + + /** + * This methods creates a generic interface builder object to set the value + * that are common irrespective of the interface type. + * + * @param portMap + * Mapping object containing attributes required to create + * interface on the device. + * + * @return InterfaceBuilder object with the data. + */ + public InterfaceBuilder getIntfBuilder(Mapping portMap) { + + InterfaceBuilder ifBuilder = new InterfaceBuilder(); + ifBuilder.setDescription(" TBD "); + ifBuilder.setCircuitId(" TBD "); + ifBuilder.setSupportingCircuitPackName(portMap.getSupportingCircuitPackName()); + ifBuilder.setSupportingPort(portMap.getSupportingPort()); + ifBuilder.setAdministrativeState(AdminStates.InService); + return ifBuilder; + } + + /** + * This methods does an edit-config operation on the openROADM device in + * order to create the given interface. + * + *

+ * Before posting the interface it checks if: + * + *

+ * 1. Interface with same name does not exist + * + *

+ * 2. If exists then admin state of interface is outOfState/Maintenance + * + * @param ifBuilder + * Builder object containing the data to post. + * + * @return Result of operation true/false based on success/failure. + */ + public boolean postInterface(InterfaceBuilder ifBuilder) { + + String intf2Post = ifBuilder.getName(); + Interface intf2PostCheck = getInterface(intf2Post); + if (intf2PostCheck != null) { + if (intf2PostCheck.getAdministrativeState() == AdminStates.InService) { + LOG.info("Interface with same name in service already exists"); + return true; + } + } + // Post interface with its specific augmentation to the device + if (netconfNodeDataBroker != null) { + InstanceIdentifier interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child( + Interface.class, new InterfaceKey(ifBuilder.getName())); + final WriteTransaction writeTransaction = netconfNodeDataBroker.newWriteOnlyTransaction(); + writeTransaction.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, ifBuilder.build()); + final CheckedFuture submit = writeTransaction.submit(); + try { + submit.checkedGet(); + LOG.info("Successfully posted interface " + ifBuilder.getName()); + return true; + } catch (TransactionCommitFailedException ex) { + LOG.warn("Failed to post {} ", ifBuilder.getName(),ex); + return false; + } + + } else { + return false; + } + } + + /** + * This private does a get on the interface subtree of the device with the + * interface name as the key and return the class corresponding to the + * interface type. + * + * @param interfaceName + * Name of the interface + * + * @return true/false based on status of operation + */ + + public Interface getInterface(String interfaceName) { + ReadOnlyTransaction rtx = netconfNodeDataBroker.newReadOnlyTransaction(); + InstanceIdentifier interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child( + Interface.class, new InterfaceKey(interfaceName)); + try { + Optional interfaceObject = rtx.read(LogicalDatastoreType.OPERATIONAL, interfacesIID).get(); + if (interfaceObject.isPresent()) { + return interfaceObject.get(); + } else { + LOG.info("Interface subtree is not present for " + interfaceName); + } + } catch (InterruptedException | ExecutionException ex) { + LOG.info("Read failed on interface subtree for",ex); + return null; + } + return null; + } + + /** + * This methods does an edit-config operation on the openROADM device in + * order to delete the given interface. + * + *

+ * Before deleting the method: + * + *

+ * 1. Checks if interface exists + * + *

+ * 2. If exists then changes the state of interface to outOfService + * + * @param interfaceName + * Name of the interface to delete. + * + * @return Result of operation true/false based on success/failure. + */ + public boolean deleteInterface(String interfaceName) { + // Post interface with its specific augmentation to the device + if (netconfNodeDataBroker != null) { + Interface intf2Delete = getInterface(interfaceName); + if (intf2Delete != null) { + // State admin state to out of service + InterfaceBuilder ifBuilder = new InterfaceBuilder(intf2Delete); + ifBuilder.setAdministrativeState(AdminStates.OutOfService); + // post interface with updated admin state + if (postInterface(ifBuilder)) { + InstanceIdentifier interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class) + .child(Interface.class, new InterfaceKey(interfaceName)); + final WriteTransaction writeTransaction = netconfNodeDataBroker.newWriteOnlyTransaction(); + writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, interfacesIID); + final CheckedFuture submit = writeTransaction.submit(); + + try { + submit.checkedGet(); + LOG.info("Successfully deleted " + interfaceName); + return true; + + } catch (TransactionCommitFailedException ex) { + LOG.error("Failed to delete interface {} ", interfaceName, ex); + return false; + } + + } else { + + LOG.error("Error changing the state of interface " + interfaceName); + return false; + } + } else { + LOG.info("Interface does not exist, cannot delete"); + return false; + } + + } else { + + LOG.info("Device databroker not found"); + return false; + } + } +} \ No newline at end of file diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOchInterface.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOchInterface.java new file mode 100644 index 000000000..eae5b81cc --- /dev/null +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOchInterface.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2017 AT&T and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.renderer.openroadminterface; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey; +import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalChannel; +import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1; +import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1Builder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.och.container.OchBuilder; + +public class OpenRoadmOchInterface extends OpenRoadmInterfaces { + + public OpenRoadmOchInterface(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint) { + super(db, mps, nodeId, logicalConnPoint); + } + + /** + * This methods creates an OCH interface on the given termination point. + * + * @param waveNumber + * wavelength number of the OCH interface. + * + * @return Name of the interface if successful, otherwise return null. + */ + + public String createInterface(Long waveNumber) { + + // Create generic interface + InterfaceBuilder ochInterfaceBldr = getIntfBuilder(portMap); + ochInterfaceBldr.setType(OpticalChannel.class); + ochInterfaceBldr.setName(logicalConnPoint + "-" + waveNumber); + ochInterfaceBldr.setKey(new InterfaceKey(logicalConnPoint + "-" + waveNumber)); + + // OCH interface specific data + OchBuilder ocIfBuilder = new OchBuilder(); + ocIfBuilder.setWavelengthNumber(waveNumber); + + //Add supporting OMS interface + ochInterfaceBldr.setSupportingInterface(portMap.getSupportingOms()); + + // Create Interface1 type object required for adding as augmentation + Interface1Builder ochIf1Builder = new Interface1Builder(); + ochInterfaceBldr.addAugmentation(Interface1.class, ochIf1Builder.setOch(ocIfBuilder.build()).build()); + + // Post interface on the device + if (postInterface(ochInterfaceBldr)) { + return ochInterfaceBldr.getName(); + } else { + return null; + } + } +} diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOdu4Interface.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOdu4Interface.java new file mode 100644 index 000000000..17a1b29fb --- /dev/null +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOdu4Interface.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2017 AT&T and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.renderer.openroadminterface; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; + +public class OpenRoadmOdu4Interface extends OpenRoadmInterfaces { + + public OpenRoadmOdu4Interface(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint) { + super(db, mps, nodeId, logicalConnPoint); + + } + + /** + * This methods creates an ODU interface on the given termination point. + * + * + * @return Name of the interface if successful, otherwise return null. + */ + + public String createInterface() { + // TODO:implement this method + return null; + } +} diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOtu4Interface.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOtu4Interface.java new file mode 100644 index 000000000..7597b366a --- /dev/null +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/openroadminterface/OpenRoadmOtu4Interface.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2017 AT&T and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.renderer.openroadminterface; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; + +public class OpenRoadmOtu4Interface extends OpenRoadmInterfaces { + + public OpenRoadmOtu4Interface(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint) { + super(db, mps, nodeId, logicalConnPoint); + + } + + /** + * This methods creates an OTU interface on the given termination point. + * + * + * @return Name of the interface if successful, otherwise return null. + */ + + public String createInterface() { + // TODO: Implement this method + return null; + } + +} diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/CrossConnect.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/CrossConnect.java new file mode 100644 index 000000000..94404c133 --- /dev/null +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/CrossConnect.java @@ -0,0 +1,292 @@ +/* + * Copyright © 2017 AT&T and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.renderer.provisiondevice; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.MountPoint; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry; +import org.opendaylight.transportpce.renderer.mapping.PortMapping; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.PowerDBm; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.GetConnectionPortTrailInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.GetConnectionPortTrailOutput; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OrgOpenroadmDeviceService; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.connection.DestinationBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.connection.SourceBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.get.connection.port.trail.output.Ports; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnections; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CrossConnect { + + private final DataBroker deviceDb; + private static final Logger LOG = LoggerFactory.getLogger(CrossConnect.class); + private final String connectionNumber; + private final InstanceIdentifier rdmConnectionIID; + + public CrossConnect(DataBroker deviceDb) { + this.deviceDb = deviceDb; + connectionNumber = null; + rdmConnectionIID = null; + } + + public CrossConnect(DataBroker deviceDb, String connectionNumber) { + this.deviceDb = deviceDb; + this.connectionNumber = connectionNumber; + rdmConnectionIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(RoadmConnections.class, + new RoadmConnectionsKey(connectionNumber)); + } + + /** + * This method return the RoadmConnection subtree for a given connection + * number. + * + * @param connectionNumber + * Name of the cross connect. + * + * @return Roadm connection subtree from the device. + */ + public RoadmConnections getCrossConnect(String connectionNumber) { + if (connectionNumber == null && this.connectionNumber != null) { + connectionNumber = this.connectionNumber; + } + if (deviceDb != null) { + ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction(); + Optional roadmConnectionsObject; + try { + roadmConnectionsObject = rtx.read(LogicalDatastoreType.OPERATIONAL, rdmConnectionIID).get(); + if (roadmConnectionsObject.isPresent()) { + return roadmConnectionsObject.get(); + } + } catch (InterruptedException | ExecutionException ex) { + LOG.info("Error getting roadm-connection subtree from the device for " + connectionNumber, ex); + return null; + } + } + return null; + } + + /** + * This method does a post(edit-config) on roadm connection subtree for a + * given connection number. + * + * @param waveNumber + * Wavelength number. + * @param srcTp + * Name of source termination point. + * @param destTp + * Name of destination termination point. + * @return true/false based on status of operation. + */ + public boolean postCrossConnect(Long waveNumber, String srcTp, String destTp) { + + RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(); + rdmConnBldr.setConnectionNumber(srcTp + "-" + destTp + "-" + waveNumber); + rdmConnBldr.setWavelengthNumber(waveNumber); + rdmConnBldr.setOpticalControlMode(OpticalControlMode.Off); + rdmConnBldr.setSource(new SourceBuilder().setSrcIf(srcTp + "-" + waveNumber.toString()).build()); + rdmConnBldr.setDestination(new DestinationBuilder().setDstIf(destTp + "-" + waveNumber.toString()).build()); + InstanceIdentifier rdmConnectionIID = InstanceIdentifier.create(OrgOpenroadmDevice.class) + .child(RoadmConnections.class, new RoadmConnectionsKey(rdmConnBldr.getConnectionNumber())); + + if (deviceDb != null) { + final WriteTransaction writeTransaction = deviceDb.newWriteOnlyTransaction(); + // post the cross connect on the device + writeTransaction.put(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID, rdmConnBldr.build()); + final CheckedFuture submit = writeTransaction.submit(); + try { + submit.checkedGet(); + LOG.info("Roadm-connection successfully created: " + srcTp + "-" + destTp + "-" + waveNumber); + return true; + } catch (TransactionCommitFailedException ex) { + LOG.info("Failed to post {} ", rdmConnBldr.build(), ex); + return false; + } + } else { + LOG.error("Invalid device databroker"); + return false; + } + } + + /** + * This method does a delete(edit-config) on roadm connection subtree for a + * given connection number. + * + * @param connectionNumber + * Name of the cross connect. + * @return true/false based on status of operation. + */ + + public boolean deleteCrossConnect(String connectionNumber) { + if (connectionNumber == null && this.connectionNumber != null) { + connectionNumber = this.connectionNumber; + } + return deleteCrossConnect(); + } + + /** + * This method does a delete(edit-config) on roadm connection subtree for a + * given connection number. + * + * @return true/false based on status of operation. + */ + + public boolean deleteCrossConnect() { + + //Check if cross connect exists before delete + if (getCrossConnect(connectionNumber) == null) { + LOG.info("Cross connect does not exist, halting delete"); + return false; + } + if (deviceDb != null) { + final WriteTransaction writeTransaction = deviceDb.newWriteOnlyTransaction(); + // post the cross connect on the device + writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID); + final CheckedFuture submit = writeTransaction.submit(); + try { + submit.checkedGet(); + LOG.info("Roadm connection successfully deleted "); + return true; + } catch (TransactionCommitFailedException ex) { + LOG.info("Failed to delete {} ", connectionNumber, ex); + return false; + } + } else { + LOG.error("Invalid device databroker"); + return false; + } + } + + /** + * This method does an edit-config on roadm connection subtree for a given + * connection number in order to set power level for use by the optical + * power control. + * + * @param mode + * Optical control modelcan be off, power or gainLoss. + * @param value + * Power value in DBm. + * @param connectionNumber + * Name of the cross connect. + * @return true/false based on status of operation. + */ + public boolean setPowerLevel(OpticalControlMode mode, PowerDBm value, String connectionNumber) { + if (connectionNumber == null && this.connectionNumber != null) { + connectionNumber = this.connectionNumber; + } + return setPowerLevel(mode, value); + } + + /** + * This method does an edit-config on roadm connection subtree for a given + * connection number in order to set power level for use by the optical + * power control. + * + * @param mode + * Optical control modelcan be off, power or gainLoss. + * @param value + * Power value in DBm. + * @return true/false based on status of operation. + */ + public boolean setPowerLevel(OpticalControlMode mode, PowerDBm value) { + + RoadmConnections rdmConn = getCrossConnect(connectionNumber); + if (rdmConn != null) { + RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConn); + rdmConnBldr.setOpticalControlMode(mode); + rdmConnBldr.setTargetOutputPower(value); + if (deviceDb != null) { + final WriteTransaction writeTransaction = deviceDb.newWriteOnlyTransaction(); + // post the cross connect on the device + writeTransaction.put(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID, rdmConnBldr.build()); + final CheckedFuture submit = writeTransaction.submit(); + try { + submit.checkedGet(); + LOG.info("Roadm connection power level successfully set "); + return false; + } catch (TransactionCommitFailedException ex) { + LOG.info("Failed to post {} ", rdmConnBldr.build(), ex); + return false; + } + } else { + LOG.error("Invalid device databroker"); + return false; + } + } else { + LOG.info("Roadm-Connection does not exist"); + return false; + } + } + + /** + * This public method returns the list of ports (port-trail) for a roadm's + * cross connect. It calls rpc get-port-trail on device. To be used store + * detailed path description. + * + * @param nodeId + * node-id of NE. + * @param mountService + * Reference to mount point service. + * @param waveNumber + * Wavelength number. + * @param srcTp + * Source logical connection point. + * @param destTp + * Destination logical connection point. + * + * @return list of Ports object type. + */ + public Ports getConnectionPortTrail(String nodeId, MountPointService mountService, Long waveNumber, String srcTp, + String destTp) { + + String connectionName = srcTp + "-" + destTp + "-" + waveNumber; + MountPoint mountPoint = PortMapping.getDeviceMountPoint(nodeId, mountService); + + final Optional service = mountPoint.getService(RpcConsumerRegistry.class); + if (!service.isPresent()) { + LOG.error("Failed to get RpcService for node {}", nodeId); + } + final OrgOpenroadmDeviceService rpcService = service.get().getRpcService(OrgOpenroadmDeviceService.class); + final GetConnectionPortTrailInputBuilder portTrainInputBuilder = new GetConnectionPortTrailInputBuilder(); + portTrainInputBuilder.setConnectionNumber(connectionName); + final Future> portTrailOutput = rpcService.getConnectionPortTrail( + portTrainInputBuilder.build()); + if (portTrailOutput != null) { + try { + LOG.info("Getting port trail for node " + nodeId + "'s connection number " + connectionName); + for (Ports ports : portTrailOutput.get().getResult().getPorts()) { + LOG.info(nodeId + " - " + "Circuit pack " + ports.getCircuitPackName() + "- Port " + ports + .getPortName()); + } + } catch (InterruptedException | ExecutionException e) { + LOG.info("Exception caught", e); + } + } else { + LOG.info("Port trail is null"); + } + return null; + } +} diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRenderer.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRenderer.java index 6df6ddb27..2a357f2dd 100644 --- a/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRenderer.java +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/DeviceRenderer.java @@ -8,8 +8,6 @@ package org.opendaylight.transportpce.renderer.provisiondevice; -import com.google.common.util.concurrent.CheckedFuture; - import java.util.HashSet; import java.util.List; import java.util.Set; @@ -17,29 +15,16 @@ import java.util.concurrent.Future; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.MountPointService; -import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.transportpce.renderer.mapping.PortMapping; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.connection.DestinationBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.connection.SourceBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnections; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey; +import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaces; +import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmOchInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererService; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.service.path.input.Nodes; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,20 +49,21 @@ public class DeviceRenderer implements RendererService { * service provides two functions: * *

- * 1. Create - * This operation results in provisioning the device for a given wavelength and a - * list of nodes with each node listing its termination points. + * 1. Create This operation results in provisioning the device for a given + * wavelength and a list of nodes with each node listing its termination + * points. * *

- * 2. Delete - * This operation results in de-provisioning the device for a given wavelength and a - * list of nodes with each node listing its termination points. + * 2. Delete This operation results in de-provisioning the device for a + * given wavelength and a list of nodes with each node listing its + * termination points. * *

* The signature for this method was generated by yang tools from the * renderer API model. * - * @param input Input parameter from the service-path yang model + * @param input + * Input parameter from the service-path yang model * * @return Result of the request */ @@ -95,23 +81,23 @@ public class DeviceRenderer implements RendererService { } /** - * This method set's wavelength path based on following steps: - * For each node: + * This method set's wavelength path based on following steps: For each + * node: * *

- * 1. Create Och interface on source termination point. - * 2. Create Och interface on destination termination point. - * 3. Create cross connect between source and destination - * tps created in step 1 and 2. + * 1. Create Och interface on source termination point. 2. Create Och + * interface on destination termination point. 3. Create cross connect + * between source and destination tps created in step 1 and 2. * *

- * Naming convention used for OCH interfaces name : tp-wavenumber - * Naming convention used for cross connect name : src-dest-wavenumber + * Naming convention used for OCH interfaces name : tp-wavenumber Naming + * convention used for cross connect name : src-dest-wavenumber * - * @param input Input parameter from the service-path yang model + * @param input + * Input parameter from the service-path yang model * - * @return Result list of all nodes if request successful - * otherwise specific reason of failure. + * @return Result list of all nodes if request successful otherwise specific + * reason of failure. */ public ServicePathOutputBuilder setupServicePath(ServicePathInput input) { @@ -120,77 +106,61 @@ public class DeviceRenderer implements RendererService { LOG.info(currentMountedDevice.toString()); for (Nodes n : nodes) { LOG.info("Starting provisioning for node : " + n.getNodeId()); - //if the node is currently mounted then proceed + String nodeId = n.getNodeId(); + // if the node is currently mounted then proceed if (currentMountedDevice.contains(n.getNodeId())) { String srcTp = n.getSrcTp(); String destTp = n.getDestTp(); + Long waveNumber = input.getWaveNumber(); - String srcIf = new OpenRoadmInterfaces(db, mps, n.getNodeId(), srcTp).createOchInterface(waveNumber); - //if source interface creation was successful then proceed otherwise return. + String srcIf = new OpenRoadmOchInterface(db, mps, nodeId, srcTp).createInterface(waveNumber); + // if source interface creation was successful then proceed + // otherwise return. if (srcIf == null) { - LOG.warn("Unable to create OCH interface on " + n.getNodeId() + " at " + srcTp); - return setServBldr.setResult("Unable to create OCH interface on " + n.getNodeId() + " at " + srcTp); + LOG.warn("Unable to create OCH interface on " + nodeId + " at " + srcTp); + return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + srcTp); } - //if destination interface creation was then proceed otherwise return. - String dstIf = new OpenRoadmInterfaces(db, mps, n.getNodeId(), destTp).createOchInterface(waveNumber); + // if destination interface creation was then proceed otherwise + // return. + String dstIf = new OpenRoadmOchInterface(db, mps, nodeId, destTp).createInterface(waveNumber); if (dstIf == null) { - LOG.warn("Unable to create OCH interface on " + n.getNodeId() + " at " + destTp); - return setServBldr.setResult("Unable to create OCH interface on " + n.getNodeId() + " at " - + destTp); + LOG.warn("Unable to create OCH interface on " + nodeId + " at " + destTp); + return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + destTp); } LOG.info("Creating cross connect between source :" + srcTp + " destination " + destTp + " for node " + n .getNodeId()); - //Build cross connect object - RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(); - rdmConnBldr.setConnectionNumber(srcTp + "-" + destTp + "-" + waveNumber); - rdmConnBldr.setWavelengthNumber(waveNumber); - rdmConnBldr.setOpticalControlMode(OpticalControlMode.Off); - rdmConnBldr.setSource(new SourceBuilder().setSrcIf(srcIf).build()); - rdmConnBldr.setDestination(new DestinationBuilder().setDstIf(dstIf).build()); - InstanceIdentifier rdmConnectionIID = InstanceIdentifier.create( - OrgOpenroadmDevice.class).child(RoadmConnections.class, new RoadmConnectionsKey(rdmConnBldr - .getConnectionNumber())); - DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(n.getNodeId(), mps); - if (netconfNodeDataBroker != null) { - final WriteTransaction writeTransaction = netconfNodeDataBroker.newWriteOnlyTransaction(); - //post the cross connect on the device - writeTransaction.put(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID, rdmConnBldr.build()); - final CheckedFuture submit = writeTransaction.submit(); - try { - submit.checkedGet(); - nodesProvisioned.add(n.getNodeId()); - LOG.info("Roadm-connection successfully created: " + srcTp + "-" + destTp); + DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps); + CrossConnect roadmConnections = new CrossConnect(netconfNodeDataBroker); + if (roadmConnections.postCrossConnect(waveNumber, srcTp, destTp) == true) { + nodesProvisioned.add(nodeId); + roadmConnections.getConnectionPortTrail(nodeId, mps, waveNumber, srcTp, destTp); - } catch (TransactionCommitFailedException ex) { - LOG.warn("Failed to post {} ", rdmConnBldr.build(), ex); - return setServBldr.setResult("Unable to post Roadm-connection for node " + n.getNodeId()); - } } else { - LOG.error("Unable to get device broker for node " + n.getNodeId()); - return setServBldr.setResult("Unable to get device broker for node " + n.getNodeId()); + return setServBldr.setResult("Unable to post Roadm-connection for node " + nodeId); } } else { - LOG.warn(n.getNodeId() + " is not mounted on the controller"); - return setServBldr.setResult(n.getNodeId() + " is not mounted on the controller"); + LOG.warn(nodeId + " is not mounted on the controller"); + return setServBldr.setResult(nodeId + " is not mounted on the controller"); } } return setServBldr.setResult("Roadm-connection successfully created for nodes " + nodesProvisioned.toString()); } /** - * This method removes wavelength path based on following steps: - * For each node: + * This method removes wavelength path based on following steps: For each + * node: * *

- * 1. Delete Cross connect between source and destination tps. - * 2. Delete Och interface on source termination point. - * 3. Delete Och interface on destination termination point. + * 1. Delete Cross connect between source and destination tps. 2. Delete Och + * interface on source termination point. 3. Delete Och interface on + * destination termination point. * - *

- * Naming convention used for OCH interfaces name : tp-wavenumber - * Naming convention used for cross connect name : src-dest-wavenumber + *

+ * Naming convention used for OCH interfaces name : tp-wavenumber Naming + * convention used for cross connect name : src-dest-wavenumber * - * @param input Input parameter from the service-path yang model + * @param input + * Input parameter from the service-path yang model * * @return Result result of the request. */ @@ -199,63 +169,37 @@ public class DeviceRenderer implements RendererService { ServicePathOutputBuilder delServBldr = new ServicePathOutputBuilder(); LOG.info(currentMountedDevice.toString()); for (Nodes n : nodes) { - LOG.info("Deleting service setup on node " + n.getNodeId()); + + String nodeId = n.getNodeId(); + LOG.info("Deleting service setup on node " + nodeId); String srcTp = n.getSrcTp(); String destTp = n.getDestTp(); Long waveNumber = input.getWaveNumber(); - //if the node is currently mounted then proceed. - if (currentMountedDevice.contains(n.getNodeId())) { - DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(n.getNodeId(), mps); - if (netconfNodeDataBroker != null) { - // Deleting roadm connection - InstanceIdentifier rdmConnectionIID = InstanceIdentifier.create( - OrgOpenroadmDevice.class).child(RoadmConnections.class, new RoadmConnectionsKey(srcTp + "-" - + destTp + "-" + waveNumber)); - ReadWriteTransaction writeTx = netconfNodeDataBroker.newReadWriteTransaction(); - writeTx.delete(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID); - final CheckedFuture submit = writeTx.submit(); - try { - submit.checkedGet(); - LOG.info("Successfully deleted interface " + srcTp + "-" + destTp + "-" + waveNumber); - } catch (TransactionCommitFailedException ex) { - LOG.error("Failed to delete {} ", srcTp + "-" + destTp + "-" + waveNumber, ex); - } - // Deleting interface on source termination point - writeTx = netconfNodeDataBroker.newReadWriteTransaction(); - InstanceIdentifier srcInterfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class) - .child(Interface.class, new InterfaceKey(srcTp + "-" + waveNumber.toString())); - writeTx.delete(LogicalDatastoreType.CONFIGURATION, srcInterfacesIID); - final CheckedFuture submitSrcDel = writeTx.submit(); - - try { - submitSrcDel.checkedGet(); - LOG.info("Successfully deleted " + srcTp + "-" + waveNumber.toString()); - } catch (TransactionCommitFailedException ex) { - LOG.error("Failed to delete interface {} ", srcTp + "-" + waveNumber.toString(), ex); - } - // Deleting interface on destination termination point - writeTx = netconfNodeDataBroker.newReadWriteTransaction(); - InstanceIdentifier destInterfacesIID = InstanceIdentifier.create( - OrgOpenroadmDevice.class).child(Interface.class, new InterfaceKey(destTp + "-" + waveNumber - .toString())); - writeTx.delete(LogicalDatastoreType.CONFIGURATION, destInterfacesIID); - final CheckedFuture submitDestDel = writeTx.submit(); - - try { - submitDestDel.checkedGet(); - LOG.info("Successfully deleted " + destTp + "-" + waveNumber.toString()); + // if the node is currently mounted then proceed. + if (currentMountedDevice.contains(nodeId)) { + String connectionNumber = srcTp + "-" + destTp + "-" + waveNumber; + CrossConnect roadmConnection = new CrossConnect(PortMapping.getDeviceDataBroker(nodeId, mps), + connectionNumber); + if (!roadmConnection.deleteCrossConnect()) { + LOG.error("Failed to delete {} ", srcTp + "-" + destTp + "-" + waveNumber); + } + // Deleting interface on source termination point + if (new OpenRoadmInterfaces(db, mps, nodeId, srcTp).deleteInterface(srcTp + "-" + waveNumber + .toString()) == false) { + LOG.error("Failed to delete interface " + srcTp + "-" + waveNumber.toString()); + } - } catch (TransactionCommitFailedException ex) { - LOG.error("Failed to delete interface {} ", destTp + "-" + waveNumber.toString(), ex); - } + // Deleting interface on destination termination point + if (new OpenRoadmInterfaces(db, mps, nodeId, srcTp).deleteInterface(destTp + "-" + waveNumber + .toString()) == false) { + LOG.error("Failed to delete interface " + srcTp + "-" + waveNumber.toString()); } } else { - LOG.warn(n.getNodeId() + " is not mounted on the controller"); - return delServBldr.setResult(n.getNodeId() + " is not mounted on the controller"); + LOG.warn(nodeId + " is not mounted on the controller"); + return delServBldr.setResult(nodeId + " is not mounted on the controller"); } } return delServBldr.setResult("Request processed"); } - -} +} \ No newline at end of file diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/OpenRoadmInterfaces.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/OpenRoadmInterfaces.java deleted file mode 100644 index 0a2a612fa..000000000 --- a/renderer/src/main/java/org/opendaylight/transportpce/renderer/provisiondevice/OpenRoadmInterfaces.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright © 2017 AT&T and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.transportpce.renderer.provisiondevice; - -import com.google.common.base.Optional; -import com.google.common.util.concurrent.CheckedFuture; - -import java.util.concurrent.ExecutionException; - -import org.apache.commons.lang3.StringUtils; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.MountPointService; -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.transportpce.renderer.mapping.PortMapping; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice; -import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.port.Interfaces; -import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalChannel; -import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1; -import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1Builder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.och.container.OchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.Network; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class OpenRoadmInterfaces { - - private final DataBroker db; - private final String nodeId; - private final String logicalConnPoint; - private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmInterfaces.class); - private final DataBroker netconfNodeDataBroker; - - public OpenRoadmInterfaces(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint) { - this.db = db; - this.logicalConnPoint = logicalConnPoint; - this.nodeId = nodeId; - netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps); - - } - - /** - * This methods creates an OCH interface on the ROADM nodes's termination point - * based on following steps: - * - *

- * 1. Get the physical mapping corresponding to logical port. - * 2. Create generic interface object based on data in mapping object. - * 3. Set the value for supporting interface (OMS) if present in the local mapping - * otherwise fetch it for the first time and update the local mapping. - * 4. Add Och interface specific augmentation such as waveNumber etc. - * - * @param waveNumber wavelength number of the Och interface. - * - * @return Name of the interface if successful, otherwise return null. - */ - public String createOchInterface(Long waveNumber) { - - // Add OOCH augmentation to the interface - Mapping portMap = getMapping(nodeId, logicalConnPoint); - if (portMap != null) { - InterfaceBuilder ifBuilder = intfBuilder(portMap); - // OCH interface specific data - OchBuilder ocIfBuilder = new OchBuilder(); - ocIfBuilder.setWavelengthNumber(waveNumber); - Interface1Builder optbld1 = new Interface1Builder(); - ifBuilder.setKey(new InterfaceKey(logicalConnPoint + "-" + waveNumber.toString())); - ifBuilder.addAugmentation(Interface1.class, optbld1.setOch(ocIfBuilder.build()).build()); - ifBuilder.setName(logicalConnPoint + "-" + waveNumber.toString()); - InstanceIdentifier interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child( - Interface.class, new InterfaceKey(logicalConnPoint + "-" + waveNumber.toString())); - if (logicalConnPoint.toUpperCase().contains("TTP") && StringUtils.isNotEmpty(portMap.getSupportingOms())) { - LOG.info("Oms interface present in local mapping for " + logicalConnPoint); - ifBuilder.setSupportingInterface(portMap.getSupportingOms()); - } else if (logicalConnPoint.toUpperCase().contains("TTP") && StringUtils.isEmpty(portMap - .getSupportingOms())) { - Ports port = getPort(portMap); - if (port != null && port.getInterfaces() != null) { - LOG.info("Oms interface not present in local mapping, getting it for the first time for " - + logicalConnPoint); - LOG.info(port.toString()); - for (Interfaces intf : port.getInterfaces()) { - LOG.info(intf.toString()); - //TODO: This method assumes the name of the interface contains OMS substring in it - //update it to fetch OMS interface more efficiently. - if (intf.getInterfaceName().toUpperCase().contains("OMS")) { - String omsInterface = intf.getInterfaceName(); - LOG.info("found oms interface for {} with name {}", logicalConnPoint, omsInterface); - ifBuilder.setSupportingInterface(omsInterface); - MappingBuilder mapBldr = new MappingBuilder(); - InstanceIdentifier mapIID = InstanceIdentifier.create(Network.class).child( - Nodes.class, new NodesKey(nodeId)).child(Mapping.class, new MappingKey(portMap - .getLogicalConnectionPoint())); - mapBldr.setSupportingOms(omsInterface); - mapBldr.setKey(new MappingKey(portMap.getLogicalConnectionPoint())); - try { - final WriteTransaction writeTransaction = db.newWriteOnlyTransaction(); - writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, mapIID, mapBldr.build()); - CheckedFuture submit = writeTransaction - .submit(); - LOG.info("Updated mapping for " + port.getPortName() + "at " + portMap - .getSupportingCircuitPackName() + " with support oms interface " + intf - .getInterfaceName()); - submit.checkedGet(); - break; - } catch (TransactionCommitFailedException ex) { - // TODO Auto-generated catch block - LOG.info("unable to save mapping for " + port.getPortName() + " at " + portMap - .getSupportingCircuitPackName()); - } - } - } - } else { - LOG.error("Interface is missing for Port " + port.getPortName() + " @ " + portMap - .getSupportingCircuitPackName()); - return null; - } - } - if (postInterface(interfacesIID, ifBuilder)) { - return ifBuilder.getName(); - } else { - return null; - } - } - - // TODO: implement OCH facility for xponder - return null; - } - - public String createODU4Interface() { - // Add ODU4 augmentation to the interface - - // TODO: implement this method - return null; - - } - - public String createOTU4Interface() { - // Add OTU4 augmentation to the interface - - // TODO: implement this method - - return null; - } - - public String createETHInterface() { - // Add ETH augmentation to the interface - - // TODO: implement this method - - return null; - - } - - /** - * This methods does a get operation on the port subtree of the device's - * operational data store.This method will be called once for each Degree port - * in order to fetch the OMS interface for the first time. - * - * @param portMap Mapping object - * - * @return Ports object read from the device. - */ - public Ports getPort(Mapping portMap) { - // Get Port subtree corresponding to the logical connection point - if (netconfNodeDataBroker != null) { - ReadOnlyTransaction rtx = netconfNodeDataBroker.newReadOnlyTransaction(); - InstanceIdentifier portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child( - CircuitPacks.class, new CircuitPacksKey(portMap.getSupportingCircuitPackName())).child(Ports.class, - new PortsKey(portMap.getSupportingPort())); - Optional portObject; - try { - portObject = rtx.read(LogicalDatastoreType.OPERATIONAL, portIID).get(); - if (portObject.isPresent()) { - return portObject.get(); - } - } catch (InterruptedException | ExecutionException ex) { - LOG.info("Error getting port subtree from the device "); - return null; - } - } - return null; - } - - /** - * This methods creates a generic interface builder object - * to set the value that are common irrespective of the interface type. - * - * @param portMap Mapping object containing attributes required to create - * interface on the device. - * - * @return InterfaceBuilder object with the data. - */ - public InterfaceBuilder intfBuilder(Mapping portMap) { - - InterfaceBuilder ifBuilder = new InterfaceBuilder(); - ifBuilder.setType(OpticalChannel.class); - ifBuilder.setDescription(" TBD "); - ifBuilder.setCircuitId(" TBD "); - ifBuilder.setSupportingCircuitPackName(portMap.getSupportingCircuitPackName()); - ifBuilder.setSupportingPort(portMap.getSupportingPort()); - return ifBuilder; - } - - /** - * This methods does an edit-config operation on the openROADM - * device in order to create the given interface. - * - * @param interfacesIID Instance identifier for the interfaces subtree in the device. - * @param ifBuilder Builder object containing the data to post. - * - * @return Result of operation true/false based on success/failure. - */ - public boolean postInterface(InstanceIdentifier interfacesIID, InterfaceBuilder ifBuilder) { - // Post interface with its specific augmentation to the device - if (netconfNodeDataBroker != null) { - final WriteTransaction writeTransaction = netconfNodeDataBroker.newWriteOnlyTransaction(); - writeTransaction.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, ifBuilder.build()); - final CheckedFuture submit = writeTransaction.submit(); - try { - - submit.checkedGet(); - LOG.info("Successfully posted interface " + ifBuilder.getName()); - return true; - } catch (TransactionCommitFailedException ex) { - LOG.warn("Failed to post {} ", ifBuilder.getName()); - return false; - } - - } else { - return false; - } - } - - /** - * This method for a given node's termination point returns the Mapping - * object based on portmapping.yang model stored in the MD-SAL - * data store which is created when the node is connected for the first time. - * The mapping object basically contains the following attributes of interest: - * - *

- * 1. Supporting circuit pack - * 2. Supporting port - * 3. Supporting OMS interface (if port on ROADM) - * - * @param nodeId unique Identifier for the node of interest. - * @param logicalConnPoint Name of the logical point - * - * @return Result Mapping object if success otherwise null. - */ - public Mapping getMapping(String nodeId, String logicalConnPoint) { - - // Getting circuit pack and port corresponding to logical connection - // point - InstanceIdentifier portMapping = InstanceIdentifier.builder(Network.class).child(Nodes.class, - new NodesKey(nodeId)).child(Mapping.class, new MappingKey(logicalConnPoint)).build(); - ReadOnlyTransaction readTx = db.newReadOnlyTransaction(); - Optional mapObject; - try { - mapObject = readTx.read(LogicalDatastoreType.CONFIGURATION, portMapping).get(); - if (mapObject.isPresent()) { - LOG.info("Found mapping for the logical port " + mapObject.get().toString()); - return mapObject.get(); - } else { - LOG.info("Could not find mapping for logical connection point : " + logicalConnPoint + " for nodeId " - + nodeId); - return null; - } - } catch (InterruptedException | ExecutionException ex) { - LOG.info("Unable to read mapping for logical connection point : " + logicalConnPoint + " for nodeId " - + nodeId); - } - return null; - } -} -- 2.36.6