Code refactor - standalone class for Vpp manipulation. 51/251/3
authorJozef Gloncak <jgloncak@cisco.com>
Mon, 8 Feb 2016 14:12:14 +0000 (15:12 +0100)
committerGerrit Code Review <gerrit@fd.io>
Mon, 8 Feb 2016 21:57:19 +0000 (21:57 +0000)
Change-Id: I3869462364f2a73177eca6848bac897ccadfd67f
Signed-off-by: Jozef Gloncak <jgloncak@cisco.com>
vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java
vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java [new file with mode: 0644]

index bb1a5b0..0ecd14c 100644 (file)
@@ -16,7 +16,6 @@ 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.Collection;
 import java.util.List;
@@ -32,28 +31,18 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 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.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.external.reference.rev160129.ExternalReference;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.interconnection.BridgeBasedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder;
@@ -64,7 +53,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TerminationPointVbridgeAugment;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TerminationPointVbridgeAugmentBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.TunnelParameters;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.BridgeMember;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.BridgeMemberBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.termination.point.InterfaceType;
@@ -100,23 +88,22 @@ import org.slf4j.LoggerFactory;
  */
 final class BridgeDomain implements DataTreeChangeListener<Topology> {
     private static final Logger LOG = LoggerFactory.getLogger(BridgeDomain.class);
+
     private static final int SOURCE_VPP_INDEX = 0;
     private static final int DESTINATION_VPP_INDEX = 1;
     private static final String TUNNEL_ID_PREFIX = "vxlan_tunnel";
-    private static final String TUNNEL_DESCRIPTION = "virtual interface which interconnects VPPs";
-    private static final Long DEFAULT_ENCAP_VRF_ID = 0L;
-    private static final String TUNNEL_ID_DEMO = TUNNEL_ID_PREFIX + "0";
+    static final String TUNNEL_ID_DEMO = TUNNEL_ID_PREFIX + "0";
     private final KeyedInstanceIdentifier<Topology, TopologyKey> topology;
     @GuardedBy("this")
 
     private final BindingTransactionChain chain;
     private final ListenerRegistration<?> reg;
     private final MountPointService mountService;
+    private final VppModifier vppModifier;
     private TopologyVbridgeAugment config;
     private final String bridgeDomainName;
     private final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain> iiBridgeDomainOnVPP;
     private final String iiBridgeDomainOnVPPRest;
-    private final DataBroker dataBroker;
     private Multimap<NodeId, KeyedInstanceIdentifier<Node, NodeKey>> nodesToVpps = ArrayListMultimap.create();
     private final List<Integer> tunnelIds;
 
@@ -132,10 +119,10 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> {
                 .child(BridgeDomains.class)
                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain.class, new BridgeDomainKey(bridgeDomainName));
 
-        this.dataBroker = dataBroker;
         reg = dataBroker.registerDataTreeChangeListener(
-                                     new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, topology), this);
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, topology), this);
         this.tunnelIds = new ArrayList<>();
+        this.vppModifier = new VppModifier(mountService);
     }
 
     private String provideIIBrdigeDomainOnVPPRest() {
@@ -210,6 +197,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> {
 
                     // Read configuration
                     final TopologyVbridgeAugment config = data.getAugmentation(TopologyVbridgeAugment.class);
+                    vppModifier.setConfig(config);
                     if (config != null) {
                         setConfiguration(config);
                     } else {
@@ -256,93 +244,38 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> {
         }
     }
 
-    private void addTunnel(final NodeId newNode) {
-        for (Map.Entry<NodeId, KeyedInstanceIdentifier<Node, NodeKey>> entryToVpp : nodesToVpps.entries()) {
-            if (!entryToVpp.getKey().equals(newNode)) {
+    private void addTunnel(final NodeId sourceNode) {
+        final KeyedInstanceIdentifier<Node, NodeKey> iiToSrcVpp = nodesToVpps.get(sourceNode).iterator().next();
+        for (Map.Entry<NodeId, KeyedInstanceIdentifier<Node, NodeKey>> nodeToVpp : nodesToVpps.entries()) {
+            if (!nodeToVpp.getKey().equals(sourceNode)) {
                 //TODO: check whether returned value from nodesToVpps is not null
-                final KeyedInstanceIdentifier<Node, NodeKey> iiToOldVpp = entryToVpp.getValue();
-                final KeyedInstanceIdentifier<Node, NodeKey> iiToNewVpp = nodesToVpps.get(newNode).iterator().next();
-                final NodeId oldNode = entryToVpp.getKey();
+                final KeyedInstanceIdentifier<Node, NodeKey> iiToDstVpp = nodeToVpp.getValue();
+                final NodeId dstNode = nodeToVpp.getKey();
 
-                final ListenableFuture<List<Optional<Ipv4AddressNoZone>>> ipAddressesFuture = readIpAddressesFromVpps(iiToOldVpp, iiToNewVpp);
+                final ListenableFuture<List<Optional<Ipv4AddressNoZone>>> ipAddressesFuture = vppModifier.readIpAddressesFromVpps(iiToDstVpp, iiToSrcVpp);
                 Futures.addCallback(ipAddressesFuture, new FutureCallback<List<Optional<Ipv4AddressNoZone>>>() {
                     @Override
                     public void onSuccess(List<Optional<Ipv4AddressNoZone>> ipAddresses) {
                         if (ipAddresses.size() == 2) {
                             LOG.debug("All required IP addresses for creating tunnel were obtained.");
-                            final Optional<Ipv4AddressNoZone> ipAddressNewVpp = ipAddresses.get(SOURCE_VPP_INDEX);
-                            final Optional<Ipv4AddressNoZone> ipAddressOldVpp = ipAddresses.get(DESTINATION_VPP_INDEX);
-                            if (ipAddressNewVpp != null && ipAddressOldVpp != null) {
-                                if (ipAddressNewVpp.isPresent() && ipAddressOldVpp.isPresent()) {
-                                    //writing v3po:vxlan container to new node
-                                    Vxlan vxlanData = prepareVxlan(ipAddressOldVpp.get(), ipAddressNewVpp.get());
-                                    Interface intfData = prepareVirtualInterfaceData(vxlanData);
-                                    createVirtualInterfaceOnVpp(intfData, iiToNewVpp);
+                            final Optional<Ipv4AddressNoZone> ipAddressSrcVpp = ipAddresses.get(SOURCE_VPP_INDEX);
+                            final Optional<Ipv4AddressNoZone> ipAddressDstVpp = ipAddresses.get(DESTINATION_VPP_INDEX);
+                            if (ipAddressSrcVpp != null && ipAddressDstVpp != null) {
+                                if (ipAddressSrcVpp.isPresent() && ipAddressDstVpp.isPresent()) {
+                                    //writing v3po:vxlan container to source node
+                                    vppModifier.createVirtualInterfaceOnVpp(ipAddressSrcVpp.get(), ipAddressDstVpp.get(), iiToSrcVpp);
 
                                     //writing v3po:vxlan container to existing node
-                                    vxlanData = prepareVxlan(ipAddressNewVpp.get(), ipAddressOldVpp.get());
-                                    intfData = prepareVirtualInterfaceData(vxlanData);
-                                    createVirtualInterfaceOnVpp(intfData, iiToOldVpp);
+                                    vppModifier.createVirtualInterfaceOnVpp(ipAddressDstVpp.get(), ipAddressSrcVpp.get(), iiToDstVpp);
 
-                                    addTerminationPoint(topology.child(Node.class, new NodeKey(oldNode)));
-                                    addTerminationPoint(topology.child(Node.class, new NodeKey(newNode)));
+                                    addTerminationPoint(topology.child(Node.class, new NodeKey(dstNode)));
+                                    addTerminationPoint(topology.child(Node.class, new NodeKey(sourceNode)));
 
-                                    addLinkBetweenTerminationPoints(newNode, oldNode);
-                                    addLinkBetweenTerminationPoints(oldNode, newNode);
+                                    addLinkBetweenTerminationPoints(sourceNode, dstNode);
+                                    addLinkBetweenTerminationPoints(dstNode, sourceNode);
                                 }
                             }
                         }
-
-                    }
-
-                    private void createVirtualInterfaceOnVpp(final Interface intfData, final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp) {
-                        final DataBroker vppDataBroker = resolveDataBrokerForMountPoint(iiToVpp);
-                        if (vppDataBroker != null) {
-                            final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
-                            final KeyedInstanceIdentifier<Interface, InterfaceKey> iiToInterface
-                                    = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(TUNNEL_ID_DEMO));
-                            wTx.put(LogicalDatastoreType.CONFIGURATION, iiToInterface, intfData);
-                            final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wTx.submit();
-                            Futures.addCallback(submitFuture, new FutureCallback<Void>() {
-                                @Override
-                                public void onSuccess(@Nullable Void result) {
-                                    LOG.debug("Writing super virtual interface to {} finished successfully.",iiToVpp.getKey().getNodeId());
-                                }
-
-                                @Override
-                                public void onFailure(Throwable t) {
-                                    LOG.debug("Writing super virtual interface to {} failed.",iiToVpp.getKey().getNodeId());
-                                }
-                            });
-                        } else {
-                            LOG.debug("Writing virtual interface {} to VPP {} wasn't successfull because missing data broker.",TUNNEL_DESCRIPTION, iiToVpp);
-                        }
-                    }
-
-                    private Interface prepareVirtualInterfaceData(final Vxlan vxlan) {
-                        final InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
-                        //TODO implement tunnel counter
-                        interfaceBuilder.setName(TUNNEL_ID_DEMO);
-                        interfaceBuilder.setType(VxlanTunnel.class);
-                        VppInterfaceAugmentationBuilder vppInterfaceAugmentationBuilder = new VppInterfaceAugmentationBuilder();
-                        vppInterfaceAugmentationBuilder.setVxlan(vxlan);
-                        interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppInterfaceAugmentationBuilder.build());
-                        return interfaceBuilder.build();
-                    }
-
-                    private Vxlan prepareVxlan(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst) {
-                        final VxlanBuilder vxlanBuilder = new VxlanBuilder();
-                        vxlanBuilder.setSrc(ipSrc);
-                        vxlanBuilder.setDst(ipDst);
-                        final TunnelParameters tunnelParameters = config.getTunnelParameters();
-                        if (tunnelParameters instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan) {
-                            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan vxlan =
-                                    (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan) tunnelParameters;
-                            //TODO: handle NPE
-                            vxlanBuilder.setVni(vxlan.getVxlan().getVni());
-                        }
-                        vxlanBuilder.setEncapVrfId(DEFAULT_ENCAP_VRF_ID);
-                        return vxlanBuilder.build();
                     }
 
                     @Override
@@ -362,7 +295,6 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> {
         final WriteTransaction wTx = chain.newWriteOnlyTransaction();
         wTx.put(LogicalDatastoreType.OPERATIONAL, iiToLink, prepareData(newVpp, odlVpp, linkId),true);
         wTx.submit();
-
     }
 
     private Link prepareData(final NodeId newVpp, final NodeId oldVpp, final LinkId linkId) {
@@ -374,7 +306,6 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> {
         sourceBuilder.setSourceTp(new TpId(TUNNEL_ID_DEMO));
         linkBuilder.setSource(sourceBuilder.build());
 
-
         final DestinationBuilder destinationBuilder = new DestinationBuilder();
         destinationBuilder.setDestNode(oldVpp);
         destinationBuilder.setDestTp(new TpId(TUNNEL_ID_DEMO));
@@ -386,54 +317,6 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> {
         return linkBuilder.build();
     }
 
-    private ListenableFuture<List<Optional<Ipv4AddressNoZone>>> readIpAddressesFromVpps(final KeyedInstanceIdentifier<Node, NodeKey>... iiToVpps) {
-        final List<ListenableFuture<Optional<Ipv4AddressNoZone>>> ipv4Futures = new ArrayList<>();
-        for (final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp : iiToVpps) {
-            ipv4Futures.add(readIpAddressFromVpp(iiToVpp));
-        }
-        return Futures.successfulAsList(ipv4Futures);
-    }
-
-    private ListenableFuture<Optional<Ipv4AddressNoZone>> readIpAddressFromVpp(final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp) {
-        final SettableFuture<Optional<Ipv4AddressNoZone>> resultFuture = SettableFuture.create();
-
-        final DataBroker vppDataBroker = resolveDataBrokerForMountPoint(iiToVpp);
-        final ReadOnlyTransaction rTx = vppDataBroker.newReadOnlyTransaction();
-        final CheckedFuture<Optional<Interfaces>, ReadFailedException> interfaceStateFuture
-                = rTx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Interfaces.class));
-
-        Futures.addCallback(interfaceStateFuture, new FutureCallback<Optional<Interfaces>>() {
-            @Override
-            public void onSuccess(Optional<Interfaces> optInterfaces) {
-                if (optInterfaces.isPresent()) {
-                    for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intf : optInterfaces.get().getInterface()) {
-                        final Interface1 interface1 = intf.getAugmentation(Interface1.class);
-                        if (interface1 != null) {
-                            final Ipv4 ipv4 = interface1.getIpv4();
-                            if (ipv4 != null) {
-                                final List<Address> addresses = ipv4.getAddress();
-                                if (!addresses.isEmpty()) {
-                                    final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
-                                    if (ip != null) {
-                                        resultFuture.set(Optional.of(ip));
-                                        break;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                resultFuture.set(Optional.<Ipv4AddressNoZone>absent());
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                resultFuture.setException(t);
-
-            }
-        });
-        return resultFuture;
-    }
 
 
     private void modifyTerminationPoint(final DataObjectModification<TerminationPoint> nodeChild, final NodeId nodeId) {
diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java
new file mode 100644 (file)
index 0000000..142272b
--- /dev/null
@@ -0,0 +1,204 @@
+/**
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ * <p>
+ * 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 io.fd.honeycomb.vbd.impl;
+
+import com.google.common.base.Optional;
+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 javax.annotation.Nullable;
+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.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.TunnelParameters;
+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.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *  Class which is used for manipulation with VPP
+ */
+public class VppModifier {
+    private static final Long DEFAULT_ENCAP_VRF_ID = 0L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(BridgeDomain.class);
+    private final MountPointService mountService;
+    private TopologyVbridgeAugment config;
+
+
+    public VppModifier(final MountPointService mountService) {
+        this.mountService = mountService;
+    }
+    /**
+     * Tryies to read ipv4 addresses from all specified {@code iiToVpps } vpps.
+     *
+     * @param iiToVpps collection of instance identifiers which points to concrete mount points.
+     * @return future which contains list of ip addreases in the same order as was specified in {@code iiToVpps}
+     */
+    ListenableFuture<List<Optional<Ipv4AddressNoZone>>> readIpAddressesFromVpps(final KeyedInstanceIdentifier<Node, NodeKey>... iiToVpps) {
+        final List<ListenableFuture<Optional<Ipv4AddressNoZone>>> ipv4Futures = new ArrayList<>();
+        for (final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp : iiToVpps) {
+            ipv4Futures.add(readIpAddressFromVpp(iiToVpp));
+        }
+        return Futures.successfulAsList(ipv4Futures);
+    }
+
+    /**
+     * Passes through interfaces at mount point specified via {@code iiToVpp}.
+     *
+     * When first ipv4 address is found then it is returned.
+     *
+     * @param iiToVpp instance idenfifier which point to mounted vpp
+     * @return if set ipv4 address is found at mounted vpp then it is returned as future. Otherwise absent value is returned
+     * in future or exception which has been thrown
+     */
+    private ListenableFuture<Optional<Ipv4AddressNoZone>> readIpAddressFromVpp(final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp) {
+        final SettableFuture<Optional<Ipv4AddressNoZone>> resultFuture = SettableFuture.create();
+
+        final DataBroker vppDataBroker = resolveDataBrokerForMountPoint(iiToVpp);
+        if (vppDataBroker != null) {
+            final ReadOnlyTransaction rTx = vppDataBroker.newReadOnlyTransaction();
+            final CheckedFuture<Optional<Interfaces>, ReadFailedException> interfaceStateFuture
+                    = rTx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Interfaces.class));
+
+            Futures.addCallback(interfaceStateFuture, new FutureCallback<Optional<Interfaces>>() {
+                @Override
+                public void onSuccess(final Optional<Interfaces> optInterfaces) {
+                    if (optInterfaces.isPresent()) {
+                        for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intf : optInterfaces.get().getInterface()) {
+                            final Interface1 interface1 = intf.getAugmentation(Interface1.class);
+                            if (interface1 != null) {
+                                final Ipv4 ipv4 = interface1.getIpv4();
+                                if (ipv4 != null) {
+                                    final List<Address> addresses = ipv4.getAddress();
+                                    if (!addresses.isEmpty()) {
+                                        final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
+                                        if (ip != null) {
+                                            resultFuture.set(Optional.of(ip));
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    } else {
+                        LOG.debug("There is no inferface with ipv4 address set at VPP {}.", iiToVpp);
+                        resultFuture.set(Optional.<Ipv4AddressNoZone>absent());
+                    }
+                }
+
+                @Override
+                public void onFailure(Throwable t) {
+                    resultFuture.setException(t);
+                }
+            });
+        } else {
+            LOG.debug("Data broker for vpp {} is missing.", iiToVpp);
+            resultFuture.set(Optional.<Ipv4AddressNoZone>absent());
+        }
+        return resultFuture;
+    }
+
+    void createVirtualInterfaceOnVpp(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst, final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp) {
+        final Vxlan vxlanData = prepareVxlan(ipSrc, ipDst);
+        final Interface intfData = prepareVirtualInterfaceData(vxlanData);
+
+        final DataBroker vppDataBroker = resolveDataBrokerForMountPoint(iiToVpp);
+        if (vppDataBroker != null) {
+            final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
+            final KeyedInstanceIdentifier<Interface, InterfaceKey> iiToInterface
+                    = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(BridgeDomain.TUNNEL_ID_DEMO));
+            wTx.put(LogicalDatastoreType.CONFIGURATION, iiToInterface, intfData);
+            final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wTx.submit();
+            Futures.addCallback(submitFuture, new FutureCallback<Void>() {
+                @Override
+                public void onSuccess(@Nullable Void result) {
+                    LOG.debug("Writing super virtual interface to {} finished successfully.",iiToVpp.getKey().getNodeId());
+                }
+
+                @Override
+                public void onFailure(Throwable t) {
+                    LOG.debug("Writing super virtual interface to {} failed.", iiToVpp.getKey().getNodeId());
+                }
+            });
+        } else {
+            LOG.debug("Writing virtual interface {} to VPP {} wasn't successfull because missing data broker.", BridgeDomain.TUNNEL_ID_DEMO, iiToVpp);
+        }
+    }
+
+
+    private DataBroker resolveDataBrokerForMountPoint(final InstanceIdentifier<Node> iiToMountPoint) {
+        final Optional<MountPoint> vppMountPointOpt = mountService.getMountPoint(iiToMountPoint);
+        if (vppMountPointOpt.isPresent()) {
+            final MountPoint vppMountPoint = vppMountPointOpt.get();
+            final Optional<DataBroker> dataBrokerOpt = vppMountPoint.getService(DataBroker.class);
+            if (dataBrokerOpt.isPresent()) {
+                return dataBrokerOpt.get();
+            }
+        }
+        return null;
+    }
+
+
+    private Interface prepareVirtualInterfaceData(final Vxlan vxlan) {
+        final InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
+        //TODO implement tunnel counter
+        interfaceBuilder.setName(BridgeDomain.TUNNEL_ID_DEMO);
+        interfaceBuilder.setType(VxlanTunnel.class);
+        VppInterfaceAugmentationBuilder vppInterfaceAugmentationBuilder = new VppInterfaceAugmentationBuilder();
+        vppInterfaceAugmentationBuilder.setVxlan(vxlan);
+        interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppInterfaceAugmentationBuilder.build());
+        return interfaceBuilder.build();
+    }
+
+    private Vxlan prepareVxlan(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst) {
+        final VxlanBuilder vxlanBuilder = new VxlanBuilder();
+        vxlanBuilder.setSrc(ipSrc);
+        vxlanBuilder.setDst(ipDst);
+        final TunnelParameters tunnelParameters = config.getTunnelParameters();
+        if (tunnelParameters instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan) {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan vxlan =
+                    (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan) tunnelParameters;
+            //TODO: handle NPE
+            vxlanBuilder.setVni(vxlan.getVxlan().getVni());
+        }
+        vxlanBuilder.setEncapVrfId(DEFAULT_ENCAP_VRF_ID);
+        return vxlanBuilder.build();
+    }
+
+
+    public void setConfig(final TopologyVbridgeAugment config) {
+        this.config = config;
+    }
+}