/*
* Copyright © 2017 Orange, Inc. 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.stubpce.impl;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.FutureCallback;
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.Iterator;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
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.stubpce.CheckCoherencyHardSoft;
import org.opendaylight.transportpce.stubpce.SendingPceRPCs;
import org.opendaylight.transportpce.stubpce.StubpceCompliancyCheck;
import org.opendaylight.transportpce.stubpce.StubpceTxRxCheck;
import org.opendaylight.transportpce.stubpce.topology.PathDescriptionsOrdered;
import org.opendaylight.transportpce.stubpce.topology.SuperNodePath;
import org.opendaylight.transportpce.stubpce.topology.Topology;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveInput;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutput;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutputBuilder;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutput;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutputBuilder;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathDescriptionList;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathDescriptionListBuilder;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathList;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathListBuilder;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResult;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResultBuilder;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.path.description.list.PathDescriptions;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.path.description.list.PathDescriptionsBuilder;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.path.description.list.PathDescriptionsKey;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.list.ServicePaths;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.list.ServicePathsBuilder;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.list.ServicePathsKey;
import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.rpc.result.PathDescriptionBuilder;
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.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.b.c._interface.service.types.rev170426.RpcStatusEx;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServicePathNotificationTypes;
import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.rpc.result.PathDescription;
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;
/**
* Class to implement StubpceService StubpceListener.
* @author Martial Coulibaly on
* behalf of Orange
*/
public class StubpceImpl implements StubpceService {
/** Logging. */
private static final Logger LOG = LoggerFactory.getLogger(StubpceImpl.class);
/** Permit to access database. */
private DataBroker db;
/** check service sdnc-request-header compliancy. */
private StubpceCompliancyCheck compliancyCheck;
/** check missing info on Tx/Rx for A/Z end. */
private StubpceTxRxCheck txrxCheck;
/** check coherency between hard and soft constraints. */
private CheckCoherencyHardSoft checkCoherencyHardSoft;
private NotificationPublishService notificationPublishService;
private ServicePathRpcResult notification;
private PathDescriptionBuilder pathDescriptionBuilder;
private SendingPceRPCs sendingPCE;
private final ListeningExecutorService executor = MoreExecutors
.listeningDecorator(Executors.newFixedThreadPool(10));
public StubpceImpl(NotificationPublishService notificationPublishService, DataBroker databroker) {
this.notificationPublishService = notificationPublishService;
this.db = databroker;
this.pathDescriptionBuilder = null;
if (initializePathDescriptionList(databroker)) {
fillPathDesciptionList();
}
initializeServicePathList(databroker);
/*if (initializeServicePathList(databroker)) {
fillServicePathList();
}*/
}
@Override
public ListenableFuture>
cancelResourceReserve(CancelResourceReserveInput input) {
LOG.info("RPC cancelResourceReserve request received");
String message = "";
String responseCode = "";
ConfigurationResponseCommonBuilder configurationResponseCommon = null;
String serviceName = input.getServiceName();
LOG.info("serviceName : {}", serviceName);
if (serviceName != null) {
this.sendingPCE = new SendingPceRPCs(input,this.db,this.executor);
FutureCallback pceCallback = new FutureCallback() {
String message = "";
ServicePathRpcResult notification = null;
@Override
public void onFailure(Throwable arg0) {
LOG.error("Cancel resource failed : {}", arg0);
this.notification = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
.setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
.setStatusMessage("Cancel resource request failed : " + arg0.getMessage()).build();
try {
StubpceImpl.this.notificationPublishService.putNotification(this.notification);
} catch (InterruptedException e) {
LOG.info("notification offer rejected : {}", e);
}
}
@Override
public void onSuccess(Boolean response) {
LOG.info("response : {}", response);
if (response) {
this.message = "Resource cancelled !";
this.notification = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
.setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
.setStatusMessage(this.message)
.build();
} else {
this.message = StubpceImpl.this.sendingPCE.getError();
this.notification = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
.setServiceName("")
.setStatus(RpcStatusEx.Failed).setStatusMessage(this.message)
.build();
this.message = "Cancel request failed !";
}
LOG.info(this.notification.toString());
try {
StubpceImpl.this.notificationPublishService.putNotification(this.notification);
} catch (InterruptedException e) {
LOG.info("notification offer rejected : {}", e);
}
LOG.info(this.message);
}
};
ListenableFuture pce = this.sendingPCE.cancelResourceReserve();
Futures.addCallback(pce, pceCallback, this.executor);
LOG.info("Cancel Resource Request in progress ...");
configurationResponseCommon = new ConfigurationResponseCommonBuilder()
.setAckFinalIndicator("No")
.setRequestId(input.getServiceHandlerHeader().getRequestId())
.setResponseMessage("Service compliant, Cancel resource request in progress...")
.setResponseCode("200");
CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder()
.setConfigurationResponseCommon(configurationResponseCommon.build());
return RpcResultBuilder.success(output.build()).buildFuture();
} else {
message = "serviceName / requestId is not correct !";
responseCode = "500";
this.notification = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
.setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
.setStatusMessage(message).build();
try {
this.notificationPublishService.putNotification(this.notification);
} catch (InterruptedException e) {
LOG.info("notification offer rejected : {}", e);
}
}
configurationResponseCommon = new ConfigurationResponseCommonBuilder();
configurationResponseCommon.setAckFinalIndicator("Yes")
.setRequestId(input.getServiceHandlerHeader().getRequestId())
.setResponseMessage(message)
.setResponseCode(responseCode).build();
CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder();
output.setConfigurationResponseCommon(configurationResponseCommon.build());
return RpcResultBuilder.success(output.build()).buildFuture();
}
@Override
public ListenableFuture>
pathComputationRequest(PathComputationRequestInput input) {
LOG.info("RPC pathcomputation request received");
String message = "";
String responseCode = "";
boolean coherencyHardSoft = false;
boolean commonId = true;
ConfigurationResponseCommonBuilder configurationResponseCommon = null;
this.compliancyCheck = new StubpceCompliancyCheck(input.getServiceName(), input.getServiceHandlerHeader());
if (this.compliancyCheck.check(false, true)) {
LOG.info("Service compliant !");
/**
* If compliant, service-request parameters are verified in order to
* check if there is no missing parameter that prevents calculating
* a path and implement a service.
*/
LOG.info("checking Tx/Rx Info for AEnd ...");
this.txrxCheck = new StubpceTxRxCheck(input.getServiceAEnd(), 1);
if (this.txrxCheck.check()) {
LOG.info("Tx/Rx Info for AEnd checked !");
LOG.info("checking Tx/Rx Info for ZEnd ...");
this.txrxCheck = new StubpceTxRxCheck(input.getServiceZEnd(), 2);
if (this.txrxCheck.check()) {
LOG.info("Tx/Rx Info for ZEnd checked !");
/**
* If OK, common-id is verified in order to see if there is
* no routing policy provided. If yes, the routing
* constraints of the policy are recovered and coherency
* with hard/soft constraints provided in the input of the
* RPC.
*/
if ((input.getHardConstraints() != null) || (input.getSoftConstraints() != null)) {
LOG.info("Constraints specified !");
this.checkCoherencyHardSoft = new CheckCoherencyHardSoft(input.getHardConstraints(),
input.getSoftConstraints());
if (this.checkCoherencyHardSoft.check()) {
LOG.info("hard/soft constraints coherent !");
coherencyHardSoft = true;
} else {
LOG.info("hard/soft constraints are not coherent !");
message = "hard/soft constraints are not coherent !";
responseCode = "500";
}
} else {
commonId = false;
}
if (!commonId || (commonId && coherencyHardSoft)) {
this.notification = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
.setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending)
.setStatusMessage("Service compliant, submitting pathComputation Request ...").build();
try {
this.notificationPublishService.putNotification(this.notification);
} catch (InterruptedException e) {
LOG.info("notification offer rejected : {}", e);
}
this.sendingPCE = new SendingPceRPCs(input,this.db,this.executor);
FutureCallback pceCallback = new FutureCallback() {
String message = "";
ServicePathRpcResult notification = null;
@Override
public void onFailure(Throwable arg0) {
LOG.error("Failure message : {}", arg0.toString());
LOG.error("Path calculation failed !");
this.notification = new ServicePathRpcResultBuilder()
.setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
.setStatusMessage("PCR Request failed : " + arg0.getMessage()).build();
try {
StubpceImpl.this.notificationPublishService.putNotification(this.notification);
} catch (InterruptedException e) {
LOG.info("notification offer rejected : {}", e);
}
}
@Override
public void onSuccess(Boolean response) {
LOG.info("response : {}", response);
if (response) {
this.message = "Path Computated !";
ServicePathRpcResultBuilder tmp = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
.setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
.setStatusMessage(this.message);
StubpceImpl.this.pathDescriptionBuilder =
StubpceImpl.this.sendingPCE.getPathDescription();
if (StubpceImpl.this.pathDescriptionBuilder != null) {
PathDescription pathDescription = new org.opendaylight.yang.gen.v1.http.org
.transportpce.b.c._interface.servicepath.rev170426.service.path
.rpc.result.PathDescriptionBuilder()
.setAToZDirection(
StubpceImpl.this.pathDescriptionBuilder.getAToZDirection())
.setZToADirection(
StubpceImpl.this.pathDescriptionBuilder.getZToADirection())
.build();
tmp.setPathDescription(new PathDescriptionBuilder()
.setAToZDirection(pathDescription.getAToZDirection())
.setZToADirection(pathDescription.getZToADirection())
.build());
}
this.notification = tmp.build();
} else {
this.message = StubpceImpl.this.sendingPCE.getError();
this.notification = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
.setServiceName("")
.setStatus(RpcStatusEx.Failed).setStatusMessage(this.message)
.build();
this.message = "Path not calculated!";
}
try {
StubpceImpl.this.notificationPublishService.putNotification(this.notification);
} catch (InterruptedException e) {
LOG.info("notification offer rejected : {}", e);
}
LOG.info(this.message);
}
};
ListenableFuture pce = this.sendingPCE.pathComputation();
Futures.addCallback(pce, pceCallback, this.executor);
LOG.info("PathComputation Request in progress ...");
configurationResponseCommon = new ConfigurationResponseCommonBuilder()
.setAckFinalIndicator("No")
.setRequestId(input.getServiceHandlerHeader().getRequestId())
.setResponseMessage("Service compliant, Path calculating in progress...")
.setResponseCode("200");
PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder()
.setConfigurationResponseCommon(configurationResponseCommon.build());
return RpcResultBuilder.success(output.build()).buildFuture();
}
} else {
message = this.txrxCheck.getMessage();
responseCode = "500";
}
} else {
message = this.txrxCheck.getMessage();
responseCode = "500";
}
} else {
message = this.compliancyCheck.getMessage();
responseCode = "500";
this.notification = new ServicePathRpcResultBuilder()
.setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
.setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
.setStatusMessage("Service not compliant : " + message).build();
try {
this.notificationPublishService.putNotification(this.notification);
} catch (InterruptedException e) {
LOG.info("notification offer rejected : {}", e);
}
}
configurationResponseCommon = new ConfigurationResponseCommonBuilder();
configurationResponseCommon.setAckFinalIndicator("Yes")
.setRequestId(input.getServiceHandlerHeader().getRequestId())
.setResponseMessage(message)
.setResponseCode(responseCode).build();
PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder();
output.setConfigurationResponseCommon(configurationResponseCommon.build());
return RpcResultBuilder.success(output.build()).buildFuture();
}
/**
* Initialize PathDescriptionList Structure on DataStore.
*
* @param DataBroker
* Access DataStore
*/
private boolean initializePathDescriptionList(DataBroker db) {
Boolean result = true;
LOG.info("Preparing to initialize the PathDescription List");
WriteTransaction transaction = db.newWriteOnlyTransaction();
InstanceIdentifier iid = InstanceIdentifier.create(PathDescriptionList.class);
PathDescriptionList pathDescriptionList = new PathDescriptionListBuilder().build();
transaction.put(LogicalDatastoreType.OPERATIONAL, iid, pathDescriptionList);
Future future = transaction.submit();
try {
Futures.getChecked(future, ExecutionException.class);
} catch (ExecutionException e) {
LOG.error("Failed to create PathDescription List");
result = false;
}
return result;
}
/**
* Initialize ServicePathList Structure on DataStore.
*
* @param DataBroker
* Access DataStore
* @return true
if ok, false
else
*/
private boolean initializeServicePathList(DataBroker db) {
Boolean result = true;
LOG.info("Preparing to initialize the ServicePathList registry");
WriteTransaction transaction = db.newWriteOnlyTransaction();
InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class);
ServicePathList servicePathList = new ServicePathListBuilder().build();
transaction.put(LogicalDatastoreType.OPERATIONAL, iid, servicePathList);
Future future = transaction.submit();
try {
Futures.getChecked(future, ExecutionException.class);
} catch (ExecutionException e) {
LOG.error("Failed to create ServicePathList List : {}", e.toString());
result = false;
}
return result;
}
/**
* fill PathDescriptionList
* with direct paths and
* indirect paths.
*/
private void fillPathDesciptionList() {
LOG.info("filling PathDescription List...");
Topology topo = new Topology();
topo.start();
LOG.info("Network : {}", topo.getNetwork());
SuperNodePath superNodePath = new SuperNodePath(topo.getNetwork());
String aend = "NodeA";
String zend = "NodeZ";
superNodePath.run(aend, zend);
fill(superNodePath.getDirectPathDesc(aend, zend, superNodePath.getPaths()));
fill(superNodePath.getIndirectPathDesc(aend, zend, superNodePath.getPaths()));
}
/**
* fill datastore with
* Pathdescriptions List.
*
* @param sortedSet PathDescriptionsOrdered List
*/
private void fill(SortedSet sortedSet) {
InstanceIdentifier iid;
WriteTransaction writeTx;
Future future;
if (!sortedSet.isEmpty()) {
Iterator it = sortedSet.iterator();
while (it.hasNext()) {
PathDescriptions pathDesc = it.next().getPathDescriptions();
if (pathDesc != null) {
iid = InstanceIdentifier.create(PathDescriptionList.class)
.child(PathDescriptions.class, new PathDescriptionsKey(pathDesc.getPathName()));
writeTx = this.db.newWriteOnlyTransaction();
writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, pathDesc);
future = writeTx.submit();
try {
Futures.getChecked(future, ExecutionException.class);
} catch (ExecutionException e) {
LOG.error("Failed to write PathDescriptions to PathDescriptionsList : {}", e.toString());
}
} else {
LOG.error("PathDescriptions gets is null !");
}
}
} else {
LOG.info("PathDescriptions List is empty !");
}
}
/**
* read Service from ServiceList DataStore.
*
* @param serviceName
* Name of Service
*
* @return Services
*/
@SuppressWarnings("unused")
private Services readServiceList(String serviceName) {
Services result = null;
ReadOnlyTransaction readTx = this.db.newReadOnlyTransaction();
InstanceIdentifier iid = InstanceIdentifier.create(ServiceList.class).child(Services.class,
new ServicesKey(serviceName));
Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
Optional optional = Optional.absent();
try {
optional = Futures.getChecked(future, ExecutionException.class);
} catch (ExecutionException e) {
LOG.error("Reading service failed:", e);
}
if (optional.isPresent()) {
LOG.debug("Service '{}' present !", serviceName);
result = new ServicesBuilder(optional.get()).build();
}
return result;
}
/**
* read ServicePath Service from ServicePathList DataStore.
*
* @param serviceName
* Name of ServicePath
*
* @return Services
*/
@SuppressWarnings("unused")
private ServicePaths readServicePathList(String serviceName) {
ServicePaths result = null;
ReadOnlyTransaction readTx = this.db.newReadOnlyTransaction();
InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class)
.child(ServicePaths.class, new ServicePathsKey(serviceName));
Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
Optional optional = Optional.absent();
try {
optional = Futures.getChecked(future, ExecutionException.class);
} catch (ExecutionException e) {
LOG.error("Reading service failed:", e);
}
if (optional.isPresent()) {
LOG.debug("Service '{}' present !", serviceName);
result = new ServicePathsBuilder(optional.get()).build();
}
return result;
}
/**
* read PathDescription information from PathDescriptionList.
*
* @param pathName
* Name of PathDescription
*
* @return PathDescriptions
*/
@SuppressWarnings("unused")
private PathDescriptions readPathDescriptionList(String pathName) {
PathDescriptions result = null;
ReadOnlyTransaction readTx = this.db.newReadOnlyTransaction();
InstanceIdentifier iid = InstanceIdentifier.create(PathDescriptionList.class)
.child(PathDescriptions.class, new PathDescriptionsKey(pathName));
Future> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
Optional optional = Optional.absent();
try {
optional = Futures.getChecked(future, ExecutionException.class);
} catch (ExecutionException e) {
LOG.error("Reading service failed:", e);
}
if (optional.isPresent()) {
LOG.debug("PathDescritions '{}' present !", pathName);
result = new PathDescriptionsBuilder(optional.get()).build();
}
return result;
}
/**
* register ServicePath Service to ServicePathList with PathDescription
* information.
*
* @param input
* PathComputationRequestInput
* @return String operations result, null if ok or not otherwise
*/
@SuppressWarnings("unused")
private String writeServicePathList(PathComputationRequestInput input) {
String serviceName = input.getServiceName();
LOG.debug("Write ServicePath '{}' Service", serviceName);
String result = null;
LOG.debug("Writing '{}' ServicePath", serviceName);
InstanceIdentifier iid = InstanceIdentifier.create(ServicePathList.class)
.child(ServicePaths.class, new ServicePathsKey(serviceName));
org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service
.path.PathDescriptionBuilder path = new org.opendaylight.yang.gen.v1.http.org.transportpce
.b.c._interface.service.types.rev170426.service.path.PathDescriptionBuilder();
path.setAToZDirection(this.pathDescriptionBuilder.getAToZDirection());
path.setZToADirection(this.pathDescriptionBuilder.getZToADirection());
ServicePaths service = new ServicePathsBuilder().setServicePathName(input.getServiceName())
.setSoftConstraints(input.getSoftConstraints()).setHardConstraints(input.getHardConstraints())
.setPathDescription(path.build()).build();
WriteTransaction writeTx = this.db.newWriteOnlyTransaction();
writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
Future future = writeTx.submit();
try {
Futures.getChecked(future, ExecutionException.class);
result = null;
} catch (ExecutionException e) {
LOG.error("Failed to write service to Service List");
result = "Failed to write service to Service List";
}
return result;
}
public PathDescriptionBuilder getPathDescriptionBuilder() {
return this.pathDescriptionBuilder;
}
public void setPathDescriptionBuilder(PathDescriptionBuilder pathDescriptionBuilder) {
this.pathDescriptionBuilder = pathDescriptionBuilder;
}
}