NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / bgpmanager / impl / src / main / java / org / opendaylight / netvirt / bgpmanager / BgpUtil.java
index cad127397b5339f8e0c3156b3468e67ee2f9fe9f..a412f8c654206d890cd02016cab75c19b23c2e86 100755 (executable)
@@ -7,35 +7,53 @@
  */
 package org.opendaylight.netvirt.bgpmanager;
 
-import com.google.common.base.Optional;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.LinkedBlockingQueue;
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.utils.batching.ActionableResource;
 import org.opendaylight.genius.utils.batching.ActionableResourceImpl;
 import org.opendaylight.genius.utils.batching.DefaultBatchHandler;
 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
 import org.opendaylight.netvirt.bgpmanager.thrift.gen.encap_type;
 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.LayerType;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrf;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.DcgwTepList;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsContainer;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.Vrfs;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.VrfsKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.vrfs.AddressFamiliesVrf;
 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.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
@@ -65,14 +83,18 @@ public class BgpUtil implements AutoCloseable {
     private static final String RESOURCE_TYPE = "BGP-RESOURCES";
     private static final int DEFAULT_BATCH_SIZE = 1000;
     private static final int DEFAULT_BATCH_INTERVAL = 500;
+    private int enableBfdFlag = -1;
 
     private final DataBroker dataBroker;
+    private final IFibManager fibManager;
+
 
     private final BlockingQueue<ActionableResource> bgpResourcesBufferQ = new LinkedBlockingQueue<>();
 
     @Inject
-    public BgpUtil(DataBroker dataBroker) {
+    public BgpUtil(DataBroker dataBroker, final IFibManager fibManager) {
         this.dataBroker = dataBroker;
+        this.fibManager = fibManager;
     }
 
     @PostConstruct
@@ -101,7 +123,7 @@ public class BgpUtil implements AutoCloseable {
     public static int getAFItranslatedfromPrefix(String argPrefix) {
         int retValue = af_afi.AFI_IP.getValue();//default afiValue is 1 (= ipv4)
         String prefixOnly;
-        if (!argPrefix.contains("/")) {
+        if (argPrefix.indexOf("/") == -1) {
             prefixOnly = argPrefix;
         } else {
             prefixOnly = argPrefix.substring(0, argPrefix.indexOf("/"));
@@ -122,7 +144,7 @@ public class BgpUtil implements AutoCloseable {
     }
 
     public <T extends DataObject> void update(final InstanceIdentifier<T> path, final T data) {
-        ActionableResource actResource = new ActionableResourceImpl(path.toString());
+        ActionableResourceImpl actResource = new ActionableResourceImpl(path.toString());
         actResource.setAction(ActionableResource.UPDATE);
         actResource.setInstanceIdentifier(path);
         actResource.setInstance(data);
@@ -130,7 +152,7 @@ public class BgpUtil implements AutoCloseable {
     }
 
     public <T extends DataObject> void write(final InstanceIdentifier<T> path, final T data) {
-        ActionableResource actResource = new ActionableResourceImpl(path.toString());
+        ActionableResourceImpl actResource = new ActionableResourceImpl(path.toString());
         actResource.setAction(ActionableResource.CREATE);
         actResource.setInstanceIdentifier(path);
         actResource.setInstance(data);
@@ -138,7 +160,7 @@ public class BgpUtil implements AutoCloseable {
     }
 
     public <T extends DataObject> void delete(final InstanceIdentifier<T> path) {
-        ActionableResource actResource = new ActionableResourceImpl(path.toString());
+        ActionableResourceImpl actResource = new ActionableResourceImpl(path.toString());
         actResource.setAction(ActionableResource.DELETE);
         actResource.setInstanceIdentifier(path);
         actResource.setInstance(null);
@@ -178,8 +200,13 @@ public class BgpUtil implements AutoCloseable {
 
     public VpnInstanceOpDataEntry getVpnInstanceOpData(String rd)  {
         InstanceIdentifier<VpnInstanceOpDataEntry> id = getVpnInstanceOpDataIdentifier(rd);
-        Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = MDSALUtil.read(dataBroker,
-                LogicalDatastoreType.OPERATIONAL, id);
+        Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = Optional.empty();
+        try {
+            vpnInstanceOpData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.OPERATIONAL, id);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("Exception while reading VpnInstanceOpDataEntry DS for the Vpn Rd {}", rd, e);
+        }
         if (vpnInstanceOpData.isPresent()) {
             return vpnInstanceOpData.get();
         }
@@ -193,8 +220,13 @@ public class BgpUtil implements AutoCloseable {
 
     private String getElanNamefromRd(String rd)  {
         InstanceIdentifier<EvpnRdToNetwork> id = getEvpnRdToNetworkIdentifier(rd);
-        Optional<EvpnRdToNetwork> evpnRdToNetworkOpData = MDSALUtil.read(dataBroker,
-                LogicalDatastoreType.CONFIGURATION, id);
+        Optional<EvpnRdToNetwork> evpnRdToNetworkOpData = Optional.empty();
+        try {
+            evpnRdToNetworkOpData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, id);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("Exception while reading EvpnRdToNetwork DS for the Vpn Rd {}", rd, e);
+        }
         if (evpnRdToNetworkOpData.isPresent()) {
             return evpnRdToNetworkOpData.get().getNetworkId();
         }
@@ -220,7 +252,6 @@ public class BgpUtil implements AutoCloseable {
         InstanceIdentifier<ExternalTeps> externalTepsId = getExternalTepsIdentifier(elanName, tepIp);
         ExternalTepsBuilder externalTepsBuilder = new ExternalTepsBuilder();
         ExternalTepsKey externalTepsKey = externalTepsId.firstKeyOf(ExternalTeps.class);
-        externalTepsBuilder.setKey(externalTepsKey);
         externalTepsBuilder.setTepIp(externalTepsKey.getTepIp());
         update(externalTepsId, externalTepsBuilder.build());
     }
@@ -241,15 +272,22 @@ public class BgpUtil implements AutoCloseable {
     }
 
     private static InstanceIdentifier<ExternalTeps> getExternalTepsIdentifier(String elanInstanceName, String tepIp) {
-        IpAddress tepAdress = tepIp == null ? null : new IpAddress(tepIp.toCharArray());
+        IpAddress tepAdress = tepIp == null ? null : new IpAddress(new Ipv4Address(tepIp));
         return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
                 new ElanInstanceKey(elanInstanceName)).child(ExternalTeps.class,
                 new ExternalTepsKey(tepAdress)).build();
     }
 
     public String getVpnNameFromRd(String rd) {
-        VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd);
-        return vpnInstanceOpData != null ? vpnInstanceOpData.getVpnInstanceName() : null;
+        final Map<String, String> rdtoVpnMap = new HashMap<>();
+        if (rdtoVpnMap.get(rd) != null) {
+            return rdtoVpnMap.get(rd);
+        } else {
+            VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd);
+            String vpnName = vpnInstanceOpData != null ? vpnInstanceOpData.getVpnInstanceName() : null;
+            rdtoVpnMap.put(rd, vpnName);
+            return vpnName;
+        }
     }
 
     /** get the vrf with the RouterDistinguisher pass in param.
@@ -259,8 +297,15 @@ public class BgpUtil implements AutoCloseable {
     public Vrfs getVrfFromRd(String rd) {
         Vrfs vrfs = null;
         KeyedInstanceIdentifier<Vrfs, VrfsKey> id = InstanceIdentifier.create(Bgp.class)
+                .child(VrfsContainer.class)
                 .child(Vrfs.class, new VrfsKey(rd));
-        Optional<Vrfs> vrfsFromDs = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+        Optional<Vrfs> vrfsFromDs = Optional.empty();
+        try {
+            vrfsFromDs = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    id);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("Exception while reading BGP VRF table for the Vpn Rd {}", rd, e);
+        }
         if (vrfsFromDs.isPresent()) {
             vrfs = vrfsFromDs.get();
         }
@@ -273,9 +318,9 @@ public class BgpUtil implements AutoCloseable {
      */
     public static LayerType getLayerType(AddressFamiliesVrf adf) {
         LayerType layerTypeValue = null;
-        if (adf.getSafi() == af_safi.SAFI_EVPN.getValue()) {
+        if (adf.getSafi().intValue() == af_safi.SAFI_EVPN.getValue()) {
             layerTypeValue = LayerType.LAYER2;
-        } else if (adf.getSafi() == af_safi.SAFI_MPLS_VPN.getValue()) {
+        } else if (adf.getSafi().intValue() == af_safi.SAFI_MPLS_VPN.getValue()) {
             layerTypeValue = LayerType.LAYER3;
         }
         return layerTypeValue;
@@ -289,4 +334,99 @@ public class BgpUtil implements AutoCloseable {
                    .child(VrfEntry.class, new VrfEntryKey(vrfEntry.getDestPrefix())).build();
         delete(vrfEntryId);
     }
+
+    public void enableBfdFlag() {
+        enableBfdFlag = 1;
+    }
+
+    public void disableBfdFlag() {
+        enableBfdFlag = 0;
+    }
+
+    public boolean isBfdEnabled() {
+        if (enableBfdFlag == 1) {
+            return true;
+        } else if (enableBfdFlag == 0) {
+            return false;
+        }
+        BfdConfig bfdConfig = getBfdConfig();
+        if (bfdConfig != null) {
+            return bfdConfig.isBfdEnabled();
+        }
+        return false;
+    }
+
+    public BfdConfig getBfdConfig() {
+        InstanceIdentifier<BfdConfig> id =
+                InstanceIdentifier.builder(BfdConfig.class).build();
+        Optional<BfdConfig> bfdConfigOptional = Optional.empty();
+        try {
+            bfdConfigOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, id);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("Exception while reading BfdConfig", e);
+        }
+        if (bfdConfigOptional.isPresent()) {
+            return bfdConfigOptional.get();
+        }
+        return null;
+    }
+
+    public DcgwTepList getDcgwTepConfig() {
+        InstanceIdentifier<DcgwTepList> id =
+                InstanceIdentifier.builder(Bgp.class).child(DcgwTepList.class).build();
+        Optional<DcgwTepList> dcgwTepListOptional = Optional.empty();
+        try {
+            dcgwTepListOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, id);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("getDcgwTepConfig: Exception while reading DcgwTepList", e);
+        }
+        if (dcgwTepListOptional.isPresent()) {
+            return dcgwTepListOptional.get();
+        }
+        return null;
+    }
+
+    public List<String> getDcgwTepConfig(String dcgwIp) {
+        InstanceIdentifier<DcgwTep> id =
+                InstanceIdentifier.builder(Bgp.class)
+                        .child(DcgwTepList.class)
+                        .child(DcgwTep.class, new DcgwTepKey(dcgwIp)).build();
+        Optional<DcgwTep> tepListOptional = Optional.empty();
+        try {
+            tepListOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, id);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("Exception while reading DcgwTep for the IP {}", dcgwIp, e);
+        }
+        if (tepListOptional.isPresent()) {
+            return tepListOptional.get().getTepIps();
+        }
+        LOG.debug("No tep configured for DCGW {}", dcgwIp);
+        return null;
+    }
+
+    public static List<DPNTEPsInfo> getDpnTEPsInfos(DataBroker dataBroker) {
+        InstanceIdentifier<DpnEndpoints> iid = InstanceIdentifier.builder(DpnEndpoints.class).build();
+        Optional<DpnEndpoints> dpnEndpoints = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
+        if (dpnEndpoints.isPresent()) {
+            return dpnEndpoints.get().getDPNTEPsInfo();
+        } else {
+            return new ArrayList<>();
+        }
+    }
+
+    public void removeOrUpdateLBGroups(String tepIp, int addRemoveOrUpdate) {
+        getDpnTEPsInfos(dataBroker).forEach(dpnInfo -> {
+            if (NwConstants.MOD_FLOW == addRemoveOrUpdate) {
+                LOG.debug("Updating bucket in DPN {}", dpnInfo.getDPNID());
+            } else if (NwConstants.DEL_FLOW == addRemoveOrUpdate) {
+                LOG.debug("Deleting groups in DPN {}", dpnInfo.getDPNID());
+            }
+            Class<? extends TunnelTypeBase> tunType = TunnelTypeMplsOverGre.class;
+            fibManager.programDcGwLoadBalancingGroup(dpnInfo.getDPNID(),
+                    tepIp, addRemoveOrUpdate, false, tunType);
+        });
+    }
 }