revision-date 2017-09-07;
}
+ import ietf-network-topology {
+ prefix ietf-network-topology;
+ revision-date 2015-06-08;
+ }
+
organization
"transportPCE";
contact
}
}
}
- /*rpc service-power-reset{
+ rpc service-power-reset{
description
"This RPC re-calculates and re-sets power for all nodes part of a
service given in input";
type string;
}
}
- }*/
+ }
}
mandatory true;
}
leaf resource-type {
- type string;
+ type org-openroadm-resource-types:resource-type-enum;
description "Type of the PM resource";
mandatory true;
}
- //container resource-identifier {
+ container resource-identifier {
leaf resource-name {
type string;
description "Identifier of particular resource of given type";
mandatory true;
}
- //}
+ }
leaf granularity {
- type string;
+ type org-openroadm-pm-types:pm-granularity;
description "Granularity of PM bin can be
notApplicable,15min,24Hour";
mandatory true;
}
}
}
- leaf service-name {
- type string;
- }
- leaf wave-number {
- type uint32;
- }
- list nodes {
- ordered-by user;
- key "node-id";
- leaf node-id {
- type string;
- description "Gloabally unique identifier
- for the node";
- }
- leaf src-tp {
- type string;
- description "Source termination point ";
- mandatory true;
- }
- leaf dest-tp {
- type string;
- description "Destination termination point ";
- mandatory true;
- }
- }
+ uses org-transportpce-common-types:olm-renderer-input;
}
output{
leaf success {
}
}
- /*rpc renderer-rollback {
+ rpc renderer-rollback {
input {
uses org-transportpce-common-types:node-interfaces;
}
}
}
}
- }*/
+ }
}
}
grouping PCE-resource {
- description
- "This resource identifier is intended to provide a generic identifer
- for any resource that can be used without specific knowledge of
- the resource.";
- container resource {
- choice resource {
- case termination-point {
- container termination-point-identifier {
- leaf tp-id {
- type string; //to be clarified with topology model
- }
- leaf node-id {
- type string; //to be clarified with topology model
- }
+ description
+ "This resource identifier is intended to provide a generic identifer
+ for any resource that can be used without specific knowledge of
+ the resource.";
+ container resource {
+ choice resource {
+ case termination-point {
+ container termination-point-identifier {
+ leaf tp-id {
+ type string; //to be clarified with topology model
+ }
+ leaf node-id {
+ type string; //to be clarified with topology model
}
}
+ }
- case link {
- container link-identifier {
- leaf link-id {
- type string; //to be clarified with topology model
- }
+ case link {
+ container link-identifier {
+ leaf link-id {
+ type string; //to be clarified with topology model
}
}
+ }
- case node {
- container node-identifier {
- leaf node-id {
- type string; // to be clarified with topology model
- }
+ case node {
+ container node-identifier {
+ leaf node-id {
+ type string; // to be clarified with topology model
}
}
}
}
}
+ }
grouping path-description {
<artifactId>transportpce-olm</artifactId>
<version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>mdsal-artifacts</artifactId>
+ <version>1.7.3-SNAPSHOT</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>netconf-artifacts</artifactId>
+ <version>1.4.3-SNAPSHOT</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>transportpce-api</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>${project.groupId}</groupId>
<artifactId>transportpce-renderer</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-common</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-network</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-service</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-device</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-topology</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
+
</project>
--- /dev/null
+/*
+ * 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.olm;
+
+import java.util.concurrent.Future;
+import org.opendaylight.transportpce.olm.service.OlmPowerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+/**
+ * The Class OlmPowerServiceRpcImpl.
+ */
+public class OlmPowerServiceRpcImpl implements OlmService {
+ private final OlmPowerService olmPowerService;
+
+ public OlmPowerServiceRpcImpl(OlmPowerService olmPowerService) {
+ this.olmPowerService = olmPowerService;
+ }
+
+ /**
+ * This method is the implementation of the 'get-pm' RESTCONF service, which
+ * is one of the external APIs into the olm application.
+ *
+ * <p>
+ * 1. get-pm This operation traverse through current PM list and gets PM for
+ * given NodeId and Resource name
+ *
+ * <p>
+ * The signature for this method was generated by yang tools from the
+ * olm API model.
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ *
+ * @return Result of the request
+ */
+ @Override
+ public Future<RpcResult<GetPmOutput>> getPm(GetPmInput input) {
+ return RpcResultBuilder.success(olmPowerService.getPm(input)).buildFuture();
+ }
+
+ /**
+ * This method is the implementation of the 'service-power-setup' RESTCONF service, which
+ * is one of the external APIs into the olm application.
+ *
+ * <p>
+ * 1. service-power-setup: This operation performs following steps:
+ * Step1: Calculate Spanloss on all links which are part of service.
+ * TODO Step2: Calculate power levels for each Tp-Id
+ * TODO Step3: Post power values on roadm connections
+ *
+ * <p>
+ * The signature for this method was generated by yang tools from the
+ * olm API model.
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ * Input will contain nodeId and termination point
+ *
+ * @return Result of the request
+ */
+ @Override
+ public Future<org.opendaylight.yangtools.yang.common.RpcResult<ServicePowerSetupOutput>> servicePowerSetup(
+ ServicePowerSetupInput input) {
+ return RpcResultBuilder.success(olmPowerService.servicePowerSetup(input)).buildFuture();
+ }
+
+ /**
+ * This method is the implementation of the 'service-power-trundown' RESTCONF service, which
+ * is one of the external APIs into the olm application.
+ *
+ * <p>
+ * 1. service-power-turndown: This operation performs following steps:
+ * Step1: For each TP within Node sets interface outofservice .
+ * Step2: For each roam-connection sets power to -60dbm
+ * Step3: Turns power mode off
+ *
+ * <p>
+ * The signature for this method was generated by yang tools from the
+ * olm API model.
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ * Input will contain nodeId and termination point
+ *
+ * @return Result of the request
+ */
+ @Override
+ public Future<RpcResult<ServicePowerTurndownOutput>> servicePowerTurndown(ServicePowerTurndownInput input) {
+ return RpcResultBuilder.success(olmPowerService.servicePowerTurndown(input)).buildFuture();
+ }
+
+ /**
+ * This method calculates Spanloss for all Roadm to Roadm links,
+ * part of active inventory in Network Model or for newly added links
+ * based on input src-type.
+ *
+ * <p>
+ * 1. Calculate-Spanloss-Base: This operation performs following steps:
+ * Step1: Read all Roadm-to-Roadm links from network model or get data for given linkID.
+ * Step2: Retrieve PMs for each end point for OTS interface
+ * Step3: Calculates Spanloss
+ * Step4: Posts calculated spanloss in Device and in network model
+ *
+ * <p>
+ * The signature for this method was generated by yang tools from the
+ * renderer API model.
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ * Input will contain SourceType and linkId if srcType is Link
+ *
+ * @return Result of the request
+ */
+ @Override
+ public Future<RpcResult<CalculateSpanlossBaseOutput>> calculateSpanlossBase(CalculateSpanlossBaseInput input) {
+ return RpcResultBuilder.success(olmPowerService.calculateSpanlossBase(input)).buildFuture();
+ }
+
+ @Override
+ public Future<RpcResult<CalculateSpanlossCurrentOutput>> calculateSpanlossCurrent(
+ CalculateSpanlossCurrentInput input) {
+ return RpcResultBuilder.success(olmPowerService.calculateSpanlossCurrent(input)).buildFuture();
+ }
+
+ @Override
+ public Future<RpcResult<ServicePowerResetOutput>> servicePowerReset(ServicePowerResetInput input) {
+ return RpcResultBuilder.success(olmPowerService.servicePowerReset(input)).buildFuture();
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.olm;
-
-import com.google.common.base.Optional;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-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.MountPointService;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.transportpce.olm.power.PowerMgmt;
-import org.opendaylight.transportpce.olm.spanloss.RoadmLinks;
-import org.opendaylight.transportpce.olm.spanloss.SpanLoss;
-import org.opendaylight.transportpce.renderer.mapping.PortMapping;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.CurrentPmlist;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.current.pm.Measurements;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.currentpmlist.CurrentPm;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmNamesEnum;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.MeasurementsBuilder;
-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;
-
-/**
- * The Class OlmPowerSetupImpl.
- */
-public class OlmPowerSetupImpl implements OlmService {
-
- /** The Constant LOG. */
- private static final Logger LOG = LoggerFactory.getLogger(OlmPowerSetupImpl.class);
-
- /** The db. */
- private final DataBroker db;
-
- /** The mps. */
- private final MountPointService mps;
-
- /**
- * Instantiates a new olm power setup impl.
- *
- * @param db
- * the db
- * @param mps
- * the mps
- */
- public OlmPowerSetupImpl(DataBroker db, MountPointService mps) {
- this.db = db;
- this.mps = mps;
- }
-
- /**
- * This method is the implementation of the 'get-pm' RESTCONF service, which
- * is one of the external APIs into the olm application.
- *
- * <p>
- * 1. get-pm This operation traverse through current PM list and gets PM for
- * given NodeId and Resource name
- *
- * <p>
- * The signature for this method was generated by yang tools from the
- * renderer API model.
- *
- * @param input
- * Input parameter from the olm yang model
- *
- * @return Result of the request
- */
- @Override
- public Future<RpcResult<GetPmOutput>> getPm(GetPmInput input) {
- LOG.info("Getting PM Data for NodeId: {} ResouceType: {} ResourceName: {}",
- input.getNodeId(),input.getResourceType(),input.getResourceName());
- new PortMapping(db, mps, input.getNodeId());
- DataBroker deviceDb = PortMapping.getDeviceDataBroker(input.getNodeId(), mps);
- InstanceIdentifier<CurrentPmlist> currentPmsIID = InstanceIdentifier.create(CurrentPmlist.class);
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- Optional<CurrentPmlist> currentPmList;
- String methodName = "";
- List<CurrentPm> currentPms = new ArrayList<>();
- GetPmOutputBuilder pmOutputBuilder = new GetPmOutputBuilder();
- List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements>
- measrements = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418
- .get.pm.output.Measurements>();
- try {
- currentPmList = rtx.read(LogicalDatastoreType.OPERATIONAL, currentPmsIID).get();
- if (currentPmList.isPresent()) {
- currentPms.addAll(currentPmList.get().getCurrentPm());
- for (CurrentPm pm : currentPms) {
- MeasurementsBuilder measurement = new MeasurementsBuilder();
- if (pm.getResource().getResourceType().getType().toString().equals(input.getResourceType())) {
-
- switch (pm.getResource().getResourceType().getType()) {
- case CircuitPack:
- methodName = "getCircuitPackName";
- break;
- case Connection:
- methodName = "getConnectionNumber";
- break;
- case Degree:
- methodName = "getDegreeNumber";
- break;
- case Interface:
- methodName = "getInterfaceName";
- break;
- case InternalLink:
- methodName = "getInternalLinkName";
- break;
- case PhysicalLink:
- methodName = "getPhysicalLinkName";
- break;
- case Service:
- methodName = "getServiceName";
- break;
- case Shelf:
- methodName = "getShelfName";
- break;
- case SharedRiskGroup:
- methodName = "getSrgNumber";
- break;
- default:
- methodName = "getPort";
- break;
- }
- try {
-
- String pmResourceId = pm.getResource().getResource().getResource().getImplementedInterface()
- .getMethod(methodName).invoke(pm.getResource().getResource().getResource()).toString();
- if (pmResourceId.equals(input.getResourceName()) && pm.getGranularity() != null) {
- if (pm.getGranularity().getName().equals(input.getGranularity())) {
- for (Measurements measure : pm.getMeasurements()) {
- if (!measure.getMeasurement().getPmParameterName().getType().equals(
- PmNamesEnum.VendorExtension)) {
- measurement.setPmparameterName(measure.getMeasurement().getPmParameterName()
- .getType().toString());
- measurement.setPmparameterValue(measure.getMeasurement()
- .getPmParameterValue().getDecimal64().toString());
- measrements.add(measurement.build());
- }
- }
- }
- }
-
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- LOG.warn("Unable to find PM for NodeID: {} ResourceName: {} ",input.getNodeId(),
- input.getResourceName(),ex);
- }
- }
- }
- if (measrements.size() > 0) {
- pmOutputBuilder.setNodeId(input.getNodeId()).setResourceType(input.getResourceType()).setResourceId(
- input.getResourceName()).setGranularity(input.getGranularity()).setMeasurements(measrements);
- }
-
- } else {
- LOG.info("Device PM Data is not available");
- }
-
- } catch (InterruptedException | ExecutionException ex) {
- LOG.warn("Unable to get currentPmList for NodeID: {}",input.getNodeId(),ex);
- }
- LOG.info("PM Data found successfully for {}-{}",pmOutputBuilder.getNodeId(),pmOutputBuilder.getResourceId());
- return RpcResultBuilder.success(pmOutputBuilder).buildFuture();
- }
-
-
- /**
- * This method is the implementation of the 'service-power-setup' RESTCONF service, which
- * is one of the external APIs into the olm application.
- *
- * <p>
- * 1. service-power-setup: This operation performs following steps:
- * Step1: Calculate Spanloss on all links which are part of service.
- * TODO Step2: Calculate power levels for each Tp-Id
- * TODO Step3: Post power values on roadm connections
- *
- * <p>
- * The signature for this method was generated by yang tools from the
- * renderer API model.
- *
- * @param input
- * Input parameter from the olm yang model
- * Input will contain nodeId and termination point
- *
- * @return Result of the request
- */
- @Override
- public Future<org.opendaylight.yangtools.yang.common.RpcResult<ServicePowerSetupOutput>> servicePowerSetup(
- ServicePowerSetupInput input) {
- List<RoadmLinks> roadmLinks = new ArrayList<RoadmLinks>();
- ServicePowerSetupOutputBuilder output = new ServicePowerSetupOutputBuilder();
- //Finds degree TpID from node and generates a list of links
- for (int i = 0; i < input.getNodes().size(); i++) {
- if (input.getNodes().get(i).getDestTp().toLowerCase().contains("deg")) {
- RoadmLinks rdmLink = new RoadmLinks();
- rdmLink.setSrcNodeId(input.getNodes().get(i).getNodeId());
- rdmLink.setSrcTpId(input.getNodes().get(i).getDestTp());
- rdmLink.setDestNodeId(input.getNodes().get(i + 1).getNodeId());
- rdmLink.setDestTpid(input.getNodes().get(i + 1).getSrcTp());
- roadmLinks.add(rdmLink);
- }
- }
- boolean successValSpanCalculation = new SpanLoss(db, mps).getLinkSpanloss(roadmLinks);
- boolean successValPowerCalculation = new PowerMgmt(db,mps).setPower(input);
-
- if (successValSpanCalculation && successValPowerCalculation) {
- output.setResult("Success");
- } else {
- output.setResult("Failed");
- }
-
- return RpcResultBuilder.success(output).buildFuture();
- }
-
-
- /**
- * This method is the implementation of the 'service-power-trundown' RESTCONF service, which
- * is one of the external APIs into the olm application.
- *
- * <p>
- * 1. service-power-turndown: This operation performs following steps:
- * Step1: For each TP within Node sets interface outofservice .
- * Step2: For each roam-connection sets power to -60dbm
- * Step3: Turns power mode off
- *
- * <p>
- * The signature for this method was generated by yang tools from the
- * renderer API model.
- *
- * @param input
- * Input parameter from the olm yang model
- * Input will contain nodeId and termination point
- *
- * @return Result of the request
- */
- @Override
- public Future<RpcResult<ServicePowerTurndownOutput>> servicePowerTurndown(ServicePowerTurndownInput input) {
- ServicePowerTurndownOutputBuilder output = new ServicePowerTurndownOutputBuilder();
- if (new PowerMgmt(db,mps).powerTurnDown(input)) {
- output.setResult("Success");
- } else {
- output.setResult("Failed");
- }
- return RpcResultBuilder.success(output).buildFuture();
- }
-}
\ No newline at end of file
package org.opendaylight.transportpce.olm;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.MountPointService;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.transportpce.olm.service.OlmPowerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* The Class OlmProvider.
*/
public class OlmProvider {
-
- /** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(OlmProvider.class);
-
- /** The data broker. */
- private final DataBroker dataBroker;
-
- /** The mount point service. */
- private final MountPointService mountPointService;
-
- /** The rpc provider registry. */
private final RpcProviderRegistry rpcProviderRegistry;
-
- /** The get pm registration. */
+ private final OlmPowerService olmPowerService;
private RpcRegistration<OlmService> olmRPCRegistration;
/**
* Instantiates a new olm provider.
- *
- * @param dataBroker
- * the data broker
- * @param mountPointService
- * the mount point service
+ * @param olmPowerService
+ * implementation of OlmService
* @param rpcProviderRegistry
* the rpc provider registry
*/
- public OlmProvider(final DataBroker dataBroker, final MountPointService mountPointService,
- final RpcProviderRegistry rpcProviderRegistry) {
- this.dataBroker = dataBroker;
- this.mountPointService = mountPointService;
+ public OlmProvider(final RpcProviderRegistry rpcProviderRegistry, final OlmPowerService olmPowerService) {
this.rpcProviderRegistry = rpcProviderRegistry;
- if (mountPointService == null) {
- LOG.error("Mount service is null");
- }
+ this.olmPowerService = olmPowerService;
}
/**
public void init() {
LOG.info("OlmProvider Session Initiated");
// Initializing Notification module
- olmRPCRegistration = rpcProviderRegistry.addRpcImplementation(OlmService.class, new OlmPowerSetupImpl(
- dataBroker,mountPointService));
+ olmRPCRegistration = rpcProviderRegistry.addRpcImplementation(OlmService.class, new OlmPowerServiceRpcImpl(
+ this.olmPowerService));
}
/**
package org.opendaylight.transportpce.olm.power;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
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.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.openroadminterface.OpenRoadmInterfaces;
-import org.opendaylight.transportpce.renderer.provisiondevice.CrossConnect;
+import org.opendaylight.transportpce.common.Timeouts;
+import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
+import org.opendaylight.transportpce.common.device.DeviceTransaction;
+import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
+import org.opendaylight.transportpce.olm.util.OlmUtils;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
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.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.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.yang.gen.v1.http.org.openroadm.equipment.states.types.rev161014.AdminStates;
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.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
-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.MappingKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PowerMgmt {
private static final Logger LOG = LoggerFactory.getLogger(PowerMgmt.class);
+ private static final long DATA_STORE_READ_TIMEOUT = 120;
private final DataBroker db;
- private final MountPointService mps;
- public static final InstanceIdentifier<Topology> NETCONF_TOPO_IID =
- InstanceIdentifier
- .create(NetworkTopology.class)
- .child(Topology.class,
- new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+ private final OpenRoadmInterfaces openRoadmInterfaces;
+ private final CrossConnect crossConnect;
+ private final DeviceTransactionManager deviceTransactionManager;
- public PowerMgmt(DataBroker db, MountPointService mps) {
+ public PowerMgmt(DataBroker db, OpenRoadmInterfaces openRoadmInterfaces,
+ CrossConnect crossConnect, DeviceTransactionManager deviceTransactionManager) {
this.db = db;
- this.mps = mps;
+ this.openRoadmInterfaces = openRoadmInterfaces;
+ this.crossConnect = crossConnect;
+ this.deviceTransactionManager = deviceTransactionManager;
}
/**
String nodeId = input.getNodes().get(i).getNodeId();
String srcTpId = input.getNodes().get(i).getSrcTp();
String destTpId = input.getNodes().get(i).getDestTp();
- DataBroker deviceDb = getDeviceDataBroker(nodeId , mps);
- Nodes inputNode = getNode(nodeId, mps, db);
- LOG.info("Getting data from input node {}",inputNode.getNodeType());
- LOG.info("Getting mapping data for node is {}",inputNode.getMapping().stream().filter(o -> o.getKey()
- .equals(new MappingKey(destTpId))).findFirst().toString());
+ Optional<Nodes> inputNodeOptional = OlmUtils.getNode(nodeId, db);
// If node type is transponder
- if (inputNode.getNodeType() != null && inputNode.getNodeType().equals(NodeTypes.Xpdr)) {
+ if (inputNodeOptional.isPresent()
+ && inputNodeOptional.get().getNodeType() != null
+ && inputNodeOptional.get().getNodeType().equals(NodeTypes.Xpdr)) {
+
+ Nodes inputNode = inputNodeOptional.get();
+ LOG.info("Getting data from input node {}", inputNode.getNodeType());
+ LOG.info("Getting mapping data for node is {}", inputNode.getMapping().stream().filter(o -> o.getKey()
+ .equals(new MappingKey(destTpId))).findFirst().toString());
// If its A-End transponder
if (destTpId.toLowerCase().contains("network")) {
java.util.Optional<Mapping> mappingObject = inputNode.getMapping().stream().filter(o -> o.getKey()
.equals(new MappingKey(destTpId))).findFirst();
if (mappingObject.isPresent()) {
- Map<String, Double> txPowerRangeMap = getXponderPowerRange(nodeId, mappingObject.get()
- .getSupportingCircuitPackName(),
- mappingObject.get().getSupportingPort(),deviceDb);
+ Map<String, Double> txPowerRangeMap = getXponderPowerRange(mappingObject.get()
+ .getSupportingCircuitPackName(), mappingObject.get().getSupportingPort(), nodeId);
if (!txPowerRangeMap.isEmpty()) {
LOG.info("Transponder range exists for nodeId: {}", nodeId);
String srgId = input.getNodes().get(i + 1).getSrcTp();
String nextNodeId = input.getNodes().get(i + 1).getNodeId();
- DataBroker deviceDbSRG = getDeviceDataBroker(nextNodeId , mps);
- Map<String, Double> rxSRGPowerRangeMap = getSRGRxPowerRange(nextNodeId, srgId, deviceDbSRG);
- Double powerValue = new Double(0);
+
+ Map<String, Double> rxSRGPowerRangeMap = getSRGRxPowerRange(nextNodeId, srgId);
+ double powerValue = 0;
if (!rxSRGPowerRangeMap.isEmpty()) {
LOG.info("SRG Rx Power range exists for nodeId: {}", nodeId);
- if (txPowerRangeMap.get("MaxTx").doubleValue()
- <= rxSRGPowerRangeMap.get("MaxRx").doubleValue()) {
- powerValue = txPowerRangeMap.get("MaxTx").doubleValue();
- } else if (rxSRGPowerRangeMap.get("MaxRx").doubleValue()
- < txPowerRangeMap.get("MaxTx").doubleValue()) {
- powerValue = rxSRGPowerRangeMap.get("MaxRx").doubleValue();
+ if (txPowerRangeMap.get("MaxTx")
+ <= rxSRGPowerRangeMap.get("MaxRx")) {
+ powerValue = txPowerRangeMap.get("MaxTx");
+ } else if (rxSRGPowerRangeMap.get("MaxRx")
+ < txPowerRangeMap.get("MaxTx")) {
+ powerValue = rxSRGPowerRangeMap.get("MaxRx");
}
LOG.info("Calculated Transponder Power value is {}" , powerValue);
- if (setTransponderPower(nodeId, destTpId, destTpId + "-" + input.getWaveNumber(),
- new BigDecimal(powerValue), deviceDb)) {
- LOG.info("Transponder OCH connection: {} power updated ",
- destTpId + "-" + input.getWaveNumber());
+ String interfaceName = destTpId + "-" + input.getWaveNumber();
+ if (setTransponderPower(nodeId, interfaceName, new BigDecimal(powerValue))) {
+ LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
try {
LOG.info("Now going in sleep mode");
- Thread.sleep(180000);
+ Thread.sleep(120000);
} catch (InterruptedException e) {
- LOG.info("Transponder warmup failed for OCH connection: {}",
- destTpId + "-" + input.getWaveNumber(), e);
+ LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
}
} else {
- LOG.info("Transponder OCH connection: {} power update failed ",
- destTpId + "-" + input.getWaveNumber());
+ LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
}
} else {
LOG.info("SRG Power Range not found");
} else {
LOG.info("Tranponder range not available seting to default "
+ "power for nodeId: {}", nodeId);
- if (setTransponderPower(nodeId, destTpId, destTpId + "-" + input.getWaveNumber(),
- new BigDecimal(-5), deviceDb)) {
- LOG.info("Transponder OCH connection: {} power updated ",
- destTpId + "-" + input.getWaveNumber());
+ String interfaceName = destTpId + "-" + input.getWaveNumber();
+ if (setTransponderPower(nodeId, interfaceName, new BigDecimal(-5))) {
+ LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
try {
- Thread.sleep(180000);
+ Thread.sleep(120000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
- LOG.info("Transponder warmup failed for OCH connection: {}",
- destTpId + "-" + input.getWaveNumber(), e);
+ LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
}
} else {
- LOG.info("Transponder OCH connection: {} power update failed ",
- destTpId + "-" + input.getWaveNumber());
+ LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
}
}
} else {
} else {
LOG.info("{} is a drop node. Net power settings needed", nodeId);
}
- } else if (inputNode.getNodeType() != null && inputNode.getNodeType().equals(NodeTypes.Rdm)) {
- // If Degree is transmitting end then set power
+ } else if (inputNodeOptional.isPresent()
+ && inputNodeOptional.get().getNodeType() != null
+ && inputNodeOptional.get().getNodeType().equals(NodeTypes.Rdm)) {
+ // If Degree is transmitting end then set power
+ Nodes inputNode = inputNodeOptional.get();
+ LOG.info("This is a roadm device ");
+ String connectionNumber = srcTpId + "-" + destTpId + "-" + input.getWaveNumber();
+ LOG.info("Connection number is {}", connectionNumber);
if (destTpId.toLowerCase().contains("deg")) {
- java.util.Optional<Mapping> mappingObject = inputNode.getMapping().stream().filter(o -> o.getKey()
+ Optional<Mapping> mappingObjectOptional = inputNode.getMapping().stream().filter(o -> o.getKey()
.equals(new MappingKey(destTpId))).findFirst();
- Mapping portMapping = mappingObject.get();
- if (portMapping != null && deviceDb != null) {
- BigDecimal spanLossTx = new OpenRoadmInterfaces(db, mps, nodeId, destTpId)
- .getInterface(portMapping.getSupportingOts()).getAugmentation(Interface1.class).getOts()
- .getSpanLossTransmit().getValue();
- Double powerValue = Math.min(spanLossTx.doubleValue() - 9 , 2);
- CrossConnect roadmCrossConnect = new CrossConnect(deviceDb, srcTpId
- + "-" + destTpId + "-" + input.getWaveNumber());
+ if (mappingObjectOptional.isPresent()) {
+ LOG.info("Dest point is Degree {}", mappingObjectOptional.get());
+ Mapping portMapping = mappingObjectOptional.get();
+ Optional<Interface> interfaceOpt;
try {
- Boolean setXconnPowerSuccessVal = roadmCrossConnect.setPowerLevel(OpticalControlMode.Power,
- new PowerDBm(BigDecimal.valueOf(powerValue)));
- if (setXconnPowerSuccessVal) {
- LOG.info("Roadm-connection: {} updated ");
- //TODO - commented code because one vendor is not supporting
- //GainLoss with target-output-power
- Thread.sleep(20000);
- roadmCrossConnect.setPowerLevel(OpticalControlMode.GainLoss,
- new PowerDBm(BigDecimal.valueOf(powerValue)));
- } else {
- LOG.info("Set Power failed for Roadm-connection: {} on Node: {}",
- srcTpId + "-" + destTpId + "-" + input.getWaveNumber(), nodeId);
+ interfaceOpt = openRoadmInterfaces.getInterface(nodeId, portMapping.getSupportingOts());
+ } catch (OpenRoadmInterfaceException ex) {
+ LOG.error("Failed to get interface {} from node {}!", portMapping.getSupportingOts(),
+ nodeId, ex);
+ return false;
+ }
+ if (interfaceOpt.isPresent()) {
+ BigDecimal spanLossTx = interfaceOpt.get().getAugmentation(Interface1.class).getOts()
+ .getSpanLossTransmit().getValue();
+ LOG.info("Spanloss TX is {}", spanLossTx);
+ BigDecimal powerValue = BigDecimal.valueOf(Math.min(spanLossTx.doubleValue() - 9, 2));
+ LOG.info("Power Value is {}", powerValue);
+ try {
+ Boolean setXconnPowerSuccessVal = setPowerLevel(nodeId,
+ OpticalControlMode.Power, powerValue, connectionNumber);
+ LOG.info("Success Value is {}", setXconnPowerSuccessVal);
+ if (setXconnPowerSuccessVal) {
+ LOG.info("Roadm-connection: {} updated ");
+ //TODO - commented code because one vendor is not supporting
+ //GainLoss with target-output-power
+ Thread.sleep(20000);
+ setPowerLevel(nodeId, OpticalControlMode.GainLoss, powerValue,
+ connectionNumber);
+ } else {
+ LOG.info("Set Power failed for Roadm-connection: {} on Node: {}", connectionNumber,
+ nodeId);
+ return false;
+ }
+ } catch (InterruptedException e) {
+ LOG.error("Olm-setPower wait failed {}", e);
return false;
}
- } catch (InterruptedException e) {
- LOG.error("Olm-setPower wait failed {}",e);
+ } else {
+ LOG.error("Interface {} on node {} is not present!", portMapping.getSupportingOts(),
+ nodeId);
return false;
}
}
// If Drop node leave node is power mode
} else if (destTpId.toLowerCase().contains("srg")) {
LOG.info("Setting power at drop node");
- CrossConnect roadmDropCrossConnect = new CrossConnect(deviceDb, srcTpId + "-"
- + destTpId + "-" + input.getWaveNumber());
- roadmDropCrossConnect.setPowerLevel(OpticalControlMode.Power, null);
+ setPowerLevel(nodeId, OpticalControlMode.Power, null, connectionNumber);
}
}
}
*/
public Boolean powerTurnDown(ServicePowerTurndownInput input) {
LOG.info("Olm-powerTurnDown initiated");
- /**Starting with last element into the list Z -> A for
- turning down A -> Z **/
+ /*Starting with last element into the list Z -> A for
+ turning down A -> Z */
for (int i = input.getNodes().size() - 1; i >= 0; i--) {
String nodeId = input.getNodes().get(i).getNodeId();
String srcTpId = input.getNodes().get(i).getSrcTp();
String destTpId = input.getNodes().get(i).getDestTp();
Long wlNumber = input.getWaveNumber();
- DataBroker deviceDb = getDeviceDataBroker(nodeId , mps);
- if (!setInterfaceOutOfService(nodeId, srcTpId,
- srcTpId + "-" + wlNumber, deviceDb)) {
- LOG.warn("Out of service status update failed for interface {} ",
- srcTpId + "-" + wlNumber);
- return false;
- }
- if (!setInterfaceOutOfService(nodeId, destTpId,
- destTpId + "-" + wlNumber, deviceDb)) {
- LOG.warn("Out of service status update failed for interface {} ",
- destTpId + "-" + wlNumber);
- return false;
- }
- CrossConnect roadmCrossConnect = new CrossConnect(deviceDb, srcTpId
- + "-" + destTpId + "-" + wlNumber);
+ String srcInterfaceName = srcTpId + "-" + wlNumber;
+ //if (!setInterfaceOutOfService(nodeId, srcTpId, srcInterfaceName, deviceDb)) {
+ // LOG.warn("Out of service status update failed for interface {} ", srcInterfaceName);
+ // return false;
+ //}
+ String destInterfaceName = destTpId + "-" + wlNumber;
+ //if (!setInterfaceOutOfService(nodeId, destTpId, destInterfaceName, deviceDb)) {
+ // LOG.warn("Out of service status update failed for interface {} ", destInterfaceName);
+ // return false;
+ //}
+ String connectionNumber = srcTpId + "-" + destTpId + "-" + wlNumber;
if (destTpId.toLowerCase().contains("srg")) {
- roadmCrossConnect.setPowerLevel(OpticalControlMode.Off, null);
+ setPowerLevel(nodeId, OpticalControlMode.Off, null, connectionNumber);
} else if (destTpId.toLowerCase().contains("deg")) {
try {
- if (!roadmCrossConnect.setPowerLevel(OpticalControlMode.Power,
- new PowerDBm(new BigDecimal(-60)))) {
- LOG.warn("Power down failed for Roadm-connection: {}", srcTpId
- + "-" + destTpId + "-" + wlNumber);
+ if (!setPowerLevel(nodeId, OpticalControlMode.Power, new BigDecimal(-60),
+ connectionNumber)) {
+ LOG.warn("Power down failed for Roadm-connection: {}", connectionNumber);
return false;
}
Thread.sleep(20000);
- if (!roadmCrossConnect.setPowerLevel(OpticalControlMode.Off,
- null)) {
- LOG.warn("Setting power-control mode off failed for Roadm-connection: {}",
- srcTpId + "-" + destTpId + "-" + wlNumber);
+ if (!setPowerLevel(nodeId, OpticalControlMode.Off, null, connectionNumber)) {
+ LOG.warn("Setting power-control mode off failed for Roadm-connection: {}", connectionNumber);
return false;
}
} catch (InterruptedException e) {
* Termination point of mounted netconf - node
* @param interfaceName
* Name of interface which needs status update
- * @param deviceDb
- * Reference to device data broker
* @return true/false based on status of operation
*/
- public Boolean setInterfaceOutOfService(String nodeId, String tpId,
- String interfaceName, DataBroker deviceDb) {
+ private Boolean setInterfaceOutOfService(String nodeId, String tpId, String interfaceName) {
InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier
.create(OrgOpenroadmDevice.class)
.child(Interface.class, new InterfaceKey(interfaceName));
- Interface nodeInterface = new OpenRoadmInterfaces(db, mps, nodeId, tpId)
- .getInterface(interfaceName);
- InterfaceBuilder intfBuilder = new InterfaceBuilder(nodeInterface);
- intfBuilder.setAdministrativeState(AdminStates.OutOfService);
- final WriteTransaction writeTransaction = deviceDb.newWriteOnlyTransaction();
- writeTransaction.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, intfBuilder.build());
- final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
+ Optional<Interface> nodeInterfaceOpt;
try {
- submit.checkedGet();
- LOG.info("Successfully posted interface {}" , interfaceName);
- return true;
- } catch (TransactionCommitFailedException ex) {
- LOG.warn("Failed to post {} ", interfaceName ,ex);
+ nodeInterfaceOpt = openRoadmInterfaces.getInterface(nodeId, interfaceName);
+ } catch (OpenRoadmInterfaceException ex) {
+ LOG.error("Failed to get interface {} from node {}!", interfaceName, nodeId, ex);
return false;
}
- }
-
- /**
- * This static method returns the DataBroker for a netconf node.
- *
- * @param nodeId
- * Unique identifier for the mounted netconf- node
- * @param mps
- * Reference to mount service
- * @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;
- }
- }
-
- /**
- * This static method returns the Mountpoint for a netconf node.
- *
- * @param nodeId
- * Unique identifier for the mounted netconf- node
- * @param mps
- * Reference to mount service
- * @return MountPoint for the given device
- */
- public static MountPoint getDeviceMountPoint(String nodeId, MountPointService mps) {
- final Optional<MountPoint> netconfNodeOptional = mps.getMountPoint(NETCONF_TOPO_IID
- .child(Node.class, new NodeKey(new NodeId(nodeId))));
- // Get mount point for specified device
- if (netconfNodeOptional.isPresent()) {
- MountPoint netconfNode = netconfNodeOptional.get();
- return netconfNode;
- } else {
- LOG.info("Mount Point not found for :" + nodeId);
- return null;
- }
-
- }
-
- /**
- * This static method returns the DataBroker for a netconf node.
- *
- * @param nodeId
- * Unique identifier for the mounted netconf- node
- * @param mps
- * Reference to mount service
- * @param db
- * Databroker
- * @return Nodes from portMapping for given nodeId
- */
- public static Nodes getNode(String nodeId, MountPointService mps, DataBroker db) {
- InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class)
- .child(Nodes.class, new NodesKey(nodeId));
- ReadOnlyTransaction readTransaction = db.newReadOnlyTransaction();
- Optional<Nodes> nodeObject;
- try {
- nodeObject = readTransaction.read(LogicalDatastoreType.CONFIGURATION, nodesIID).get();
- if (nodeObject.isPresent()) {
- LOG.info("Found Node in Portmapping for nodeId {}", nodeObject.get().getNodeId());
- return nodeObject.get();
- } else {
- LOG.info("Could not find Portmapping for nodeId {}", nodeId);
- return null;
+ if (nodeInterfaceOpt.isPresent()) {
+ InterfaceBuilder intfBuilder = new InterfaceBuilder(nodeInterfaceOpt.get());
+ intfBuilder.setAdministrativeState(AdminStates.OutOfService);
+ Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(nodeId);
+ DeviceTransaction deviceTx;
+ try {
+ Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
+ if (deviceTxOpt.isPresent()) {
+ deviceTx = deviceTxOpt.get();
+ } else {
+ LOG.error("Transaction for device {} was not found!", nodeId);
+ return false;
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Unable to get transaction for device {}!", nodeId, e);
+ return false;
}
- } catch (InterruptedException | ExecutionException ex) {
- LOG.info("Unable to read Portmapping for nodeId {}", nodeId, ex);
+ deviceTx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, intfBuilder.build());
+ ListenableFuture<Void> submit = deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT,
+ Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
+ try {
+ submit.get();
+ LOG.info("Successfully posted interface {}", interfaceName);
+ return true;
+ } catch (InterruptedException | ExecutionException ex) {
+ LOG.warn("Failed to post {} ", interfaceName, ex);
+ return false;
+ }
+ } else {
+ LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
+ return false;
}
- return null;
}
/**
* This method provides Transponder transmit power range.
*
- * @param nodeId
- * Unique identifier for the mounted netconf- node
* @param circuitPackName
* Transponder circuitPack name
* @param portName
* Transponder port name
- * @param deviceDb
+ * @param deviceId
* Databroker for the given device
* @return HashMap holding Min and Max transmit power for given port
*/
- public Map<String, Double> getXponderPowerRange(String nodeId, String circuitPackName, String portName,
- DataBroker deviceDb) {
- InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
- CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class, new PortsKey(portName));
- ReadOnlyTransaction readTransaction = deviceDb.newReadOnlyTransaction();
- Map<String, Double> powerRangeMap = new HashMap<String, Double>();
- try {
- LOG.info("Fetching logical Connection Point value for port " + portName + " at circuit pack "
- + circuitPackName);
- Optional<Ports> portObject = readTransaction.read(LogicalDatastoreType.OPERATIONAL, portIID).get();
- if (portObject.isPresent()) {
- Ports port = portObject.get();
- if (port.getTransponderPort() != null) {
- powerRangeMap.put("MaxTx", port.getTransponderPort().getPortPowerCapabilityMaxTx()
- .getValue().doubleValue());
- powerRangeMap.put("MinTx", port.getTransponderPort().getPortPowerCapabilityMinTx()
- .getValue().doubleValue());
- } else {
- LOG.warn("Logical Connection Point value missing for " + circuitPackName + " " + port
- .getPortName());
- }
+ private Map<String, Double> getXponderPowerRange(String circuitPackName, String portName, String deviceId) {
+ InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
+ .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
+ .child(Ports.class, new PortsKey(portName));
+ Map<String, Double> powerRangeMap = new HashMap<>();
+ LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}", portName, circuitPackName);
+ Optional<Ports> portObject =
+ deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.OPERATIONAL, portIID,
+ Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
+ if (portObject.isPresent()) {
+ Ports port = portObject.get();
+ if (port.getTransponderPort().getPortPowerCapabilityMaxTx() != null) {
+ powerRangeMap.put("MaxTx", port.getTransponderPort().getPortPowerCapabilityMaxTx().getValue()
+ .doubleValue());
+ powerRangeMap.put("MinTx", port.getTransponderPort().getPortPowerCapabilityMinTx().getValue()
+ .doubleValue());
+ } else {
+ LOG.warn("Logical Connection Point value missing for {} {}", circuitPackName, port.getPortName());
}
- } catch (InterruptedException | ExecutionException ex) {
- LOG.warn("Read failed for Logical Connection Point value missing for " + circuitPackName + " "
- + portName,ex);
- return powerRangeMap;
}
return powerRangeMap;
}
* Unique identifier for the mounted netconf- node
* @param srgId
* SRG Id connected to transponder
- * @param deviceDb
- * Databroker for the given device
* @return HashMap holding Min and Max transmit power for given port
*/
- public Map<String, Double> getSRGRxPowerRange(String nodeId, String srgId, DataBroker deviceDb) {
- Map<String, Double> powerRangeMap = new HashMap<String, Double>();
+ private Map<String, Double> getSRGRxPowerRange(String nodeId, String srgId) {
+ Map<String, Double> powerRangeMap = new HashMap<>();
LOG.info("Coming inside Xpdr power range");
- java.util.Optional<Mapping> mappingSRGObject = getNode(nodeId, mps, db).getMapping()
+ Optional<Mapping> mappingSRGOptional = OlmUtils.getNode(nodeId, db).flatMap(node -> node.getMapping()
.stream().filter(o -> o.getKey()
- .equals(new MappingKey(srgId))).findFirst();
- if (mappingSRGObject.isPresent()) {
+ .equals(new MappingKey(srgId))).findFirst());
+ if (mappingSRGOptional.isPresent()) {
LOG.info("Mapping object exists.");
- String circuitPackName = mappingSRGObject.get().getSupportingCircuitPackName();
- String portName = mappingSRGObject.get().getSupportingPort();
+ String circuitPackName = mappingSRGOptional.get().getSupportingCircuitPackName();
+ String portName = mappingSRGOptional.get().getSupportingPort();
InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
.child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
.child(Ports.class, new PortsKey(portName));
- try {
- LOG.info("Fetching logical Connection Point value for port " + portName + " at circuit pack "
- + circuitPackName + portIID);
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- Optional<Ports> portObject = rtx.read(LogicalDatastoreType.OPERATIONAL, portIID).get();
- if (portObject.isPresent()) {
- Ports port = portObject.get();
- if (port.getRoadmPort() != null) {
- LOG.info("Port found on the node ID");
- powerRangeMap.put("MinRx", port.getRoadmPort()
- .getPortPowerCapabilityMinRx().getValue().doubleValue());
- powerRangeMap.put("MaxRx", port.getRoadmPort()
- .getPortPowerCapabilityMaxRx().getValue().doubleValue());
- return powerRangeMap;
- } else {
- LOG.warn("Roadm ports power value is missing for " + circuitPackName + " " + port
- .getPortName());
- }
+
+ LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}{}", portName,
+ circuitPackName, portIID);
+ Optional<Ports> portObject =
+ deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, portIID,
+ Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
+ if (portObject.isPresent()) {
+ Ports port = portObject.get();
+ if (port.getRoadmPort() != null) {
+ LOG.info("Port found on the node ID");
+ powerRangeMap.put("MinRx", port.getRoadmPort()
+ .getPortPowerCapabilityMinRx().getValue().doubleValue());
+ powerRangeMap.put("MaxRx", port.getRoadmPort()
+ .getPortPowerCapabilityMaxRx().getValue().doubleValue());
+ return powerRangeMap;
} else {
- LOG.info("Port not found");
+ LOG.warn("Roadm ports power value is missing for {} {}", circuitPackName, port.getPortName());
}
- } catch (InterruptedException | ExecutionException ex) {
- LOG.warn("Read failed for Logical Connection Point value missing for " + circuitPackName + " "
- + portName,ex);
+ } else {
+ LOG.info("Port not found");
}
+
} else {
LOG.info("Port mapping not found for nodeId: {} and srgId: {} ",
nodeId, srgId);
*
* @param nodeId
* Unique identifier for the mounted netconf- node
- * @param tpId
- * Termination port for transponder connected to SRG
* @param interfaceName
* OCH interface name carrying WL
* @param txPower
* Calculated transmit power
- * @param deviceDb
- * Databroker for the given device
* @return true/false based on status of operation
*/
- public boolean setTransponderPower(String nodeId, String tpId, String interfaceName, BigDecimal txPower,
- DataBroker deviceDb) {
+ private boolean setTransponderPower(String nodeId, String interfaceName, BigDecimal txPower) {
LOG.info("Setting target-power for transponder nodeId: {} InterfaceName: {}",
nodeId, interfaceName);
- InterfaceBuilder ochInterfaceBuilder = new InterfaceBuilder(
- new OpenRoadmInterfaces(db, mps, nodeId, tpId)
- .getInterface(interfaceName));
- OchBuilder ochBuilder = new OchBuilder(ochInterfaceBuilder
- .getAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.optical
- .channel.interfaces.rev161014.Interface1.class).getOch());
- ochBuilder.setTransmitPower(new PowerDBm(txPower));
- ochInterfaceBuilder.addAugmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.optical
- .channel.interfaces.rev161014.Interface1.class,
- new Interface1Builder().setOch(ochBuilder.build()).build());
- ReadWriteTransaction rwtx = deviceDb.newReadWriteTransaction();
- InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
- .child(Interface.class, new InterfaceKey(interfaceName));
- rwtx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, ochInterfaceBuilder.build());
- CheckedFuture<Void, TransactionCommitFailedException> submit = rwtx.submit();
+ Optional<Interface> interfaceOptional;
try {
- submit.checkedGet();
- LOG.info("Power update is submitted");
- return true;
- } catch (TransactionCommitFailedException e) {
- LOG.info("Setting transponder power failed {}" ,e);
+ interfaceOptional = openRoadmInterfaces.getInterface(nodeId, interfaceName);
+ } catch (OpenRoadmInterfaceException ex) {
+ LOG.error("Failed to get interface {} from node {}!", interfaceName, nodeId, ex);
+ return false;
+ }
+ if (interfaceOptional.isPresent()) {
+ InterfaceBuilder ochInterfaceBuilder =
+ new InterfaceBuilder(interfaceOptional.get());
+ OchBuilder ochBuilder = new OchBuilder(ochInterfaceBuilder.getAugmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014
+ .Interface1.class).getOch());
+ ochBuilder.setTransmitPower(new PowerDBm(txPower));
+ ochInterfaceBuilder.addAugmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014
+ .Interface1.class, new Interface1Builder().setOch(ochBuilder.build()).build());
+
+ Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(nodeId);
+ DeviceTransaction deviceTx;
+ try {
+ Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
+ if (deviceTxOpt.isPresent()) {
+ deviceTx = deviceTxOpt.get();
+ } else {
+ LOG.error("Transaction for device {} was not found!", nodeId);
+ return false;
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Unable to get transaction for device {}!", nodeId, e);
+ return false;
+ }
+
+ InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
+ .child(Interface.class, new InterfaceKey(interfaceName));
+ deviceTx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, ochInterfaceBuilder.build());
+ ListenableFuture<Void> submit = deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT,
+ Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
+ try {
+ submit.get();
+ LOG.info("Power update is submitted");
+ return true;
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Setting transponder power failed {}", e);
+ }
+ } else {
+ LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
+ }
+ 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 deviceId
+ * Device id.
+ * @param mode
+ * Optical control modelcan be off, power or gainLoss.
+ * @param powerValue
+ * Power value in DBm.
+ * @param connectionNumber
+ * Name of the cross connect.
+ * @return true/false based on status of operation.
+ */
+ private boolean setPowerLevel(String deviceId, OpticalControlMode mode, BigDecimal powerValue,
+ String connectionNumber) {
+ Optional<RoadmConnections> rdmConnOpt = crossConnect.getCrossConnect(deviceId, connectionNumber);
+ if (rdmConnOpt.isPresent()) {
+ RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConnOpt.get());
+ rdmConnBldr.setOpticalControlMode(mode);
+ if (powerValue != null) {
+ rdmConnBldr.setTargetOutputPower(new PowerDBm(powerValue));
+ }
+ RoadmConnections newRdmConn = rdmConnBldr.build();
+
+ Future<Optional<DeviceTransaction>> deviceTxFuture =
+ deviceTransactionManager.getDeviceTransaction(deviceId);
+ DeviceTransaction deviceTx;
+ try {
+ Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
+ if (deviceTxOpt.isPresent()) {
+ deviceTx = deviceTxOpt.get();
+ } else {
+ LOG.error("Transaction for device {} was not found!", deviceId);
+ return false;
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Unable to get transaction for device {}!", deviceId, e);
+ return false;
+ }
+
+ // post the cross connect on the device
+ InstanceIdentifier<RoadmConnections> roadmConnIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
+ .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber));
+ deviceTx.put(LogicalDatastoreType.CONFIGURATION, roadmConnIID, newRdmConn);
+ ListenableFuture<Void> submit = deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT,
+ Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
+ try {
+ submit.get();
+ LOG.info("Roadm connection power level successfully set ");
+ return true;
+ } catch (InterruptedException | ExecutionException ex) {
+ LOG.warn("Failed to post {}", newRdmConn, ex);
+ }
+
+ } else {
+ LOG.warn("Roadm-Connection is null in set power level ({})", connectionNumber);
}
return false;
}
-}
\ No newline at end of file
+}
--- /dev/null
+/*
+ * 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.olm.service;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
+
+public interface OlmPowerService {
+
+ /**
+ * This method is the implementation of the 'get-pm' service.
+ *
+ * <p>
+ * 1. get-pm This operation traverse through current PM list and gets PM for
+ * given NodeId and Resource name
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ *
+ * @return Result of the request
+ */
+ GetPmOutput getPm(GetPmInput input);
+
+ /**
+ * This method is the implementation of the 'service-power-setup'.
+ *
+ * <p>
+ * 1. service-power-setup: This operation performs following steps:
+ * Step1: Calculate Spanloss on all links which are part of service.
+ * TODO Step2: Calculate power levels for each Tp-Id
+ * TODO Step3: Post power values on roadm connections
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ * Input will contain nodeId and termination point
+ *
+ * @return Result of the request
+ */
+ ServicePowerSetupOutput servicePowerSetup(ServicePowerSetupInput input);
+
+ /**
+ * This method is the implementation of the 'service-power-trundown'.
+ *
+ * <p>
+ * 1. service-power-turndown: This operation performs following steps:
+ * Step1: For each TP within Node sets interface outofservice .
+ * Step2: For each roam-connection sets power to -60dbm
+ * Step3: Turns power mode off
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ * Input will contain nodeId and termination point
+ *
+ * @return Result of the request
+ */
+ ServicePowerTurndownOutput servicePowerTurndown(ServicePowerTurndownInput input);
+
+ /**
+ * This method calculates Spanloss for all Roadm to Roadm links,
+ * part of active inventory in Network Model or for newly added links
+ * based on input src-type.
+ *
+ * <p>
+ * 1. Calculate-Spanloss-Base: This operation performs following steps:
+ * Step1: Read all Roadm-to-Roadm links from network model or get data for given linkID.
+ * Step2: Retrieve PMs for each end point for OTS interface
+ * Step3: Calculates Spanloss
+ * Step4: Posts calculated spanloss in Device and in network model
+ *
+ * @param input
+ * Input parameter from the olm yang model
+ * Input will contain SourceType and linkId if srcType is Link
+ *
+ * @return Result of the request
+ */
+ CalculateSpanlossBaseOutput calculateSpanlossBase(CalculateSpanlossBaseInput input);
+
+ CalculateSpanlossCurrentOutput calculateSpanlossCurrent(
+ CalculateSpanlossCurrentInput input);
+
+ ServicePowerResetOutput servicePowerReset(ServicePowerResetInput input);
+}
--- /dev/null
+/*
+ * 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.olm.service;
+
+import com.google.common.base.Strings;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.transportpce.common.InstanceIdentifiers;
+import org.opendaylight.transportpce.common.NetworkUtils;
+import org.opendaylight.transportpce.common.Timeouts;
+import org.opendaylight.transportpce.common.device.DeviceTransaction;
+import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
+import org.opendaylight.transportpce.common.mapping.PortMapping;
+import org.opendaylight.transportpce.olm.power.PowerMgmt;
+import org.opendaylight.transportpce.olm.util.OlmUtils;
+import org.opendaylight.transportpce.olm.util.OtsPmHolder;
+import org.opendaylight.transportpce.olm.util.RoadmLinks;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.RatioDB;
+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.network.topology.rev170929.Link1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev170929.OpenroadmLinkType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.Ots;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.OtsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmGranularity;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.get.pm.input.ResourceIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.Network;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NodeId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.Node;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.node.SupportingNode;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Network1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.Link;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements;
+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.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OlmPowerServiceImpl implements OlmPowerService {
+ private static final Logger LOG = LoggerFactory.getLogger(OlmPowerServiceImpl.class);
+ private static final String SUCCESS = "Success";
+ private static final String FAILED = "Failed";
+ private final DataBroker dataBroker;
+ private final PowerMgmt powerMgmt;
+ private final DeviceTransactionManager deviceTransactionManager;
+ private final PortMapping portMapping;
+
+ public OlmPowerServiceImpl(DataBroker dataBroker, PowerMgmt powerMgmt,
+ DeviceTransactionManager deviceTransactionManager, PortMapping portMapping) {
+ this.dataBroker = dataBroker;
+ this.powerMgmt = powerMgmt;
+ this.portMapping = portMapping;
+ this.deviceTransactionManager = deviceTransactionManager;
+ }
+
+ public void init() {
+ LOG.info("init ...");
+ }
+
+ public void close() {
+ LOG.info("close ...");
+ }
+
+
+ @Override
+ public GetPmOutput getPm(GetPmInput pmInput) {
+ GetPmOutputBuilder pmOutputBuilder = OlmUtils.pmFetch(pmInput, deviceTransactionManager);
+ return pmOutputBuilder.build();
+ }
+
+ @Override
+ public ServicePowerSetupOutput servicePowerSetup(ServicePowerSetupInput powerSetupInput) {
+ ServicePowerSetupOutputBuilder powerSetupOutput = new ServicePowerSetupOutputBuilder();
+ boolean successValPowerCalculation = powerMgmt.setPower(powerSetupInput);
+
+ if (successValPowerCalculation) {
+ powerSetupOutput.setResult(SUCCESS);
+ } else {
+ powerSetupOutput.setResult(FAILED);
+ }
+ return powerSetupOutput.build();
+ }
+
+ @Override
+ public ServicePowerTurndownOutput servicePowerTurndown(
+ ServicePowerTurndownInput powerTurndownInput) {
+
+ ServicePowerTurndownOutputBuilder powerTurnDownOutput = new ServicePowerTurndownOutputBuilder();
+ // TODO add flag or return failure instead of string
+ if (powerMgmt.powerTurnDown(powerTurndownInput)) {
+ powerTurnDownOutput.setResult(SUCCESS);
+ } else {
+ powerTurnDownOutput.setResult(FAILED);
+ }
+ return powerTurnDownOutput.build();
+ }
+
+ @Override
+ public CalculateSpanlossBaseOutput calculateSpanlossBase(CalculateSpanlossBaseInput spanlossBaseInput) {
+
+ LOG.info("CalculateSpanlossBase Request received for source type {}", spanlossBaseInput.getSrcType());
+
+ List<Link> networkLinks = getNetworkLinks();
+ if (networkLinks.isEmpty()) {
+ LOG.warn("Failed to get links form {} topology.", NetworkUtils.OVERLAY_NETWORK_ID);
+ return new CalculateSpanlossBaseOutputBuilder().setResult(FAILED).build();
+ }
+
+ if (! CalculateSpanlossBaseInput.SrcType.All.equals(spanlossBaseInput.getSrcType())) {
+ networkLinks = networkLinks.stream()
+ .filter(link -> link.getLinkId().equals(spanlossBaseInput.getLinkId()))
+ .collect(Collectors.toList());
+ }
+
+ List<RoadmLinks> roadmLinks = new ArrayList<>();
+ for (Link link : networkLinks) {
+ Link1 roadmLinkAugmentation = link.getAugmentation(Link1.class);
+ if (roadmLinkAugmentation == null) {
+ LOG.debug("Missing OpenRoadm link augmentation in link {} from {} topology.",
+ link.getLinkId().getValue(), NetworkUtils.OVERLAY_NETWORK_ID);
+ continue;
+ }
+ if (OpenroadmLinkType.ROADMTOROADM.equals(roadmLinkAugmentation.getLinkType())) {
+ // Only calculate spanloss for Roadm-to-Roadm links
+ RoadmLinks roadmLink = new RoadmLinks();
+ roadmLink.setSrcNodeId(link.getSource().getSourceNode().getValue());
+ roadmLink.setSrcTpId(link.getSource().getSourceTp().toString());
+ roadmLink.setDestNodeId(link.getDestination().getDestNode().getValue());
+ roadmLink.setDestTpid(link.getDestination().getDestTp().toString());
+ roadmLinks.add(roadmLink);
+ }
+ }
+
+ if (roadmLinks.isEmpty()) {
+ LOG.warn("Topology {} does not have any Roadm-to-Roadm links.", NetworkUtils.OVERLAY_NETWORK_ID);
+ return new CalculateSpanlossBaseOutputBuilder().setResult(FAILED).build();
+ }
+
+ boolean spanLossResult = getLinkSpanloss(roadmLinks);
+ CalculateSpanlossBaseOutputBuilder spanLossBaseBuilder = new CalculateSpanlossBaseOutputBuilder();
+ if (spanLossResult) {
+ spanLossBaseBuilder.setResult(SUCCESS);
+ return spanLossBaseBuilder.build();
+ } else {
+ LOG.warn("Spanloss calculation failed");
+ spanLossBaseBuilder.setResult(FAILED);
+ return spanLossBaseBuilder.build();
+ }
+
+ }
+
+ @Override
+ public CalculateSpanlossCurrentOutput calculateSpanlossCurrent(CalculateSpanlossCurrentInput input) {
+ LOG.info("calculateSpanlossCurrent Request received for all links in network model.");
+ List<Link> networkLinks = getNetworkLinks();
+ if (networkLinks.isEmpty()) {
+ LOG.warn("Failed to get links form {} topology.", NetworkUtils.OVERLAY_NETWORK_ID);
+ return null;
+ }
+ List<RoadmLinks> roadmLinks = new ArrayList<>();
+ for (Link link : networkLinks) {
+ Link1 roadmLinkAugmentation = link.getAugmentation(Link1.class);
+ if (roadmLinkAugmentation == null) {
+ LOG.debug("Missing OpenRoadm link augmentation in link {} from {} topology.",
+ link.getLinkId().getValue(), NetworkUtils.OVERLAY_NETWORK_ID);
+ continue;
+ }
+ if (OpenroadmLinkType.ROADMTOROADM.equals(roadmLinkAugmentation.getLinkType())) {
+ // Only calculate spanloss for Roadm-to-Roadm links
+ RoadmLinks roadmLink = new RoadmLinks();
+ roadmLink.setSrcNodeId(link.getSource().getSourceNode().toString());
+ roadmLink.setSrcTpId(link.getSource().getSourceTp().toString());
+ roadmLink.setDestNodeId(link.getDestination().getDestNode().toString());
+ roadmLink.setDestTpid(link.getDestination().getDestTp().toString());
+ roadmLinks.add(roadmLink);
+ }
+ }
+
+ if (roadmLinks.isEmpty()) {
+ LOG.warn("Topology {} does not have any Roadm-to-Roadm links.", NetworkUtils.OVERLAY_NETWORK_ID);
+ return null;
+ }
+
+ boolean spanLossResult = getLinkSpanloss(roadmLinks);
+ CalculateSpanlossCurrentOutputBuilder spanLossCurrentBuilder = new CalculateSpanlossCurrentOutputBuilder();
+ if (spanLossResult) {
+ spanLossCurrentBuilder.setResult(SUCCESS);
+ return spanLossCurrentBuilder.build();
+ } else {
+ LOG.error("Spanloss Current calculation failed");
+ spanLossCurrentBuilder.setResult(FAILED);
+ return spanLossCurrentBuilder.build();
+ }
+ }
+
+ @Override
+ public ServicePowerResetOutput servicePowerReset(ServicePowerResetInput input) {
+ // TODO
+ return null;
+ }
+
+ private List<Link> getNetworkLinks() {
+ NetworkKey overlayTopologyKey = new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID));
+
+ InstanceIdentifier<Network1> networkIID = InstanceIdentifier.builder(Network.class, overlayTopologyKey)
+ .augmentation(Network1.class)
+ .build();
+ Optional<Network1> networkOptional;
+ try (ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction()) {
+ //TODO change to constant from Timeouts class when it will be merged.
+ networkOptional = rtx.read(LogicalDatastoreType.CONFIGURATION, networkIID).get(Timeouts.DATASTORE_READ,
+ TimeUnit.MILLISECONDS).toJavaUtil();
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("Read of {} topology failed", NetworkUtils.OVERLAY_NETWORK_ID);
+ return Collections.emptyList();
+ }
+
+ if (! networkOptional.isPresent()) {
+ LOG.warn("Network augmentation with links data is not present in {} topology.",
+ NetworkUtils.OVERLAY_NETWORK_ID);
+ return Collections.emptyList();
+ }
+
+ List<Link> networkLinks = networkOptional.get().getLink();
+ if (networkLinks == null || networkLinks.isEmpty()) {
+ LOG.warn("Links are not present in {} topology.", NetworkUtils.OVERLAY_NETWORK_ID);
+ return Collections.emptyList();
+ }
+ return networkLinks;
+ }
+
+ /**
+ * This method retrieves OTS PM from current PM list by nodeId and TPId: Steps:
+ *
+ * <p>
+ * 1. Get OTS interface name from port mapping by TPId 2. Call getPm RPC to get OTS PM
+ *
+ * <p>
+ *
+ * @param nodeId Node-id of the NE.
+ * @param tpID Termination point Name.
+ * @param pmName PM name which need to be retrieved
+ * @return reference to OtsPmHolder
+ */
+ private OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
+ String realNodeId = getRealNodeId(nodeId);
+ Mapping mapping = portMapping.getMapping(realNodeId, tpID);
+ if (mapping == null) {
+ return null;
+ }
+ GetPmInput getPmInput = new GetPmInputBuilder().setNodeId(realNodeId)
+ .setResourceType(ResourceTypeEnum.Interface).setGranularity(PmGranularity._15min)
+ .setResourceIdentifier(
+ new ResourceIdentifierBuilder().setResourceName(mapping.getSupportingOts()).build())
+ .build();
+ GetPmOutput otsPmOutput = getPm(getPmInput);
+
+ if (otsPmOutput == null) {
+ LOG.info("OTS PM not found for NodeId: {} TP Id:{} PMName:{}", realNodeId, tpID, pmName);
+ return null;
+ }
+ try {
+ for (Measurements measurement : otsPmOutput.getMeasurements()) {
+ if (pmName.equals(measurement.getPmparameterName())) {
+ return new OtsPmHolder(pmName, Double.parseDouble(measurement.getPmparameterValue()),
+ mapping.getSupportingOts());
+ }
+ }
+ } catch (NumberFormatException e) {
+ LOG.warn("Unable to get PM for NodeId: {} TP Id:{} PMName:{}", realNodeId, tpID, pmName, e);
+ }
+ return null;
+ }
+
+ /**
+ * This method Sets Spanloss on A-End and Z-End OTS interface: Steps:
+ *
+ * <p>
+ * 1. Read existing interface details
+ *
+ * <p>
+ * 2. Set spanloss
+ *
+ * @param nodeId nodeId of NE on which spanloss need to be updated
+ * @param interfaceName OTS interface for NE on which spanloss is cacluated
+ * @param spanLoss calculated spanloss value
+ * @param direction for which spanloss is calculated.It can be either Tx or Rx
+ * @return true/false
+ */
+ private boolean setSpanLoss(String nodeId, String interfaceName, BigDecimal spanLoss, String direction) {
+ String realNodeId = getRealNodeId(nodeId);
+ LOG.info("Setting Spanloss in device for {}, InterfaceName: {}", realNodeId, interfaceName);
+ InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
+ .child(Interface.class, new InterfaceKey(interfaceName));
+ com.google.common.base.Optional<Interface> interfaceObject;
+ try {
+ Future<Optional<DeviceTransaction>> deviceTxFuture =
+ deviceTransactionManager.getDeviceTransaction(realNodeId);
+ java.util.Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
+ DeviceTransaction deviceTx;
+ if (deviceTxOpt.isPresent()) {
+ deviceTx = deviceTxOpt.get();
+ } else {
+ LOG.error("Device transaction for device {} was not found!", nodeId);
+ return false;
+ }
+ interfaceObject = deviceTx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
+ BigDecimal initialSpanloss = new BigDecimal(0);
+ RatioDB spanLossRx = new RatioDB(initialSpanloss);
+ RatioDB spanLossTx = new RatioDB(initialSpanloss);
+ if (interfaceObject.isPresent()) {
+ Interface intf = interfaceObject.get();
+ InterfaceBuilder interfaceBuilder = new InterfaceBuilder(intf);
+ OtsBuilder otsBuilder = new OtsBuilder();
+ if (intf.getAugmentation(Interface1.class) != null
+ && intf.getAugmentation(Interface1.class).getOts() != null) {
+ Ots ots = intf.getAugmentation(Interface1.class).getOts();
+ otsBuilder.setFiberType(ots.getFiberType());
+ spanLossRx = ots.getSpanLossReceive();
+ spanLossTx = ots.getSpanLossTransmit();
+ } else {
+ spanLossRx = new RatioDB(spanLoss);
+ spanLossTx = new RatioDB(spanLoss);
+ }
+ Interface1Builder intf1Builder = new Interface1Builder();
+ if (direction.equals("TX")) {
+ otsBuilder.setSpanLossTransmit(new RatioDB(spanLoss));
+ otsBuilder.setSpanLossReceive(spanLossRx);
+ } else {
+ otsBuilder.setSpanLossTransmit(spanLossTx).setSpanLossReceive(new RatioDB(spanLoss));
+ }
+ interfaceBuilder.addAugmentation(Interface1.class, intf1Builder.setOts(otsBuilder.build()).build());
+ deviceTx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, interfaceBuilder.build());
+ ListenableFuture<Void> submit =
+ deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
+ submit.get();
+ LOG.info("Spanloss Value update completed successfully");
+ return true;
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Unable to set spanloss", e);
+ }
+ return false;
+ }
+
+ /**
+ * This method calculates Spanloss by TranmistPower - Receive Power Steps:
+ *
+ * <p>
+ * 1. Read PM measurement
+ *
+ * <p>
+ * 2. Set Spanloss value for interface
+ *
+ * @param roadmLinks reference to list of RoadmLinks
+ * @return true/false
+ */
+ private boolean getLinkSpanloss(List<RoadmLinks> roadmLinks) {
+ LOG.info("Executing GetLinkSpanLoss");
+ BigDecimal spanLoss = new BigDecimal(0);
+ for (int i = 0; i < roadmLinks.size(); i++) {
+
+ OtsPmHolder srcOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getSrcNodeId(),
+ roadmLinks.get(i).getSrcTpId(), "OpticalPowerOutput");
+ OtsPmHolder destOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getDestNodeId(),
+ roadmLinks.get(i).getDestTpid(), "OpticalPowerInput");
+ spanLoss = new BigDecimal(srcOtsPmHoler.getOtsParameterVal() - destOtsPmHoler.getOtsParameterVal())
+ .setScale(0, RoundingMode.HALF_UP);
+ LOG.info("Spanloss Calculated as :" + spanLoss + "=" + srcOtsPmHoler.getOtsParameterVal() + "-"
+ + destOtsPmHoler.getOtsParameterVal());
+ if (spanLoss.doubleValue() < 28 && spanLoss.doubleValue() > 0) {
+ if (!setSpanLoss(roadmLinks.get(i).getSrcNodeId(), srcOtsPmHoler.getOtsInterfaceName(), spanLoss,
+ "TX")) {
+ LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getSrcNodeId());
+ return false;
+ }
+ if (!setSpanLoss(roadmLinks.get(i).getDestNodeId(), destOtsPmHoler.getOtsInterfaceName(), spanLoss,
+ "RX")) {
+ LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getDestNodeId());
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private String getRealNodeId(String mappedNodeId) {
+ KeyedInstanceIdentifier<Node, NodeKey> mappedNodeII =
+ InstanceIdentifiers.OVERLAY_NETWORK_II.child(Node.class, new NodeKey(new NodeId(mappedNodeId)));
+ com.google.common.base.Optional<Node> realNode;
+ try (ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction()) {
+ realNode = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, mappedNodeII).get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error(e.getMessage(), e);
+ throw new IllegalStateException(e);
+ }
+ if (!realNode.isPresent() || realNode.get().getSupportingNode() == null) {
+ throw new IllegalArgumentException(
+ String.format("Could not find node %s, or supporting node is not present", mappedNodeId));
+ }
+ List<SupportingNode> collect = realNode.get().getSupportingNode().stream()
+ .filter(node -> node.getNetworkRef() != null
+ && NetworkUtils.UNDERLAY_NETWORK_ID.equals(node.getNetworkRef().getValue())
+ && node.getNodeRef() != null && !Strings.isNullOrEmpty(node.getNodeRef().getValue()))
+ .collect(Collectors.toList());
+ if (collect.isEmpty() || collect.size() > 1) {
+ throw new IllegalArgumentException(String.format("Invalid support node count [%d] was found for node %s",
+ collect.size(), mappedNodeId));
+ }
+ return collect.iterator().next().getNodeRef().getValue();
+ }
+
+}
+++ /dev/null
-/*
- * 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.olm.spanloss;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.List;
-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.MountPointService;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.transportpce.olm.OlmPowerSetupImpl;
-import org.opendaylight.transportpce.renderer.mapping.PortMapping;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.RatioDB;
-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.optical.transport.interfaces.rev161014.Interface1;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1Builder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.Ots;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.OtsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements;
-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.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SpanLoss {
- private static final Logger LOG = LoggerFactory.getLogger(SpanLoss.class);
- private final DataBroker db;
- private final MountPointService mps;
-
- /**
- * Instantiates a new span loss.
- *
- * @param db
- * the db
- * @param mps
- * the mps
- */
- public SpanLoss(DataBroker db, MountPointService mps) {
- this.db = db;
- this.mps = mps;
- }
-
- /**
- * This method retrieves OTS PM from current PM list by nodeId and TPId:
- * Steps:
- *
- * <p>
- * 1. Get OTS interface name from port mapping by TPId 2. Call getPm RPC to
- * get OTS PM
- *
- * <p>
- *
- * @param nodeId
- * Node-id of the NE.
- * @param tpID
- * Termination point Name.
- * @param pmName
- * PM name which need to be retrieved
- * @return reference to OtsPmHolder
- */
- public OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
- GetPmInputBuilder otsPmInputBuilder = new GetPmInputBuilder();
- new PortMapping(db, mps, nodeId);
- Mapping portMapping = PortMapping.getMapping(nodeId, tpID, db);
- if (portMapping != null) {
- otsPmInputBuilder.setNodeId(nodeId).setResourceType("Interface").setGranularity("15min")
- .setResourceName(portMapping.getSupportingOts());
- Future<RpcResult<GetPmOutput>> otsPmOutput = new OlmPowerSetupImpl(db, mps)
- .getPm(otsPmInputBuilder.build());
- if (otsPmOutput != null) {
- try {
- for (Measurements measurement : otsPmOutput.get().getResult().getMeasurements()) {
- if (measurement.getPmparameterName().equals(pmName)) {
- return new OtsPmHolder(pmName,Double.parseDouble(measurement.getPmparameterValue()),
- portMapping.getSupportingOts());
- }
- }
- } catch (NumberFormatException | InterruptedException | ExecutionException e) {
- LOG.warn("Unable to get PM for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName, e);
- }
- } else {
- LOG.info("OTS PM not found for NodeId: {} TP Id:{} PMName:{}", nodeId, tpID, pmName);
- }
- }
- return null;
- }
-
- /**
- * This method Sets Spanloss on A-End and Z-End OTS interface: Steps:
- *
- * <p>
- * 1. Read existing interface details
- *
- * <p>
- * 2. Set spanloss
- *
- * @param nodeId
- * nodeId of NE on which spanloss need to be updated
- * @param interfaceName
- * OTS interface for NE on which spanloss is cacluated
- * @param spanLoss
- * calculated spanloss value
- * @param direction
- * for which spanloss is calculated.It can be either Tx or Rx
- * @return true/false
- */
- public boolean setSpanLoss(String nodeId, String interfaceName, BigDecimal spanLoss, String direction) {
- LOG.info("Setting Spanloss in device for:" + nodeId + " InterfaceName:" + interfaceName);
- InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
- .child(Interface.class, new InterfaceKey(interfaceName));
- Optional<Interface> interfaceObject;
- try {
- DataBroker deviceDb = PortMapping.getDeviceDataBroker(nodeId, mps);
- ReadWriteTransaction rwtx = deviceDb.newReadWriteTransaction();
- interfaceObject = rwtx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
- if (interfaceObject.isPresent()) {
- Interface intf = interfaceObject.get();
- InterfaceBuilder interfaceBuilder = new InterfaceBuilder(intf);
- Ots ots = intf.getAugmentation(Interface1.class).getOts();
- Interface1Builder intf1Builder = new Interface1Builder();
- OtsBuilder otsBuilder = new OtsBuilder();
- otsBuilder.setFiberType(ots.getFiberType());
- if (direction.equals("TX")) {
- otsBuilder.setSpanLossTransmit(new RatioDB(spanLoss)).setSpanLossReceive(ots.getSpanLossReceive());
- } else {
- otsBuilder.setSpanLossTransmit(ots.getSpanLossTransmit()).setSpanLossReceive(new RatioDB(spanLoss));
- }
- interfaceBuilder.addAugmentation(Interface1.class, intf1Builder.setOts(otsBuilder.build()).build());
- rwtx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, interfaceBuilder.build());
- CheckedFuture<Void, TransactionCommitFailedException> submit = rwtx.submit();
- submit.checkedGet();
- LOG.info("Spanloss Value update completed successfully");
- return true;
- }
- } catch (InterruptedException | ExecutionException | TransactionCommitFailedException e) {
- LOG.warn("Unable to set spanloss", e);
- }
- return false;
- }
-
- /**
- * This method calculates Spanloss by TranmistPower - Receive Power Steps:
- *
- * <p>
- * 1. Read PM measurement
- *
- * <p>
- * 2. Set Spanloss value for interface
- *
- * @param roadmLinks
- * reference to list of RoadmLinks
- * @return true/false
- */
- public boolean getLinkSpanloss(List<RoadmLinks> roadmLinks) {
- LOG.info("Executing GetLinkSpanLoss");
- BigDecimal spanLoss = new BigDecimal(0);
- for (int i = 0; i < roadmLinks.size(); i++) {
- OtsPmHolder srcOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getSrcNodeId(),
- roadmLinks.get(i).getSrcTpId(), "OpticalPowerOutput");
- OtsPmHolder destOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getDestNodeId(),
- roadmLinks.get(i).getDestTpid(), "OpticalPowerInput");
- spanLoss = new BigDecimal(srcOtsPmHoler.getOtsParameterVal() - destOtsPmHoler.getOtsParameterVal())
- .setScale(0, RoundingMode.HALF_UP);
- LOG.info("Spanloss Calculated as :" + spanLoss + "=" + srcOtsPmHoler.getOtsParameterVal() + "-"
- + destOtsPmHoler.getOtsParameterVal());
- if (spanLoss.doubleValue() < 28 && spanLoss.doubleValue() > 0) {
- if (!setSpanLoss(roadmLinks.get(i).getSrcNodeId(), srcOtsPmHoler.getOtsInterfaceName(), spanLoss,
- "TX")) {
- LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getSrcNodeId());
- return false;
- }
- if (!setSpanLoss(roadmLinks.get(i).getDestNodeId(), destOtsPmHoler.getOtsInterfaceName(), spanLoss,
- "RX")) {
- LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getDestNodeId());
- return false;
- }
- }
- }
- return true;
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.olm.util;
+
+import com.google.common.base.Strings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+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.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.transportpce.common.Timeouts;
+import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.CurrentPmlist;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.current.pm.Measurements;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.currentpmlist.CurrentPm;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmGranularity;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmNamesEnum;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.Resource;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.CircuitPack;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Connection;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Degree;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Interface;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.InternalLink;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.PhysicalLink;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Port;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Service;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Shelf;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Srg;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.get.pm.input.ResourceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.MeasurementsBuilder;
+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.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OlmUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OlmUtils.class);
+ private static long DATABROKER_READ_TIMEOUT_SECONDS = 120;
+ private static final InstanceIdentifier<Topology> NETCONF_TOPO_IID =
+ InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class,
+ new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+
+ /**
+ * This static method returns the port mapping {@link Nodes} for node.
+ *
+ * @param nodeId
+ * Unique identifier for the mounted netconf node
+ * @param db
+ * Databroker used to read data from data store.
+ * @return {@link Nodes } from portMapping for given nodeId
+ */
+ public static Optional<Nodes> getNode(String nodeId, DataBroker db) {
+ InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class)
+ .child(Nodes.class, new NodesKey(nodeId));
+ try (ReadOnlyTransaction readTransaction = db.newReadOnlyTransaction()) {
+ return readTransaction.read(LogicalDatastoreType.CONFIGURATION, nodesIID)
+ .get(DATABROKER_READ_TIMEOUT_SECONDS, TimeUnit.SECONDS).toJavaUtil();
+ } catch (InterruptedException | ExecutionException | TimeoutException ex) {
+ LOG.info("Unable to read Portmapping for nodeId {}", nodeId, ex);
+ return Optional.empty();
+ }
+ }
+
+ /**
+ * This method retrieves list of current PMs for given nodeId,
+ * resourceType, resourceName and Granularity.Currently vendorExtentions
+ * are excluded but can be added back based on requirement
+ *
+ * <p>
+ * 1. pmFetch This operation traverse through current PM list and gets PM for
+ * given NodeId and Resource name
+ *
+ * @param input
+ * Input parameter from the olm yang model get-pm rpc
+ * @param deviceTransactionManager
+ * Device tx manager
+ *
+ * @return Result of the request list of PM readings
+ */
+ public static GetPmOutputBuilder pmFetch(GetPmInput input, DeviceTransactionManager deviceTransactionManager) {
+ LOG.info("Getting PM Data for NodeId: {} ResourceType: {} ResourceName: {}", input.getNodeId(),
+ input.getResourceType(), input.getResourceIdentifier());
+ GetPmOutputBuilder pmOutputBuilder = new GetPmOutputBuilder();
+ InstanceIdentifier<CurrentPmlist> currentPmsIID = InstanceIdentifier.create(CurrentPmlist.class);
+ Optional<CurrentPmlist> currentPmList;
+
+ currentPmList = deviceTransactionManager
+ .getDataFromDevice(input.getNodeId(), LogicalDatastoreType.OPERATIONAL, currentPmsIID,
+ Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
+ if (currentPmList.isPresent()) {
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output
+ .Measurements> measurements = extractWantedMeasurements(currentPmList.get(),
+ input.getResourceType(), input.getResourceIdentifier(), input.getGranularity());
+ if (measurements.isEmpty()) {
+ LOG.error("No Matching PM data found for node: {}, " + "resource type: {}, resource name: {}",
+ input.getNodeId(), input.getResourceType(),
+ getResourceIdentifierAsString(input.getResourceIdentifier()));
+ } else {
+ pmOutputBuilder.setNodeId(input.getNodeId()).setResourceType(input.getResourceType())
+ .setResourceIdentifier(input.getResourceIdentifier()).setGranularity(input.getGranularity())
+ .setMeasurements(measurements);
+ LOG.info("PM Data found successfully for node: {}, resource type: {}, " + "resource name {}",
+ input.getNodeId(), input.getResourceType(),
+ getResourceIdentifierAsString(input.getResourceIdentifier()));
+ }
+
+ } else {
+ LOG.info("Device PM Data for node: {} is not available", input.getNodeId());
+ }
+
+ return pmOutputBuilder;
+ }
+
+ private static String getResourceIdentifierAsString(ResourceIdentifier resourceIdentifier) {
+ if (Strings.isNullOrEmpty(resourceIdentifier.getCircuitPackName())) {
+ return resourceIdentifier.getResourceName();
+ } else {
+ return resourceIdentifier.getResourceName() + ", circuit pack name: "
+ + resourceIdentifier.getCircuitPackName();
+ }
+ }
+
+ private static List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm
+ .output.Measurements> extractWantedMeasurements(CurrentPmlist currentPmList,
+ ResourceTypeEnum wantedResourceType, ResourceIdentifier wantedResourceIdentifier,
+ PmGranularity wantedGranularity) {
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm
+ .output.Measurements> measurements = new ArrayList<>();
+ for (CurrentPm pm : currentPmList.getCurrentPm()) {
+ ResourceTypeEnum currentResourceType = pm.getResource().getResourceType().getType();
+ if (currentResourceType.equals(wantedResourceType)) {
+ Resource currentResource = pm.getResource().getResource().getResource();
+ PmGranularity currentGranularity = pm.getGranularity();
+ boolean isWantedPowerMeasure = isWantedPowerMeasure(currentResource, currentGranularity,
+ wantedResourceType, wantedResourceIdentifier, wantedGranularity);
+ if (isWantedPowerMeasure) {
+ measurements.addAll(extractMeasurements(pm.getMeasurements()));
+ }
+ }
+ }
+ return measurements;
+ }
+
+ private static List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm
+ .output.Measurements> extractMeasurements(List<Measurements> measurementsFromDevice) {
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements>
+ extractedMeasurements = new ArrayList<>();
+ for (Measurements measure : measurementsFromDevice) {
+ MeasurementsBuilder measurement = new MeasurementsBuilder();
+ if (!measure.getMeasurement().getPmParameterName().getType().equals(PmNamesEnum.VendorExtension)) {
+ measurement.setPmparameterName(measure.getMeasurement().getPmParameterName().getType().toString());
+ } else {
+ measurement.setPmparameterName(measure.getMeasurement().getPmParameterName().getExtension());
+ }
+
+ if (measure.getMeasurement().getPmParameterValue().getDecimal64() != null) {
+ measurement.setPmparameterValue(measure.getMeasurement().getPmParameterValue().getDecimal64()
+ .toPlainString());
+ } else if (measure.getMeasurement().getPmParameterValue().getUint64() != null) {
+ measurement.setPmparameterValue(measure.getMeasurement().getPmParameterValue().getUint64().toString());
+ }
+ extractedMeasurements.add(measurement.build());
+ }
+ return extractedMeasurements;
+ }
+
+ private static boolean isWantedPowerMeasure(Resource resource, PmGranularity granularity,
+ ResourceTypeEnum wantedResourceType, ResourceIdentifier wantedResourceIdentifier,
+ PmGranularity wantedGranularity) {
+ boolean identifiersAreEqual = compareResourceIdentifiers(resource, wantedResourceType,
+ wantedResourceIdentifier);
+ return identifiersAreEqual && granularity != null && granularity.equals(wantedGranularity);
+ }
+
+ private static boolean compareResourceIdentifiers(Resource resource, ResourceTypeEnum wantedResourceType,
+ ResourceIdentifier wantedResourceIdentifier) {
+ switch (wantedResourceType) {
+ case CircuitPack:
+ Optional<CircuitPack> circuitPackOptional = tryCastToParticularResource(CircuitPack.class, resource);
+ return circuitPackOptional.flatMap(
+ circuitPack -> Optional.ofNullable(circuitPack.getCircuitPackName()))
+ .map(circuitPackName -> circuitPackName.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case Connection:
+ Optional<Connection> connectionOptional = tryCastToParticularResource(Connection.class, resource);
+ return connectionOptional.flatMap(
+ connection -> Optional.ofNullable(connection.getConnectionNumber()))
+ .map(connectionNumber -> connectionNumber.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case Degree:
+ Optional<Degree> degreeOptional = tryCastToParticularResource(Degree.class, resource);
+ return degreeOptional.flatMap(
+ degree -> Optional.ofNullable(degree.getDegreeNumber()))
+ .flatMap(degreeInteger -> Optional.of(degreeInteger.toString()))
+ .map(degreeNumberAsString ->
+ degreeNumberAsString.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case Interface:
+ Optional<Interface> interfaceOptional = tryCastToParticularResource(Interface.class, resource);
+ return interfaceOptional.flatMap(
+ interfaceResource -> Optional.ofNullable(interfaceResource.getInterfaceName()))
+ .map(interfaceName -> interfaceName.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case InternalLink:
+ Optional<InternalLink> internalLinkOptional = tryCastToParticularResource(InternalLink.class, resource);
+ return internalLinkOptional.flatMap(
+ internalLink -> Optional.ofNullable(internalLink.getInternalLinkName()))
+ .map(internalLinkName -> internalLinkName.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case PhysicalLink:
+ Optional<PhysicalLink> physicalLinkOptional = tryCastToParticularResource(PhysicalLink.class, resource);
+ return physicalLinkOptional.flatMap(
+ physicalLink -> Optional.ofNullable(physicalLink.getPhysicalLinkName()))
+ .map(physicalLinkName -> physicalLinkName.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case Service:
+ Optional<Service> serviceOptional = tryCastToParticularResource(Service.class, resource);
+ return serviceOptional.flatMap(
+ service -> Optional.ofNullable(service.getServiceName()))
+ .map(serviceName -> serviceName.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case Shelf:
+ Optional<Shelf> shelfOptional = tryCastToParticularResource(Shelf.class, resource);
+ return shelfOptional.flatMap(
+ shelf -> Optional.ofNullable(shelf.getShelfName()))
+ .map(shelfName -> shelfName.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case SharedRiskGroup:
+ Optional<Srg> sharedRiskGroupOptional = tryCastToParticularResource(Srg.class, resource);
+ return sharedRiskGroupOptional.flatMap(
+ sharedRiskGroup -> Optional.ofNullable(sharedRiskGroup.getSrgNumber()))
+ .flatMap(sharedRiskGroupNumberInteger -> Optional.of(sharedRiskGroupNumberInteger.toString()))
+ .map(srgNumberAsString -> srgNumberAsString.equals(wantedResourceIdentifier.getResourceName()))
+ .orElse(false);
+ case Port:
+ Optional<Port> portContainerOptional = tryCastToParticularResource(Port.class, resource);
+ return portContainerOptional.flatMap(
+ portContainer -> Optional.ofNullable(portContainer.getPort()))
+ .map(port -> {
+ String portName = port.getPortName();
+ String circuitPackName = port.getCircuitPackName();
+ return portName != null
+ && circuitPackName != null
+ && portName.equals(wantedResourceIdentifier.getResourceName())
+ && circuitPackName.equals(wantedResourceIdentifier.getCircuitPackName());
+ })
+ .orElse(false);
+ default:
+ LOG.warn("Unknown resource type {}", wantedResourceType);
+ return false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T extends Resource> Optional<T> tryCastToParticularResource(Class<T> resourceClass,
+ Resource resource) {
+ if (resource == null) {
+ LOG.warn("Resource is null.");
+ } else if (! resourceClass.isInstance(resource)) {
+ LOG.warn("Resource implement different type than expected. Expected {}, actual {}.",
+ resourceClass.getSimpleName(), resource.getClass().getSimpleName());
+ } else {
+ return Optional.of((T) resource);
+ }
+ return Optional.empty();
+ }
+
+}
* 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.olm.spanloss;
+package org.opendaylight.transportpce.olm.util;
/**
* The Class OtsPmHolder.
--- /dev/null
+/*
+ * 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.olm.util;
+/**
+ * The Class RoadmLinks.
+ */
+public class RoadmLinks {
+
+ /** The src node id. */
+ private String srcNodeId;
+
+ /** The src tp id. */
+ private String srcTpId;
+
+ /** The dest node id. */
+ private String destNodeId;
+
+ /** The dest tpid. */
+ private String destTpid;
+
+ /**
+ * Gets the src node id.
+ *
+ * @return the src node id
+ */
+ public String getSrcNodeId() {
+ return srcNodeId;
+ }
+
+ /**
+ * Sets the src node id.
+ *
+ * @param srcNodeId the new src node id
+ */
+ public void setSrcNodeId(String srcNodeId) {
+ this.srcNodeId = srcNodeId;
+ }
+
+ /**
+ * Gets the src tp id.
+ *
+ * @return the src tp id
+ */
+ public String getSrcTpId() {
+ return srcTpId;
+ }
+
+ /**
+ * Sets the src tp id.
+ *
+ * @param srcTpId the new src tp id
+ */
+ public void setSrcTpId(String srcTpId) {
+ this.srcTpId = srcTpId;
+ }
+
+ /**
+ * Gets the dest node id.
+ *
+ * @return the dest node id
+ */
+ public String getDestNodeId() {
+ return destNodeId;
+ }
+
+ /**
+ * Sets the dest node id.
+ *
+ * @param destNodeId the new dest node id
+ */
+ public void setDestNodeId(String destNodeId) {
+ this.destNodeId = destNodeId;
+ }
+
+ /**
+ * Gets the dest tpid.
+ *
+ * @return the dest tpid
+ */
+ public String getDestTpid() {
+ return destTpid;
+ }
+
+ /**
+ * Sets the dest tpid.
+ *
+ * @param destTpid the new dest tpid
+ */
+ public void setDestTpid(String destTpid) {
+ this.destTpid = destTpid;
+ }
+
+}
and is available at http://www.eclipse.org/legal/epl-v10.html
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
- odl:use-default-for-reference-types="true">
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
<reference id="dataBroker"
- interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
- odl:type="default" />
- <reference id="mountPointService"
- interface="org.opendaylight.controller.md.sal.binding.api.MountPointService" />
+ interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
+ odl:type="default" />
<reference id="rpcProviderRegistry"
- interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" />
- <bean id="provider"
- class="org.opendaylight.transportpce.olm.OlmProvider"
- init-method="init" destroy-method="close">
+ interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" />
+ <reference id="openRoadmInterfaces"
+ interface="org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces" />
+ <reference id="crossConnect"
+ interface="org.opendaylight.transportpce.common.crossconnect.CrossConnect" />
+ <reference id="deviceTransactionManager"
+ interface="org.opendaylight.transportpce.common.device.DeviceTransactionManager" />
+ <reference id="portMapping"
+ interface="org.opendaylight.transportpce.common.mapping.PortMapping" />
+
+ <bean id="olmPowerServiceImpl"
+ class="org.opendaylight.transportpce.olm.service.OlmPowerServiceImpl"
+ init-method="init" destroy-method="close">
+ <argument ref="dataBroker" />
+ <argument ref="powerMgmt" />
+ <argument ref="deviceTransactionManager" />
+ <argument ref="portMapping" />
+ </bean>
+
+ <bean id="powerMgmt" class="org.opendaylight.transportpce.olm.power.PowerMgmt" >
<argument ref="dataBroker" />
- <argument ref="mountPointService" />
+ <argument ref="openRoadmInterfaces" />
+ <argument ref="crossConnect" />
+ <argument ref="deviceTransactionManager" />
+ </bean>
+
+ <bean id="provider"
+ class="org.opendaylight.transportpce.olm.OlmProvider"
+ init-method="init" destroy-method="close">
<argument ref="rpcProviderRegistry" />
+ <argument ref="olmPowerServiceImpl" />
</bean>
+ <service ref="olmPowerServiceImpl"
+ interface="org.opendaylight.transportpce.olm.service.OlmPowerService"/>
+
</blueprint>
--- /dev/null
+/*
+ * 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.olm;
+
+import org.junit.Test;
+
+public class OlmProviderTest {
+ @Test
+ public void init() throws Exception {
+ //TODO implement test
+ }
+
+}
<version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>mdsal-artifacts</artifactId>
+ <version>1.7.3-SNAPSHOT</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.netconf</groupId>
+ <artifactId>netconf-artifacts</artifactId>
+ <version>1.4.3-SNAPSHOT</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
</dependency>
<dependency>
<groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-common</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-network</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-service</artifactId>
+ <artifactId>transportpce-ordmodels-device</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>${project.groupId}.ordmodels</groupId>
- <artifactId>transportpce-ordmodels-device</artifactId>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>transportpce-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<scope>test</scope>
</dependency>
</dependencies>
+
</project>
--- /dev/null
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.Future;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommon;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceDeleteInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.PathDescription;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.Nodes;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.NodesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.NodesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInputBuilder;
+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.ServicePathInputBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class ModelMappingUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ModelMappingUtils.class);
+ private static final String TERMINATION_POINT = "TerminationPoint";
+
+ private ModelMappingUtils() {
+ }
+
+ public static ServicePowerSetupInput createServicePowerSetupInput(List<Nodes> olmList,
+ ServiceImplementationRequestInput input) {
+ ServicePowerSetupInputBuilder olmSetupBldr = new ServicePowerSetupInputBuilder();
+ olmSetupBldr.setNodes(olmList);
+ olmSetupBldr.setWaveNumber(input.getPathDescription().getAToZDirection().getAToZWavelengthNumber());
+ return olmSetupBldr.build();
+ }
+
+ public static ServiceImplementationRequestOutput createServiceImplResponse(String responseCode, String message) {
+ ServiceImplementationRequestOutputBuilder outputBldr = new ServiceImplementationRequestOutputBuilder();
+ outputBldr.setConfigurationResponseCommon(createCommonResponse(responseCode, message));
+ return outputBldr.build();
+ }
+
+ public static ServiceDeleteOutput createServiceDeleteResponse(String responseCode, String message) {
+ ServiceDeleteOutputBuilder outputBldr = new ServiceDeleteOutputBuilder();
+ outputBldr.setConfigurationResponseCommon(createCommonResponse(responseCode, message));
+ return outputBldr.build();
+ }
+
+ public static ConfigurationResponseCommon createCommonResponse(String responseCode, String message) {
+ ConfigurationResponseCommonBuilder cmBldr = new ConfigurationResponseCommonBuilder();
+ cmBldr.setResponseMessage(message);
+ cmBldr.setResponseCode(responseCode);
+ return cmBldr.build();
+ }
+
+ public static Future<RpcResult<ServiceImplementationRequestOutput>>
+ createRpcResponse(ServiceImplementationRequestOutput payload) {
+ return RpcResultBuilder.success(payload).buildFuture();
+ }
+
+ public static ServicePathInputData rendererCreateServiceInputAToZ(String serviceName,
+ PathDescription pathDescription) {
+ ServicePathInputBuilder servicePathInputBuilder = new ServicePathInputBuilder();
+ servicePathInputBuilder.setServiceName(serviceName);
+ NodeLists nodeLists = getNodesListAToZ(pathDescription.getAToZDirection().getAToZ().iterator());
+ servicePathInputBuilder.setServiceName(serviceName);
+ servicePathInputBuilder.setOperation(ServicePathInput.Operation.Create);
+ servicePathInputBuilder.setWaveNumber(new Long(pathDescription.getAToZDirection().getAToZWavelengthNumber()));
+ servicePathInputBuilder.setNodes(nodeLists.getList());
+ return new ServicePathInputData(servicePathInputBuilder.build(), nodeLists);
+ }
+
+ public static ServicePathInputData rendererCreateServiceInputZToA(String serviceName,
+ PathDescription pathDescription) {
+ ServicePathInputBuilder servicePathInputBuilder = new ServicePathInputBuilder();
+ NodeLists nodeLists = getNodesListZtoA(pathDescription.getZToADirection().getZToA().iterator());
+ servicePathInputBuilder.setOperation(ServicePathInput.Operation.Create);
+ servicePathInputBuilder.setServiceName(serviceName);
+ servicePathInputBuilder.setWaveNumber(new Long(pathDescription.getZToADirection().getZToAWavelengthNumber()));
+ servicePathInputBuilder.setNodes(nodeLists.getList());
+ return new ServicePathInputData(servicePathInputBuilder.build(), nodeLists);
+ }
+
+ public static ServicePathInput rendererDeleteServiceInput(String serviceName,
+ ServiceDeleteInput serviceDeleteInput) {
+ ServicePathInputBuilder servicePathInput = new ServicePathInputBuilder();
+ servicePathInput.setServiceName(serviceName);
+ //TODO: finish model-model mapping
+ return servicePathInput.build();
+ }
+
+ public static NodeLists getNodesListZtoA(Iterator<ZToA> iterator) {
+ Map<Integer, NodeIdPair> treeMap = new TreeMap<>();
+ List<Nodes> olmList = new ArrayList<>();
+ List<Nodes> list = new ArrayList<>();
+ String resourceType;
+ TerminationPoint tp;
+ String tpID = "";
+ String nodeID = "";
+ String sortId = "";
+ while (iterator.hasNext()) {
+ ZToA pathDesObj = iterator.next();
+ resourceType = pathDesObj.getResource().getResource().getImplementedInterface().getSimpleName();
+ LOG.info("Inside AtoZ {}", resourceType);
+
+ try {
+ if (TERMINATION_POINT.equals(resourceType)) {
+ tp = (TerminationPoint) pathDesObj.getResource().getResource();
+ LOG.info(" TP is {} {}", tp.getTerminationPointIdentifier().getTpId(),
+ tp.getTerminationPointIdentifier().getNodeId());
+ tpID = tp.getTerminationPointIdentifier().getTpId();
+ nodeID = tp.getTerminationPointIdentifier().getNodeId();
+ sortId = pathDesObj.getId();
+
+ //TODO: do not rely on ID to be in certain format
+ if (tpID.contains("CTP") || tpID.contains("CP")) {
+ continue;
+ }
+ if (!tpID.contains("TTP") && !tpID.contains("PP") && !tpID.contains("NETWORK")
+ && !tpID.contains("CLIENT")) {
+ continue;
+ }
+
+ int[] pos = findTheLongestSubstring(nodeID, tpID);
+ //TODO: do not rely on nodeId to be integer
+ int id = Integer.parseInt(sortId);
+ treeMap.put(id, new NodeIdPair(nodeID.substring(0, pos[0] - 1), tpID));
+ } else if (resourceType.equals("Link")) {
+ LOG.info("The type is link");
+ } else {
+ LOG.info("The type is not indentified: {}", resourceType);
+ }
+ } catch (IllegalArgumentException | SecurityException e) {
+ // TODO Auto-generated catch block
+ LOG.error("Dont find the getResource method", e);
+ }
+ }
+
+ String desID = null;
+ String srcID = null;
+ for (NodeIdPair values : treeMap.values()) {
+ if (srcID == null) {
+ srcID = values.getTpID();
+ } else if (desID == null) {
+ desID = values.getTpID();
+ NodesBuilder nb = new NodesBuilder();
+ nb.setKey(new NodesKey(values.getNodeID()));
+ nb.setDestTp(desID);
+ nb.setSrcTp(srcID);
+ list.add(nb.build());
+
+ NodesBuilder olmNb = new NodesBuilder();
+ olmNb.setNodeId(values.getNodeID());
+ olmNb.setDestTp(desID);
+ olmNb.setSrcTp(srcID);
+ olmList.add(olmNb.build());
+ srcID = null;
+ desID = null;
+ } else {
+ LOG.warn("both, the source and destination id are null!");
+ }
+ }
+ return new NodeLists(olmList, list);
+ }
+
+ public static NodeLists getNodesListAToZ(Iterator<AToZ> iterator) {
+ Map<Integer, NodeIdPair> treeMap = new TreeMap<>();
+ List<Nodes> list = new ArrayList<>();
+ List<Nodes> olmList = new ArrayList<>();
+ String resourceType;
+ TerminationPoint tp;
+ String tpID = "";
+ String nodeID = "";
+ String sortId = "";
+
+ while (iterator.hasNext()) {
+ AToZ pathDesObj = iterator.next();
+ resourceType = pathDesObj.getResource().getResource().getImplementedInterface().getSimpleName();
+ LOG.info("Inside AtoZ {}", resourceType);
+ try {
+ if (TERMINATION_POINT.equals(resourceType)) {
+ tp = (TerminationPoint) pathDesObj.getResource().getResource();
+ LOG.info(" TP is {} {}", tp.getTerminationPointIdentifier().getTpId(),
+ tp.getTerminationPointIdentifier().getNodeId());
+ tpID = tp.getTerminationPointIdentifier().getTpId();
+ nodeID = tp.getTerminationPointIdentifier().getNodeId();
+ sortId = pathDesObj.getId();
+
+ //TODO: do not rely on ID to be in certain format
+ if (tpID.contains("CTP") || tpID.contains("CP")) {
+ continue;
+ }
+ if (!tpID.contains("TTP") && !tpID.contains("PP") && !tpID.contains("NETWORK")
+ && !tpID.contains("CLIENT")) {
+ continue;
+ }
+
+ int[] pos = findTheLongestSubstring(nodeID, tpID);
+ //TODO: do not rely on nodeId to be integer
+ int id = Integer.parseInt(sortId);
+ treeMap.put(id, new NodeIdPair(nodeID.substring(0, pos[0] - 1), tpID));
+ } else if (resourceType.equals("Link")) {
+ LOG.info("The type is link");
+ } else {
+ LOG.info("The type is not indentified: {}", resourceType);
+ }
+ } catch (IllegalArgumentException | SecurityException e) {
+ //TODO: Auto-generated catch block
+ LOG.error("Dont find the getResource method", e);
+ }
+ }
+
+ String desID = null;
+ String srcID = null;
+ for (NodeIdPair values : treeMap.values()) {
+ if (srcID == null) {
+ srcID = values.getTpID();
+ } else if (desID == null) {
+ desID = values.getTpID();
+ NodesBuilder nb = new NodesBuilder();
+ nb.setKey(new NodesKey(values.getNodeID()));
+ nb.setDestTp(desID);
+ nb.setSrcTp(srcID);
+ list.add(nb.build());
+
+ NodesBuilder olmNb = new NodesBuilder();
+ olmNb.setNodeId(values.getNodeID());
+ olmNb.setDestTp(desID);
+ olmNb.setSrcTp(srcID);
+ olmList.add(olmNb.build());
+ srcID = null;
+ desID = null;
+ } else {
+ LOG.warn("both, the source and destination id are null!");
+ }
+ }
+ return new NodeLists(olmList, list);
+ }
+
+ public static int[] findTheLongestSubstring(String s1, String s2) {
+ if (s1 == null || s2 == null) {
+ return null;
+ }
+ int[][] dp = new int[s1.length() + 1][s2.length() + 1];
+ int maxLen = 0;
+ int endPos = 0;
+ for (int i = 1; i < dp.length; i++) {
+ for (int j = 1; j < dp[0].length; j++) {
+ char ch1 = s1.charAt(i - 1);
+ char ch2 = s2.charAt(j - 1);
+ if (ch1 == ch2) {
+ dp[i][j] = dp[i - 1][j - 1] + 1;
+ if (dp[i][j] >= maxLen) {
+ maxLen = dp[i][j];
+ endPos = i;
+ }
+ }
+ }
+ }
+ return new int[] { endPos - maxLen, endPos };
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.PathDescription;
+
+public interface NetworkModelWavelengthService {
+
+ /**
+ * Remove wavelength from available and add it to used wavelength list.
+ *
+ * @param pathDescription
+ * path description containing a-to-z and z-to-a path
+ */
+ void useWavelengths(PathDescription pathDescription);
+
+ /**
+ * Remove wavelength from used and add it to available wavelength list.
+ *
+ * @param pathDescription
+ * path description containing a-to-z and z-to-a path
+ */
+ void freeWavelengths(PathDescription pathDescription);
+
+}
--- /dev/null
+/*
+ * 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;
+
+import com.google.common.base.Optional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.common.NetworkUtils;
+import org.opendaylight.transportpce.common.Timeouts;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.node.attributes.AvailableWavelengthsKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.used.wavelengths.UsedWavelengths;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.used.wavelengths.UsedWavelengthsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.used.wavelengths.UsedWavelengthsKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.TerminationPoint1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.DegreeAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.DegreeAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.SrgAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.SrgAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.CpAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.CpAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.CtpAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.CtpAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.PpAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.PpAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.RxTtpAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.RxTtpAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.TxTtpAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.TxTtpAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrClientAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrClientAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrNetworkAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrNetworkAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrPortAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.XpdrPortAttributesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.pp.attributes.UsedWavelength;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.pp.attributes.UsedWavelengthBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node.termination.point.pp.attributes.UsedWavelengthKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev170929.OpenroadmTpType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes.AvailableWavelengthsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev170929.xpdr.port.connection.attributes.Wavelength;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev170929.xpdr.port.connection.attributes.WavelengthBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.PathDescription;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.termination.point.TerminationPointIdentifier;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.Network;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NodeId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.Node;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.TpId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetworkModelWavelengthServiceImpl implements NetworkModelWavelengthService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NetworkModelWavelengthServiceImpl.class);
+ private final DataBroker dataBroker;
+
+ public NetworkModelWavelengthServiceImpl(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ public void useWavelengths(PathDescription pathDescription) {
+
+ List<NodeIdPair> atozTpIds = getAToZTpList(pathDescription);
+ List<NodeIdPair> ztoaTpIds = getZToATpList(pathDescription);
+
+ deleteAvailableWL(atozTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
+ pathDescription.getAToZDirection().getAToZWavelengthNumber());
+ deleteAvailableWL(ztoaTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
+ pathDescription.getZToADirection().getZToAWavelengthNumber());
+
+ addUsedWL(pathDescription.getAToZDirection().getAToZWavelengthNumber(), atozTpIds);
+ addUsedWL(pathDescription.getZToADirection().getZToAWavelengthNumber(), ztoaTpIds);
+ }
+
+ @Override
+ public void freeWavelengths(PathDescription pathDescription) {
+ List<NodeIdPair> atozTpIds = getAToZTpList(pathDescription);
+ List<NodeIdPair> ztoaTpIds = getZToATpList(pathDescription);
+
+ deleteUsedWL(pathDescription.getAToZDirection().getAToZWavelengthNumber(), atozTpIds);
+ deleteUsedWL(pathDescription.getZToADirection().getZToAWavelengthNumber(), ztoaTpIds);
+
+ addAvailableWL(atozTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
+ pathDescription.getAToZDirection().getAToZWavelengthNumber());
+ addAvailableWL(ztoaTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
+ pathDescription.getZToADirection().getZToAWavelengthNumber());
+ }
+
+ private List<NodeIdPair> getAToZTpList(PathDescription pathDescription) {
+ List<AToZ> atozList = pathDescription.getAToZDirection().getAToZ();
+ return atozList.stream()
+ .filter(aToZ -> {
+ if ((aToZ.getResource() == null) || (aToZ.getResource().getResource() == null)) {
+ LOG.warn("Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
+ return false;
+ }
+ return aToZ.getResource().getResource() instanceof TerminationPoint;
+ }).filter(aToZ -> {
+ TerminationPoint tp = (TerminationPoint) aToZ.getResource().getResource();
+ if ((tp.getTerminationPointIdentifier() == null)
+ || (tp.getTerminationPointIdentifier().getNodeId() == null)
+ || (tp.getTerminationPointIdentifier().getTpId() == null)) {
+ LOG.warn("Termination point in AToZ node {} contains nulls! Skipping this node!", aToZ.getId());
+ return false;
+ }
+ return true;
+ }).map(aToZ -> {
+ TerminationPointIdentifier tp =
+ ((TerminationPoint) aToZ.getResource().getResource()).getTerminationPointIdentifier();
+ return new NodeIdPair(tp.getNodeId(), tp.getTpId());
+ }).collect(Collectors.toList());
+ }
+
+ private List<NodeIdPair> getZToATpList(PathDescription pathDescription) {
+ List<ZToA> ztoaList = pathDescription.getZToADirection().getZToA();
+ return ztoaList.stream()
+ .filter(zToA -> {
+ if ((zToA.getResource() == null) || (zToA.getResource().getResource() == null)) {
+ LOG.warn("Resource of ZToA node {} is null! Skipping this node!", zToA.getId());
+ return false;
+ }
+ return zToA.getResource().getResource() instanceof TerminationPoint;
+ }).filter(zToA -> {
+ TerminationPoint tp = (TerminationPoint) zToA.getResource().getResource();
+ if ((tp.getTerminationPointIdentifier() == null)
+ || (tp.getTerminationPointIdentifier().getNodeId() == null)
+ || (tp.getTerminationPointIdentifier().getTpId() == null)) {
+ LOG.warn("Termination point in ZToA node {} contains nulls! Skipping this node!", zToA.getId());
+ return false;
+ }
+ return true;
+ })
+ .map(zToA -> {
+ TerminationPointIdentifier tp =
+ ((TerminationPoint) zToA.getResource().getResource()).getTerminationPointIdentifier();
+ return new NodeIdPair(tp.getNodeId(), tp.getTpId());
+ }).collect(Collectors.toList());
+ }
+
+ private InstanceIdentifier<Node1> createNode1IID(String nodeId) {
+ return InstanceIdentifier
+ .builder(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608
+ .network.Node.class, new NodeKey(new NodeId(nodeId)))
+ .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929
+ .Node1.class)
+ .build();
+ }
+
+ private Optional<Node1> getNode1FromDatastore(String nodeId) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1>
+ nodeIID = createNode1IID(nodeId);
+ Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1> nodeOpt;
+ try (ReadOnlyTransaction nodeReadTx = this.dataBroker.newReadOnlyTransaction()) {
+ nodeOpt = nodeReadTx.read(LogicalDatastoreType.CONFIGURATION, nodeIID)
+ .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("Exception while getting node from {} topology!", NetworkUtils.OVERLAY_NETWORK_ID, e);
+ nodeOpt = Optional.absent();
+ }
+ return nodeOpt;
+ }
+
+ private void addAvailableWL(List<String> nodeIds, Long wavelengthNumber) {
+ WriteTransaction nodeWriteTx = this.dataBroker.newWriteOnlyTransaction();
+ for (String nodeId : nodeIds) {
+ Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1> nodeOpt =
+ getNode1FromDatastore(nodeId);
+ org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1 node;
+ if (nodeOpt.isPresent()) {
+ node = nodeOpt.get();
+ } else {
+ LOG.error("Unable to get node {} from topology {}! Skipping addition of available wavelength for this"
+ + "node.", nodeId, NetworkUtils.OVERLAY_NETWORK_ID);
+ continue;
+ }
+
+ org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1Builder
+ node1Builder = new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929
+ .Node1Builder(node);
+
+ switch (node.getNodeType()) {
+ case DEGREE:
+ DegreeAttributes degreeAttributes = node.getDegreeAttributes();
+ DegreeAttributesBuilder degreeAttributesBuilder;
+ if (degreeAttributes == null) {
+ degreeAttributesBuilder = new DegreeAttributesBuilder();
+ } else {
+ degreeAttributesBuilder = new DegreeAttributesBuilder(degreeAttributes);
+ }
+ List<org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.node.attributes
+ .AvailableWavelengths> availableDegreeWLs =
+ degreeAttributesBuilder.getAvailableWavelengths();
+ if (availableDegreeWLs == null) {
+ availableDegreeWLs = new ArrayList<>();
+ degreeAttributesBuilder.setAvailableWavelengths(availableDegreeWLs);
+ }
+ availableDegreeWLs.add(new org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree
+ .node.attributes.AvailableWavelengthsBuilder().setIndex(wavelengthNumber).build());
+ node1Builder.setDegreeAttributes(degreeAttributesBuilder.build());
+ break;
+ case SRG:
+ SrgAttributes srgAttributes = node.getSrgAttributes();
+ SrgAttributesBuilder srgAttributesBuilder;
+ if (srgAttributes == null) {
+ srgAttributesBuilder = new SrgAttributesBuilder();
+ } else {
+ srgAttributesBuilder = new SrgAttributesBuilder(srgAttributes);
+ }
+ List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes
+ .AvailableWavelengths> availableSrgWLs = srgAttributesBuilder.getAvailableWavelengths();
+ if (availableSrgWLs == null) {
+ availableSrgWLs = new ArrayList<>();
+ srgAttributesBuilder.setAvailableWavelengths(availableSrgWLs);
+ }
+ availableSrgWLs.add(new AvailableWavelengthsBuilder().setIndex(wavelengthNumber).build());
+ node1Builder.setSrgAttributes(srgAttributesBuilder.build());
+ break;
+
+ default:
+ // TODO skip for now
+ continue;
+ }
+ nodeWriteTx.put(LogicalDatastoreType.CONFIGURATION, createNode1IID(nodeId), node1Builder.build(), true);
+ }
+ try {
+ nodeWriteTx.submit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.error("Unable to add available WL {} for nodes {}!", wavelengthNumber, String.join(", ", nodeIds), e);
+ }
+ }
+
+ private void deleteAvailableWL(List<String> nodeIds, Long wavelengthNumber) {
+ WriteTransaction nodeWriteTx = this.dataBroker.newWriteOnlyTransaction();
+ for (String nodeId : nodeIds) {
+ Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1> nodeOpt =
+ getNode1FromDatastore(nodeId);
+ org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Node1 node;
+ if (nodeOpt.isPresent()) {
+ node = nodeOpt.get();
+ } else {
+ LOG.error("Unable to get node {} from topology {}! Skipping addition of available wavelength for this"
+ + "node.", nodeId, NetworkUtils.OVERLAY_NETWORK_ID);
+ continue;
+ }
+
+ InstanceIdentifierBuilder<Node1> nodeIIDBuilder = InstanceIdentifier
+ .builder(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
+ .child(Node.class, new NodeKey(new NodeId(nodeId))).augmentation(Node1.class);
+ InstanceIdentifier availableWlIID;
+
+ switch (node.getNodeType()) {
+ case DEGREE:
+ availableWlIID = nodeIIDBuilder.child(DegreeAttributes.class)
+ .child(org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev170929.degree.node
+ .attributes.AvailableWavelengths.class,
+ new AvailableWavelengthsKey(wavelengthNumber))
+ .build();
+ break;
+ case SRG:
+ availableWlIID = nodeIIDBuilder.child(SrgAttributes.class)
+ .child(org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node.attributes
+ .AvailableWavelengths.class,
+ new org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev170929.srg.node
+ .attributes.AvailableWavelengthsKey(wavelengthNumber))
+ .build();
+ break;
+
+ default:
+ // TODO skip for now
+ continue;
+ }
+ nodeWriteTx.delete(LogicalDatastoreType.CONFIGURATION, availableWlIID);
+ }
+ try {
+ nodeWriteTx.submit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.error("Unable to delete available WL {} for nodes {}!", wavelengthNumber, String.join(", ", nodeIds),
+ e);
+ }
+ }
+
+ private InstanceIdentifierBuilder<TerminationPoint1> createTerminationPoint1IIDBuilder(String nodeId, String tpId) {
+ return InstanceIdentifier
+ .builder(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network
+ .Node.class, new NodeKey(new NodeId(nodeId))).augmentation(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Node1.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608
+ .network.node.TerminationPoint.class,
+ new TerminationPointKey(new TpId(tpId))).augmentation(TerminationPoint1.class);
+ }
+
+ private Optional<TerminationPoint1> getTerminationPoint1FromDatastore(String nodeId, String tpId) {
+ InstanceIdentifier<TerminationPoint1> tpIID = createTerminationPoint1IIDBuilder(nodeId, tpId).build();
+ Optional<TerminationPoint1> tpOpt;
+ try (ReadOnlyTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
+ tpOpt = readTx.read(LogicalDatastoreType.CONFIGURATION, tpIID)
+ .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("Exception while getting termination point from {} topology!", NetworkUtils.OVERLAY_NETWORK_ID,
+ e);
+ tpOpt = Optional.absent();
+ }
+ return tpOpt;
+ }
+
+ private void deleteUsedWL(long wavelengthIndex, List<NodeIdPair> tpIds) {
+ WriteTransaction deleteUsedWlTx = this.dataBroker.newWriteOnlyTransaction();
+ for (NodeIdPair idPair : tpIds) {
+ Optional<TerminationPoint1> tpOpt = getTerminationPoint1FromDatastore(idPair.getNodeID(), idPair.getTpID());
+
+ OpenroadmTpType tpType;
+ if (tpOpt.isPresent()) {
+ tpType = tpOpt.get().getTpType();
+ } else {
+ LOG.error("Unable to get termination point {} from topology {}! Skipping removal of used wavelength"
+ + " for this node.", idPair.getTpID(), NetworkUtils.OVERLAY_NETWORK_ID);
+ continue;
+ }
+ InstanceIdentifier.InstanceIdentifierBuilder<TerminationPoint1> usedWlIIDBuilder =
+ createTerminationPoint1IIDBuilder(idPair.getNodeID(), idPair.getTpID());
+ InstanceIdentifier usedWlIID;
+ switch (tpType) {
+ case DEGREETXTTP:
+ case DEGREETXRXTTP:
+ usedWlIID = usedWlIIDBuilder.child(TxTtpAttributes.class).child(UsedWavelengths.class,
+ new UsedWavelengthsKey(wavelengthIndex)).build();
+ break;
+
+ case DEGREERXTTP:
+ usedWlIID = usedWlIIDBuilder.child(RxTtpAttributes.class).child(UsedWavelengths.class,
+ new UsedWavelengthsKey(wavelengthIndex)).build();
+ break;
+
+ case DEGREETXCTP:
+ case DEGREERXCTP:
+ case DEGREETXRXCTP:
+ usedWlIID = usedWlIIDBuilder.child(CtpAttributes.class).child(UsedWavelengths.class,
+ new UsedWavelengthsKey(wavelengthIndex)).build();
+ break;
+
+ case SRGTXCP:
+ case SRGRXCP:
+ case SRGTXRXCP:
+ usedWlIID = usedWlIIDBuilder.child(CpAttributes.class).child(org.opendaylight.yang.gen.v1.http.org
+ .openroadm.network.topology.rev170929.network.node.termination.point.cp.attributes
+ .UsedWavelengths.class,
+ new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node
+ .termination.point.cp.attributes.UsedWavelengthsKey(
+ wavelengthIndex)).build();
+ break;
+
+ case SRGTXRXPP:
+ case SRGRXPP:
+ case SRGTXPP:
+ usedWlIID = usedWlIIDBuilder.child(PpAttributes.class).child(UsedWavelength.class,
+ new UsedWavelengthKey(wavelengthIndex)).build();
+ break;
+
+ case XPONDERNETWORK:
+ usedWlIID = usedWlIIDBuilder.child(XpdrNetworkAttributes.class).child(Wavelength.class).build();
+ break;
+ case XPONDERCLIENT:
+ usedWlIID = usedWlIIDBuilder.child(XpdrClientAttributes.class).child(Wavelength.class).build();
+ break;
+ case XPONDERPORT:
+ usedWlIID = usedWlIIDBuilder.child(XpdrPortAttributes.class).child(Wavelength.class).build();
+ break;
+
+ default:
+ // TODO skip for now
+ continue;
+ }
+ deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION, usedWlIID);
+ }
+ try {
+ deleteUsedWlTx.submit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ List<String> tpIdsString = tpIds.stream().map(NodeIdPair::toString).collect(Collectors.toList());
+ LOG.error("Unable to delete used WL {} from TPs {}!", wavelengthIndex, String.join(", ", tpIdsString), e);
+ }
+ }
+
+ private void addUsedWL(long wavelengthIndex, List<NodeIdPair> tpIds) {
+ WriteTransaction addUsedWlTx = this.dataBroker.newWriteOnlyTransaction();
+ for (NodeIdPair idPair : tpIds) {
+ Optional<TerminationPoint1> tpOpt = getTerminationPoint1FromDatastore(idPair.getNodeID(), idPair.getTpID());
+
+ TerminationPoint1 tp;
+ if (tpOpt.isPresent()) {
+ tp = tpOpt.get();
+ } else {
+ LOG.error("Unable to get termination point {} from topology {}! Skipping removal of used wavelength"
+ + " for this node.", idPair.getTpID(), NetworkUtils.OVERLAY_NETWORK_ID);
+ continue;
+ }
+
+ TerminationPoint1Builder tp1Builder = new TerminationPoint1Builder(tp);
+
+ switch (tp.getTpType()) {
+ case DEGREETXTTP:
+ case DEGREETXRXTTP:
+ TxTtpAttributes txTtpAttributes = tp.getTxTtpAttributes();
+ TxTtpAttributesBuilder txTtpAttributesBuilder;
+ if (txTtpAttributes == null) {
+ txTtpAttributesBuilder = new TxTtpAttributesBuilder();
+ } else {
+ txTtpAttributesBuilder = new TxTtpAttributesBuilder(txTtpAttributes);
+ }
+ List<UsedWavelengths> usedDegreeTxTtpWls = txTtpAttributesBuilder.getUsedWavelengths();
+ if (usedDegreeTxTtpWls == null) {
+ usedDegreeTxTtpWls = new ArrayList<>();
+ txTtpAttributesBuilder.setUsedWavelengths(usedDegreeTxTtpWls);
+ }
+ usedDegreeTxTtpWls.add(new UsedWavelengthsBuilder().setIndex(wavelengthIndex).build());
+ tp1Builder.setTxTtpAttributes(txTtpAttributesBuilder.build());
+ break;
+
+ case DEGREERXTTP:
+ RxTtpAttributes rxTtpAttributes = tp.getRxTtpAttributes();
+ RxTtpAttributesBuilder rxTtpAttributesBuilder;
+ if (rxTtpAttributes == null) {
+ rxTtpAttributesBuilder = new RxTtpAttributesBuilder();
+ } else {
+ rxTtpAttributesBuilder = new RxTtpAttributesBuilder(rxTtpAttributes);
+ }
+ List<UsedWavelengths> usedDegreeRxTtpWls = rxTtpAttributesBuilder.getUsedWavelengths();
+ if (usedDegreeRxTtpWls == null) {
+ usedDegreeRxTtpWls = new ArrayList<>();
+ rxTtpAttributesBuilder.setUsedWavelengths(usedDegreeRxTtpWls);
+ }
+ usedDegreeRxTtpWls.add(new UsedWavelengthsBuilder().setIndex(wavelengthIndex).build());
+ tp1Builder.setRxTtpAttributes(rxTtpAttributesBuilder.build());
+ break;
+
+ case DEGREETXCTP:
+ case DEGREERXCTP:
+ case DEGREETXRXCTP:
+ CtpAttributes ctpAttributes = tp.getCtpAttributes();
+ CtpAttributesBuilder ctpAttributesBuilder;
+ if (ctpAttributes == null) {
+ ctpAttributesBuilder = new CtpAttributesBuilder();
+ } else {
+ ctpAttributesBuilder = new CtpAttributesBuilder(ctpAttributes);
+ }
+ List<UsedWavelengths> usedDegreeCtpWls = ctpAttributesBuilder.getUsedWavelengths();
+ if (usedDegreeCtpWls == null) {
+ usedDegreeCtpWls = new ArrayList<>();
+ ctpAttributesBuilder.setUsedWavelengths(usedDegreeCtpWls);
+ }
+ usedDegreeCtpWls.add(new UsedWavelengthsBuilder().setIndex(wavelengthIndex).build());
+ tp1Builder.setCtpAttributes(ctpAttributesBuilder.build());
+ break;
+
+ case SRGTXCP:
+ case SRGRXCP:
+ case SRGTXRXCP:
+ CpAttributes cpAttributes = tp.getCpAttributes();
+ CpAttributesBuilder cpAttributesBuilder;
+ if (cpAttributes == null) {
+ cpAttributesBuilder = new CpAttributesBuilder();
+ } else {
+ cpAttributesBuilder = new CpAttributesBuilder(cpAttributes);
+ }
+ List<org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.network.node
+ .termination.point.cp.attributes.UsedWavelengths> usedDegreeCpWls =
+ cpAttributesBuilder.getUsedWavelengths();
+ if (usedDegreeCpWls == null) {
+ usedDegreeCpWls = new ArrayList<>();
+ cpAttributesBuilder.setUsedWavelengths(usedDegreeCpWls);
+ }
+ usedDegreeCpWls.add(new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929
+ .network.node.termination.point.cp.attributes.UsedWavelengthsBuilder()
+ .setIndex(wavelengthIndex).build());
+ tp1Builder.setCpAttributes(cpAttributesBuilder.build());
+ break;
+
+ case SRGTXRXPP:
+ case SRGRXPP:
+ case SRGTXPP:
+ PpAttributes ppAttributes = tp.getPpAttributes();
+ PpAttributesBuilder ppAttributesBuilder;
+ if (ppAttributes == null) {
+ ppAttributesBuilder = new PpAttributesBuilder();
+ } else {
+ ppAttributesBuilder = new PpAttributesBuilder(ppAttributes);
+ }
+ List<UsedWavelength> usedDegreePpWls = ppAttributesBuilder.getUsedWavelength();
+ if (usedDegreePpWls == null) {
+ usedDegreePpWls = new ArrayList<>();
+ ppAttributesBuilder.setUsedWavelength(usedDegreePpWls);
+ }
+ usedDegreePpWls.add(new UsedWavelengthBuilder().setIndex(wavelengthIndex).build());
+ tp1Builder.setPpAttributes(ppAttributesBuilder.build());
+ break;
+
+ case XPONDERNETWORK:
+ XpdrNetworkAttributes xpdrNetworkAttributes = tp.getXpdrNetworkAttributes();
+ XpdrNetworkAttributesBuilder xpdrNetworkAttributesBuilder;
+ if (xpdrNetworkAttributes == null) {
+ xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder();
+ } else {
+ xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder(xpdrNetworkAttributes);
+ }
+ Wavelength usedXpdrNetworkWl = new WavelengthBuilder().setIndex(wavelengthIndex).build();
+ tp1Builder.setXpdrNetworkAttributes(xpdrNetworkAttributesBuilder
+ .setWavelength(usedXpdrNetworkWl)
+ .build());
+ break;
+ case XPONDERCLIENT:
+ XpdrClientAttributes xpdrClientAttributes = tp.getXpdrClientAttributes();
+ XpdrClientAttributesBuilder xpdrClientAttributesBuilder;
+ if (xpdrClientAttributes == null) {
+ xpdrClientAttributesBuilder = new XpdrClientAttributesBuilder();
+ } else {
+ xpdrClientAttributesBuilder = new XpdrClientAttributesBuilder(xpdrClientAttributes);
+ }
+ Wavelength usedXpdrClientWl = new WavelengthBuilder().setIndex(wavelengthIndex).build();
+ tp1Builder.setXpdrClientAttributes(xpdrClientAttributesBuilder
+ .setWavelength(usedXpdrClientWl)
+ .build());
+ break;
+ case XPONDERPORT:
+ XpdrPortAttributes xpdrPortAttributes = tp.getXpdrPortAttributes();
+ XpdrPortAttributesBuilder xpdrPortAttributesBuilder;
+ if (xpdrPortAttributes == null) {
+ xpdrPortAttributesBuilder = new XpdrPortAttributesBuilder();
+ } else {
+ xpdrPortAttributesBuilder = new XpdrPortAttributesBuilder(xpdrPortAttributes);
+ }
+ Wavelength usedXpdrPortWl = new WavelengthBuilder().setIndex(wavelengthIndex).build();
+ tp1Builder.setXpdrPortAttributes(xpdrPortAttributesBuilder
+ .setWavelength(usedXpdrPortWl)
+ .build());
+ break;
+
+ default:
+ // TODO skip for now
+ continue;
+ }
+ addUsedWlTx.put(LogicalDatastoreType.CONFIGURATION, createTerminationPoint1IIDBuilder(idPair.getNodeID(),
+ idPair.getTpID()).build(), tp1Builder.build(), true);
+ }
+ try {
+ addUsedWlTx.submit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ List<String> tpIdsString = tpIds.stream().map(NodeIdPair::toString).collect(Collectors.toList());
+ LOG.error("Unable to add used WL {} for TPs {}!", wavelengthIndex, String.join(", ", tpIdsString), e);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+
+public class NodeIdPair {
+
+ private String nodeID;
+ private String tpID;
+
+ public NodeIdPair(String nodeID, String tpID) {
+ this.nodeID = nodeID;
+ this.tpID = tpID;
+ }
+
+ public String getNodeID() {
+ return this.nodeID;
+ }
+
+ public String getTpID() {
+ return this.tpID;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if ((object == null) || (getClass() != object.getClass())) {
+ return false;
+ }
+
+ NodeIdPair that = (NodeIdPair) object;
+
+ if (this.nodeID != null ? !this.nodeID.equals(that.nodeID) : that.nodeID != null) {
+ return false;
+ }
+ return this.tpID != null ? this.tpID.equals(that.tpID) : that.tpID == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = this.nodeID != null ? this.nodeID.hashCode() : 0;
+ result = (31 * result) + (this.tpID != null ? this.tpID.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "NodeIdPair{" + "nodeID='" + this.nodeID + '\'' + ", tpID='" + this.tpID + '\'' + '}';
+ }
+}
--- /dev/null
+/*
+ * 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;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.Nodes;
+
+public class NodeLists {
+
+ private List<Nodes> olmList;
+ private List<Nodes> list;
+
+ public NodeLists(List<Nodes> olmList, List<Nodes> list) {
+ this.olmList = olmList;
+ this.list = list;
+ }
+
+ public List<Nodes> getOlmList() {
+ return olmList;
+ }
+
+ public List<Nodes> getList() {
+ return list;
+ }
+
+}
*/
package org.opendaylight.transportpce.renderer;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
+
import java.util.Collection;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
+
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
+import org.opendaylight.transportpce.common.mapping.PortMapping;
import org.opendaylight.transportpce.renderer.listeners.AlarmNotificationListener;
import org.opendaylight.transportpce.renderer.listeners.DeOperationsListener;
import org.opendaylight.transportpce.renderer.listeners.DeviceListener;
import org.opendaylight.transportpce.renderer.listeners.LldpListener;
import org.opendaylight.transportpce.renderer.listeners.TcaListener;
-import org.opendaylight.transportpce.renderer.mapping.PortMapping;
import org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev161014.AlarmNotification;
import org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev161014.OrgOpenroadmAlarmListener;
import org.opendaylight.yang.gen.v1.http.org.openroadm.de.operations.rev161014.OrgOpenroadmDeOperationsListener;
import org.slf4j.LoggerFactory;
public class RendererNotificationsImpl implements DataTreeChangeListener<Node> {
-
private final DataBroker dataBroker;
private final MountPointService mountService;
private static final Logger LOG = LoggerFactory.getLogger(RendererNotificationsImpl.class);
private ListenerRegistration<RendererNotificationsImpl> dataTreeChangeListenerRegistration;
-
+ private final PortMapping portMapping;
+ private final DeviceTransactionManager deviceTransactionManager;
private final Set<String> currentMountedDevice;
public static final InstanceIdentifier<Topology> NETCONF_TOPO_IID = InstanceIdentifier.create(NetworkTopology.class)
.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
});
public RendererNotificationsImpl(final DataBroker dataBroker, final MountPointService mountService,
- Set<String> currentMountedDevice) {
+ Set<String> currentMountedDevice, PortMapping portMapping,DeviceTransactionManager deviceTransactionManager) {
this.dataBroker = dataBroker;
this.mountService = mountService;
this.currentMountedDevice = currentMountedDevice;
+ this.portMapping = portMapping;
+ this.deviceTransactionManager = deviceTransactionManager;
+ if (portMapping == null) {
+ LOG.error("Portmapping is null !");
+ }
+ if (deviceTransactionManager == null) {
+ LOG.error("deviceTransactionManager is null");
+ }
if (mountService == null) {
LOG.error("Mount service is null");
-
}
if (dataBroker != null) {
this.dataTreeChangeListenerRegistration = dataBroker.registerDataTreeChangeListener(
}
}
- private void registerNotificationListener(final NodeId nodeId) {
+ private void registerNotificationListener(final String nodeId) {
- MountPoint mountPoint = PortMapping.getDeviceMountPoint(nodeId.getValue(), this.mountService);
+ LOG.info("onDeviceConnected: {}", nodeId);
+ Optional<MountPoint> mountPointOpt = this.deviceTransactionManager.getDeviceMountPoint(nodeId);
+ MountPoint mountPoint;
+ if (mountPointOpt.isPresent()) {
+ mountPoint = mountPointOpt.get();
+ } else {
+ LOG.error("Failed to get mount point for node {}", nodeId);
+ return;
+ }
- // Register notification service
- final Optional<NotificationService> notificationService = mountPoint.getService(
- NotificationService.class);
+ final Optional<NotificationService> notificationService =
+ mountPoint.getService(NotificationService.class).toJavaUtil();
if (!notificationService.isPresent()) {
- LOG.error("Failed to get RpcService for node {}", nodeId.getValue());
+ LOG.error("Failed to get RpcService for node {}", nodeId);
+ return;
}
final OrgOpenroadmAlarmListener alarmListener;
// Listening to NETCONF datastream
final String streamName = "NETCONF";
- final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class);
+ final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class).toJavaUtil();
if (!service.isPresent()) {
- LOG.error("Failed to get RpcService for node {}", nodeId.getValue());
+ LOG.error("Failed to get RpcService for node {}", nodeId);
}
final NotificationsService rpcService = service.get().getRpcService(NotificationsService.class);
String nodeid = rootNode.getDataBefore().getKey().getNodeId().getValue();
LOG.info("Node {} removed...", nodeid);
this.currentMountedDevice.remove(nodeid);
- new PortMapping(this.dataBroker, this.mountService, nodeid).deleteMappingData();
}
if (nnode != null) {
* TODO: check for required capabilities to listen
* for notifications
*/
- registerNotificationListener(rootNode.getDataAfter().getNodeId());
+ registerNotificationListener(nodeId);
this.currentMountedDevice.add(nodeId);
- new PortMapping(this.dataBroker, this.mountService, nodeId).createMappingData();
+ this.portMapping.createMappingData(nodeId);
break;
}
case Connecting: {
* 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;
import java.util.HashSet;
import org.opendaylight.controller.md.sal.binding.api.MountPointService;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.transportpce.renderer.provisiondevice.DeviceRenderer;
+import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
+import org.opendaylight.transportpce.common.mapping.PortMapping;
+import org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperations;
+import org.opendaylight.transportpce.renderer.rpcs.DeviceRendererRPCImpl;
+import org.opendaylight.transportpce.renderer.rpcs.TransportPCEServicePathRPCImpl;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final DataBroker dataBroker;
private final MountPointService mountPointService;
private final RpcProviderRegistry rpcProviderRegistry;
- private RendererNotificationsImpl rendererNotificationImpl;
+ private final PortMapping portMapping;
+ private final DeviceTransactionManager deviceTransactionManager;
private RpcRegistration<RendererService> deviceRendererRegistration;
+ private DeviceRendererRPCImpl deviceRendererRPCImpl;
+ private RpcRegistration<TransportpceServicepathService> tpceServiceRegistry;
+ private RendererServiceOperations rendererServiceOperations;
+ private RendererNotificationsImpl rendererNotificationsImpl;
private final Set<String> currentMountedDevice;
- public RendererProvider(final DataBroker dataBroker, final MountPointService mountPointService,
- final RpcProviderRegistry rpcProviderRegistry) {
+ public RendererProvider(RpcProviderRegistry rpcProviderRegistry, DeviceRendererRPCImpl deviceRendererRPCImpl,
+ RendererServiceOperations rendererServiceOperations,DataBroker dataBroker,
+ MountPointService mountPointService, PortMapping portMapping,
+ DeviceTransactionManager deviceTransactionManager) {
+ this.rpcProviderRegistry = rpcProviderRegistry;
+ this.deviceRendererRPCImpl = deviceRendererRPCImpl;
+ this.rendererServiceOperations = rendererServiceOperations;
this.dataBroker = dataBroker;
this.mountPointService = mountPointService;
- this.rpcProviderRegistry = rpcProviderRegistry;
this.currentMountedDevice = new HashSet<>();
- if (mountPointService == null) {
- LOG.error("Mount service is null");
- }
+ this.portMapping = portMapping;
+ this.deviceTransactionManager = deviceTransactionManager;
}
/**
*/
public void init() {
LOG.info("RendererProvider Session Initiated");
- // Initializing Notification module
- rendererNotificationImpl = new RendererNotificationsImpl(dataBroker, mountPointService,
- currentMountedDevice);
- //Register REST API RPC implementation for Renderer Service
- deviceRendererRegistration = rpcProviderRegistry.addRpcImplementation(RendererService.class, new DeviceRenderer(
- dataBroker, mountPointService, currentMountedDevice));
+ TransportPCEServicePathRPCImpl transportPCEServicePathRPCImpl =
+ new TransportPCEServicePathRPCImpl(this.rendererServiceOperations);
+ this.deviceRendererRegistration = this.rpcProviderRegistry
+ .addRpcImplementation(RendererService.class, this.deviceRendererRPCImpl);
+ this.tpceServiceRegistry = this.rpcProviderRegistry
+ .addRpcImplementation(TransportpceServicepathService.class, transportPCEServicePathRPCImpl);
+ this.rendererNotificationsImpl = new RendererNotificationsImpl(this.dataBroker, this.mountPointService,
+ this.currentMountedDevice,this.portMapping,this.deviceTransactionManager);
}
/**
*/
public void close() {
LOG.info("RendererProvider Closed");
- // Clean up the RPC service registration
- if (deviceRendererRegistration != null) {
- deviceRendererRegistration.close();
+ if (this.deviceRendererRegistration != null) {
+ this.deviceRendererRegistration.close();
+ }
+ if (this.tpceServiceRegistry != null) {
+ this.tpceServiceRegistry.close();
}
// Clean up the RendererNotificationsImpl
- if (rendererNotificationImpl != null) {
- rendererNotificationImpl.close();
+ if (this.rendererNotificationsImpl != null) {
+ this.rendererNotificationsImpl.close();
}
}
-}
\ No newline at end of file
+
+}
--- /dev/null
+/*
+ * 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;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathInput;
+
+public class ServicePathInputData {
+
+ private ServicePathInput servicePathInput;
+ private NodeLists nodeLists;
+
+ public ServicePathInputData(ServicePathInput servicePathInput, NodeLists nodeLists) {
+ this.servicePathInput = servicePathInput;
+ this.nodeLists = nodeLists;
+ }
+
+ public ServicePathInput getServicePathInput() {
+ return servicePathInput;
+ }
+
+ public NodeLists getNodeLists() {
+ return nodeLists;
+ }
+
+}
+++ /dev/null
-/*
- * 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.mapping;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-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.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.transportpce.renderer.openroadminterface.OpenRoadmInterfaces;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
-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.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;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Info;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.port.Interfaces;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.InterfaceType;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpenROADMOpticalMultiplex;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalTransport;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
-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.NetworkBuilder;
-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.NodesBuilder;
-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.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class PortMapping {
-
- private static final Logger LOG = LoggerFactory.getLogger(PortMapping.class);
- private final DataBroker db;
- private final MountPointService mps;
- private final String nodeId;
-
- public PortMapping(DataBroker db, MountPointService mps, String nodeId) {
- this.db = db;
- this.mps = mps;
- this.nodeId = nodeId;
-
- }
-
- /**
- * This method creates logical to physical port mapping for a given device.
- * Instead of parsing all the circuit packs/ports in the device this methods
- * does a selective read operation on degree/srg subtree to get circuit
- * packs/ports that map to :
- *
- * <p>
- * 1. DEGn-TTP-TX, DEGn-TTP-RX, DEGn-TTP-TXRX
- *
- * <p>
- * 2. SRGn-PPp-TX, SRGn-PPp-RX, SRGn-PPp-TXRX
- *
- * <p>
- * 3. LINEn
- *
- * <p>
- * 4. CLNTn.
- *
- * <p>
- * If the port is Mw it also store the OMS, OTS interface provisioned on the
- * port. It skips the logical ports that are internal. If operation is
- * successful the mapping gets stored in datastore corresponding to
- * portmapping.yang data model.
- *
- * @return true/false based on status of operation
- */
- public boolean createMappingData() {
-
- LOG.info("Create Mapping Data for node " + nodeId);
- DataBroker deviceDb = getDeviceDataBroker(nodeId, mps);
- List<Mapping> portMapList = new ArrayList<>();
- Info deviceInfo;
- Integer nodeType = 1;
- if (deviceDb != null) {
- deviceInfo = getDeviceInfo(deviceDb);
- if (deviceInfo != null) {
- if (deviceInfo.getNodeType() == null) {
- LOG.info("Node type mandatory field is missing");
- return false;
- }
- nodeType = deviceInfo.getNodeType().getIntValue();
- // Create Mapping for Roadm Node
- if (nodeType == 1) {
- // Get TTP port mapping
- if (!createTtpPortMapping(deviceDb, deviceInfo, portMapList)) {
- // return false if mapping creation for TTP's failed
- LOG.info("Unable to create mapping for TTP's");
- return false;
- }
-
- // Get PP port mapping
- if (!createPpPortMapping(deviceDb, deviceInfo, portMapList)) {
- // return false if mapping creation for PP's failed
- LOG.info("Unable tp create mapping for PP's");
- return false;
- }
- }
- // Create Mapping for Xponder Node
- if (nodeType == 2) {
- if (!createXpdrPortMapping(deviceDb, deviceInfo, portMapList)) {
- LOG.info("Unable to create mapping for Xponder");
- return false;
- }
- }
- } else {
- LOG.info("Device info subtree is absent for " + nodeId);
- return false;
- }
-
- } else {
- LOG.info("Unable to get Data broker for node " + nodeId);
- return false;
- }
- return postPortMapping(deviceInfo, portMapList, nodeType);
- }
-
- /**
- * This method removes mapping data from the datastore after disconnecting
- * ODL from a Netconf device.
- */
- public void deleteMappingData() {
- LOG.info("Deleting Mapping Data corresponding at node " + nodeId);
- WriteTransaction rw = db.newWriteOnlyTransaction();
- InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class)
- .child(Nodes.class, new NodesKey(nodeId));
- rw.delete(LogicalDatastoreType.CONFIGURATION, nodesIID);
- try {
- rw.submit().get(1, TimeUnit.SECONDS);
- LOG.info("Port mapping removal for node " + nodeId);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- LOG.error("Error for removing port mapping infos for node " + nodeId);
- }
- }
-
- /**
- * This private method gets the list of external ports on a degree. For each
- * port in the degree, it does a get on port subtree with
- * circuit-pack-name/port-name as key in order to get the logical connection
- * point name corresponding to it.
- *
- * @param deviceDb
- * Reference to device's databroker
- * @param deviceInfo
- * Info subtree read from the device
- * @param portMapList
- * Reference to the list containing the mapping to be pushed to
- * MD-SAL
- *
- * @return true/false based on status of operation
- */
- private boolean createTtpPortMapping(DataBroker deviceDb, Info deviceInfo, List<Mapping> portMapList) {
- // Creating mapping data for degree TTP's
- List<ConnectionPorts> degreeConPorts = getDegreePorts(deviceDb, deviceInfo);
-
- // Getting circuit-pack-name/port-name corresponding to TTP's
- for (ConnectionPorts cp : degreeConPorts) {
- String circuitPackName = cp.getCircuitPackName();
- String portName = cp.getPortName().toString();
- InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
- CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class, new PortsKey(portName));
- try {
- LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}", portName,
- circuitPackName);
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- Optional<Ports> portObject = rtx.read(LogicalDatastoreType.OPERATIONAL, portIID).get();
- if (portObject.isPresent()) {
- Ports port = portObject.get();
- if (port.getLogicalConnectionPoint() != null) {
- LOG.info("Logical Connection Point for {} {} is {}", circuitPackName, portName, port
- .getLogicalConnectionPoint());
- portMapList.add(createMappingObject(port, circuitPackName, port.getLogicalConnectionPoint(),
- deviceDb));
- } else {
-
- LOG.warn("Logical Connection Point value missing for {} {}", circuitPackName, port
- .getPortName());
- }
- }
- } catch (InterruptedException | ExecutionException ex) {
- LOG.warn("Read failed for Logical Connection Point value missing for " + circuitPackName + " "
- + portName, ex);
- return false;
- }
- }
- return true;
- }
-
- /**
- * This private method gets the list of circuit packs on an Srg. For each
- * circuit pack on an Srg, it does a get on circuit-pack subtree with
- * circuit-pack-name as key in order to get the list of ports. It then
- * iterates over the list of ports to get ports with port-qual as
- * roadm-external. It appends a TX,RX,TXRX to the logical connection point
- * name based on the direction of the port.
- *
- * @param deviceDb
- * Reference to device's databroker
- * @param deviceInfo
- * Info subtree read from the device
- * @param portMapList
- * Reference to the list containing the mapping to be pushed to
- * MD-SAL
- *
- * @return true/false based on status of operation
- */
-
- private boolean createPpPortMapping(DataBroker deviceDb, Info deviceInfo, List<Mapping> portMapList) {
- // Creating mapping data for degree PP's
-
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- Integer maxSrg;
- // Get value for max Srg from subtree, required for iteration
- // if it is not defined in the netconf node then set maxSrg to 20
- if (deviceInfo.getMaxSrgs() != null) {
- maxSrg = deviceInfo.getMaxSrgs();
- } else {
- maxSrg = 20;
- }
-
- Integer srgCounter = 1;
- Integer nbSrg = 0;
- while (srgCounter <= maxSrg) {
- List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> srgCps =
- new ArrayList<>();
- LOG.info("Getting CircuitPacks for Srg Number {}", srgCounter);
- InstanceIdentifier<SharedRiskGroup> srgIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
- SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
- try {
- Optional<SharedRiskGroup> ordmSrgObject = rtx.read(LogicalDatastoreType.CONFIGURATION, srgIID).get();
-
- if (ordmSrgObject.isPresent()) {
- srgCps.addAll(new ArrayList<>(ordmSrgObject.get().getCircuitPacks()));
- nbSrg++;
- }
- } catch (InterruptedException | ExecutionException ex) {
- LOG.warn("Failed to read Srg {}", srgCounter, ex);
- break;
- }
-
- for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks cps : srgCps) {
- String circuitPackName = cps.getCircuitPackName();
- try {
- InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
- CircuitPacks.class, new CircuitPacksKey(circuitPackName));
- Optional<CircuitPacks> circuitPackObject = rtx.read(LogicalDatastoreType.OPERATIONAL, cpIID).get();
-
- if (circuitPackObject.isPresent()) {
- CircuitPacks cp = circuitPackObject.get();
- if (cp.getPorts() == null) {
- LOG.warn("No port found for {} {}", deviceInfo.getNodeId(), circuitPackName);
- } else if (!cp.getPorts().isEmpty()) {
- for (Ports port : cp.getPorts()) {
-
- if (port.getLogicalConnectionPoint() != null && port.getPortQual().getIntValue() == 2) {
- String logicalConnectionPoint = null;
- if (port.getPortDirection().getIntValue() == 1) {
- // Port direction is transmit
- if (!port.getLogicalConnectionPoint().contains("SRG")) {
- logicalConnectionPoint = "SRG" + srgCounter + "-" + port
- .getLogicalConnectionPoint() + "-TX";
- } else {
- logicalConnectionPoint = port.getLogicalConnectionPoint() + "-TX";
- }
- }
- if (port.getPortDirection().getIntValue() == 2) {
- // Port direction is receive
- if (!port.getLogicalConnectionPoint().contains("SRG")) {
- logicalConnectionPoint = "SRG" + srgCounter + "-" + port
- .getLogicalConnectionPoint() + "-RX";
- } else {
- logicalConnectionPoint = port.getLogicalConnectionPoint() + "-RX";
- }
- }
- if (port.getPortDirection().getIntValue() == 3) {
- // port is bi-directional
- if (!port.getLogicalConnectionPoint().contains("SRG")) {
- logicalConnectionPoint = "SRG" + srgCounter + "-" + port
- .getLogicalConnectionPoint() + "-TXRX";
- } else {
- logicalConnectionPoint = port.getLogicalConnectionPoint() + "-TXRX";
- }
- }
-
- LOG.info("Logical Connection Point for {} {} is {}", circuitPackName, port
- .getPortName(), logicalConnectionPoint);
-
- portMapList.add(createMappingObject(port, circuitPackName, logicalConnectionPoint,
- deviceDb));
-
- } else if (port.getPortQual().getIntValue() == 1) {
-
- LOG.info("Port is internal, skipping Logical Connection Point missing for "
- + circuitPackName + " " + port.getPortName());
-
- } else if (port.getLogicalConnectionPoint() == null) {
-
- LOG.info("Value missing, Skipping Logical Connection Point missing for {} {}",
- circuitPackName, port.getPortName());
- }
-
- }
-
- }
-
- }
- } catch (InterruptedException | ExecutionException ex) {
- LOG.warn("Read failed for {}", circuitPackName, ex);
- return false;
- }
- }
- srgCounter++;
- }
- LOG.info("Device has {} Srg", nbSrg);
- return true;
- }
-
- /**
- * This private method gets the list of circuit packs on a xponder. For each
- * circuit pack on a Xponder, it does a get on circuit-pack subtree with
- * circuit-pack-name as key in order to get the list of ports. It then
- * iterates over the list of ports to get ports with port-qual as
- * xpdr-network/xpdr-client. The line and client ports are saved as:
- *
- * <p>
- * 1. LINEn
- *
- * <p>
- * 2. CLNTn
- *
- * @param deviceDb
- * Reference to device's databroker
- * @param deviceInfo
- * Info subtree read from the device
- * @param portMapList
- * Reference to the list containing the mapping to be pushed to
- * MD-SAL
- *
- * @return true/false based on status of operation
- */
-
- private boolean createXpdrPortMapping(DataBroker deviceDb, Info deviceInfo, List<Mapping> portMapList) {
- // Creating for Xponder Line and Client Ports
- try {
- InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- Optional<OrgOpenroadmDevice> deviceObject = rtx.read(LogicalDatastoreType.OPERATIONAL, deviceIID).get();
-
- // Variable to keep track of number of line ports
- int line = 1;
- // Variable to keep track of number of client ports
- int client = 1;
- if (deviceObject.isPresent()) {
- for (CircuitPacks cp : deviceObject.get().getCircuitPacks()) {
- String circuitPackName = cp.getCircuitPackName();
- if (cp.getPorts() == null) {
- LOG.warn("No port found for {}, circuit pack {}", deviceInfo.getNodeId(), circuitPackName);
- } else {
- for (Ports port : cp.getPorts()) {
- if (port.getPortQual() != null) {
- if (port.getPortQual().getIntValue() == 3) {
- // Port is xpdr-network
- portMapList.add(createMappingObject(port, circuitPackName, "XPDR-LINE"
- + line, deviceDb));
- LOG.info("Logical Connection Point for {} {} is XPDR-LINE{}", circuitPackName, port
- .getPortName(), line);
- line++;
- }
- if (port.getPortQual().getIntValue() == 4) {
- // port is xpdr-client
- portMapList.add(createMappingObject(port, circuitPackName, "XPDR-CLNT"
- + client, deviceDb));
- LOG.info("Logical Connection Point for {} {} is XPDR-CLNT{}", circuitPackName, port
- .getPortName(), client);
- client++;
- }
- } else {
- LOG.info("no PortQual for port {} of circuit pack {}", port.getPortName(), cp
- .getCircuitPackName());
- }
- }
- }
- }
- } else {
- LOG.info("No deviceObject present for {}", nodeId);
- return false;
- }
-
- } catch (InterruptedException | ExecutionException ex) {
- LOG.warn("Read failed for CircuitPacks of {}", nodeId, ex);
- return false;
- }
- return true;
- }
-
- /**
- * This private method builds the mapping object to be pushed in MD-SAL in
- * order to save port mapping. In case of TTP ports, it also saves the
- * OTS,OMS interfaces provisioned on the port.
- *
- * @param port
- * Reference to device's port subtree object.
- * @param circuitPackName
- * Name of cp where port exists.
- * @param logicalConnectionPoint
- * logical name of the port.
- * @param deviceDb
- * Reference to device's databroker.
- *
- * @return true/false based on status of operation
- */
-
- private Mapping createMappingObject(Ports port, String circuitPackName, String logicalConnectionPoint,
- DataBroker deviceDb) {
- MappingBuilder mpBldr = new MappingBuilder();
- mpBldr.setKey(new MappingKey(logicalConnectionPoint)).setLogicalConnectionPoint(logicalConnectionPoint)
- .setSupportingCircuitPackName(circuitPackName).setSupportingPort(port.getPortName());
-
- // Get OMS and OTS interface provisioned on the TTP's
- if (logicalConnectionPoint.contains("TTP") && port.getInterfaces() != null) {
- for (Interfaces interfaces : port.getInterfaces()) {
- Class<? extends InterfaceType> 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();
- mpBldr.setSupportingOms(omsInterfaceName);
- }
- if (interfaceType.equals(OpticalTransport.class)) {
- String otsInterfaceName = interfaces.getInterfaceName();
- mpBldr.setSupportingOts(otsInterfaceName);
- }
- }
- }
- return mpBldr.build();
- }
-
- /**
- * 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
- * device attributes such as maxDegrees,maxSrgs and node-type.
- *
- * @param deviceDb
- * Reference to device's databroker
- * @return Info object
- *
- */
- private Info getDeviceInfo(DataBroker deviceDb) {
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
- try {
- Optional<Info> ordmInfoObject = rtx.read(LogicalDatastoreType.OPERATIONAL, infoIID).get();
- if (ordmInfoObject.isPresent()) {
- LOG.info("Info subtree is present {}", ordmInfoObject.get());
- return ordmInfoObject.get();
- } else {
- LOG.error("Info subtree is not present");
- }
- } catch (NullPointerException ex) {
- LOG.warn("Try to get Info from a non Open ROADM device {}", deviceDb);
- return null;
- } catch (InterruptedException | ExecutionException ex) {
- LOG.error("Read failed on info subtree ", ex);
- return null;
- }
- return null;
- }
-
- /**
- * This method does a get operation on degree subtree of the netconf
- * device's config datastore and returns a list of all connection port
- * objects. It is required for doing a selective get on ports that
- * correspond to logical connection points of interest.
- *
- * @param deviceDb
- * Reference to device's databroker
- * @param ordmInfo
- * Info subtree from the device
- * @return List of connection ports object belonging to- degree subtree
- */
- private List<ConnectionPorts> getDegreePorts(DataBroker deviceDb, Info ordmInfo) {
-
- List<ConnectionPorts> degreeConPorts = new ArrayList<>();
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- Integer maxDegree;
-
- // Get value for max degree from info subtree, required for iteration
- // if not present assume to be 20 (temporary)
- if (ordmInfo.getMaxDegrees() != null) {
- maxDegree = ordmInfo.getMaxDegrees();
- } else {
- maxDegree = 20;
- }
- Integer degreeCounter = 1;
- while (degreeCounter <= maxDegree) {
- LOG.info("Getting Connection ports for Degree Number " + degreeCounter);
- InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
- Degree.class, new DegreeKey(degreeCounter));
- try {
- Optional<Degree> ordmDegreeObject = rtx.read(LogicalDatastoreType.CONFIGURATION, deviceIID).get();
-
- if (ordmDegreeObject.isPresent()) {
- degreeConPorts.addAll(new ArrayList<>(ordmDegreeObject.get().getConnectionPorts()));
-
- } else {
- LOG.info("Device has " + (degreeCounter - 1) + " degree");
- break;
- }
- } catch (InterruptedException | ExecutionException ex) {
- LOG.error("Failed to read degree " + degreeCounter, ex);
- break;
-
- }
- degreeCounter++;
- }
- return degreeConPorts;
- }
-
- /**
- * This method for ports the portMapping corresponding to the
- * portmapping.yang file to the MD-SAL datastore.
- *
- * <p>
- * 1. Supporting circuit pack 2. Supporting port 3. Supporting OMS interface
- * (if port on ROADM)
- *
- * @param deviceInfo
- * Info subtree from the device.
- * @param portMapList
- * Reference to the list containing the mapping to be pushed to
- * MD-SAL.
- *
- * @return Result true/false based on status of operation.
- */
- private boolean postPortMapping(Info deviceInfo, List<Mapping> portMapList, Integer nodeType) {
-
- NodesBuilder nodesBldr = new NodesBuilder();
- nodesBldr.setKey(new NodesKey(deviceInfo.getNodeId())).setNodeId(deviceInfo.getNodeId());
- nodesBldr.setNodeType(NodeTypes.forValue(nodeType));
- nodesBldr.setMapping(portMapList);
- List<Nodes> nodesList = new ArrayList<>();
- nodesList.add(nodesBldr.build());
- NetworkBuilder nwBldr = new NetworkBuilder();
- nwBldr.setNodes(nodesList);
- final WriteTransaction writeTransaction = db.newWriteOnlyTransaction();
- InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
- writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, nwBldr.build());
- CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
- try {
- submit.checkedGet();
- return true;
-
- } catch (TransactionCommitFailedException e) {
- LOG.warn("Failed to post {} ", nwBldr.build(), e);
- 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:
- *
- * <p>
- * 1. Supporting circuit pack
- *
- * <p>
- * 2. Supporting port
- *
- * <p>
- * 3. Supporting OMS interface (if port on ROADM) 4. Supporting OTS
- * interface (if port on ROADM)
- *
- * @param nodeId
- * Unique Identifier for the node of interest.
- * @param logicalConnPoint
- * Name of the logical point
- * @param db
- * Databroker / MD-SAL data store
- *
- * @return Result Mapping object if success otherwise null.
- */
- public static Mapping getMapping(String nodeId, String logicalConnPoint, DataBroker db) {
-
- /*
- * Getting physical mapping corresponding to logical connection point
- */
- InstanceIdentifier<Mapping> portMapping = InstanceIdentifier.builder(Network.class).child(Nodes.class,
- new NodesKey(nodeId)).child(Mapping.class, new MappingKey(logicalConnPoint)).build();
- ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
- Optional<Mapping> 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.error("Unable to read mapping for logical connection point : " + logicalConnPoint + " for nodeId "
- + nodeId, ex);
- }
- return null;
- }
-
- /**
- * This static method returns the DataBroker for a netconf node.
- *
- * @param nodeId
- * Unique identifier for the mounted netconf- node
- * @param mps
- * Reference to mount service
- * @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.error("Device Data broker not found for :" + nodeId);
- return null;
- }
- }
-
- public static MountPoint getDeviceMountPoint(String nodeId, MountPointService mps) {
- InstanceIdentifier<Node> 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 mount point for specified device
- final Optional<MountPoint> netconfNodeOptional = mps.getMountPoint(netconfNodeIID);
- if (netconfNodeOptional.isPresent()) {
- MountPoint netconfNode = netconfNodeOptional.get();
- return netconfNode;
- } else {
- LOG.error("Mount Point not found for :" + nodeId);
- return null;
- }
-
- }
-}
+++ /dev/null
-/*
- * 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.ethernet.interfaces.rev161014.EthAttributes.AutoNegotiation;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.EthAttributes.Duplex;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.EthAttributes.Fec;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.Interface1;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.Interface1Builder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.ethernet.container.EthernetBuilder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.EthernetCsmacd;
-
-public class OpenRoadmEthIterface extends OpenRoadmInterfaces {
-
- public OpenRoadmEthIterface(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint,
- String serviceName) {
- super(db, mps, nodeId, logicalConnPoint, serviceName);
-
- }
-
- public String createInterface() {
- InterfaceBuilder ethInterfaceBldr = getIntfBuilder(portMap);
- ethInterfaceBldr.setType(EthernetCsmacd.class);
- ethInterfaceBldr.setName(logicalConnPoint + "-ETHERNET");
- ethInterfaceBldr.setKey(new InterfaceKey(logicalConnPoint + "-ETHERNET"));
-
- // Ethernet interface specific data
- EthernetBuilder ethIfBuilder = new EthernetBuilder();
- ethIfBuilder.setAutoNegotiation(AutoNegotiation.Enabled);
- ethIfBuilder.setDuplex(Duplex.Full);
- ethIfBuilder.setFec(Fec.Off);
- ethIfBuilder.setSpeed(new Long(100000));
- ethIfBuilder.setMtu(new Long(9000));
-
- // Create Interface1 type object required for adding as augmentation
- Interface1Builder ethIf1Builder = new Interface1Builder();
- ethInterfaceBldr.addAugmentation(Interface1.class, ethIf1Builder.setEthernet(ethIfBuilder.build()).build());
-
- // Post interface on the device
- if (postInterface(ethInterfaceBldr)) {
- return ethInterfaceBldr.getName();
- } else {
- return null;
- }
-
- }
-
-}
--- /dev/null
+/*
+ * 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 java.math.BigDecimal;
+
+import org.opendaylight.transportpce.common.mapping.PortMapping;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.PowerDBm;
+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.equipment.states.types.rev161014.AdminStates;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.EthAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.Interface1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.Interface1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev161014.ethernet.container.EthernetBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.EthernetCsmacd;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.InterfaceType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalChannel;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OtnOdu;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OtnOtu;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.OchAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.RateIdentity;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.och.container.OchBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.ODU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.OduAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.odu.container.OduBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.opu.OpuBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.OTU4;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.OtuAttributes;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.otu.container.OtuBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
+
+public class OpenRoadmInterfaceFactory {
+
+ private final PortMapping portMapping;
+ private final OpenRoadmInterfaces openRoadmInterfaces;
+
+ public OpenRoadmInterfaceFactory(PortMapping portMapping, OpenRoadmInterfaces openRoadmInterfaces) {
+ this.portMapping = portMapping;
+ this.openRoadmInterfaces = openRoadmInterfaces;
+ }
+
+ public String createOpenRoadmEthInterface(String nodeId,
+ String logicalConnPoint) throws OpenRoadmInterfaceException {
+ Mapping portMap = this.portMapping.getMapping(nodeId, logicalConnPoint);
+ if (portMap == null) {
+ throw new OpenRoadmInterfaceException(String.format("Unable to get mapping from PortMapping for node % and"
+ + " logical connection port %s", nodeId, logicalConnPoint));
+ }
+
+ // Ethernet interface specific data
+ EthernetBuilder ethIfBuilder = new EthernetBuilder();
+ ethIfBuilder.setAutoNegotiation(EthAttributes.AutoNegotiation.Enabled);
+ ethIfBuilder.setDuplex(EthAttributes.Duplex.Full);
+ ethIfBuilder.setFec(EthAttributes.Fec.Off);
+ ethIfBuilder.setSpeed(100000L);
+ ethIfBuilder.setMtu(9000L);
+
+ InterfaceBuilder ethInterfaceBldr = createGenericInterfaceBuilder(portMap, EthernetCsmacd.class,
+ logicalConnPoint + "-ETHERNET");
+
+ // Create Interface1 type object required for adding as augmentation
+ Interface1Builder ethIf1Builder = new Interface1Builder();
+ ethInterfaceBldr.addAugmentation(Interface1.class, ethIf1Builder.setEthernet(ethIfBuilder.build()).build());
+
+ // Post interface on the device
+ this.openRoadmInterfaces.postInterface(nodeId, ethInterfaceBldr);
+ return ethInterfaceBldr.getName();
+ }
+
+ /**
+ * This methods creates an OCH interface on the given termination point on
+ * Roadm.
+ *
+ * @param waveNumber
+ * wavelength number of the OCH interface.
+ *
+ * @return Name of the interface if successful, otherwise return null.
+ */
+
+ public String createOpenRoadmOchInterface(String nodeId, String logicalConnPoint, Long waveNumber) throws
+ OpenRoadmInterfaceException {
+ Mapping portMap = this.portMapping.getMapping(nodeId, logicalConnPoint);
+ if (portMap == null) {
+ throw new OpenRoadmInterfaceException(String.format("Unable to get mapping from PortMapping for node %s and"
+ + " logical connection port %s", nodeId, logicalConnPoint));
+ }
+ // Create generic interface
+ InterfaceBuilder ochInterfaceBldr = createGenericInterfaceBuilder(portMap, OpticalChannel.class,
+ createOpenRoadmOchInterfaceName(logicalConnPoint, waveNumber));
+
+ // OCH interface specific data
+ OchBuilder ocIfBuilder = new OchBuilder();
+ ocIfBuilder.setWavelengthNumber(waveNumber);
+
+ // Add supporting OMS interface
+ if (portMap.getSupportingOms() != null) {
+ ochInterfaceBldr.setSupportingInterface(portMap.getSupportingOms());
+ }
+ // Create Interface1 type object required for adding as augmentation
+ // TODO look at imports of different versions of class
+ org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1Builder
+ ochIf1Builder = new org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces
+ .rev161014.Interface1Builder();
+ ochInterfaceBldr.addAugmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1.class,
+ ochIf1Builder.setOch(ocIfBuilder.build()).build());
+
+ // Post interface on the device
+ this.openRoadmInterfaces.postInterface(nodeId, ochInterfaceBldr);
+ return ochInterfaceBldr.getName();
+ }
+
+ public String createOpenRoadmOchInterface(String nodeId, String logicalConnPoint, Long waveNumber,
+ Class<? extends RateIdentity> rate, OchAttributes.ModulationFormat format) throws OpenRoadmInterfaceException {
+ Mapping portMap = this.portMapping.getMapping(nodeId, logicalConnPoint);
+ if (portMap == null) {
+ throw new OpenRoadmInterfaceException(String.format("Unable to get mapping from PortMapping for node %s and"
+ + " logical connection port %s", nodeId, logicalConnPoint));
+ }
+
+ // OCH interface specific data
+ OchBuilder ocIfBuilder = new OchBuilder();
+ ocIfBuilder.setWavelengthNumber(waveNumber);
+ ocIfBuilder.setModulationFormat(format);
+ ocIfBuilder.setRate(rate);
+ ocIfBuilder.setTransmitPower(new PowerDBm(new BigDecimal("-5")));
+
+ // Create Interface1 type object required for adding as augmentation
+ // TODO look at imports of different versions of class
+ org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1Builder
+ ochIf1Builder = new org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces
+ .rev161014.Interface1Builder();
+ // Create generic interface
+ InterfaceBuilder ochInterfaceBldr = createGenericInterfaceBuilder(portMap, OpticalChannel.class,
+ createOpenRoadmOchInterfaceName(logicalConnPoint, waveNumber));
+ ochInterfaceBldr.addAugmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1.class,
+ ochIf1Builder.setOch(ocIfBuilder.build()).build());
+
+ // Post interface on the device
+ this.openRoadmInterfaces.postInterface(nodeId, ochInterfaceBldr);
+ return ochInterfaceBldr.getName();
+ }
+
+ public String createOpenRoadmOchInterfaceName(String logicalConnectionPoint, Long waveNumber) {
+ return logicalConnectionPoint + "-" + waveNumber;
+ }
+
+ /**
+ * This methods creates an ODU interface on the given termination point.
+ *
+ *
+ * @return Name of the interface if successful, otherwise return null.
+ */
+
+ public String createOpenRoadmOdu4Interface(String nodeId, String logicalConnPoint, String supportingOtuInterface)
+ throws OpenRoadmInterfaceException {
+ Mapping portMap = this.portMapping.getMapping(nodeId, logicalConnPoint);
+ if (portMap == null) {
+ throw new OpenRoadmInterfaceException(String.format("Unable to get mapping from PortMapping for node % and"
+ + " logical connection port %s", nodeId, logicalConnPoint));
+ }
+ InterfaceBuilder oduInterfaceBldr = createGenericInterfaceBuilder(portMap, OtnOdu.class,
+ logicalConnPoint + "-ODU");
+ oduInterfaceBldr.setSupportingInterface(supportingOtuInterface);
+
+ // ODU interface specific data
+ OduBuilder oduIfBuilder = new OduBuilder();
+ oduIfBuilder.setRate(ODU4.class);
+ oduIfBuilder.setMonitoringMode(OduAttributes.MonitoringMode.Terminated);
+
+ //Set Opu attributes
+ OpuBuilder opuBldr = new OpuBuilder();
+ opuBldr.setPayloadType("07");
+ opuBldr.setExpPayloadType("07");
+ oduIfBuilder.setOpu(opuBldr.build());
+
+
+ // Create Interface1 type object required for adding as augmentation
+ // TODO look at imports of different versions of class
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.Interface1Builder oduIf1Builder =
+ new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.Interface1Builder();
+ oduInterfaceBldr.addAugmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.Interface1.class,
+ oduIf1Builder.setOdu(oduIfBuilder.build()).build());
+
+ // Post interface on the device
+ this.openRoadmInterfaces.postInterface(nodeId, oduInterfaceBldr);
+ return oduInterfaceBldr.getName();
+ }
+
+ /**
+ * This methods creates an OTU interface on the given termination point.
+ *
+ *
+ * @return Name of the interface if successful, otherwise return null.
+ */
+
+ public String createOpenRoadmOtu4Interface(String nodeId, String logicalConnPoint, String supportOchInterface)
+ throws OpenRoadmInterfaceException {
+ Mapping portMap = this.portMapping.getMapping(nodeId, logicalConnPoint);
+ if (portMap == null) {
+ throw new OpenRoadmInterfaceException(String.format("Unable to get mapping from PortMapping for node % and"
+ + " logical connection port %s", nodeId, logicalConnPoint));
+ }
+ // Create generic interface
+ InterfaceBuilder otuInterfaceBldr = createGenericInterfaceBuilder(portMap, OtnOtu.class,
+ logicalConnPoint + "-OTU");
+ otuInterfaceBldr.setSupportingInterface(supportOchInterface);
+
+ // OTU interface specific data
+ OtuBuilder otuIfBuilder = new OtuBuilder();
+ otuIfBuilder.setFec(OtuAttributes.Fec.Scfec);
+ otuIfBuilder.setRate(OTU4.class);
+
+ // Create Interface1 type object required for adding as augmentation
+ // TODO look at imports of different versions of class
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.Interface1Builder otuIf1Builder =
+ new org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.Interface1Builder();
+ otuInterfaceBldr.addAugmentation(
+ org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.Interface1.class,
+ otuIf1Builder.setOtu(otuIfBuilder.build()).build());
+
+ // Post interface on the device
+ this.openRoadmInterfaces.postInterface(nodeId, otuInterfaceBldr);
+ return otuInterfaceBldr.getName();
+ }
+
+ private InterfaceBuilder createGenericInterfaceBuilder(Mapping portMap, Class<? extends InterfaceType> type,
+ String key) {
+ InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
+ interfaceBuilder.setDescription(" TBD ");
+ interfaceBuilder.setCircuitId(" TBD ");
+ interfaceBuilder.setSupportingCircuitPackName(portMap.getSupportingCircuitPackName());
+ interfaceBuilder.setSupportingPort(portMap.getSupportingPort());
+ interfaceBuilder.setAdministrativeState(AdminStates.InService);
+ interfaceBuilder.setType(type);
+ interfaceBuilder.setName(key);
+ interfaceBuilder.setKey(new InterfaceKey(key));
+ return interfaceBuilder;
+ }
+}
+++ /dev/null
-/*
- * 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 MountPointService mps;
- protected final Mapping portMap;
- protected final String logicalConnPoint;
- private final String serviceName;
- private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmInterfaces.class);
-
- public OpenRoadmInterfaces(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint) {
- this.db = db;
- this.mps = mps;
- this.logicalConnPoint = logicalConnPoint;
- this.nodeId = nodeId;
- if (logicalConnPoint != null) {
- this.portMap = PortMapping.getMapping(nodeId, logicalConnPoint, db);
- } else {
- this.portMap = null;
- }
- this.serviceName = null;
- netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps);
- }
-
- public OpenRoadmInterfaces(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint,
- String serviceName) {
- this.db = db;
- this.mps = mps;
- this.logicalConnPoint = logicalConnPoint;
- this.nodeId = nodeId;
- if (logicalConnPoint != null) {
- this.portMap = PortMapping.getMapping(nodeId, logicalConnPoint, db);
- } else {
- this.portMap = null;
- }
- this.serviceName = serviceName;
- 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.
- *
- * <p>
- * Before posting the interface it checks if:
- *
- * <p>
- * 1. Interface with same name does not exist
- *
- * <p>
- * 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 && intf2PostCheck.getAdministrativeState() == AdminStates.InService) {
- LOG.info("Interface with same name in service already exists on node " + nodeId);
- return true;
- }
-
- // Post interface with its specific augmentation to the device
- if (netconfNodeDataBroker != null) {
- InstanceIdentifier<Interface> 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<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
- try {
- submit.checkedGet();
- LOG.info("Successfully posted interface " + ifBuilder.getName() + " on node " + nodeId);
- return true;
- } catch (TransactionCommitFailedException ex) {
- LOG.warn("Failed to post {} ", ifBuilder.getName() + " on node " + nodeId, 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<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
- .child(Interface.class, new InterfaceKey(interfaceName));
- try {
- Optional<Interface> interfaceObject = rtx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
- if (interfaceObject.isPresent()) {
- return interfaceObject.get();
- } else {
- LOG.info("Interface subtree is not present for " + interfaceName + " on node " + nodeId);
- }
- } catch (InterruptedException | ExecutionException ex) {
- LOG.info("Read failed on interface subtree for" + interfaceName + " on node " + nodeId, ex);
- return null;
- }
- return null;
- }
-
- /**
- * This methods does an edit-config operation on the openROADM device in order
- * to delete the given interface.
- *
- * <p>
- * Before deleting the method:
- *
- * <p>
- * 1. Checks if interface exists
- *
- * <p>
- * 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<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
- .child(Interface.class, new InterfaceKey(interfaceName));
- final WriteTransaction writeTransaction = netconfNodeDataBroker.newWriteOnlyTransaction();
- writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, interfacesIID);
- final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
-
- try {
- submit.checkedGet();
- LOG.info("Successfully deleted " + interfaceName + " on node " + nodeId);
- return true;
-
- } catch (TransactionCommitFailedException ex) {
- LOG.error("Failed to delete interface " + interfaceName + " on node " + nodeId);
- return false;
- }
-
- } else {
-
- LOG.error("Error changing the state of interface " + interfaceName + " on node " + nodeId);
- return false;
- }
- } else {
- LOG.info("Interface does not exist, cannot delete on node " + nodeId);
- return false;
- }
-
- } else {
-
- LOG.info("Device databroker not found on node " + nodeId);
- return false;
- }
- }
-}
+++ /dev/null
-/*
- * 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 java.math.BigDecimal;
-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.common.types.rev161014.PowerDBm;
-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.OchAttributes.ModulationFormat;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.RateIdentity;
-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,
- String serviceName) {
- super(db, mps, nodeId, logicalConnPoint, serviceName);
- }
-
- /**
- * This methods creates an OCH interface on the given termination point on
- * Roadm.
- *
- * @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
- if (portMap.getSupportingOms() != null) {
- 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;
- }
- }
-
- public String createInterface(Long waveNumber, Class<? extends RateIdentity> rate, ModulationFormat format) {
-
- // 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);
- ocIfBuilder.setModulationFormat(format);
- ocIfBuilder.setRate(rate);
- ocIfBuilder.setTransmitPower(new PowerDBm(new BigDecimal("-5")));
-
- // 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;
- }
- }
-
-}
+++ /dev/null
-/*
- * 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.OtnOdu;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.Interface1;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.Interface1Builder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.ODU4;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.OduAttributes.MonitoringMode;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.odu.interfaces.rev161014.odu.container.OduBuilder;
-
-public class OpenRoadmOdu4Interface extends OpenRoadmInterfaces {
-
- public OpenRoadmOdu4Interface(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint,
- String serviceName) {
- super(db, mps, nodeId, logicalConnPoint, serviceName);
-
- }
-
- /**
- * This methods creates an ODU interface on the given termination point.
- *
- * @param supportingOtuInterface
- * supporting Otu Interface
- *
- * @return Name of the interface if successful, otherwise return null.
- */
-
- public String createInterface(String supportingOtuInterface) {
-
- InterfaceBuilder oduInterfaceBldr = getIntfBuilder(portMap);
- oduInterfaceBldr.setType(OtnOdu.class);
- oduInterfaceBldr.setSupportingInterface(supportingOtuInterface);
- oduInterfaceBldr.setName(logicalConnPoint + "-ODU");
- oduInterfaceBldr.setKey(new InterfaceKey(logicalConnPoint + "-ODU"));
-
- // ODU interface specific data
- OduBuilder oduIfBuilder = new OduBuilder();
- oduIfBuilder.setRate(ODU4.class);
- oduIfBuilder.setMonitoringMode(MonitoringMode.Monitored);
-
- // Create Interface1 type object required for adding as augmentation
- Interface1Builder oduIf1Builder = new Interface1Builder();
- oduInterfaceBldr.addAugmentation(Interface1.class, oduIf1Builder.setOdu(oduIfBuilder.build()).build());
-
- // Post interface on the device
- if (postInterface(oduInterfaceBldr)) {
- return oduInterfaceBldr.getName();
- } else {
- return null;
- }
- }
-}
+++ /dev/null
-/*
- * 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.OtnOtu;
-
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.Interface1;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.Interface1Builder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.OTU4;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.OtuAttributes.Fec;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.otu.interfaces.rev161014.otu.container.OtuBuilder;
-
-public class OpenRoadmOtu4Interface extends OpenRoadmInterfaces {
-
- public OpenRoadmOtu4Interface(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint,
- String serviceName) {
- super(db, mps, nodeId, logicalConnPoint, serviceName);
-
- }
-
- /**
- * This methods creates an OTU interface on the given termination point.
- *
- * @param supportOchInterface
- * support Och Interface
- *
- * @return Name of the interface if successful, otherwise return null.
- */
-
- public String createInterface(String supportOchInterface) {
- // Create generic interface
- InterfaceBuilder otuInterfaceBldr = getIntfBuilder(portMap);
- otuInterfaceBldr.setType(OtnOtu.class);
- otuInterfaceBldr.setSupportingInterface(supportOchInterface);
- otuInterfaceBldr.setName(logicalConnPoint + "-OTU");
- otuInterfaceBldr.setKey(new InterfaceKey(logicalConnPoint + "-OTU"));
-
- // OTU interface specific data
- OtuBuilder otuIfBuilder = new OtuBuilder();
- otuIfBuilder.setFec(Fec.Scfec);
- otuIfBuilder.setRate(OTU4.class);
-
- // Create Interface1 type object required for adding as augmentation
- Interface1Builder otuIf1Builder = new Interface1Builder();
- otuInterfaceBldr.addAugmentation(Interface1.class, otuIf1Builder.setOtu(otuIfBuilder.build()).build());
-
- // Post interface on the device
- if (postInterface(otuInterfaceBldr)) {
- return otuInterfaceBldr.getName();
- } else {
- return null;
- }
- }
-}
+++ /dev/null
-/*
- * 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.optical.channel.interfaces.rev161014.OchAttributes.ModulationFormat;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.RateIdentity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class OpenRoadmXponderInterface extends OpenRoadmInterfaces {
-
- private static final Logger LOG = LoggerFactory.getLogger(OpenRoadmXponderInterface.class);
- private final String serviceName;
-
- public OpenRoadmXponderInterface(DataBroker db, MountPointService mps, String nodeId, String logicalConnPoint,
- String serviceName) {
- super(db, mps, nodeId, logicalConnPoint,serviceName);
- this.serviceName = serviceName;
-
- }
-
- public boolean createLineInterfaces(Long waveNumber, Class<? extends RateIdentity> rate, ModulationFormat format) {
-
- String supportOchInterface = new OpenRoadmOchInterface(db, mps, nodeId, logicalConnPoint,serviceName)
- .createInterface(waveNumber, rate, format);
- String supportingOtuInterface;
- String supportingOduInterface;
-
- if (supportOchInterface != null) {
- supportingOtuInterface = new OpenRoadmOtu4Interface(db, mps, nodeId, logicalConnPoint,serviceName)
- .createInterface(supportOchInterface);
- } else {
- LOG.error("Unable to create OCH interface on the transponder");
- return false;
- }
- if (supportingOtuInterface != null) {
- supportingOduInterface = new OpenRoadmOdu4Interface(db, mps, nodeId, logicalConnPoint,serviceName)
- .createInterface(supportingOtuInterface);
- } else {
- LOG.error("Unable to create OTU interface on the transponder");
- return false;
- }
- if (supportingOduInterface != null) {
- return true;
- } else {
- LOG.error("Unable to create ODU interface on the transponder");
- return false;
- }
- }
-
- public boolean createClientInterfaces() {
-
- if (new OpenRoadmEthIterface(db, mps, nodeId, logicalConnPoint,serviceName).createInterface() != null) {
- return true;
- }
- return false;
- }
-}
+++ /dev/null
-/*
- * 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<RoadmConnections> 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.
- *
- * @return Roadm connection subtree from the device.
- */
- public RoadmConnections getCrossConnect() {
-
- if (deviceDb != null && connectionNumber != null) {
- ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
- Optional<RoadmConnections> 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<RoadmConnections> 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<Void, TransactionCommitFailedException> 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.
- *
- * @return true/false based on status of operation.
- */
-
- public boolean deleteCrossConnect() {
-
- //Check if cross connect exists before delete
- if (getCrossConnect() == 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<Void, TransactionCommitFailedException> 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.
- * @return true/false based on status of operation.
- */
- public boolean setPowerLevel(OpticalControlMode mode, PowerDBm value) {
-
- RoadmConnections rdmConn = getCrossConnect();
- 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<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
- try {
- submit.checkedGet();
- LOG.info("Roadm connection power level successfully set ");
- return true;
- } 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<RpcConsumerRegistry> 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<RpcResult<GetConnectionPortTrailOutput>> 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;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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 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;
-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;
-
-public class DeviceRenderer implements RendererService {
-
- private final DataBroker db;
- private final MountPointService mps;
- private static final Logger LOG = LoggerFactory.getLogger(RendererService.class);
- private final Set<String> currentMountedDevice;
- private final Set<String> nodesProvisioned;
-
- public DeviceRenderer(DataBroker db, MountPointService mps, Set<String> currentMountedDevice) {
- this.db = db;
- this.mps = mps;
- this.currentMountedDevice = currentMountedDevice;
- this.nodesProvisioned = new HashSet<>();
- }
-
- /**
- * 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:
- *
- * <p>
- * 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.
- *
- * <p>
- * 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.
- *
- * <p>
- * 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
- *
- * @return Result of the request
- */
- @Override
- public Future<RpcResult<ServicePathOutput>> servicePath(ServicePathInput input) {
-
- if (input.getOperation().getIntValue() == 1) {
- LOG.info("Create operation request received");
- return RpcResultBuilder.success(setupServicePath(input)).buildFuture();
- } else if (input.getOperation().getIntValue() == 2) {
- LOG.info("Delete operation request received");
- return RpcResultBuilder.success(deleteServicePath(input)).buildFuture();
- }
- return RpcResultBuilder.success(new ServicePathOutputBuilder().setResult("Invalid operation")).buildFuture();
- }
-
- /**
- * This method set's wavelength path based on the following steps.
- * For each node:
- *
- * <p>
- * 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.
- *
- * <p>
- * 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
- *
- * @return Result list of all nodes if request successful otherwise specific
- * reason of failure.
- */
- public ServicePathOutputBuilder setupServicePath(ServicePathInput input) {
-
- String serviceName = input.getServiceName();
- List<Nodes> nodes = input.getNodes();
- ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder();
- LOG.info(currentMountedDevice.toString());
- int crossConnectFlag;
- for (Nodes n : nodes) {
- LOG.info("Starting provisioning for node : {}", n.getNodeId());
- crossConnectFlag = 0;
- 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 mf = input.getModulationFormat();
- if (destTp.contains("LINE")) {
- crossConnectFlag++;
-
- ModulationFormat modulationFormat = null;
- for (int i = 0; i < ModulationFormat.values().length; i++) {
- ModulationFormat smodulationFormat = ModulationFormat.forValue(i);
- if (smodulationFormat.getName().equals(mf)) {
- modulationFormat = smodulationFormat;
- }
- }
- try {
- LOG.info("Modulation Format {} configured exists.", modulationFormat.getName());
- } catch (NullPointerException e) {
- LOG.error("{} modulation format does not exist.",mf);
- }
-
- if (!new OpenRoadmXponderInterface(db, mps, nodeId, destTp, serviceName)
- .createLineInterfaces(waveNumber, R100G.class, modulationFormat)) {
-
- return setServBldr.setResult("Unable to LINE interface on " + nodeId + " at " + destTp);
- }
- if (!activateService(nodeId, destTp, mps, true)) {
- return setServBldr
- .setResult("Unable to activate Equipment State on " + nodeId + " for " + destTp);
- }
- }
- if (srcTp.contains("CLNT")) {
- crossConnectFlag++;
- if (!new OpenRoadmXponderInterface(db, mps, nodeId, srcTp, serviceName).createClientInterfaces()) {
- return setServBldr.setResult("Unable to Client interface on " + nodeId + " at " + srcTp);
- }
- }
- String srcIf;
- 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 (srcIf == null) {
- 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 (dstIf == null) {
- 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 :{} destination {} for node {}", srcTp, destTp,
- n.getNodeId());
- DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps);
- String crossConnectName = srcTp + "-" + destTp + "-" + waveNumber;
- CrossConnect roadmConnections = new CrossConnect(netconfNodeDataBroker);
- if (roadmConnections.postCrossConnect(waveNumber, srcTp, destTp)) {
- nodesProvisioned.add(nodeId);
- roadmConnections.getConnectionPortTrail(nodeId, mps, waveNumber, srcTp, destTp);
- } else {
- return setServBldr.setResult("Unable to post Roadm-connection for node " + nodeId);
- }
- }
- } else {
- LOG.warn("{} is not mounted on the controller", nodeId);
- 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:
- *
- * <p>
- * 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.
- *
- * <p>
- * 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
- *
- * @return Result result of the request.
- */
- public ServicePathOutputBuilder deleteServicePath(ServicePathInput input) {
- List<Nodes> nodes = input.getNodes();
- ServicePathOutputBuilder delServBldr = new ServicePathOutputBuilder();
- LOG.info(currentMountedDevice.toString());
- for (Nodes n : nodes) {
-
- 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(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 {}-ODU on {}", destTp, nodeId);
- }
- if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
- .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 {}-{} 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 {} on {}", srcTp, nodeId);
- }
- continue;
- }
- String connectionNumber = srcTp + "-" + destTp + "-" + waveNumber;
- CrossConnect roadmConnection = new CrossConnect(PortMapping.getDeviceDataBroker(nodeId, mps),
- connectionNumber);
- if (!roadmConnection.deleteCrossConnect()) {
- 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 {}-{} 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 {}-{} on {}", destTp, waveNumber.toString(), nodeId);
- }
- } else {
- 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<CircuitPacks> circuitPackIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
- .child(CircuitPacks.class, new CircuitPacksKey(circuitPack));
- ReadOnlyTransaction readTx = deviceDb.newReadOnlyTransaction();
- // retrieve relevent CircuitPack object
- Optional<CircuitPacks> 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;
- }
- }
-}
--- /dev/null
+/*
+ * 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 org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackOutput;
+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;
+
+public interface DeviceRendererService {
+
+ /**
+ * This method set's wavelength path based on following steps.
+ *
+ * <p>
+ * 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.
+ *
+ * Naming convention used for OCH interfaces name : tp-wavenumber Naming
+ * convention used for cross connect name : src-dest-wavenumber
+ * </p>
+ *
+ * @param input
+ * Input parameter from the service-path yang model
+ *
+ * @return Result list of all nodes if request successful otherwise specific
+ * reason of failure.
+ */
+ ServicePathOutput setupServicePath(ServicePathInput input, ServicePathDirection direction);
+
+ /**
+ * This method removes wavelength path based on following steps.
+ *
+ * <p>
+ * 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.
+ *
+ * Naming convention used for OCH interfaces name : tp-wavenumber Naming
+ * convention used for cross connect name : src-dest-wavenumber
+ * </p>
+ *
+ * @param input
+ * Input parameter from the service-path yang model
+ *
+ * @return Result result of the request.
+ */
+ ServicePathOutput deleteServicePath(ServicePathInput input);
+
+ /**
+ * Rollback created interfaces and cross connects specified by input.
+ *
+ * @param input Lists of created interfaces and connections per node
+ * @return Success flag and nodes which failed to rollback
+ */
+ RendererRollbackOutput rendererRollback(RendererRollbackInput input);
+}
--- /dev/null
+/*
+ * 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.collect.Sets;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.common.Timeouts;
+import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
+import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl;
+import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory;
+import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServiceListTopology;
+import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.Topology;
+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.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.http.org.openroadm.service.rev161014.ServiceList;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.Services;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.node.interfaces.NodeInterface;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.node.interfaces.NodeInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.node.interfaces.NodeInterfaceKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.alarmsuppression.rev171102.ServiceNodelist;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.alarmsuppression.rev171102.service.nodelist.NodelistBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.alarmsuppression.rev171102.service.nodelist.NodelistKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackOutputBuilder;
+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.renderer.rollback.output.FailedToRollback;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.renderer.rollback.output.FailedToRollbackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.renderer.rollback.output.FailedToRollbackKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeviceRendererServiceImpl implements DeviceRendererService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeviceRendererServiceImpl.class);
+
+ private final DataBroker dataBroker;
+ private final DeviceTransactionManager deviceTransactionManager;
+ private final OpenRoadmInterfaceFactory openRoadmInterfaceFactory;
+ private final OpenRoadmInterfaces openRoadmInterfaces;
+ private final CrossConnect crossConnect;
+
+ public DeviceRendererServiceImpl(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
+ OpenRoadmInterfaceFactory openRoadmInterfaceFactory, OpenRoadmInterfaces openRoadmInterfaces,
+ CrossConnect crossConnect) {
+ this.dataBroker = dataBroker;
+ this.deviceTransactionManager = deviceTransactionManager;
+ this.openRoadmInterfaceFactory = openRoadmInterfaceFactory;
+ this.openRoadmInterfaces = openRoadmInterfaces;
+ this.crossConnect = crossConnect;
+ }
+
+ @Override
+ public ServicePathOutput setupServicePath(ServicePathInput input, ServicePathDirection direction) {
+ List<Nodes> nodes = input.getNodes();
+ // Register node for suppressing alarms
+ if (!alarmSuppressionNodeRegistration(input)) {
+ LOG.warn("Alarm suppresion node registraion failed!!!!");
+ }
+
+ ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
+ Set<NodeInterface> nodeInterfaces = Sets.newConcurrentHashSet();
+ Set<String> nodesProvisioned = Sets.newConcurrentHashSet();
+ ServiceListTopology topology = new ServiceListTopology();
+ AtomicBoolean success = new AtomicBoolean(true);
+
+ ForkJoinPool forkJoinPool = new ForkJoinPool();
+ ForkJoinTask forkJoinTask = forkJoinPool.submit(() ->
+ nodes.parallelStream().forEach(node -> {
+ String nodeId = node.getNodeId();
+ LOG.info("Starting provisioning for node : {}", nodeId);
+ List<String> createdEthInterfaces = new ArrayList<>();
+ List<String> createdOtuInterfaces = new ArrayList<>();
+ List<String> createdOduInterfaces = new ArrayList<>();
+ List<String> createdOchInterfaces = new ArrayList<>();
+ List<String> createdConnections = new ArrayList<>();
+ int crossConnectFlag = 0;
+
+ try {
+ // if the node is currently mounted then proceed
+ if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
+ String srcTp = node.getSrcTp();
+ String destTp = node.getDestTp();
+
+ Long waveNumber = input.getWaveNumber();
+ if ((destTp != null) && destTp.contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)) {
+ crossConnectFlag++;
+ // create OpenRoadm Xponder Line Interfaces
+ String supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
+ nodeId, destTp, waveNumber, R100G.class, ModulationFormat.DpQpsk);
+ createdOchInterfaces.add(supportingOchInterface);
+
+ String supportingOtuInterface = this.openRoadmInterfaceFactory.createOpenRoadmOtu4Interface(
+ nodeId, destTp, supportingOchInterface);
+ createdOtuInterfaces.add(supportingOtuInterface);
+
+ createdOduInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmOdu4Interface(
+ nodeId, destTp,supportingOtuInterface));
+ }
+ if ((srcTp != null) && srcTp.contains(OpenRoadmInterfacesImpl.CLIENT_TOKEN)) {
+ crossConnectFlag++;
+ // create OpenRoadm Xponder Client Interfaces
+ createdEthInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmEthInterface(nodeId,
+ srcTp));
+
+
+ }
+ if ((srcTp != null) && srcTp.contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)) {
+ crossConnectFlag++;
+ // create OpenRoadm Xponder Line Interfaces
+ String supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
+ nodeId, srcTp, waveNumber, R100G.class, ModulationFormat.DpQpsk);
+ createdOchInterfaces.add(supportingOchInterface);
+
+ String supportingOtuInterface = this.openRoadmInterfaceFactory.createOpenRoadmOtu4Interface(
+ nodeId, srcTp, supportingOchInterface);
+ createdOtuInterfaces.add(supportingOtuInterface);
+
+ createdOduInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmOdu4Interface(
+ nodeId, srcTp, supportingOtuInterface));
+ }
+ if ((destTp != null) && destTp.contains(OpenRoadmInterfacesImpl.CLIENT_TOKEN)) {
+ crossConnectFlag++;
+ // create OpenRoadm Xponder Client Interfaces
+ createdEthInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmEthInterface(nodeId,
+ destTp));
+
+
+ }
+ if ((srcTp != null) && (srcTp.contains(OpenRoadmInterfacesImpl.TTP_TOKEN)
+ || srcTp.contains(OpenRoadmInterfacesImpl.PP_TOKEN))) {
+ createdOchInterfaces.add(this.openRoadmInterfaceFactory .createOpenRoadmOchInterface(nodeId,
+ srcTp, waveNumber));
+ }
+ if ((destTp != null) && (destTp.contains(OpenRoadmInterfacesImpl.TTP_TOKEN)
+ || destTp.contains(OpenRoadmInterfacesImpl.PP_TOKEN))) {
+ createdOchInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(nodeId,
+ destTp, waveNumber));
+ }
+ if (crossConnectFlag < 1) {
+ LOG.info("Creating cross connect between source {} and destination {} for node {}",
+ srcTp, destTp, nodeId);
+ Optional<String> connectionNameOpt = this.crossConnect.postCrossConnect(nodeId, waveNumber,
+ srcTp, destTp);
+ if (connectionNameOpt.isPresent()) {
+ nodesProvisioned.add(nodeId);
+ List<Ports> ports = this.crossConnect.getConnectionPortTrail(nodeId, waveNumber, srcTp,
+ destTp);
+ if (ServicePathDirection.A_TO_Z.equals(direction)) {
+ topology.updateAtoZTopologyList(ports, nodeId);
+ }
+ if (ServicePathDirection.Z_TO_A.equals(direction)) {
+ topology.updateZtoATopologyList(ports, nodeId);
+
+ }
+ createdConnections.add(connectionNameOpt.get());
+ } else {
+ processErrorMessage("Unable to post Roadm-connection for node " + nodeId, forkJoinPool,
+ results);
+ success.set(false);
+ }
+ }
+ } else {
+ processErrorMessage(nodeId + " is not mounted on the controller", forkJoinPool, results);
+ success.set(false);
+ }
+ } catch (OpenRoadmInterfaceException ex) {
+ processErrorMessage("Setup service path failed! Exception:" + ex.toString(), forkJoinPool, results);
+ success.set(false);
+ }
+
+ NodeInterfaceBuilder nodeInterfaceBuilder = new NodeInterfaceBuilder();
+ nodeInterfaceBuilder.setKey(new NodeInterfaceKey(nodeId));
+ nodeInterfaceBuilder.setNodeId(nodeId);
+ nodeInterfaceBuilder.setConnectionId(createdConnections);
+ nodeInterfaceBuilder.setEthInterfaceId(createdEthInterfaces);
+ nodeInterfaceBuilder.setOtuInterfaceId(createdOtuInterfaces);
+ nodeInterfaceBuilder.setOduInterfaceId(createdOduInterfaces);
+ nodeInterfaceBuilder.setOchInterfaceId(createdOchInterfaces);
+ nodeInterfaces.add(nodeInterfaceBuilder.build());
+ })
+ );
+
+ try {
+ forkJoinTask.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Error while setting up service paths!", e);
+ }
+
+ forkJoinPool.shutdown();
+
+ if (success.get()) {
+ results.add("Roadm-connection successfully created for nodes: " + String.join(", ", nodesProvisioned));
+ }
+ ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder();
+ setServBldr.setNodeInterface(new ArrayList<>(nodeInterfaces));
+ setServBldr.setSuccess(success.get());
+ setServBldr.setResult(String.join("\n", results));
+
+ //setting topology in the service list data store
+ try {
+ setTopologyForService(input.getServiceName(), topology.getTopology());
+ } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ LOG.warn("Failed to write topologies for service {}.", input.getServiceName(), e);
+ }
+
+ if (!alarmSuppressionNodeRemoval(input.getServiceName())) {
+ LOG.error("Alarm suppresion node removal failed!!!!");
+ }
+
+ return setServBldr.build();
+ }
+
+ private ConcurrentLinkedQueue<String> processErrorMessage(String message, ForkJoinPool forkJoinPool,
+ ConcurrentLinkedQueue<String> messages) {
+ LOG.warn(message);
+ messages.add(message);
+ forkJoinPool.shutdown();
+ return messages;
+ }
+
+ @Override
+ public ServicePathOutput deleteServicePath(ServicePathInput input) {
+ List<Nodes> nodes = input.getNodes();
+ ServicePathOutputBuilder delServBldr = new ServicePathOutputBuilder();
+
+ ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
+ if (!alarmSuppressionNodeRegistration(input)) {
+ LOG.warn("Alarm suppresion node registraion failed!!!!");
+ }
+ ForkJoinPool forkJoinPool = new ForkJoinPool();
+ ForkJoinTask forkJoinTask = forkJoinPool.submit(() ->
+ nodes.parallelStream().forEach(node -> {
+ List<String> interfacesToDelete = new LinkedList<>();
+ String nodeId = node.getNodeId();
+ LOG.info("Deleting service setup on node {}", nodeId);
+ String srcTp = node.getSrcTp();
+ String destTp = node.getDestTp();
+ Long waveNumber = input.getWaveNumber();
+
+ if ((srcTp == null) || (destTp == null)) {
+ LOG.error("Source ({}) or destination ({}) termination point is null.", srcTp, destTp);
+ return;
+ }
+
+ // if the node is currently mounted then proceed.
+ if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
+ if (destTp.contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)
+ || srcTp.contains(OpenRoadmInterfacesImpl.CLIENT_TOKEN)) {
+ if (destTp.contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)) {
+ interfacesToDelete.add(destTp + "-ODU");
+ interfacesToDelete.add(destTp + "-OTU");
+ interfacesToDelete.add(
+ this.openRoadmInterfaceFactory.createOpenRoadmOchInterfaceName(destTp, waveNumber));
+ }
+ if (srcTp.contains(OpenRoadmInterfacesImpl.CLIENT_TOKEN)) {
+ interfacesToDelete.add(srcTp + "-ETHERNET");
+ }
+ } else {
+ String connectionNumber = srcTp + "-" + destTp + "-" + waveNumber;
+ if (!this.crossConnect.deleteCrossConnect(nodeId, connectionNumber)) {
+ LOG.error("Failed to delete cross connect {}", srcTp + "-" + destTp + "-" + waveNumber);
+ }
+ interfacesToDelete.add(
+ this.openRoadmInterfaceFactory.createOpenRoadmOchInterfaceName(srcTp, waveNumber));
+ interfacesToDelete.add(
+ this.openRoadmInterfaceFactory.createOpenRoadmOchInterfaceName(destTp, waveNumber));
+ }
+ } else {
+ String result = nodeId + " is not mounted on the controller";
+ results.add(result);
+ LOG.warn(result);
+ forkJoinPool.shutdown();
+ return; // TODO should deletion end here?
+ }
+
+ for (String interfaceId : interfacesToDelete) {
+ try {
+ this.openRoadmInterfaces.deleteInterface(nodeId, interfaceId);
+ } catch (OpenRoadmInterfaceException e) {
+ String result = String.format("Failed to delete interface %s on node %s!", interfaceId, nodeId);
+ LOG.error(result, e);
+ results.add(result);
+ }
+ }
+ })
+ );
+
+ try {
+ forkJoinTask.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Error while deleting service paths!", e);
+ }
+
+ forkJoinPool.shutdown();
+ if (!alarmSuppressionNodeRemoval(input.getServiceName())) {
+ LOG.error("Alarm suppresion node removal failed!!!!");
+ }
+ if (results.isEmpty()) {
+ return delServBldr.setResult("Request processed").build();
+ } else {
+ return delServBldr.setResult(String.join("\n", results)).build();
+ }
+ }
+
+ @Override
+ public RendererRollbackOutput rendererRollback(RendererRollbackInput input) {
+ boolean success = true;
+ List<FailedToRollback> failedToRollbackList = new ArrayList<>();
+ for (NodeInterface nodeInterfaces : input.getNodeInterface()) {
+ List<String> failedInterfaces = new ArrayList<>();
+ String nodeId = nodeInterfaces.getNodeId();
+ for (String connectionId : nodeInterfaces.getConnectionId()) {
+ if (this.crossConnect.deleteCrossConnect(nodeId, connectionId)) {
+ LOG.info("Cross connect {} on node {} successfully deleted.", connectionId, nodeId);
+ } else {
+ LOG.error("Failed to delete cross connect {} on node {}!", connectionId, nodeId);
+ success = false;
+ failedInterfaces.add(connectionId);
+ }
+ }
+ // Interfaces needs to be in specific order to delete. Order is:
+ // 1. ODU interfaces
+ // 2. OTU interfaces
+ // 3. OCH interfaces
+ // 4. ETH interfaces
+ LinkedList<String> interfacesToDelete = new LinkedList<>();
+ if (nodeInterfaces.getOduInterfaceId() != null) {
+ interfacesToDelete.addAll(nodeInterfaces.getOduInterfaceId());
+ }
+ if (nodeInterfaces.getOtuInterfaceId() != null) {
+ interfacesToDelete.addAll(nodeInterfaces.getOtuInterfaceId());
+ }
+ if (nodeInterfaces.getOchInterfaceId() != null) {
+ interfacesToDelete.addAll(nodeInterfaces.getOchInterfaceId());
+ }
+ if (nodeInterfaces.getEthInterfaceId() != null) {
+ interfacesToDelete.addAll(nodeInterfaces.getEthInterfaceId());
+ }
+
+ LOG.info("Going to execute rollback on node {}. Interfaces to rollback: {}", nodeId,
+ String.join(", ", interfacesToDelete));
+
+ for (String interfaceId : interfacesToDelete) {
+ try {
+ this.openRoadmInterfaces.deleteInterface(nodeId, interfaceId);
+ LOG.info("Interface {} on node {} successfully deleted.", interfaceId, nodeId);
+ } catch (OpenRoadmInterfaceException e) {
+ LOG.error("Failed to delete interface {} on node {}!", interfaceId, nodeId);
+ success = false;
+ failedInterfaces.add(interfaceId);
+ }
+ }
+ failedToRollbackList.add(new FailedToRollbackBuilder()
+ .setKey(new FailedToRollbackKey(nodeId))
+ .setNodeId(nodeId)
+ .setInterface(failedInterfaces)
+ .build()
+ );
+ }
+ return new RendererRollbackOutputBuilder()
+ .setSuccess(success)
+ .setFailedToRollback(failedToRollbackList)
+ .build();
+ }
+
+ private boolean alarmSuppressionNodeRegistration(ServicePathInput input) {
+ NodelistBuilder nodeListBuilder = new NodelistBuilder();
+ nodeListBuilder.setKey(new NodelistKey(input.getServiceName()));
+ nodeListBuilder.setServiceName(input.getServiceName());
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.alarmsuppression.rev171102.service
+ .nodelist.nodelist.Nodes> nodeList = new ArrayList<>();
+ for (Nodes node: input.getNodes()) {
+ nodeList.add(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
+ .yang.alarmsuppression.rev171102.service.nodelist.nodelist.NodesBuilder()
+ .setNodeId(node.getNodeId()).build());
+ }
+ nodeListBuilder.setNodes(nodeList);
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params
+ .xml.ns.yang.alarmsuppression.rev171102.service.nodelist.Nodelist> nodeListIID =
+ InstanceIdentifier.create(ServiceNodelist.class).child(org.opendaylight.yang.gen.v1.urn
+ .opendaylight.params.xml.ns.yang.alarmsuppression.rev171102.service.nodelist.Nodelist.class,
+ new NodelistKey(input.getServiceName()));
+ final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
+ writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodeListIID, nodeListBuilder.build());
+ Future<Void> submit = writeTransaction.submit();
+ try {
+ submit.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
+ LOG.info("Nodes are register for alarm suppression for service: {}",
+ input.getServiceName());
+ return true;
+
+ } catch (ExecutionException | InterruptedException | TimeoutException e) {
+ LOG.warn("Failed to alarm suppresslist for service: {}", input.getServiceName(), e);
+ return false;
+ }
+ }
+
+ private boolean alarmSuppressionNodeRemoval(String serviceName) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params
+ .xml.ns.yang.alarmsuppression.rev171102.service.nodelist.Nodelist> nodeListIID =
+ InstanceIdentifier.create(ServiceNodelist.class).child(org.opendaylight.yang.gen.v1.urn
+ .opendaylight.params.xml.ns.yang.alarmsuppression.rev171102.service.nodelist.Nodelist.class,
+ new NodelistKey(serviceName));
+ final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, nodeListIID);
+ Future<Void> submit = writeTransaction.submit();
+ try {
+ submit.get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
+ LOG.info("Nodes are unregister for alarm suppression for service: {}", serviceName);
+ return true;
+
+ } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ LOG.warn("Failed to alarm suppresslist for service: {}", serviceName, e);
+ return false;
+ }
+ }
+
+ private void setTopologyForService(String serviceName, Topology topo)
+ throws InterruptedException, ExecutionException, TimeoutException {
+
+ ServicesBuilder servicesBuilder;
+ //Get the service from the service list inventory
+
+ ServicesKey serviceKey = new ServicesKey(serviceName);
+ InstanceIdentifier<Services> iid =
+ InstanceIdentifier.create(ServiceList.class).child(Services.class, serviceKey);
+ Optional<Services> services;
+ try (ReadOnlyTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
+ Future<com.google.common.base.Optional<Services>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,
+ iid);
+ services = future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).toJavaUtil();
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw e;
+ }
+
+ if (services.isPresent()) {
+ servicesBuilder = new ServicesBuilder(services.get());
+ } else {
+ servicesBuilder = new ServicesBuilder();
+ servicesBuilder.setKey(serviceKey);
+ }
+ servicesBuilder.setTopology(topo);
+
+ WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+ writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, servicesBuilder.build());
+ writeTx.submit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
+
+ }
+}
--- /dev/null
+/*
+ * 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 java.util.Collections;
+import java.util.List;
+import org.opendaylight.transportpce.common.OperationResult;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.node.interfaces.NodeInterface;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.Nodes;
+
+public class DeviceRenderingResult extends OperationResult {
+
+ private final List<Nodes> olmList;
+ private final List<NodeInterface> renderedNodeInterfaces;
+
+ private DeviceRenderingResult(boolean success, String message, List<Nodes> olmList,
+ List<NodeInterface> renderedNodeInterfaces) {
+ super(success, message);
+ if (olmList != null) {
+ this.olmList = Collections.unmodifiableList(olmList);
+ } else {
+ this.olmList = Collections.emptyList();
+ }
+
+ if (renderedNodeInterfaces != null) {
+ this.renderedNodeInterfaces = Collections.unmodifiableList(renderedNodeInterfaces);
+ } else {
+ this.renderedNodeInterfaces = Collections.emptyList();
+ }
+ }
+
+ public List<Nodes> getOlmList() {
+ return this.olmList;
+ }
+
+ public List<NodeInterface> getRenderedNodeInterfaces() {
+ return this.renderedNodeInterfaces;
+ }
+
+ public static DeviceRenderingResult failed(String message) {
+ return new DeviceRenderingResult(false, message, null, null);
+ }
+
+ public static DeviceRenderingResult ok(List<Nodes> olmList, List<NodeInterface> renderedNodeInterfaces) {
+ return new DeviceRenderingResult(true, "", olmList, renderedNodeInterfaces);
+ }
+
+}
--- /dev/null
+/*
+ * 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 org.opendaylight.transportpce.common.OperationResult;
+
+public class OLMRenderingResult extends OperationResult {
+
+ private OLMRenderingResult(boolean success, String message) {
+ super(success, message);
+ }
+
+ public static OLMRenderingResult failed(String message) {
+ return new OLMRenderingResult(false, message);
+ }
+
+ public static OLMRenderingResult ok() {
+ return new OLMRenderingResult(true, "");
+ }
+
+}
--- /dev/null
+/*
+ * 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 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutput;
+
+public interface RendererServiceOperations {
+
+ ServiceImplementationRequestOutput serviceImplementation(ServiceImplementationRequestInput input);
+
+ ServiceDeleteOutput serviceDelete(ServiceDeleteInput input);
+
+}
--- /dev/null
+/*
+ * 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.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+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.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.transportpce.common.ResponseCodes;
+import org.opendaylight.transportpce.common.Timeouts;
+import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl;
+import org.opendaylight.transportpce.renderer.ModelMappingUtils;
+import org.opendaylight.transportpce.renderer.NetworkModelWavelengthService;
+import org.opendaylight.transportpce.renderer.ServicePathInputData;
+import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
+import org.opendaylight.transportpce.renderer.provisiondevice.tasks.DeviceRenderingRollbackTask;
+import org.opendaylight.transportpce.renderer.provisiondevice.tasks.DeviceRenderingTask;
+import org.opendaylight.transportpce.renderer.provisiondevice.tasks.OlmPowerSetupRollbackTask;
+import org.opendaylight.transportpce.renderer.provisiondevice.tasks.OlmPowerSetupTask;
+import org.opendaylight.transportpce.renderer.provisiondevice.tasks.RollbackProcessor;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmGranularity;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.PathDescription;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathList;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePaths;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.get.pm.input.ResourceIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class RendererServiceOperationsImpl implements RendererServiceOperations {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RendererServiceOperationsImpl.class);
+ private static final String FAILED = "Failed";
+ private static final String OPERATION_FAILED = "Operation Failed";
+ private static final String OPERATION_SUCCESSFUL = "Operation Successful";
+ private static final int NUMBER_OF_THREADS = 4;
+
+ private final DeviceRendererService deviceRenderer;
+ private final OlmService olmService;
+ private final DataBroker dataBroker;
+ private ListeningExecutorService executor;
+ private NetworkModelWavelengthService networkModelWavelengthService;
+
+ public RendererServiceOperationsImpl(DeviceRendererService deviceRenderer, OlmService olmService,
+ DataBroker dataBroker, NetworkModelWavelengthService networkModelWavelengthService) {
+ this.deviceRenderer = deviceRenderer;
+ this.olmService = olmService;
+ this.dataBroker = dataBroker;
+ this.networkModelWavelengthService = networkModelWavelengthService;
+ this.executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUMBER_OF_THREADS));
+ }
+
+ @Override
+ public ServiceImplementationRequestOutput serviceImplementation(ServiceImplementationRequestInput input) {
+ LOG.info("Calling service impl request {} {}", input.getServiceName());
+ RollbackProcessor rollbackProcessor = new RollbackProcessor();
+
+ ServicePathInputData servicePathInputDataAtoZ
+ = ModelMappingUtils.rendererCreateServiceInputAToZ(input.getServiceName(),
+ input.getPathDescription());
+ ServicePathInputData servicePathInputDataZtoA
+ = ModelMappingUtils.rendererCreateServiceInputZToA(input.getServiceName(),
+ input.getPathDescription());
+ List<DeviceRenderingResult> renderingResults = deviceRendering(rollbackProcessor, servicePathInputDataAtoZ,
+ servicePathInputDataZtoA);
+ if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
+ return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
+ }
+
+ ServicePowerSetupInput olmPowerSetupInputAtoZ = ModelMappingUtils.createServicePowerSetupInput(
+ renderingResults.get(0).getOlmList(), input);
+ ServicePowerSetupInput olmPowerSetupInputZtoA = ModelMappingUtils.createServicePowerSetupInput(
+ renderingResults.get(1).getOlmList(), input);
+ olmPowerSetup(rollbackProcessor, olmPowerSetupInputAtoZ, olmPowerSetupInputZtoA);
+ if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
+ return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
+ }
+
+ // run service activation test twice - once on source node and once on destination node
+ List<Nodes> nodes = servicePathInputDataAtoZ.getServicePathInput().getNodes();
+ Nodes sourceNode = nodes.get(0);
+ Nodes destNode = nodes.get(nodes.size() - 1);
+
+ String srcNetworkTp;
+ String dstNetowrkTp;
+
+ if (sourceNode.getDestTp().contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)) {
+ srcNetworkTp = sourceNode.getDestTp();
+ } else {
+ srcNetworkTp = sourceNode.getSrcTp();
+ }
+ if (destNode.getDestTp().contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)) {
+ dstNetowrkTp = destNode.getDestTp();
+ } else {
+ dstNetowrkTp = destNode.getSrcTp();
+ }
+
+ if (!isServiceActivated(sourceNode.getNodeId(), srcNetworkTp)
+ || !isServiceActivated(destNode.getNodeId(), dstNetowrkTp)) {
+ rollbackProcessor.rollbackAll();
+ return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
+ }
+
+ //If Service activation is success update Network ModelMappingUtils
+ this.networkModelWavelengthService.useWavelengths(input.getPathDescription());
+
+ return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
+ }
+
+ @Override
+ public ServiceDeleteOutput serviceDelete(ServiceDeleteInput input) {
+ String serviceName = input.getServiceName();
+
+ // Obtain path description
+ Optional<PathDescription> pathDescriptionOpt = getPathDescriptionFromDatastore(serviceName);
+ PathDescription pathDescription;
+ if (pathDescriptionOpt.isPresent()) {
+ pathDescription = pathDescriptionOpt.get();
+ } else {
+ LOG.error("Unable to get path description for service {}!", serviceName);
+ return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
+ }
+
+ ServicePathInputData servicePathInputDataAtoZ
+ = ModelMappingUtils.rendererCreateServiceInputAToZ(serviceName, pathDescription);
+ ServicePathInputData servicePathInputDataZtoA
+ = ModelMappingUtils.rendererCreateServiceInputZToA(serviceName, pathDescription);
+
+ // OLM turn down power
+ try {
+ LOG.debug("Turning down power on A-to-Z path");
+ ServicePowerTurndownOutput atozPowerTurndownOutput = olmPowerTurndown(servicePathInputDataAtoZ);
+ // TODO add some flag rather than string
+ if (FAILED.equals(atozPowerTurndownOutput.getResult())) {
+ LOG.error("Service power turndown failed on A-to-Z path for service {}!", serviceName);
+ return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
+ }
+
+ LOG.debug("Turning down power on Z-to-A path");
+ ServicePowerTurndownOutput ztoaPowerTurndownOutput = olmPowerTurndown(servicePathInputDataZtoA);
+ // TODO add some flag rather than string
+ if (FAILED.equals(ztoaPowerTurndownOutput.getResult())) {
+ LOG.error("Service power turndown failed on Z-to-A path for service {}!", serviceName);
+ return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
+ }
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.error("Error while turning down power!", e);
+ return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
+ }
+
+ // delete service path with renderer
+ LOG.debug("Deleting service path via renderer");
+ this.deviceRenderer.deleteServicePath(servicePathInputDataAtoZ.getServicePathInput());
+ this.deviceRenderer.deleteServicePath(servicePathInputDataZtoA.getServicePathInput());
+
+ this.networkModelWavelengthService.freeWavelengths(pathDescription);
+
+ return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
+ }
+
+ private ServicePowerTurndownOutput olmPowerTurndown(ServicePathInputData servicePathInputData)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ LOG.debug("Turning down power on A-to-Z path");
+ Future<RpcResult<ServicePowerTurndownOutput>> powerTurndownFuture = this.olmService.servicePowerTurndown(
+ new ServicePowerTurndownInputBuilder(servicePathInputData.getServicePathInput()).build());
+ return powerTurndownFuture.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).getResult();
+ }
+
+ private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
+ InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
+ .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
+ ReadOnlyTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
+ try {
+ LOG.debug("Getting path description for service {}", serviceName);
+ return pathDescReadTx.read(LogicalDatastoreType.OPERATIONAL, pathDescriptionIID)
+ .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("Exception while getting path description from datastore {} for service {}!", pathDescriptionIID,
+ serviceName, e);
+ return Optional.absent();
+ }
+ }
+
+ private List<DeviceRenderingResult> deviceRendering(RollbackProcessor rollbackProcessor,
+ ServicePathInputData servicePathDataAtoZ, ServicePathInputData servicePathDataZtoA) {
+ LOG.info("Rendering devices A-Z");
+ ListenableFuture<DeviceRenderingResult> atozrenderingFuture =
+ this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataAtoZ,
+ ServicePathDirection.A_TO_Z));
+
+ LOG.info("Rendering devices Z-A");
+ ListenableFuture<DeviceRenderingResult> ztoarenderingFuture =
+ this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataZtoA,
+ ServicePathDirection.Z_TO_A));
+ ListenableFuture<List<DeviceRenderingResult>> renderingCombinedFuture =
+ Futures.allAsList(atozrenderingFuture, ztoarenderingFuture);
+
+ List<DeviceRenderingResult> renderingResults = new ArrayList<>(2);
+ try {
+ LOG.info("Waiting for A-Z and Z-A device renderers ...");
+ renderingResults = renderingCombinedFuture.get(Timeouts.RENDERING_TIMEOUT, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("Device rendering was not successful! Rendering will be rolled back.", e);
+ //FIXME we can't do rollback here, because we don't have rendering results.
+ //rollbackProcessor.addTask(new DeviceRenderingRollbackTask("AtoZDeviceTask", true));
+ //rollbackProcessor.addTask(new DeviceRenderingRollbackTask("ZtoADeviceTask", true));
+ return renderingResults;
+ }
+
+ rollbackProcessor.addTask(new DeviceRenderingRollbackTask("AtoZDeviceTask",
+ ! renderingResults.get(0).isSuccess(), renderingResults.get(0).getRenderedNodeInterfaces(),
+ this.deviceRenderer));
+ rollbackProcessor.addTask(new DeviceRenderingRollbackTask("ZtoADeviceTask",
+ ! renderingResults.get(1).isSuccess(), renderingResults.get(1).getRenderedNodeInterfaces(),
+ this.deviceRenderer));
+ return renderingResults;
+ }
+
+ private void olmPowerSetup(RollbackProcessor rollbackProcessor, ServicePowerSetupInput powerSetupInputAtoZ,
+ ServicePowerSetupInput powerSetupInputZtoA) {
+ LOG.info("Olm power setup A-Z");
+ ListenableFuture<OLMRenderingResult> olmPowerSetupFutureAtoZ
+ = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputAtoZ));
+
+ LOG.info("OLM power setup Z-A");
+ ListenableFuture<OLMRenderingResult> olmPowerSetupFutureZtoA
+ = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputZtoA));
+ ListenableFuture<List<OLMRenderingResult>> olmFutures =
+ Futures.allAsList(olmPowerSetupFutureAtoZ, olmPowerSetupFutureZtoA);
+
+ List<OLMRenderingResult> olmResults;
+ try {
+ LOG.info("Waiting for A-Z and Z-A OLM power setup ...");
+ olmResults = olmFutures.get(Timeouts.OLM_TIMEOUT, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ LOG.warn("OLM power setup was not successful! Rendering and OLM will be rolled back.", e);
+ rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", true,
+ this.olmService, powerSetupInputAtoZ));
+ rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", true,
+ this.olmService, powerSetupInputZtoA));
+ return;
+ }
+
+ rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", ! olmResults.get(0).isSuccess(),
+ this.olmService, powerSetupInputAtoZ));
+ rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", ! olmResults.get(1).isSuccess(),
+ this.olmService, powerSetupInputZtoA));
+ }
+
+ private boolean isServiceActivated(String nodeId, String tpId) {
+ LOG.info("Starting service activation test on node {} and tp {}", nodeId, tpId);
+ for (int i = 0; i < 3; i++) {
+ List<Measurements> measurements = getMeasurements(nodeId, tpId);
+ if ((measurements != null) && verifyPreFecBer(measurements)) {
+ return true;
+ } else if (measurements == null) {
+ LOG.warn("Device {} is not reporting PreFEC on TP: {}", nodeId, tpId);
+ return true;
+ } else {
+ try {
+ Thread.sleep(Timeouts.SERVICE_ACTIVATION_TEST_RETRY_TIME);
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ LOG.error("Service activation test failed on node {} and termination point {}!", nodeId, tpId);
+ return false;
+ }
+
+ private List<Measurements> getMeasurements(String nodeId, String tp) {
+ GetPmInputBuilder getPmIpBldr = new GetPmInputBuilder();
+ getPmIpBldr.setNodeId(nodeId);
+ getPmIpBldr.setGranularity(PmGranularity._15min);
+ ResourceIdentifierBuilder rsrcBldr = new ResourceIdentifierBuilder();
+ rsrcBldr.setResourceName(tp + "-OTU");
+ getPmIpBldr.setResourceIdentifier(rsrcBldr.build());
+ getPmIpBldr.setResourceType(ResourceTypeEnum.Interface);
+
+ try {
+ Future<RpcResult<GetPmOutput>> getPmFuture = this.olmService.getPm(getPmIpBldr.build());
+ RpcResult<GetPmOutput> getPmRpcResult = getPmFuture.get();
+ GetPmOutput getPmOutput = getPmRpcResult.getResult();
+ if ((getPmOutput != null) && (getPmOutput.getNodeId() != null)) {
+ LOG.info("successfully finished calling OLM's get PM");
+ return getPmOutput.getMeasurements(); // may return null
+
+ } else {
+ LOG.warn("OLM's get PM failed for node {} and tp {}", nodeId, tp);
+ }
+
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.warn("Error occurred while getting PM for node {} and tp {}", nodeId, tp, e);
+ }
+ return null;
+ }
+
+
+ private boolean verifyPreFecBer(List<Measurements> measurements) {
+ double preFecCorrectedErrors = Double.MIN_VALUE;
+ double fecUncorrectableBlocks = Double.MIN_VALUE;
+
+ for (Measurements measurement : measurements) {
+ if (measurement.getPmparameterName().equals("preFECCorrectedErrors")) {
+ preFecCorrectedErrors = Double.parseDouble(measurement.getPmparameterValue());
+ }
+ if (measurement.getPmparameterName().equals("FECUncorrectableBlocks")) {
+ fecUncorrectableBlocks = Double.parseDouble(measurement.getPmparameterValue());
+ }
+ }
+
+ LOG.info("Measurements: preFECCorrectedErrors = {}; FECUncorrectableBlocks = {}", preFecCorrectedErrors,
+ fecUncorrectableBlocks);
+
+ if (fecUncorrectableBlocks > Double.MIN_VALUE) {
+ LOG.error("Data has uncorrectable errors, BER test failed");
+ return false;
+ } else {
+ double numOfBitsPerSecond = 112000000000d;
+ double threshold = 0.00002d;
+ double result = preFecCorrectedErrors / numOfBitsPerSecond;
+ LOG.info("PreFEC value is {}", Double.toString(result));
+ return result <= threshold;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.servicepath;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.Topology;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.TopologyBuilder;
+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.resource.rev161014.resource.DeviceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.ResourceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.ResourceTypeBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.port.PortBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.Hop.HopType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.AToZBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.ZToABuilder;
+
+public class ServiceListTopology {
+
+
+ private List<AToZ> a2zTopologyList;
+ private List<ZToA> z2aTopologyList;
+ private TopologyBuilder serviceTopology;
+
+ public ServiceListTopology() {
+
+ this.a2zTopologyList = new ArrayList<>();
+ this.z2aTopologyList = new ArrayList<>();
+ this.serviceTopology = new TopologyBuilder();
+
+ }
+
+ public void updateAtoZTopologyList(List<Ports> ports, String nodeId) {
+
+ String circuitPackName = "";
+ String portName = "";
+
+ int id = this.a2zTopologyList.size();
+
+ DeviceBuilder deviceBldr = new DeviceBuilder();
+ deviceBldr.setNodeId(nodeId);
+
+
+ for (Ports port : ports) {
+
+ id = id + 1;
+
+ //Get circuitpack name
+ circuitPackName = port.getCircuitPackName();
+
+ //Get port name
+ portName = port.getPortName().toString();
+
+ AToZBuilder a2zBldr = new AToZBuilder();
+
+ //Set Resource Id
+ a2zBldr.setId(Integer.toString(id));
+
+ //Set device Node-id
+ a2zBldr.setDevice(deviceBldr.build());
+
+ //Set hop type to internal
+ a2zBldr.setHopType(HopType.NodeInternal);
+
+ //Set Resource Type to port
+ ResourceTypeBuilder rsrcTypeBldr = new ResourceTypeBuilder();
+ rsrcTypeBldr.setType(ResourceTypeEnum.Port);
+ a2zBldr.setResourceType(rsrcTypeBldr.build());
+
+ //building port resource
+ PortBuilder portBldr = new PortBuilder();
+ portBldr.setCircuitPackName(circuitPackName);
+ portBldr.setPortName(portName);
+ org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource
+ .PortBuilder portCase =
+ new org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource
+ .PortBuilder();
+ portCase.setPort(portBldr.build());
+ ResourceBuilder rsrcBldr = new ResourceBuilder();
+ rsrcBldr.setResource(portCase.build());
+ a2zBldr.setResource(rsrcBldr.build());
+
+ //Add port resource to the list
+ this.a2zTopologyList.add(a2zBldr.build());
+
+ }
+
+ //update Topology
+ this.serviceTopology.setAToZ(this.a2zTopologyList);
+
+ }
+
+ public void updateZtoATopologyList(List<Ports> ports, String nodeId) {
+
+ String circuitPackName = "";
+ String portName = "";
+
+ int id = this.a2zTopologyList.size();
+
+ DeviceBuilder deviceBldr = new DeviceBuilder();
+ deviceBldr.setNodeId(nodeId);
+
+ for (Ports port : ports) {
+
+ id = id + 1;
+
+ //Get circuitpack name
+ circuitPackName = port.getCircuitPackName();
+
+ //Get port name
+ portName = port.getPortName().toString();
+
+ ZToABuilder z2aBldr = new ZToABuilder();
+
+ //Set Resource Id
+ z2aBldr.setId(Integer.toString(id));
+
+ //Set device Node-id
+ z2aBldr.setDevice(deviceBldr.build());
+
+ //Set hop type to internal
+ z2aBldr.setHopType(HopType.NodeInternal);
+
+ //Set Resource Type to port
+ ResourceTypeBuilder rsrcTypeBldr = new ResourceTypeBuilder();
+ rsrcTypeBldr.setType(ResourceTypeEnum.Port);
+ z2aBldr.setResourceType(rsrcTypeBldr.build());
+
+ //building port resource
+ PortBuilder portBldr = new PortBuilder();
+ portBldr.setCircuitPackName(circuitPackName);
+ portBldr.setPortName(portName);
+ org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource
+ .PortBuilder portCase =
+ new org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource
+ .PortBuilder();
+ portCase.setPort(portBldr.build());
+ ResourceBuilder rsrcBldr = new ResourceBuilder();
+ rsrcBldr.setResource(portCase.build());
+ z2aBldr.setResource(rsrcBldr.build());
+
+ //Add port resource to the list
+ this.z2aTopologyList.add(z2aBldr.build());
+
+ }
+
+ }
+
+ public Topology getTopology() {
+ this.serviceTopology.setAToZ(this.a2zTopologyList);
+ this.serviceTopology.setZToA(this.z2aTopologyList);
+ return this.serviceTopology.build();
+ }
+
+}
--- /dev/null
+/*
+ * 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.servicepath;
+
+public enum ServicePathDirection {
+ A_TO_Z,
+ Z_TO_A
+}
--- /dev/null
+/*
+ * 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.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.transportpce.renderer.provisiondevice.DeviceRendererService;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.node.interfaces.NodeInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.renderer.rollback.output.FailedToRollback;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeviceRenderingRollbackTask extends RollbackTask {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeviceRenderingRollbackTask.class);
+ private final boolean isRollbackNecessary;
+ private final DeviceRendererService rendererService;
+ private final List<NodeInterface> renderedInterfaces;
+
+ public DeviceRenderingRollbackTask(String id, boolean isRollbackNecessary, List<NodeInterface> renderedInterfaces,
+ DeviceRendererService rendererService) {
+ super(id);
+ this.isRollbackNecessary = isRollbackNecessary;
+ this.rendererService = rendererService;
+ this.renderedInterfaces = renderedInterfaces;
+ }
+
+ @Override
+ public boolean isRollbackNecessary() {
+ return isRollbackNecessary;
+ }
+
+ @Override
+ public Void call() throws Exception {
+ RendererRollbackInput rollbackInput = new RendererRollbackInputBuilder()
+ .setNodeInterface(this.renderedInterfaces)
+ .build();
+ RendererRollbackOutput rollbackOutput = this.rendererService.rendererRollback(rollbackInput);
+ if (! rollbackOutput.isSuccess()) {
+ LOG.warn("Device rendering rollback of {} was not successful! Failed rollback on {}.", this.getId(),
+ createErrorMessage(rollbackOutput.getFailedToRollback()));
+ } else {
+ LOG.info("Device rollback of {} successful.", this.getId());
+ }
+ return null;
+ }
+
+ private String createErrorMessage(List<FailedToRollback> failedRollbacks) {
+ List<String> failedRollbackNodes = new ArrayList<>();
+ failedRollbacks.forEach(failedRollback -> {
+ String nodeId = failedRollback.getNodeId();
+ failedRollbackNodes.add(nodeId + ": " + String.join(", ", failedRollback.getInterface()));
+ });
+ return String.join(System.lineSeparator(), failedRollbackNodes);
+ }
+
+}
--- /dev/null
+/*
+ * 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.tasks;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.opendaylight.transportpce.renderer.ServicePathInputData;
+import org.opendaylight.transportpce.renderer.provisiondevice.DeviceRendererService;
+import org.opendaylight.transportpce.renderer.provisiondevice.DeviceRenderingResult;
+import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.renderer.input.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeviceRenderingTask implements Callable<DeviceRenderingResult> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeviceRenderingTask.class);
+
+ private final DeviceRendererService deviceRenderer;
+ private final ServicePathInputData servicePathInputData;
+ private final ServicePathDirection direction;
+
+ public DeviceRenderingTask(DeviceRendererService deviceRenderer, ServicePathInputData servicePathInputData,
+ ServicePathDirection direction) {
+ this.deviceRenderer = deviceRenderer;
+ this.servicePathInputData = servicePathInputData;
+ this.direction = direction;
+ }
+
+ @Override
+ public DeviceRenderingResult call() throws Exception {
+ ServicePathOutput output = this.deviceRenderer.setupServicePath(this.servicePathInputData.getServicePathInput(),
+ this.direction);
+ if (! output.isSuccess()) {
+ LOG.warn("Device rendering not successfully finished.");
+ return DeviceRenderingResult.failed("Operation Failed");
+ }
+ List<Nodes> olmList = this.servicePathInputData.getNodeLists().getOlmList();
+ LOG.info("Device rendering finished successfully.");
+ return DeviceRenderingResult.ok(olmList, output.getNodeInterface());
+ }
+
+}
--- /dev/null
+/*
+ * 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.tasks;
+
+import java.util.concurrent.Future;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OlmPowerSetupRollbackTask extends RollbackTask {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OlmPowerSetupRollbackTask.class);
+ private static final String FAILED = "Failed";
+ private final boolean isRollbackNecessary;
+ private final OlmService olmService;
+ private final ServicePowerSetupInput powerSetupInput;
+
+ public OlmPowerSetupRollbackTask(String id, boolean isRollbackNecessary, OlmService olmService,
+ ServicePowerSetupInput powerSetupInput) {
+ super(id);
+ this.isRollbackNecessary = isRollbackNecessary;
+ this.olmService = olmService;
+ this.powerSetupInput = powerSetupInput;
+ }
+
+ @Override
+ public boolean isRollbackNecessary() {
+ return isRollbackNecessary;
+ }
+
+ @Override
+ public Void call() throws Exception {
+ ServicePowerTurndownInput powerTurndownInput = new ServicePowerTurndownInputBuilder()
+ .setNodes(this.powerSetupInput.getNodes())
+ .setServiceName(this.powerSetupInput.getServiceName())
+ .setWaveNumber(this.powerSetupInput.getWaveNumber())
+ .build();
+
+ Future<RpcResult<ServicePowerTurndownOutput>> powerTurndownResultFuture =
+ this.olmService.servicePowerTurndown(powerTurndownInput);
+ RpcResult<ServicePowerTurndownOutput> powerTurndownResult = powerTurndownResultFuture.get();
+ if (FAILED.equals(powerTurndownResult.getResult().getResult())) {
+ LOG.warn("Olmp power setup rollback for {} was not successful!", this.getId());
+ } else {
+ LOG.info("Olm power setup rollback for {} was successful.");
+ }
+ return null;
+ }
+}
--- /dev/null
+/*
+ * 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.tasks;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+import org.opendaylight.transportpce.renderer.provisiondevice.OLMRenderingResult;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OlmPowerSetupTask implements Callable<OLMRenderingResult> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OlmPowerSetupTask.class);
+
+ private final OlmService olmService;
+ private final ServicePowerSetupInput input;
+
+ public OlmPowerSetupTask(OlmService olmService, ServicePowerSetupInput input) {
+ this.olmService = olmService;
+ this.input = input;
+ }
+
+ @Override
+ public OLMRenderingResult call() throws Exception {
+ Future<RpcResult<ServicePowerSetupOutput>> fr = this.olmService.servicePowerSetup(this.input);
+ RpcResult<ServicePowerSetupOutput> result = fr.get();
+ if (result == null) {
+ LOG.warn("Result is NULL");
+ return OLMRenderingResult.failed("Operation Failed");
+ }
+
+ LOG.debug("Result: {}", result.getResult());
+ if (result.isSuccessful()) {
+ LOG.info("OLM power setup finished successfully");
+ return OLMRenderingResult.ok();
+ } else {
+ LOG.warn("OLM power setup not successfully finished");
+ return OLMRenderingResult.failed("Operation Failed");
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.tasks;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class collects tasks for later rollback.
+ * This implementation is not thread safe, it must be called from single orchestration thread.
+ * Rollback order is: last added task is rolled back first.
+ * After rollback, each task is removed from rollback processor.
+ * All rollback tasks are executed in single thread.
+ */
+public class RollbackProcessor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RollbackProcessor.class);
+
+ private final Deque<RollbackTask> tasks;
+
+ public RollbackProcessor() {
+ this.tasks = new LinkedList<>();
+ }
+
+ /**
+ * Add task to the rollback processor.
+ * @param task the task to add
+ */
+ public void addTask(RollbackTask task) {
+ this.tasks.add(task);
+ }
+
+ /**
+ * Check if any previously added task requires rollback.
+ * Rollback is necessary if just single task requires rollback.
+ * @return
+ * true if any of added tasks requires rollback. false if none of added tasks requires rollback.
+ */
+ public boolean isRollbackNecessary() {
+ for (RollbackTask task: this.tasks) {
+ if (task.isRollbackNecessary()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Rollback all tasks previously added to this processor.
+ * It does not matter if any of the tasks requires rollback.
+ * All previously added tasks will be rolled back and removed from this processor.
+ * @return
+ * number of tasks rolled back
+ */
+ public int rollbackAll() {
+ int rollbackCounter = 0;
+ while (this.tasks.size() > 0) {
+ RollbackTask task = this.tasks.pollLast();
+ rollbackCounter++;
+ try {
+ LOG.info("rolling back: {}", task.getId());
+ task.call();
+ } catch (Exception e) {
+ LOG.error("ERROR: Rollback task {} has failed", task.getId(), e);
+ }
+ }
+ return rollbackCounter;
+ }
+
+ /**
+ * Rollback all tasks in case any task has failed.
+ * If rollback is necessary, all previously added tasks will be rolled back and removed from this processor.
+ * @return
+ * number of tasks rolled back
+ */
+ public int rollbackAllIfNecessary() {
+ if (!isRollbackNecessary()) {
+ return 0;
+ }
+ return rollbackAll();
+ }
+
+}
--- /dev/null
+/*
+ * 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.tasks;
+
+import java.util.concurrent.Callable;
+
+public abstract class RollbackTask implements Callable<Void> {
+
+ private final String id;
+
+ public RollbackTask(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return this.id;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if ((object == null) || (getClass() != object.getClass())) {
+ return false;
+ }
+ RollbackTask that = (RollbackTask) object;
+ return this.id.equals(that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.id.hashCode();
+ }
+
+ public abstract boolean isRollbackNecessary();
+
+}
--- /dev/null
+/*
+ * 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.rpcs;
+
+import java.util.concurrent.Future;
+
+import org.opendaylight.transportpce.renderer.provisiondevice.DeviceRendererService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererRollbackOutput;
+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.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeviceRendererRPCImpl implements RendererService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeviceRendererRPCImpl.class);
+ private DeviceRendererService deviceRenderer;
+
+ public DeviceRendererRPCImpl(DeviceRendererService deviceRenderer) {
+ this.deviceRenderer = deviceRenderer;
+ }
+
+ /**
+ * 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:
+ *
+ * <p>
+ * 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.
+ *
+ * <p>
+ * 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.
+ *
+ * <p>
+ * 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
+ *
+ * @return Result of the request
+ */
+ @Override
+ public Future<RpcResult<ServicePathOutput>> servicePath(ServicePathInput input) {
+ if (input.getOperation().getIntValue() == 1) {
+ LOG.info("Create operation request received");
+ return RpcResultBuilder.success(deviceRenderer.setupServicePath(input, null)).buildFuture();
+ } else if (input.getOperation().getIntValue() == 2) {
+ LOG.info("Delete operation request received");
+ return RpcResultBuilder.success(deviceRenderer.deleteServicePath(input)).buildFuture();
+ }
+ return RpcResultBuilder.success(new ServicePathOutputBuilder().setResult("Invalid operation")).buildFuture();
+ }
+
+ /**
+ * Rollback created interfaces and cross connects specified by input.
+ *
+ * @param input Lists of created interfaces and connections per node
+ * @return Success flag and nodes which failed to rollback
+ */
+ @Override
+ public Future<RpcResult<RendererRollbackOutput>> rendererRollback(RendererRollbackInput input) {
+ return RpcResultBuilder.success(deviceRenderer.rendererRollback(input)).buildFuture();
+ }
+}
--- /dev/null
+/*
+ * 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.rpcs;
+
+import java.util.concurrent.Future;
+
+import org.opendaylight.transportpce.renderer.ModelMappingUtils;
+import org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperations;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TransportPCEServicePathRPCImpl implements TransportpceServicepathService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TransportPCEServicePathRPCImpl.class);
+
+ private final RendererServiceOperations rendererServiceOperations;
+
+ public TransportPCEServicePathRPCImpl(RendererServiceOperations rendererServiceOperations) {
+ this.rendererServiceOperations = rendererServiceOperations;
+ }
+
+ @Override
+ public Future<RpcResult<CancelResourceReserveOutput>> cancelResourceReserve(CancelResourceReserveInput input) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<ServiceImplementationRequestOutput>> serviceImplementationRequest(
+ ServiceImplementationRequestInput input) {
+ String serviceName = input.getServiceName();
+ LOG.info("Calling RPC service impl request {} {}", serviceName);
+ return ModelMappingUtils.createRpcResponse(rendererServiceOperations.serviceImplementation(input));
+ }
+
+ @Override
+ public Future<RpcResult<PathComputationRequestOutput>> pathComputationRequest(PathComputationRequestInput input) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
+
xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
odl:use-default-for-reference-types="true">
- <reference id="dataBroker"
- interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
- odl:type="default" />
- <reference id="mountPointService"
- interface="org.opendaylight.controller.md.sal.binding.api.MountPointService" />
- <reference id="rpcProviderRegistry"
- interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" />
- <bean id="provider"
- class="org.opendaylight.transportpce.renderer.RendererProvider"
- init-method="init" destroy-method="close">
+ <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
+ odl:type="default" />
+ <reference id="mountPointService" interface="org.opendaylight.controller.md.sal.binding.api.MountPointService" />
+ <reference id="rpcProviderRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" />
+ <reference id="deviceTransactionManager" interface="org.opendaylight.transportpce.common.device.DeviceTransactionManager" />
+ <reference id="openRoadmInterfaces" interface="org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces" />
+ <reference id="portMapping" interface="org.opendaylight.transportpce.common.mapping.PortMapping" />
+ <reference id="crossConnect" interface="org.opendaylight.transportpce.common.crossconnect.CrossConnect" />
+
+ <odl:rpc-service id="olmService"
+ interface="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.OlmService"/>
+
+ <bean id="openRoadmInterfaceFactory" class="org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory" >
+ <argument ref="portMapping" />
+ <argument ref="openRoadmInterfaces" />
+ </bean>
+
+ <bean id="deviceRenderer" class="org.opendaylight.transportpce.renderer.provisiondevice.DeviceRendererServiceImpl" >
+ <argument ref="dataBroker" />
+ <argument ref="deviceTransactionManager" />
+ <argument ref="openRoadmInterfaceFactory" />
+ <argument ref="openRoadmInterfaces" />
+ <argument ref="crossConnect" />
+ </bean>
+
+ <bean id="deviceRendererRPCImpl" class="org.opendaylight.transportpce.renderer.rpcs.DeviceRendererRPCImpl" >
+ <argument ref="deviceRenderer" />
+ </bean>
+
+ <bean id="networkModelWavelengthService"
+ class="org.opendaylight.transportpce.renderer.NetworkModelWavelengthServiceImpl">
+ <argument ref="dataBroker" />
+ </bean>
+
+ <bean id="rendererServiceOperations" class="org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperationsImpl" >
+ <argument ref="deviceRenderer" />
+ <argument ref="olmService" />
<argument ref="dataBroker" />
- <argument ref="mountPointService" />
+ <argument ref="networkModelWavelengthService" />
+ </bean>
+
+ <bean id="rendererProvider" class="org.opendaylight.transportpce.renderer.RendererProvider"
+ init-method="init" destroy-method="close">
+ <argument ref="dataBroker"/>
+ <argument ref="mountPointService"/>
<argument ref="rpcProviderRegistry" />
+ <argument ref="deviceRendererRPCImpl" />
+ <argument ref="rendererServiceOperations" />
+ <argument ref="portMapping" />
+ <argument ref="deviceTransactionManager" />
</bean>
+ <service ref="deviceRenderer"
+ interface="org.opendaylight.transportpce.renderer.provisiondevice.DeviceRendererService" />
+
+ <service ref="rendererServiceOperations"
+ interface="org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperations" />
+
</blueprint>
--- /dev/null
+/*
+ * 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;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.transportpce.renderer.provisiondevice.tasks.RollbackProcessor;
+
+public class RollbackProcessorTest {
+
+ @Test
+ public void rollbackIfNecessaryTest() throws Exception {
+ int rolledBack = -1;
+ RollbackProcessor rollbackProcessor = new RollbackProcessor();
+ rollbackProcessor.addTask(new TestRollbackTask("task1", false));
+ rollbackProcessor.addTask(new TestRollbackTask("task2", false));
+ rolledBack = rollbackProcessor.rollbackAllIfNecessary();
+ Assert.assertTrue(rolledBack == 0);
+ rollbackProcessor.addTask(new TestRollbackTask("task3", true));
+ rollbackProcessor.addTask(new TestRollbackTask("task4", false));
+ rolledBack = rollbackProcessor.rollbackAllIfNecessary();
+ Assert.assertTrue(rolledBack == 4);
+ rolledBack = rollbackProcessor.rollbackAllIfNecessary();
+ Assert.assertTrue(rolledBack == 0);
+ }
+
+ @Test
+ public void rollbackAllTest() throws Exception {
+ RollbackProcessor rollbackProcessor = new RollbackProcessor();
+ rollbackProcessor.addTask(new TestRollbackTask("task1", false));
+ rollbackProcessor.addTask(new TestRollbackTask("task2", false));
+ rollbackProcessor.addTask(new TestRollbackTask("task3", false));
+ rollbackProcessor.addTask(new TestRollbackTask("task4", false));
+ int rolledBack = -1;
+ rolledBack = rollbackProcessor.rollbackAll();
+ Assert.assertTrue(rolledBack == 4);
+ rolledBack = rollbackProcessor.rollbackAll();
+ Assert.assertTrue(rolledBack == 0);
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+
+import org.opendaylight.transportpce.renderer.provisiondevice.tasks.RollbackTask;
+
+public class TestRollbackTask extends RollbackTask {
+
+ private boolean rollbackNecessary;
+
+ public TestRollbackTask(String id, boolean rollbackNecessary) {
+ super(id);
+ this.rollbackNecessary = rollbackNecessary;
+ }
+
+ @Override
+ public boolean isRollbackNecessary() {
+ return rollbackNecessary;
+ }
+
+ @Override
+ public Void call() throws Exception {
+ return null;
+ }
+}