Java tutorial
/** * 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.util.concurrent.AsyncFunction; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.util.List; import java.util.UUID; 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.sal.binding.api.BindingAwareBroker.RpcRegistration; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.faas.fabric.utils.InterfaceManager; import org.opendaylight.faas.fabric.utils.IpAddressUtils; import org.opendaylight.faas.fabric.utils.MdSalUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.rev150930.FabricId; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.AddAclInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.AddPortFunctionInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.AddStaticRouteInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.ClearStaticRouteInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateGatewayInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateGatewayOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateGatewayOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalPortInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalPortOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalPortOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalRouterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalRouterOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalRouterOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalSwitchInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalSwitchOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.CreateLogicalSwitchOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.DelAclInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.FabricServiceService; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.LogicalPortAugment; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.LogicalPortAugmentBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.LogicalRouterAugment; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.LogicalRouterAugmentBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.LogicalSwitchAugment; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.LogicalSwitchAugmentBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.PortBindingLogicalToDeviceInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.PortBindingLogicalToFabricInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.RmGatewayInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.RmLogicalPortInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.RmLogicalRouterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.RmLogicalSwitchInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.RmStaticRouteInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.create.logical.port.input.Attribute; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.network.topology.topology.node.LrAttribute; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.network.topology.topology.node.LrAttributeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.network.topology.topology.node.LswAttribute; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.network.topology.topology.node.LswAttributeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.network.topology.topology.node.termination.point.LportAttribute; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.services.rev150930.network.topology.topology.node.termination.point.LportAttributeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.TpRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.acl.list.FabricAcl; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.acl.list.FabricAclBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.acl.list.FabricAclKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.logical.port.PortLayerBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.logical.port.port.layer.Layer1InfoBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.logical.port.port.layer.Layer3InfoBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.logical.router.Routes; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.logical.router.RoutesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.port.functions.PortFunction; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.route.group.Route; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.route.group.RouteBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.fabric.type.rev150930.route.group.RouteKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId; 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.TpId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.SourceBuilder; 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.Link; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey; 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.network.topology.topology.node.TerminationPoint; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey; 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 FabricServiceAPIProvider implements AutoCloseable, FabricServiceService { private static final Logger LOG = LoggerFactory.getLogger(FabricServiceAPIProvider.class); private final DataBroker dataBroker; private final RpcProviderRegistry rpcRegistry; private RpcRegistration<FabricServiceService> rpcRegistration; private final ExecutorService executor; public FabricServiceAPIProvider(final DataBroker dataBroker, final RpcProviderRegistry rpcRegistry, ExecutorService executor) { this.dataBroker = dataBroker; this.rpcRegistry = rpcRegistry; this.executor = executor; } public void start() { rpcRegistration = rpcRegistry.addRpcImplementation(FabricServiceService.class, this); } @Override public void close() throws Exception { if (rpcRegistration != null) { rpcRegistration.close(); } } @Override public Future<RpcResult<Void>> rmGateway(RmGatewayInput input) { FabricId fabricId = input.getFabricId(); final NodeId routerId = input.getLogicalRouter(); IpAddress gwIp = input.getIpAddress(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } ReadWriteTransaction trans = dataBroker.newReadWriteTransaction(); TpId tpOnRouter = null; NodeId lswId = null; TpId tpOnSwitch = null; Link link = null; tpOnRouter = new TpId(String.valueOf(gwIp.getValue())); if (tpOnRouter != null) { link = findGWLink(trans, fabricId, tpOnRouter, routerId); trans.delete(LogicalDatastoreType.OPERATIONAL, MdSalUtils.createLinkIId(fabricId, link.getLinkId())); } if (link != null) { lswId = link.getDestination().getDestNode(); tpOnSwitch = link.getDestination().getDestTp(); trans.delete(LogicalDatastoreType.OPERATIONAL, MdSalUtils.createLogicPortIId(fabricId, lswId, tpOnSwitch)); } final NodeId flswid = lswId == null ? null : lswId; trans.delete(LogicalDatastoreType.OPERATIONAL, MdSalUtils.createLogicPortIId(fabricId, routerId, tpOnRouter)); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyGatewayRemoved(flswid, routerId); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } private Link findGWLink(ReadWriteTransaction trans, FabricId fabricid, TpId tpid, NodeId routerid) { InstanceIdentifier<Link> linkIId = InstanceIdentifier.create(NetworkTopology.class) .child(Topology.class, new TopologyKey(new TopologyId(fabricid))) .child(Link.class, new LinkKey(this.createGatewayLink(routerid, tpid))); CheckedFuture<Optional<Link>, ReadFailedException> readFuture = trans.read(LogicalDatastoreType.OPERATIONAL, linkIId); try { Optional<Link> optional = readFuture.get(); Link link = optional.get(); return link; } catch (InterruptedException | ExecutionException e) { LOG.error("", e); } return null; } @Override public Future<RpcResult<Void>> rmLogicalSwitch(RmLogicalSwitchInput input) { final FabricId fabricId = input.getFabricId(); NodeId nodeid = input.getNodeId(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final InstanceIdentifier<Node> lswIId = MdSalUtils.createNodeIId(fabricId.getValue(), nodeid); ReadOnlyTransaction trans = dataBroker.newReadOnlyTransaction(); CheckedFuture<Optional<Node>, ReadFailedException> readFuture = trans.read(LogicalDatastoreType.OPERATIONAL, lswIId); return Futures.transform(readFuture, new AsyncFunction<Optional<Node>, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Optional<Node> optional) throws Exception { if (optional.isPresent()) { Node lsw = optional.get(); fabricObj.notifyLogicSwitchRemoved(lsw); WriteTransaction wt = dataBroker.newWriteOnlyTransaction(); wt.delete(LogicalDatastoreType.OPERATIONAL, lswIId); MdSalUtils.wrapperSubmit(wt, executor); } return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<CreateGatewayOutput>> createGateway(CreateGatewayInput input) { final RpcResultBuilder<CreateGatewayOutput> resultBuilder = RpcResultBuilder.<CreateGatewayOutput>success(); CreateGatewayOutputBuilder outputBuilder = new CreateGatewayOutputBuilder(); final FabricId fabricId = input.getFabricId(); final NodeId routerId = input.getLogicalRouter(); final NodeId swId = input.getLogicalSwitch(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); // add logic port to Router TpId tpid1 = createGWPortOnRouter(input, outputBuilder, trans, fabricObj); // add logic port to switch TpId tpid2 = createGWPortOnSwitch(fabricId, swId, trans); // add link LinkId linkId = createGatewayLink(routerId, tpid1); createLogicLink(fabricId, routerId, swId, trans, tpid1, tpid2, linkId); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<CreateGatewayOutput>>() { @Override public ListenableFuture<RpcResult<CreateGatewayOutput>> apply(Void submitResult) throws Exception { resultBuilder.withResult(outputBuilder); return Futures.immediateFuture(resultBuilder.build()); } }, executor); } private LinkId createGatewayLink(NodeId routerId, TpId gwPort) { return new LinkId(String.format("gateway:%s, router:%s", gwPort.getValue(), routerId)); } private void createLogicLink(FabricId fabricid, NodeId routeId, NodeId swId, WriteTransaction trans, TpId tpid1, TpId tpid2, LinkId lid) { final LinkId linkid = lid == null ? new LinkId(UUID.randomUUID().toString()) : lid; LinkBuilder linkBuilder = new LinkBuilder(); linkBuilder.setLinkId(linkid); linkBuilder.setKey(new LinkKey(linkid)); SourceBuilder srcBuilder = new SourceBuilder(); srcBuilder.setSourceNode(routeId); srcBuilder.setSourceTp(tpid1); linkBuilder.setSource(srcBuilder.build()); DestinationBuilder destBuilder = new DestinationBuilder(); destBuilder.setDestNode(swId); destBuilder.setDestTp(tpid2); linkBuilder.setDestination(destBuilder.build()); InstanceIdentifier<Link> linkIId = MdSalUtils.createLinkIId(fabricid, linkid); trans.put(LogicalDatastoreType.OPERATIONAL, linkIId, linkBuilder.build()); } private TpId createGWPortOnSwitch(FabricId fabricid, NodeId swId, WriteTransaction trans) { final TpId tpid = new TpId(UUID.randomUUID().toString()); final InstanceIdentifier<TerminationPoint> tpIId = MdSalUtils.createLogicPortIId(fabricid, swId, tpid); TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); tpBuilder.setTpId(tpid); tpBuilder.setKey(new TerminationPointKey(tpid)); LogicalPortAugmentBuilder lpCtx = new LogicalPortAugmentBuilder(); LportAttributeBuilder lpAttr = new LportAttributeBuilder(); lpCtx.setLportAttribute(lpAttr.build()); tpBuilder.addAugmentation(LogicalPortAugment.class, lpCtx.build()); trans.put(LogicalDatastoreType.OPERATIONAL, tpIId, tpBuilder.build(), true); return tpid; } private TpId createGWPortOnRouter(CreateGatewayInput input, CreateGatewayOutputBuilder outputBuilder, WriteTransaction trans, FabricInstance fabricObj) { final FabricId fabricId = input.getFabricId(); final NodeId routerId = input.getLogicalRouter(); final NodeId swId = input.getLogicalSwitch(); final IpAddress gwIp = input.getIpAddress(); IpPrefix network = input.getNetwork(); if (network == null) { network = IpAddressUtils.createDefaultPrefix(gwIp); } else { network = IpAddressUtils.createGwPrefix(gwIp, network); } final IpPrefix ipPrefix = network; final TpId tpid = new TpId(String.valueOf(gwIp.getValue())); TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); tpBuilder.setTpId(tpid); tpBuilder.setKey(new TerminationPointKey(tpid)); LportAttributeBuilder lpAttr = new LportAttributeBuilder(); lpAttr.setPortLayer(new PortLayerBuilder() .setLayer3Info( new Layer3InfoBuilder().setIp(gwIp).setNetwork(ipPrefix).setForwardEnable(true).build()) .build()); fabricObj.buildGateway(swId, ipPrefix, routerId, fabricId, lpAttr); LogicalPortAugmentBuilder lpCtx = new LogicalPortAugmentBuilder(); lpCtx.setLportAttribute(lpAttr.build()); tpBuilder.addAugmentation(LogicalPortAugment.class, lpCtx.build()); InstanceIdentifier<TerminationPoint> tpIId = MdSalUtils.createLogicPortIId(fabricId, routerId, tpid); trans.put(LogicalDatastoreType.OPERATIONAL, tpIId, tpBuilder.build(), true); outputBuilder.setTpId(tpid); outputBuilder.setPortLayer(lpAttr.getPortLayer()); return tpid; } @Override public Future<RpcResult<CreateLogicalSwitchOutput>> createLogicalSwitch(final CreateLogicalSwitchInput input) { final RpcResultBuilder<CreateLogicalSwitchOutput> resultBuilder = RpcResultBuilder .<CreateLogicalSwitchOutput>success(); final CreateLogicalSwitchOutputBuilder outputBuilder = new CreateLogicalSwitchOutputBuilder(); FabricId fabricId = input.getFabricId(); String name = input.getName(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final String uuid = UUID.randomUUID().toString(); final NodeId newNodeId = new NodeId(name == null ? uuid : name); final InstanceIdentifier<Node> newRouterIId = MdSalUtils.createNodeIId(fabricId.getValue(), newNodeId); NodeBuilder nodeBuilder = new NodeBuilder(); nodeBuilder.setKey(new NodeKey(newNodeId)); nodeBuilder.setNodeId(newNodeId); nodeBuilder.setSupportingNode(createDefaultSuplNode(fabricId)); LswAttributeBuilder lswAttr = new LswAttributeBuilder(); lswAttr.setName(input.getName()); lswAttr.setLswUuid(new Uuid(uuid)); fabricObj.buildLogicalSwitch(newNodeId, lswAttr, input); LogicalSwitchAugmentBuilder lswCtx = new LogicalSwitchAugmentBuilder(); lswCtx.setLswAttribute(lswAttr.build()); nodeBuilder.addAugmentation(LogicalSwitchAugment.class, lswCtx.build()); final Node lsw = nodeBuilder.build(); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.put(LogicalDatastoreType.OPERATIONAL, newRouterIId, lsw); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<CreateLogicalSwitchOutput>>() { @Override public ListenableFuture<RpcResult<CreateLogicalSwitchOutput>> apply(Void submitResult) throws Exception { outputBuilder.setLswUuid(new Uuid(uuid)); outputBuilder.setName(input.getName()); outputBuilder.setNodeId(newNodeId); fabricObj.notifyLogicSwitchCreated(newNodeId, lsw); return Futures.immediateFuture(resultBuilder.withResult(outputBuilder.build()).build()); } }, executor); } @Override public Future<RpcResult<Void>> rmLogicalRouter(RmLogicalRouterInput input) { FabricId fabricId = input.getFabricId(); NodeId nodeid = input.getNodeId(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final InstanceIdentifier<Node> routerIId = MdSalUtils.createNodeIId(fabricId.getValue(), nodeid); ReadOnlyTransaction trans = dataBroker.newReadOnlyTransaction(); CheckedFuture<Optional<Node>, ReadFailedException> readFuture = trans.read(LogicalDatastoreType.OPERATIONAL, routerIId); return Futures.transform(readFuture, new AsyncFunction<Optional<Node>, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Optional<Node> optional) throws Exception { if (optional.isPresent()) { Node lr = optional.get(); fabricObj.notifyLogicRouterRemoved(lr); WriteTransaction wt = dataBroker.newWriteOnlyTransaction(); wt.delete(LogicalDatastoreType.OPERATIONAL, routerIId); MdSalUtils.wrapperSubmit(wt, executor); } return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<Void>> rmLogicalPort(RmLogicalPortInput input) { FabricId fabricId = input.getFabricId(); NodeId deviceId = input.getLogicalDevice(); TpId tpid = input.getTpId(); final InstanceIdentifier<TerminationPoint> tpIId = MdSalUtils.createLogicPortIId(fabricId, deviceId, tpid); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.delete(LogicalDatastoreType.OPERATIONAL, tpIId); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<CreateLogicalRouterOutput>> createLogicalRouter(final CreateLogicalRouterInput input) { final RpcResultBuilder<CreateLogicalRouterOutput> resultBuilder = RpcResultBuilder .<CreateLogicalRouterOutput>success(); final CreateLogicalRouterOutputBuilder outputBuilder = new CreateLogicalRouterOutputBuilder(); FabricId fabricId = input.getFabricId(); String name = input.getName(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final String uuid = UUID.randomUUID().toString(); final NodeId newNodeId = new NodeId(name == null ? uuid : name); final InstanceIdentifier<Node> newRouterIId = MdSalUtils.createNodeIId(fabricId.getValue(), newNodeId); NodeBuilder nodeBuilder = new NodeBuilder(); nodeBuilder.setKey(new NodeKey(newNodeId)); nodeBuilder.setNodeId(newNodeId); nodeBuilder.setSupportingNode(createDefaultSuplNode(fabricId)); LrAttributeBuilder lrAttr = new LrAttributeBuilder(); lrAttr.setName(name); lrAttr.setLrUuid(new Uuid(uuid)); fabricObj.buildLogicalRouter(newNodeId, lrAttr, input); LogicalRouterAugmentBuilder lrCtx = new LogicalRouterAugmentBuilder(); lrCtx.setLrAttribute(lrAttr.build()); nodeBuilder.addAugmentation(LogicalRouterAugment.class, lrCtx.build()); final Node lr = nodeBuilder.build(); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.put(LogicalDatastoreType.OPERATIONAL, newRouterIId, lr, true); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<CreateLogicalRouterOutput>>() { @Override public ListenableFuture<RpcResult<CreateLogicalRouterOutput>> apply(Void submitResult) throws Exception { outputBuilder.setLrUuid(new Uuid(uuid)); outputBuilder.setName(input.getName()); outputBuilder.setNodeId(newNodeId); fabricObj.notifyLogicRouterCreated(newNodeId, lr); return Futures.immediateFuture(resultBuilder.withResult(outputBuilder.build()).build()); } }, executor); } @Override public Future<RpcResult<CreateLogicalPortOutput>> createLogicalPort(CreateLogicalPortInput input) { final RpcResultBuilder<CreateLogicalPortOutput> resultBuilder = RpcResultBuilder .<CreateLogicalPortOutput>success(); final CreateLogicalPortOutputBuilder outputBuilder = new CreateLogicalPortOutputBuilder(); final FabricId fabricId = input.getFabricId(); final String name = input.getName(); final NodeId nodeId = input.getLogicalDevice(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final TpId tpid = new TpId(name == null ? UUID.randomUUID().toString() : name); TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); tpBuilder.setTpId(tpid); tpBuilder.setKey(new TerminationPointKey(tpid)); LportAttributeBuilder lpAttr = new LportAttributeBuilder(); lpAttr.setName(input.getName()); Attribute portAttr = input.getAttribute(); if (portAttr != null) { lpAttr.setPortLayer(portAttr.getPortLayer()); lpAttr.setFabricAcl(portAttr.getFabricAcl()); lpAttr.setPortFunction(portAttr.getPortFunction()); } fabricObj.buildLogicalPort(tpid, lpAttr, input); LogicalPortAugmentBuilder lpCtx = new LogicalPortAugmentBuilder(); lpCtx.setLportAttribute(lpAttr.build()); tpBuilder.addAugmentation(LogicalPortAugment.class, lpCtx.build()); InstanceIdentifier<TerminationPoint> tpIId = MdSalUtils.createLogicPortIId(fabricId, nodeId, tpid); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.put(LogicalDatastoreType.OPERATIONAL, tpIId, tpBuilder.build()); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<CreateLogicalPortOutput>>() { @Override public ListenableFuture<RpcResult<CreateLogicalPortOutput>> apply(Void submitResult) throws Exception { outputBuilder.setTpId(tpid); outputBuilder.setName(name); return Futures.immediateFuture(resultBuilder.withResult(outputBuilder.build()).build()); } }, executor); } @Override public Future<RpcResult<Void>> addAcl(AddAclInput input) { String aclName = input.getAclName(); FabricId fabricId = input.getFabricId(); NodeId ldev = input.getLogicalDevice(); TpId tpId = input.getLogicalPort(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final InstanceIdentifier<FabricAcl> aclIId = fabricObj.addAcl(ldev, tpId, aclName); if (aclIId == null) { return Futures.immediateFailedFuture( new IllegalArgumentException("Can not add acl, maybe the target is not exists !")); } FabricAclBuilder aclBuilder = new FabricAclBuilder(); aclBuilder.setFabricAclName(aclName); aclBuilder.setKey(new FabricAclKey(aclName)); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.merge(LogicalDatastoreType.OPERATIONAL, aclIId, aclBuilder.build(), false); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyAclUpdated(aclIId, false); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<Void>> delAcl(DelAclInput input) { String aclName = input.getAclName(); FabricId fabricId = input.getFabricId(); NodeId ldev = input.getLogicalDevice(); TpId tpid = input.getLogicalPort(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } InstanceIdentifier<FabricAcl> aclIId = null; if (tpid != null) { aclIId = MdSalUtils.createLogicPortIId(fabricId, ldev, tpid).augmentation(LogicalPortAugment.class) .child(LportAttribute.class).child(FabricAcl.class, new FabricAclKey(aclName)); } else { aclIId = MdSalUtils.createNodeIId(fabricId, ldev).augmentation(LogicalSwitchAugment.class) .child(LswAttribute.class).child(FabricAcl.class, new FabricAclKey(aclName)); } final InstanceIdentifier<FabricAcl> tgtAclIId = aclIId; WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.delete(LogicalDatastoreType.OPERATIONAL, aclIId); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyAclUpdated(tgtAclIId, true); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<Void>> addPortFunction(AddPortFunctionInput input) { final PortFunction function = input.getPortFunction(); FabricId fabricId = input.getFabricId(); TpId tpid = input.getLogicalPort(); NodeId ldev = input.getLogicalDevice(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final InstanceIdentifier<PortFunction> fncIId = MdSalUtils.createLogicPortIId(fabricId, ldev, tpid) .augmentation(LogicalPortAugment.class).child(LportAttribute.class).child(PortFunction.class); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.merge(LogicalDatastoreType.OPERATIONAL, fncIId, function, false); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyPortFuncUpdated(fncIId, function, false); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<Void>> addStaticRoute(AddStaticRouteInput input) { final List<Route> routes = input.getRoute(); FabricId fabricId = input.getFabricId(); NodeId ldev = input.getNodeId(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } for (Route route : routes) { if (route.getNextHopOptions() == null) { return Futures.immediateFailedFuture(new IllegalArgumentException(String.format( "next hop is required. (destination = %s)", route.getDestinationPrefix().getValue()))); } } final InstanceIdentifier<Routes> routesIId = MdSalUtils.createNodeIId(fabricId, ldev) .augmentation(LogicalRouterAugment.class).child(LrAttribute.class).child(Routes.class); final List<InstanceIdentifier<Route>> routeKeys = Lists.newArrayList(); for (Route route : routes) { routeKeys.add(routesIId.child(Route.class, route.getKey())); } RoutesBuilder builder = new RoutesBuilder(); builder.setRoute(routes); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.merge(LogicalDatastoreType.OPERATIONAL, routesIId, builder.build(), true); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyRouteUpdated(routesIId.firstIdentifierOf(Node.class), routes, false); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<Void>> portBindingLogicalToFabric(PortBindingLogicalToFabricInput input) { FabricId fabricId = input.getFabricId(); TpId tpid = input.getLogicalPort(); NodeId ldev = input.getLogicalDevice(); TpId portId = input.getFabricPort(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final InstanceIdentifier<LportAttribute> attrIId = MdSalUtils.createLogicPortIId(fabricId, ldev, tpid) .augmentation(LogicalPortAugment.class).child(LportAttribute.class); LportAttributeBuilder builder = new LportAttributeBuilder(); builder.setPortLayer( new PortLayerBuilder().setLayer1Info(new Layer1InfoBuilder().setLocation(portId).build()).build()); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.merge(LogicalDatastoreType.OPERATIONAL, attrIId, builder.build(), false); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyLogicalPortLocated(attrIId.firstIdentifierOf(TerminationPoint.class), portId); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } private List<SupportingNode> createDefaultSuplNode(FabricId fabricid) { SupportingNodeBuilder builder = new SupportingNodeBuilder(); builder.setNodeRef(fabricid); builder.setKey(new SupportingNodeKey(fabricid, new TopologyId(Constants.FABRICS_TOPOLOGY_ID))); return Lists.newArrayList(builder.build()); } @Override public Future<RpcResult<Void>> portBindingLogicalToDevice(PortBindingLogicalToDeviceInput input) { FabricId fabricId = input.getFabricId(); TpId tpid = input.getLogicalPort(); NodeId ldev = input.getLogicalDevice(); TpRef physicalPort = input.getPhysicalPort(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } @SuppressWarnings("unchecked") InstanceIdentifier<TerminationPoint> fportIid = InterfaceManager.convDevPort2FabricPort(dataBroker, fabricId, (InstanceIdentifier<TerminationPoint>) physicalPort.getValue()); final TpId portId = fportIid.firstKeyOf(TerminationPoint.class).getTpId(); final InstanceIdentifier<LportAttribute> attrIId = MdSalUtils.createLogicPortIId(fabricId, ldev, tpid) .augmentation(LogicalPortAugment.class).child(LportAttribute.class); LportAttributeBuilder builder = new LportAttributeBuilder(); builder.setPortLayer( new PortLayerBuilder() .setLayer1Info(new Layer1InfoBuilder() .setLocation(fportIid.firstKeyOf(TerminationPoint.class).getTpId()).build()) .build()); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); trans.merge(LogicalDatastoreType.OPERATIONAL, attrIId, builder.build(), false); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyLogicalPortLocated(attrIId.firstIdentifierOf(TerminationPoint.class), portId); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } @Override public Future<RpcResult<Void>> clearStaticRoute(ClearStaticRouteInput input) { FabricId fabricId = input.getFabricId(); NodeId ldev = input.getNodeId(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final InstanceIdentifier<Routes> routesIId = MdSalUtils.createNodeIId(fabricId, ldev) .augmentation(LogicalRouterAugment.class).child(LrAttribute.class).child(Routes.class); ReadWriteTransaction trans = dataBroker.newReadWriteTransaction(); if (MdSalUtils.syncReadOper(trans, routesIId).isPresent()) { trans.delete(LogicalDatastoreType.OPERATIONAL, routesIId); return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyRouteCleared(routesIId.firstIdentifierOf(Node.class)); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } else { return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } } @Override public Future<RpcResult<Void>> rmStaticRoute(RmStaticRouteInput input) { final List<Ipv4Prefix> destIps = input.getDestinationPrefix(); FabricId fabricId = input.getFabricId(); NodeId ldev = input.getNodeId(); final FabricInstance fabricObj = FabricInstanceCache.INSTANCE.retrieveFabric(fabricId); if (fabricObj == null) { return Futures.immediateFailedFuture( new IllegalArgumentException(String.format("fabric %s does not exist", fabricId))); } final List<Route> routes = Lists.newArrayList(); for (Ipv4Prefix destIp : destIps) { routes.add(new RouteBuilder().setKey(new RouteKey(destIp)).build()); } final InstanceIdentifier<Routes> routesIId = MdSalUtils.createNodeIId(fabricId, ldev) .augmentation(LogicalRouterAugment.class).child(LrAttribute.class).child(Routes.class); WriteTransaction trans = dataBroker.newWriteOnlyTransaction(); for (Route route : routes) { trans.delete(LogicalDatastoreType.OPERATIONAL, routesIId.child(Route.class, route.getKey())); } return Futures.transform(trans.submit(), new AsyncFunction<Void, RpcResult<Void>>() { @Override public ListenableFuture<RpcResult<Void>> apply(Void submitResult) throws Exception { fabricObj.notifyRouteUpdated(routesIId.firstIdentifierOf(Node.class), routes, true); return Futures.immediateFuture(RpcResultBuilder.<Void>success().build()); } }, executor); } }