Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.opendaylight.faas.fabric.general.FabricManagementAPIProvider Maven / Gradle / Ivy
/**
* Copyright (c) 2015 Huawei Technologies Co. Ltd. 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.faas.fabric.general;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.CheckedFuture;
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.SettableFuture;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
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.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.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.faas.fabric.general.spi.FabricRenderer;
import org.opendaylight.faas.fabric.general.spi.FabricRendererFactory;
import org.opendaylight.faas.fabric.utils.MdSalUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.capable.device.rev150930.FabricCapableDevice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.AddLinkToFabricInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.AddNodeToFabricInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.ComposeFabricInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.ComposeFabricInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.ComposeFabricOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.ComposeFabricOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.DecomposeFabricInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.FabricId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.FabricNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.FabricNodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.FabricService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.GetAllFabricsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.GetAllFabricsOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.RmLinkFromFabricInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.RmNodeFromFabricInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.fabric.attributes.DeviceLinks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.fabric.attributes.DeviceLinksBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.fabric.attributes.DeviceLinksKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.fabric.attributes.DeviceNodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.fabric.attributes.DeviceNodesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.fabric.attributes.DeviceNodesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.fabric.attributes.OptionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.network.topology.topology.node.FabricAttribute;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.network.topology.topology.node.FabricAttributeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.DeviceRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.LinkRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.ServiceCapabilities;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.VlanFabric;
import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.VxlanFabric;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.fabric.impl.rev150930.FabricsSetting;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.fabric.impl.rev150930.FabricsSettingBuilder;
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.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNode;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeKey;
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 FabricManagementAPIProvider implements AutoCloseable, FabricService {
private static final Logger LOG = LoggerFactory.getLogger(FabricManagementAPIProvider.class);
private final DataBroker dataBroker;
private final RpcProviderRegistry rpcRegistry;
private RpcRegistration rpcRegistration;
private final FabricRendererRegistry rendererMgr;
private final ExecutorService executor;
public FabricManagementAPIProvider(final DataBroker dataBroker,
final RpcProviderRegistry rpcRegistry, ExecutorService executor, FabricRendererRegistry rendererMgr) {
this.dataBroker = dataBroker;
this.rpcRegistry = rpcRegistry;
this.executor = executor;
this.rendererMgr = rendererMgr;
}
public void start() {
rpcRegistration = rpcRegistry.addRpcImplementation(FabricService.class, this);
}
@Override
public void close() throws Exception {
if (rpcRegistration != null) {
rpcRegistration.close();
}
}
@Override
public Future> decomposeFabric(DecomposeFabricInput input) {
final RpcResult result = RpcResultBuilder.success().build();
if ( input == null) {
return Futures.immediateFailedCheckedFuture(new IllegalArgumentException("fabricId can not be empty!"));
}
final FabricId fabricId = input.getFabricId();
if ( fabricId == null) {
return Futures.immediateFailedCheckedFuture(new IllegalArgumentException("fabricId can not be empty!"));
}
ReadWriteTransaction rt = dataBroker.newReadWriteTransaction();
final InstanceIdentifier fabricpath = Constants.DOM_FABRICS_PATH.child(Node.class, new NodeKey(fabricId));
CheckedFuture,ReadFailedException> readFuture =
rt.read(LogicalDatastoreType.OPERATIONAL, fabricpath);
return Futures.transform(readFuture, new AsyncFunction, RpcResult>() {
@Override
public ListenableFuture> apply(Optional optional) throws Exception {
if (optional.isPresent()) {
Node fabric = optional.get();
FabricInstanceCache.INSTANCE.retrieveFabric(fabricId).notifyFabricDeleted(fabric);
WriteTransaction wt = dataBroker.newWriteOnlyTransaction();
wt.delete(LogicalDatastoreType.OPERATIONAL, fabricpath);
wt.delete(LogicalDatastoreType.CONFIGURATION, fabricpath);
wt.delete(LogicalDatastoreType.OPERATIONAL, MdSalUtils.createTopoIId(fabricId.getValue()));
MdSalUtils.wrapperSubmit(wt, executor);
FabricInstanceCache.INSTANCE.removeFabric(fabricId);
}
return Futures.immediateFuture(result);
}
});
}
@Override
public Future> getAllFabrics() {
final SettableFuture> futureResult = SettableFuture.create();
final RpcResultBuilder resultBuilder = RpcResultBuilder.success();
final GetAllFabricsOutputBuilder outputBuilder = new GetAllFabricsOutputBuilder();
ReadOnlyTransaction trans = dataBroker.newReadOnlyTransaction();
ListenableFuture> readFuture =
trans.read(LogicalDatastoreType.OPERATIONAL, Constants.DOM_FABRICS_PATH);
Futures.addCallback(readFuture, new FutureCallback>() {
@Override
public void onSuccess(Optional result) {
if (result.isPresent()) {
List nodes = result.get().getNode();
List fabricIds = new ArrayList();
if (nodes != null) {
for (Node node : nodes) {
FabricNode fnode = node.getAugmentation(FabricNode.class);
if (fnode != null) {
fabricIds.add(new FabricId(node.getNodeId()));
}
}
outputBuilder.setFabricId(fabricIds);
}
}
futureResult.set(resultBuilder.withResult(outputBuilder.build()).build());
}
@Override
public void onFailure(Throwable th) {
LOG.debug( "Failed to read network-topology dom", th);
futureResult.setException(th);
}
}, executor);
return futureResult;
}
@Override
public Future> composeFabric(final ComposeFabricInput input) {
ComposeFabricInputBuilder inputBuilder = new ComposeFabricInputBuilder(input);
String msg = null;
if ((msg = checkFabricOptions(inputBuilder)) != null) {
return Futures.immediateFailedCheckedFuture(new IllegalArgumentException(msg));
}
final FabricId fabricId = new FabricId(String.format("fabric:%d", this.genNextFabricNum()));
final InstanceIdentifier fnodepath = MdSalUtils.createFNodeIId(fabricId);
final InstanceIdentifier fabricpath = fnodepath.augmentation(FabricNode.class);
NodeBuilder fnodeBuilder = new NodeBuilder();
buildNodeAttribute(fnodeBuilder, input, fabricId);
FabricNodeBuilder fabricBuilder = new FabricNodeBuilder();
FabricAttributeBuilder attrBuilder = new FabricAttributeBuilder();
buildFabricAttribute(attrBuilder, inputBuilder);
FabricRendererFactory rendererFactory = rendererMgr.getFabricRendererFactory(input.getType());
FabricRenderer renderer = rendererFactory.composeFabric(fabricpath, attrBuilder, input);
if (renderer == null) {
return Futures.immediateFailedCheckedFuture(
new RuntimeException("Can not compose fabric due the renderer return false."));
}
fabricBuilder.setFabricAttribute(attrBuilder.build());
FabricInstance fabric = FabricInstanceCache.INSTANCE.addFabric(fabricId, input.getType(), renderer);
fabric.addListener(rendererFactory.createListener(fabricpath, fabricBuilder.getFabricAttribute()));
final FabricNode fabricNode = fabricBuilder.build();
fnodeBuilder.addAugmentation(FabricNode.class, fabricNode);
ReadWriteTransaction trans = dataBroker.newReadWriteTransaction();
trans.put(LogicalDatastoreType.OPERATIONAL, fnodepath, fnodeBuilder.build(), true);
trans.put(LogicalDatastoreType.CONFIGURATION, fnodepath, fnodeBuilder.build(), true);
trans.put(LogicalDatastoreType.OPERATIONAL, MdSalUtils.createTopoIId(fabricId.getValue()),
MdSalUtils.newTopo(fabricId.getValue()));
CheckedFuture future = trans.submit();
return Futures.transform(future, new AsyncFunction>() {
@Override
public ListenableFuture> apply(Void submitResult) throws Exception {
RpcResultBuilder resultBuilder = RpcResultBuilder.success();
ComposeFabricOutputBuilder outputBuilder = new ComposeFabricOutputBuilder();
outputBuilder.setFabricId(fabricId);
FabricInstanceCache.INSTANCE.retrieveFabric(fabricId).notifyFabricCreated(fabricNode);
return Futures.immediateFuture(resultBuilder.withResult(outputBuilder.build()).build());
}
});
}
private String checkFabricOptions(final ComposeFabricInputBuilder input) {
List capabilities = null;
if (input.getOptions() != null) {
capabilities = input.getOptions().getCapabilitySupported();
}
if (capabilities == null) {
capabilities = Lists.newArrayList();
}
Set allDevCapabilities = Sets.newHashSet();
List devices = input.getDeviceNodes();
if (devices == null || devices.isEmpty()) {
return "No device can support the capability of fabric.";
}
ReadOnlyTransaction rt = dataBroker.newReadOnlyTransaction();
List,ReadFailedException>> futures = Lists.newArrayList();
for (DeviceNodes device : devices) {
@SuppressWarnings("unchecked")
InstanceIdentifier devIid = (InstanceIdentifier) device.getDeviceRef().getValue();
CheckedFuture,ReadFailedException> future =
rt.read(LogicalDatastoreType.OPERATIONAL, devIid.augmentation(FabricCapableDevice.class));
futures.add(future);
}
try {
List> capDevices = Futures.allAsList(futures).get();
for (Optional opt : capDevices) {
if (opt.isPresent()) {
FabricCapableDevice capDevice = opt.get();
if (capDevice.getCapabilitySupported() != null) {
allDevCapabilities.addAll(capDevice.getCapabilitySupported());
}
if (capDevice.getSupportedFabric() != null) {
boolean supported = false;
switch (input.getType()) {
case VXLAN:
supported = capDevice.getSupportedFabric().contains(VxlanFabric.class);
break;
case VLAN:
supported = capDevice.getSupportedFabric().contains(VlanFabric.class);
break;
default:
break;
}
if (!supported) {
return String.format("Device does not support this fabric type.");
}
} else {
return String.format("Device does not support this fabric type.");
}
} else {
return String.format("Device is not a fabric capable device.");
}
}
for (ServiceCapabilities cap : capabilities) {
if (!allDevCapabilities.contains(cap)) {
return String.format("No device can support this capability [%s].", cap.name());
}
}
if (capabilities.isEmpty()) {
OptionsBuilder builder = input.getOptions() == null
? new OptionsBuilder() : new OptionsBuilder(input.getOptions());
input.setOptions(builder.setCapabilitySupported(Lists.newArrayList(allDevCapabilities)).build());
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("", e);
return "Exception ocurred when reading DomStore.";
}
return null;
}
private void buildNodeAttribute(NodeBuilder builder, ComposeFabricInput input, FabricId fabricId) {
builder.setKey(new NodeKey(fabricId));
List devices = input.getDeviceNodes();
if (devices != null) {
List snodes = Lists.newArrayList();
for (DeviceNodes device : devices) {
InstanceIdentifier> nodeRef = device.getDeviceRef().getValue();
NodeId nodeid = nodeRef.firstKeyOf(Node.class).getNodeId();
TopologyId topoId = nodeRef.firstKeyOf(Topology.class).getTopologyId();
SupportingNodeBuilder snodeBuilder = new SupportingNodeBuilder();
snodeBuilder.setNodeRef(nodeid);
snodeBuilder.setTopologyRef(topoId);
snodeBuilder.setKey(new SupportingNodeKey(nodeid, topoId));
snodes.add(snodeBuilder.build());
}
builder.setSupportingNode(snodes);
}
}
private void buildFabricAttribute(FabricAttributeBuilder builder, ComposeFabricInputBuilder input) {
builder.setName(input.getName());
builder.setDescription(input.getDescription());
builder.setType(input.getType());
builder.setDeviceLinks(input.getDeviceLinks());
// remove augment
builder.setDeviceNodes(getDeviceNodesInput(input.getDeviceNodes()));
builder.setOptions(input.getOptions());
}
private List getDeviceNodesInput(List input) {
if (input == null) {
return null;
}
List ret = Lists.newArrayList();
for (DeviceNodes node : input) {
DeviceNodesBuilder builder = new DeviceNodesBuilder();
builder.setDeviceRef(node.getDeviceRef());
builder.setKey(node.getKey());
builder.setRole(node.getRole());
ret.add(builder.build());
}
return ret;
}
private long genNextFabricNum() {
long ret = 1;
FabricsSettingBuilder settingBuilder = new FabricsSettingBuilder();
ReadWriteTransaction trans = dataBroker.newReadWriteTransaction();
InstanceIdentifier fabricImplPath = InstanceIdentifier.create(FabricsSetting.class);
ListenableFuture> readFuture =
trans.read(LogicalDatastoreType.CONFIGURATION, fabricImplPath);
Optional optional;
try {
optional = readFuture.get();
if (optional.isPresent()) {
ret = optional.get().getNextFabricNum();
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("can not read fabric setting", e);
}
settingBuilder.setNextFabricNum(ret + 1);
trans.put(LogicalDatastoreType.CONFIGURATION, fabricImplPath, settingBuilder.build());
MdSalUtils.wrapperSubmit(trans, executor);
return ret;
}
@Override
public Future> rmNodeFromFabric(RmNodeFromFabricInput input) {
final RpcResult result = RpcResultBuilder.success().build();
FabricId fabricId = input.getFabricId();
final NodeRef device = input.getNodeRef();
final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId);
if (fabricObj == null) {
return Futures.immediateFailedFuture(new IllegalArgumentException("fabric is not exist!"));
}
ReadWriteTransaction trans = dataBroker.newReadWriteTransaction();
// del fabric attribute
InstanceIdentifier devicepath = Constants.DOM_FABRICS_PATH
.child(Node.class, new NodeKey(fabricId)).augmentation(FabricNode.class)
.child(FabricAttribute.class)
.child(DeviceNodes.class, new DeviceNodesKey(device));
trans.delete(LogicalDatastoreType.OPERATIONAL, devicepath);
// del node attribute
@SuppressWarnings("unchecked")
InstanceIdentifier noderef = (InstanceIdentifier) device.getValue();
NodeId deviceid = noderef.firstKeyOf(Node.class).getNodeId();
TopologyId topoid = noderef.firstKeyOf(Topology.class).getTopologyId();
InstanceIdentifier suplNodeIid = MdSalUtils.createFNodeIId(input.getFabricId())
.child(SupportingNode.class, new SupportingNodeKey(deviceid, topoid));
trans.delete(LogicalDatastoreType.OPERATIONAL, suplNodeIid);
CheckedFuture future = trans.submit();
return Futures.transform(future, new AsyncFunction>() {
@SuppressWarnings("unchecked")
@Override
public ListenableFuture> apply(Void submitResult) throws Exception {
fabricObj.notifyDeviceRemoved((InstanceIdentifier) device.getValue());
return Futures.immediateFuture(result);
}
});
}
@Override
public Future> addNodeToFabric(AddNodeToFabricInput input) {
final RpcResult result = RpcResultBuilder.success().build();
final FabricId fabricId = input.getFabricId();
final NodeRef device = input.getNodeRef();
final DeviceRole role = input.getRole();
final InstanceIdentifier path = Constants.DOM_FABRICS_PATH.child(Node.class, new NodeKey(fabricId))
.augmentation(FabricNode.class).child(FabricAttribute.class)
.child(DeviceNodes.class, new DeviceNodesKey(device));
final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId);
if (fabricObj == null) {
return Futures.immediateFailedFuture(new IllegalArgumentException("fabric is not exist!"));
}
WriteTransaction trans = dataBroker.newWriteOnlyTransaction();
// set fabric attribute
DeviceNodesBuilder dnodeBuilder = new DeviceNodesBuilder();
dnodeBuilder.setKey(new DeviceNodesKey(device)).setDeviceRef(device).build();
fabricObj.addNodeToFabric(dnodeBuilder, input);
trans.put(LogicalDatastoreType.OPERATIONAL, path, dnodeBuilder.build(), true);
// set node attribute
@SuppressWarnings("unchecked")
InstanceIdentifier noderef = (InstanceIdentifier) device.getValue();
NodeId deviceid = noderef.firstKeyOf(Node.class).getNodeId();
TopologyId topoid = noderef.firstKeyOf(Topology.class).getTopologyId();
final InstanceIdentifier suplNodeIid = MdSalUtils.createFNodeIId(input.getFabricId())
.child(SupportingNode.class, new SupportingNodeKey(deviceid, topoid));
SupportingNodeBuilder suplNodeBuilder = new SupportingNodeBuilder();
suplNodeBuilder.setNodeRef(deviceid);
suplNodeBuilder.setTopologyRef(topoid);
suplNodeBuilder.setKey(new SupportingNodeKey(deviceid, topoid));
trans.put(LogicalDatastoreType.OPERATIONAL, suplNodeIid, suplNodeBuilder.build(), true);
CheckedFuture future = trans.submit();
return Futures.transform(future, new AsyncFunction>() {
@SuppressWarnings("unchecked")
@Override
public ListenableFuture> apply(Void submitResult) throws Exception {
fabricObj.notifyDeviceAdded((InstanceIdentifier) device.getValue(), role);
return Futures.immediateFuture(result);
}
});
}
@Override
public Future> rmLinkFromFabric(RmLinkFromFabricInput input) {
final RpcResult result = RpcResultBuilder.success().build();
FabricId fabricId = input.getFabricId();
LinkRef link = input.getLinkRef();
InstanceIdentifier devicepath = Constants.DOM_FABRICS_PATH
.child(Node.class, new NodeKey(fabricId)).augmentation(FabricNode.class)
.child(FabricAttribute.class)
.child(DeviceLinks.class, new DeviceLinksKey(link));
WriteTransaction trans = dataBroker.newWriteOnlyTransaction();
trans.delete(LogicalDatastoreType.OPERATIONAL, devicepath);
CheckedFuture future = trans.submit();
return Futures.transform(future, new AsyncFunction>() {
@Override
public ListenableFuture> apply(Void submitResult) throws Exception {
return Futures.immediateFuture(result);
}
});
}
@Override
public Future> addLinkToFabric(AddLinkToFabricInput input) {
final RpcResult result = RpcResultBuilder.success().build();
FabricId fabricId = input.getFabricId();
LinkRef link = input.getLinkRef();
final InstanceIdentifier path = Constants.DOM_FABRICS_PATH.child(Node.class, new NodeKey(fabricId))
.augmentation(FabricNode.class).child(FabricAttribute.class)
.child(DeviceLinks.class, new DeviceLinksKey(link));
final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId);
if (fabricObj == null) {
return Futures.immediateFailedFuture(new IllegalArgumentException("fabric is not exist!"));
}
WriteTransaction trans = dataBroker.newWriteOnlyTransaction();
DeviceLinksBuilder linkBuilder = new DeviceLinksBuilder();
linkBuilder.setKey(new DeviceLinksKey(link)).setLinkRef(link).build();
trans.put(LogicalDatastoreType.OPERATIONAL, path, linkBuilder.build(), false);
CheckedFuture future = trans.submit();
return Futures.transform(future, new AsyncFunction>() {
@Override
public ListenableFuture> apply(Void submitResult) throws Exception {
return Futures.immediateFuture(result);
}
});
}
}