From: Christophe Betoule Date: Tue, 17 Oct 2017 11:05:03 +0000 (+0200) Subject: improves services activation in the renderer X-Git-Tag: v0.2.0~87^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=transportpce.git;a=commitdiff_plain;h=9e604d96746a08a485eeb9f55a0f8463bde28ab1 improves services activation in the renderer Adds the new method 'activateService' in DeviceRenderer.java This method changes the equipment state on circuit-packs supporting the service terminations points (XPDR device) during a service path creation and/or removal. Rewrites all LOG messages according to Best Practices at the URL below. https://wiki.opendaylight.org/view/BestPractices/Logging_Best_Practices#Use_parameterized_logging Change-Id: Ibee4e9e428cb91233cea6c88ec2fdbb8dfc5015f Signed-off-by: Christophe Betoule Co-authored-by: Gilles Thouenon --- 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 ee4caacfc..b4bbc52f1 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,17 +8,30 @@ package org.opendaylight.transportpce.renderer.provisiondevice; +import com.google.common.base.Optional; + import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; 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.transportpce.renderer.mapping.PortMapping; import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaces; import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmOchInterface; import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmXponderInterface; +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.CircuitPacksBuilder; +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.org.openroadm.device.container.OrgOpenroadmDevice; +import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev161014.States; import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.OchAttributes.ModulationFormat; import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.R100G; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererService; @@ -26,8 +39,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer 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; @@ -48,20 +63,22 @@ public class DeviceRenderer implements RendererService { /** * This method is the implementation of the 'service-path' RESTCONF service, - * which is one of the external APIs into the renderer application. The service - * provides two functions: + * which is one of the external APIs into the renderer application. The + * 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. + * 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. + * 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 @@ -82,12 +99,13 @@ 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 the 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 @@ -107,7 +125,7 @@ public class DeviceRenderer implements RendererService { LOG.info(currentMountedDevice.toString()); int crossConnectFlag; for (Nodes n : nodes) { - LOG.info("Starting provisioning for node : " + n.getNodeId()); + LOG.info("Starting provisioning for node : {}", n.getNodeId()); crossConnectFlag = 0; String nodeId = n.getNodeId(); // if the node is currently mounted then proceed @@ -130,7 +148,7 @@ public class DeviceRenderer implements RendererService { try { LOG.info("Modulation Format {} configured exists.", modulationFormat.getName()); } catch (NullPointerException e) { - LOG.error(mf + " modulation format does not exist."); + LOG.error("{} modulation format does not exist.",mf); } if (!new OpenRoadmXponderInterface(db, mps, nodeId, destTp, serviceName) @@ -138,7 +156,10 @@ public class DeviceRenderer implements RendererService { return setServBldr.setResult("Unable to LINE interface on " + nodeId + " at " + destTp); } - LOG.info("LINE interface created for node " + nodeId); + if (!activateService(nodeId, destTp, mps, true)) { + return setServBldr + .setResult("Unable to activate Equipment State on " + nodeId + " for " + destTp); + } } if (srcTp.contains("CLNT")) { crossConnectFlag++; @@ -150,25 +171,25 @@ public class DeviceRenderer implements RendererService { String dstIf; if (srcTp.contains("TTP") || srcTp.contains("PP")) { srcIf = new OpenRoadmOchInterface(db, mps, nodeId, srcTp, serviceName).createInterface(waveNumber); - // if source interface creation was successful then proceed - // otherwise return. + // if source interface creation was successful + // then proceed otherwise return. if (srcIf == null) { - LOG.warn("Unable to create OCH interface on " + nodeId + " at " + srcTp); + LOG.warn("Unable to create OCH interface on {} at {}", nodeId, srcTp); return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + srcTp); } } if (destTp.contains("TTP") || destTp.contains("PP")) { dstIf = new OpenRoadmOchInterface(db, mps, nodeId, destTp, serviceName).createInterface(waveNumber); - // if destination interface creation was successful then proceed - // otherwise return. + // if destination interface creation was successful + // then proceed otherwise return. if (dstIf == null) { - LOG.warn("Unable to create OCH interface on " + nodeId + " at " + destTp); + LOG.warn("Unable to create OCH interface on {} at {}", nodeId, destTp); return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + destTp); } } if (crossConnectFlag < 1) { - LOG.info("Creating cross connect between source :" + srcTp + " destination " + destTp + " for node " - + n.getNodeId()); + LOG.info("Creating cross connect between source :{} destination {} for node {}", srcTp, destTp, + n.getNodeId()); DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps); String crossConnectName = srcTp + "-" + destTp + "-" + waveNumber; CrossConnect roadmConnections = new CrossConnect(netconfNodeDataBroker); @@ -180,7 +201,7 @@ public class DeviceRenderer implements RendererService { } } } else { - LOG.warn(nodeId + " is not mounted on the controller"); + LOG.warn("{} is not mounted on the controller", nodeId); return setServBldr.setResult(nodeId + " is not mounted on the controller"); } } @@ -188,12 +209,13 @@ public class DeviceRenderer implements RendererService { } /** - * 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 @@ -211,7 +233,7 @@ public class DeviceRenderer implements RendererService { for (Nodes n : nodes) { String nodeId = n.getNodeId(); - LOG.info("Deleting service setup on node " + nodeId); + LOG.info("Deleting service setup on node {}", nodeId); String srcTp = n.getSrcTp(); String destTp = n.getDestTp(); Long waveNumber = input.getWaveNumber(); @@ -220,49 +242,109 @@ public class DeviceRenderer implements RendererService { if (currentMountedDevice.contains(nodeId)) { if (destTp.contains("LINE")) { + if (!activateService(nodeId, destTp, mps, false)) { + LOG.error("Unable to desactivate Equipment State on {} for {}", nodeId, destTp); + } if (new OpenRoadmInterfaces(db, mps, nodeId, destTp) - .deleteInterface(destTp + "-ODU") == false) { - LOG.error("Failed to delete interface " + destTp + "-ODU"); + .deleteInterface(destTp + "-ODU") == false) { + LOG.error("Failed to delete interface {}-ODU on {}", destTp, nodeId); } if (new OpenRoadmInterfaces(db, mps, nodeId, destTp) - .deleteInterface(destTp + "-OTU") == false) { - LOG.error("Failed to delete interface " + destTp + "-OTU"); + .deleteInterface(destTp + "-OTU") == false) { + LOG.error("Failed to delete interface {}-OTU on {}", destTp, nodeId); } if (new OpenRoadmInterfaces(db, mps, nodeId, destTp) - .deleteInterface(destTp + "-" + waveNumber) == false) { - LOG.error("Failed to delete interface " + destTp + "-" + waveNumber); + .deleteInterface(destTp + "-" + waveNumber) == false) { + LOG.error("Failed to delete interface {}-{} on {}", destTp, waveNumber, nodeId); } } if (srcTp.contains("CLNT")) { // Deleting interface on source termination point if (new OpenRoadmInterfaces(db, mps, nodeId, srcTp) - .deleteInterface(srcTp + "-ETHERNET") == false) { - LOG.error("Failed to delete Ethernet interface on " + srcTp); + .deleteInterface(srcTp + "-ETHERNET") == false) { + LOG.error("Failed to delete Ethernet interface on {} on {}", srcTp, nodeId); } continue; } String connectionNumber = srcTp + "-" + destTp + "-" + waveNumber; CrossConnect roadmConnection = new CrossConnect(PortMapping.getDeviceDataBroker(nodeId, mps), - connectionNumber); + connectionNumber); if (!roadmConnection.deleteCrossConnect()) { - LOG.error("Failed to delete {} ", srcTp + "-" + destTp + "-" + waveNumber); + LOG.error("Failed to delete {} on {}", connectionNumber, nodeId); } // Deleting interface on source termination point if (!new OpenRoadmInterfaces(db, mps, nodeId, srcTp) - .deleteInterface(srcTp + "-" + waveNumber.toString())) { - LOG.error("Failed to delete interface " + srcTp + "-" + waveNumber.toString()); + .deleteInterface(srcTp + "-" + waveNumber.toString())) { + LOG.error("Failed to delete interface {}-{} on {}", srcTp, waveNumber.toString(), nodeId); } // Deleting interface on destination termination point if (!new OpenRoadmInterfaces(db, mps, nodeId, destTp) - .deleteInterface(destTp + "-" + waveNumber.toString())) { - LOG.error("Failed to delete interface " + destTp + "-" + waveNumber.toString()); + .deleteInterface(destTp + "-" + waveNumber.toString())) { + LOG.error("Failed to delete interface {}-{} on {}", destTp, waveNumber.toString(), nodeId); } } else { - LOG.warn(nodeId + " is not mounted on the controller"); + LOG.warn("{} is not mounted on the controller", nodeId); return delServBldr.setResult(nodeId + " is not mounted on the controller"); } } return delServBldr.setResult("Request processed"); } + + /** + * This method does a post(edit-config) on a given circuit-packs subtree to + * change its equipment-state. + * + * @param nodeId + * Netconf device. + * @param logicalConnPoint + * Logical Connection point resulting from PortMapping to + * retrieve associated circuit-pack. + * @param mps + * Mount point service. + * @param activate + * true to configure the circuit-pack to "NotReservedInuse". + * false to configure the circuit-pack to "NotReservedAvailable". + * @return true/false based on status of operation. + */ + private boolean activateService(String nodeId, String logicalConnPoint, MountPointService mps, boolean activate) { + DataBroker deviceDb = PortMapping.getDeviceDataBroker(nodeId, mps); + String circuitPack = PortMapping.getMapping(nodeId, logicalConnPoint, db).getSupportingCircuitPackName(); + + InstanceIdentifier circuitPackIID = InstanceIdentifier.create(OrgOpenroadmDevice.class) + .child(CircuitPacks.class, new CircuitPacksKey(circuitPack)); + ReadOnlyTransaction readTx = deviceDb.newReadOnlyTransaction(); + // retrieve relevent CircuitPack object + Optional cpObject; + CircuitPacks cp = null; + try { + cpObject = readTx.read(LogicalDatastoreType.CONFIGURATION, circuitPackIID).get(); + if (cpObject.isPresent()) { + cp = cpObject.get(); + } else { + LOG.info("Could not find CircuitPack {} in equipment config datastore for nodeId {}", circuitPack, + nodeId); + return false; + } + + } catch (InterruptedException | ExecutionException ex) { + LOG.error("Issue reading config datastore on node {}", nodeId, ex); + } + CircuitPacksBuilder cpBldr = new CircuitPacksBuilder(cp); + if (activate) { + cpBldr.setEquipmentState(States.NotReservedInuse); + } else { + cpBldr.setEquipmentState(States.NotReservedAvailable); + } + WriteTransaction wt = deviceDb.newWriteOnlyTransaction(); + wt.put(LogicalDatastoreType.CONFIGURATION, circuitPackIID, cpBldr.build()); + try { + wt.submit().get(15, TimeUnit.SECONDS); + LOG.info("Successfully posted Equipment State on circuit pack {} on node {}", circuitPack, nodeId); + return true; + } catch (InterruptedException | ExecutionException | TimeoutException e) { + LOG.warn("Failed to post {} on node {}", circuitPack, nodeId, e); + return false; + } + } }