Add decoder constraint based on treat-as-withdrawn configuration
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / config / OpenConfigMappingUtil.java
index a516deb513b31ebaf0a4159a838dea5c884230b8..7190b1d63395cbbd061bf051cba360b43683a471 100644 (file)
@@ -11,8 +11,6 @@ package org.opendaylight.protocol.bgp.rib.impl.config;
 import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil.INSTANCE;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.primitives.Shorts;
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -20,127 +18,125 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.function.BiFunction;
 import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
-import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
-import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
-import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
+import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandlingSupport;
+import org.opendaylight.protocol.bgp.parser.spi.pojo.RevisedErrorHandlingSupportImpl;
 import org.opendaylight.protocol.concepts.KeyMapping;
 import org.opendaylight.protocol.util.Ipv4Util;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.BgpCommonAfiSafiList;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborAddPathsConfig;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.AfiSafisBuilder;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.ConfigBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborGroup;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborTransportConfig;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.GracefulRestart;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandling;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflector;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflectorBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TimersBuilder;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TransportBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.Config;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroup;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.GlobalBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.CommunityType;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.PeerType;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.RrClusterIdType;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
 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.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.BgpTableType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.SendReceive;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamilies;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamiliesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.GlobalConfigAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.GlobalConfigAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.NeighborConfigAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.NeighborConfigAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.ApplicationRibId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.RibId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.SimpleRoutingPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.SendReceive;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp.capabilities.add.path.capability.AddressFamilies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp.capabilities.add.path.capability.AddressFamiliesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.GlobalAddPathsConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.GlobalConfigAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAddPathsConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborPeerGroupConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTransportConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.PeerGroupTransportConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.TransportConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.ClusterIdentifier;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-public final class OpenConfigMappingUtil {
+final class OpenConfigMappingUtil {
 
     static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
+    static final Optional<String> APPLICATION_PEER_GROUP_NAME_OPT = Optional.of(APPLICATION_PEER_GROUP_NAME);
+    static final int HOLDTIMER = 90;
     private static final AfiSafi IPV4_AFISAFI = new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build();
     private static final List<AfiSafi> DEFAULT_AFISAFI = ImmutableList.of(IPV4_AFISAFI);
-    private static final int HOLDTIMER = 90;
     private static final int CONNECT_RETRY = 30;
     private static final PortNumber PORT = new PortNumber(179);
-    private static final BigDecimal DEFAULT_KEEP_ALIVE = BigDecimal.valueOf(30);
-    private static final BigDecimal DEFAULT_MINIMUM_ADV_INTERVAL = BigDecimal.valueOf(30);
 
     private OpenConfigMappingUtil() {
         throw new UnsupportedOperationException();
     }
 
-    public static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
+    static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
         return rootIdentifier.firstKeyOf(Protocol.class).getName();
     }
 
-    public static int getHoldTimer(final Neighbor neighbor) {
-        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.Config config =
-            getTimersConfig(neighbor);
+    @Nullable
+    private static Integer getHoldTimer(final Timers timers) {
+        if (timers == null) {
+            return null;
+        }
+        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
+                .Config config = timers.getConfig();
         if (config != null && config.getHoldTime() != null) {
             return config.getHoldTime().intValue();
         }
-        return HOLDTIMER;
+        return null;
     }
 
-    public static AsNumber getPeerAs(final Neighbor neighbor, final RIB rib) {
-        if (neighbor.getConfig() != null) {
-            final AsNumber peerAs = neighbor.getConfig().getPeerAs();
+    @Nullable
+    private static AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
+            .rev151009.bgp.neighbor.group.Config config) {
+        if (config != null) {
+            final AsNumber peerAs = config.getPeerAs();
             if (peerAs != null) {
                 return peerAs;
             }
         }
-        return rib.getLocalAs();
+        return null;
     }
 
-    public static boolean isActive(final Neighbor neighbor) {
-        if (neighbor.getTransport() != null) {
-            final Config config = neighbor.getTransport().getConfig();
+    @Nullable
+    private static Boolean isActive(final Transport transport) {
+        if (transport != null) {
+            final Config config = transport.getConfig();
             if (config != null && config.isPassiveMode() != null) {
                 return !config.isPassiveMode();
             }
         }
-        return true;
+        return null;
     }
 
-    public static int getRetryTimer(final Neighbor neighbor) {
-        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.Config config =
-            getTimersConfig(neighbor);
+    @Nullable
+    private static Integer getRetryTimer(final Timers timers) {
+        if (timers == null) {
+            return null;
+        }
+        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
+                .Config config = timers.getConfig();
         if (config != null && config.getConnectRetry() != null) {
             return config.getConnectRetry().intValue();
         }
-        return CONNECT_RETRY;
+        return null;
     }
 
-    public static KeyMapping getNeighborKey(final Neighbor neighbor) {
+    static KeyMapping getNeighborKey(final Neighbor neighbor) {
         if (neighbor.getConfig() != null) {
             final String authPassword = neighbor.getConfig().getAuthPassword();
             if (authPassword != null) {
@@ -150,36 +146,41 @@ public final class OpenConfigMappingUtil {
         return null;
     }
 
-    public static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(final InstanceIdentifier<Bgp> rootIdentifier,
-        final NeighborKey neighborKey) {
+    static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(
+            final InstanceIdentifier<Bgp> rootIdentifier,
+            final NeighborKey neighborKey) {
         return rootIdentifier.child(Neighbors.class).child(Neighbor.class, neighborKey);
     }
 
-    public static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
+    static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
         return Ipv4Util.toStringIP(rootIdentifier.firstKeyOf(Neighbor.class).getNeighborAddress());
     }
 
-    public static PortNumber getPort(final Neighbor neighbor) {
-        if (neighbor.getTransport() != null) {
-            final Config config = neighbor.getTransport().getConfig();
-            if (config != null && config.getAugmentation(Config1.class) != null) {
-                final PortNumber remotePort = config.getAugmentation(Config1.class).getRemotePort();
-                if (remotePort != null) {
-                    return remotePort;
+    @Nullable
+    private static <T extends TransportConfig & Augmentation<Config>> PortNumber getPort(
+            @Nullable final Transport transport, final Class<T> augment) {
+        if (transport != null) {
+            final Config config = transport.getConfig();
+            if (config != null) {
+                final T peerTc = config.augmentation(augment);
+                if (peerTc != null) {
+                    return peerTc.getRemotePort();
                 }
             }
         }
-        return PORT;
+        return null;
     }
 
     //make sure IPv4 Unicast (RFC 4271) when required
-    public static List<AfiSafi> getAfiSafiWithDefault(final BgpCommonAfiSafiList afiSAfis, final boolean setDeafultIPv4) {
+    static List<AfiSafi> getAfiSafiWithDefault(
+            final BgpCommonAfiSafiList afiSAfis, final boolean setDeafultIPv4) {
         if (afiSAfis == null || afiSAfis.getAfiSafi() == null) {
             return setDeafultIPv4 ? DEFAULT_AFISAFI : Collections.emptyList();
         }
         final List<AfiSafi> afiSafi = afiSAfis.getAfiSafi();
         if (setDeafultIPv4) {
-            final boolean anyMatch = afiSafi.stream().anyMatch(input -> input.getAfiSafiName().equals(IPV4UNICAST.class));
+            final boolean anyMatch = afiSafi.stream()
+                    .anyMatch(input -> input.getAfiSafiName().equals(IPV4UNICAST.class));
             if (!anyMatch) {
                 afiSafi.add(IPV4_AFISAFI);
             }
@@ -187,43 +188,55 @@ public final class OpenConfigMappingUtil {
         return afiSafi;
     }
 
-    public static ClusterIdentifier getClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config globalConfig) {
-        final GlobalConfigAugmentation globalConfigAugmentation = globalConfig.getAugmentation(GlobalConfigAugmentation.class);
+    static ClusterIdentifier getGlobalClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net
+            .yang.bgp.rev151009.bgp.global.base.Config globalConfig) {
+        final GlobalConfigAugmentation globalConfigAugmentation
+                = globalConfig.augmentation(GlobalConfigAugmentation.class);
         if (globalConfigAugmentation != null && globalConfigAugmentation.getRouteReflectorClusterId() != null) {
             return new ClusterIdentifier(globalConfigAugmentation.getRouteReflectorClusterId().getIpv4Address());
         }
         return new ClusterIdentifier(globalConfig.getRouterId());
     }
 
-    public static SimpleRoutingPolicy getSimpleRoutingPolicy(final Neighbor neighbor) {
-        if (neighbor.getConfig() != null) {
-            final NeighborConfigAugmentation augmentation = neighbor.getConfig().getAugmentation(NeighborConfigAugmentation.class);
-            if (augmentation != null) {
-                return augmentation.getSimpleRoutingPolicy();
+    @Nullable
+    static ClusterIdentifier getNeighborClusterIdentifier(
+            @Nullable final RouteReflector routeReflector,
+            @Nullable final PeerGroup peerGroup) {
+        if (peerGroup != null) {
+            final ClusterIdentifier clusteriId = extractClusterId(peerGroup.getRouteReflector());
+            if (clusteriId != null) {
+                return clusteriId;
             }
         }
-        return null;
+
+        return extractClusterId(routeReflector);
     }
 
-    private static org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.Config getTimersConfig(final Neighbor neighbor) {
-        final Timers timers = neighbor.getTimers();
-        return timers != null ? timers.getConfig() : null;
+    private static ClusterIdentifier extractClusterId(final RouteReflector routeReflector) {
+        if (routeReflector != null) {
+            final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.route
+                    .reflector.Config config = routeReflector.getConfig();
+            if (config != null && config.getRouteReflectorClusterId() != null) {
+                return new ClusterIdentifier(config.getRouteReflectorClusterId().getIpv4Address());
+            }
+        }
+        return null;
     }
 
-    public static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
-            final BGPTableTypeRegistryConsumer tableTypeRegistry, final BGPPeerTracker peerTracker) {
+    static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
+            final BGPTableTypeRegistryConsumer tableTypeRegistry) {
         final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
         for (final AfiSafi afiSafi : afiSafis) {
-            final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.getAugmentation(AfiSafi2.class);
+            final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.augmentation(GlobalAddPathsConfig.class);
             if (afiSafi2 != null) {
                 final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
                 if (bgpTableType.isPresent()) {
-                    final Short sendMax = afiSafi2.getSendMax();
+                    final int sendMax = afiSafi2.getSendMax();
                     final PathSelectionMode selectionMode;
                     if (sendMax > 1) {
-                        selectionMode = new AddPathBestNPathSelection(sendMax.longValue(), peerTracker);
+                        selectionMode = new AddPathBestNPathSelection(sendMax);
                     } else {
-                        selectionMode = new AllPathSelection(peerTracker);
+                        selectionMode = new AllPathSelection();
                     }
                     pathSelectionModes.put(bgpTableType.get(), selectionMode);
                 }
@@ -232,10 +245,11 @@ public final class OpenConfigMappingUtil {
         return pathSelectionModes;
     }
 
-    public static boolean isApplicationPeer(final Neighbor neighbor) {
-        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Config config = neighbor.getConfig();
+    static boolean isApplicationPeer(final Neighbor neighbor) {
+        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group
+                .Config config = neighbor.getConfig();
         if (config != null) {
-            final Config2 config1 = config.getAugmentation(Config2.class);
+            final NeighborPeerGroupConfig config1 = config.augmentation(NeighborPeerGroupConfig.class);
             if (config1 != null) {
                 final String peerGroup = config1.getPeerGroup();
                 return peerGroup != null && peerGroup.equals(APPLICATION_PEER_GROUP_NAME);
@@ -244,10 +258,11 @@ public final class OpenConfigMappingUtil {
         return false;
     }
 
-    public static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
+    static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis,
+            final BGPTableTypeRegistryConsumer tableTypeRegistry) {
         final List<AddressFamilies> addPathCapability = new ArrayList<>();
         for (final AfiSafi afiSafi : afiSafis) {
-            final BgpNeighborAddPathsConfig afiSafi1 = afiSafi.getAugmentation(AfiSafi1.class);
+            final BgpNeighborAddPathsConfig afiSafi1 = afiSafi.augmentation(NeighborAddPathsConfig.class);
             final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
             if (afiSafi1 != null && bgpTableType.isPresent()) {
                 final AddressFamiliesBuilder builder = new AddressFamiliesBuilder(bgpTableType.get());
@@ -268,87 +283,7 @@ public final class OpenConfigMappingUtil {
         return SendReceive.Receive;
     }
 
-    public static Global fromRib(final BgpId bgpId, final ClusterIdentifier clusterIdentifier, final RibId ribId,
-        final AsNumber localAs, final List<BgpTableType> localTables,
-        final Map<TablesKey, PathSelectionMode> pathSelectionStrategies, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
-        return toGlobalConfiguration(bgpId, clusterIdentifier, localAs, localTables, pathSelectionStrategies, bgpTableTypeRegistryConsumer);
-    }
-
-    private static Global toGlobalConfiguration(final BgpId bgpId, final ClusterIdentifier clusterIdentifier,
-        final AsNumber localAs, final List<BgpTableType> localTables,
-        final Map<TablesKey, PathSelectionMode> pathSelectionStrategies, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
-        final ConfigBuilder configBuilder = new ConfigBuilder();
-        configBuilder.setAs(localAs);
-        configBuilder.setRouterId(bgpId);
-        if (clusterIdentifier != null) {
-            configBuilder.addAugmentation(GlobalConfigAugmentation.class,
-                new GlobalConfigAugmentationBuilder().setRouteReflectorClusterId(new RrClusterIdType(clusterIdentifier)).build());
-        }
-        return new GlobalBuilder().setAfiSafis(new AfiSafisBuilder().setAfiSafi(toAfiSafis(localTables,
-            (afiSafi, tableType) -> toGlobalAfiSafiAddPath(afiSafi, tableType, pathSelectionStrategies), bgpTableTypeRegistryConsumer)).build())
-            .setConfig(configBuilder.build()).build();
-    }
-
-    public static Neighbor fromBgpPeer(final List<AddressFamilies> addPathCapabilities,
-        final List<BgpTableType> advertisedTables, final Integer holdTimer, final IpAddress ipAddress,
-        final Boolean isActive, final Rfc2385Key password, final PortNumber portNumber, final Integer retryTimer,
-        final AsNumber remoteAs, final PeerRole peerRole, final SimpleRoutingPolicy simpleRoutingPolicy, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
-        final NeighborBuilder neighborBuilder = new NeighborBuilder();
-        neighborBuilder.setNeighborAddress(ipAddress);
-        neighborBuilder.setKey(new NeighborKey(ipAddress));
-        neighborBuilder.setAfiSafis(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder().setAfiSafi(toAfiSafis(advertisedTables,
-            (afiSafi, tableType) -> toNeighborAfiSafiAddPath(afiSafi, tableType, addPathCapabilities), bgpTableTypeRegistryConsumer)).build());
-        neighborBuilder.setTransport(new TransportBuilder().setConfig(
-            new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.ConfigBuilder()
-                .setPassiveMode(!isActive)
-                .setMtuDiscovery(Boolean.FALSE)
-                .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1.class,
-                    new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1Builder()
-                        .setRemotePort(portNumber).build())
-                .build()).build());
-        neighborBuilder.setConfig(
-            new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
-                .setAuthPassword(password != null ? password.getValue() : null)
-                .setPeerAs(remoteAs)
-                .setPeerType(toPeerType(peerRole))
-                .setSendCommunity(CommunityType.NONE)
-                .setRouteFlapDamping(Boolean.FALSE)
-                .addAugmentation(NeighborConfigAugmentation.class, setNeighborAugmentation(simpleRoutingPolicy))
-                .build());
-        neighborBuilder.setTimers(new TimersBuilder().setConfig(
-            new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.ConfigBuilder()
-                .setHoldTime(BigDecimal.valueOf(holdTimer))
-                .setConnectRetry(BigDecimal.valueOf(retryTimer))
-                .setKeepaliveInterval(DEFAULT_KEEP_ALIVE)
-                .setMinimumAdvertisementInterval(DEFAULT_MINIMUM_ADV_INTERVAL)
-                .build()).build());
-        neighborBuilder.setRouteReflector(new RouteReflectorBuilder().setConfig(
-            new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.route.reflector.ConfigBuilder()
-                .setRouteReflectorClient(peerRole == PeerRole.RrClient).build()).build());
-        return neighborBuilder.build();
-    }
-
-
-    public static Neighbor fromApplicationPeer(final ApplicationRibId applicationRibId, final BgpId bgpId) {
-        final NeighborBuilder neighborBuilder = new NeighborBuilder();
-        neighborBuilder.setNeighborAddress(new IpAddress(new Ipv4Address(bgpId.getValue())));
-        neighborBuilder.setKey(new NeighborKey(neighborBuilder.getNeighborAddress()));
-        neighborBuilder.setConfig(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
-            .setDescription(applicationRibId.getValue())
-            .addAugmentation(Config2.class, new Config2Builder().setPeerGroup(APPLICATION_PEER_GROUP_NAME).build())
-            .build());
-
-        return neighborBuilder.build();
-    }
-
-    private static NeighborConfigAugmentation setNeighborAugmentation(final SimpleRoutingPolicy simpleRoutingPolicy) {
-        if (simpleRoutingPolicy != null) {
-            return new NeighborConfigAugmentationBuilder().setSimpleRoutingPolicy(simpleRoutingPolicy).build();
-        }
-        return null;
-    }
-
-    public static PeerRole toPeerRole(final Neighbor neighbor) {
+    static PeerRole toPeerRole(final BgpNeighborGroup neighbor) {
         if (isRrClient(neighbor)) {
             return PeerRole.RrClient;
         }
@@ -357,27 +292,14 @@ public final class OpenConfigMappingUtil {
             final PeerType peerType = neighbor.getConfig().getPeerType();
             if (peerType == PeerType.EXTERNAL) {
                 return PeerRole.Ebgp;
+            } else if (peerType == PeerType.INTERNAL) {
+                return PeerRole.Ibgp;
             }
         }
-        return PeerRole.Ibgp;
-    }
-
-    static PeerType toPeerType(final PeerRole peerRole) {
-        switch (peerRole) {
-        case Ibgp:
-        case RrClient:
-            return PeerType.INTERNAL;
-        case Ebgp:
-            return PeerType.EXTERNAL;
-        case Internal:
-            break;
-        default:
-            break;
-        }
         return null;
     }
 
-    private static boolean isRrClient(final Neighbor neighbor) {
+    private static boolean isRrClient(final BgpNeighborGroup neighbor) {
         final RouteReflector routeReflector = neighbor.getRouteReflector();
         if (routeReflector != null && routeReflector.getConfig() != null) {
             return routeReflector.getConfig().isRouteReflectorClient();
@@ -385,93 +307,215 @@ public final class OpenConfigMappingUtil {
         return false;
     }
 
-    static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables, final BiFunction<AfiSafi, BgpTableType, AfiSafi> function,
-        final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
-        final List<AfiSafi> afiSafis = new ArrayList<>(advertizedTables.size());
-        for (final BgpTableType tableType : advertizedTables) {
-            final Optional<AfiSafi> afiSafiMaybe = toAfiSafi(new BgpTableTypeImpl(tableType.getAfi(), tableType.getSafi()), bgpTableTypeRegistryConsumer);
-            if (afiSafiMaybe.isPresent()) {
-                final AfiSafi afiSafi = function.apply(afiSafiMaybe.get(), tableType);
-                afiSafis.add(afiSafi);
+    static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis,
+            final BGPTableTypeRegistryConsumer tableTypeRegistry) {
+        return afiSafis.stream()
+                .map(afiSafi -> tableTypeRegistry.getTableType(afiSafi.getAfiSafiName()))
+                .filter(Optional::isPresent)
+                .map(Optional::get)
+                .collect(Collectors.toList());
+    }
+
+    static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
+            tableTypeRegistry) {
+        return afiSafis.stream()
+                .map(afiSafi -> tableTypeRegistry.getTableKey(afiSafi.getAfiSafiName()))
+                .filter(Optional::isPresent)
+                .map(Optional::get)
+                .collect(Collectors.toSet());
+    }
+
+    static boolean isActive(final Neighbor neighbor, final PeerGroup peerGroup) {
+        Boolean activeConnection = null;
+        if (peerGroup != null) {
+            activeConnection = isActive(peerGroup.getTransport());
+        }
+
+        if (activeConnection == null) {
+            activeConnection = isActive(neighbor.getTransport());
+        }
+        if (activeConnection == null) {
+            return true;
+        }
+        return activeConnection;
+    }
+
+    @Nonnull
+    static PeerRole toPeerRole(final Neighbor neighbor, final PeerGroup peerGroup) {
+        PeerRole role = null;
+        if (peerGroup != null) {
+            role = toPeerRole(peerGroup);
+        }
+
+        if (role == null) {
+            role = toPeerRole(neighbor);
+        }
+
+        if (role == null) {
+            return PeerRole.Ibgp;
+        }
+        return role;
+    }
+
+    static int getHoldTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
+        Integer hold = null;
+        if (peerGroup != null) {
+            hold = getHoldTimer(peerGroup.getTimers());
+        }
+
+        if (hold == null) {
+            hold = getHoldTimer(neighbor.getTimers());
+        }
+
+        if (hold == null) {
+            return HOLDTIMER;
+        }
+
+        return hold;
+    }
+
+    static int getGracefulRestartTimer(final Neighbor neighbor, final PeerGroup peerGroup, final int holdTimer) {
+        Integer timer = null;
+        if (peerGroup != null) {
+            timer = getGracefulRestartTimer(peerGroup.getGracefulRestart());
+        }
+
+        if (timer == null) {
+            timer = getGracefulRestartTimer(neighbor.getGracefulRestart());
+        }
+
+        /*
+         * RFC4724: "A suggested default for the Restart Time is a value less than or
+         * equal to the HOLDTIME carried in the OPEN."
+         */
+        if (timer == null) {
+            timer = holdTimer;
+        }
+
+        return timer;
+    }
+
+    @Nullable
+    private static Integer getGracefulRestartTimer(final GracefulRestart gracefulRestart) {
+        if (gracefulRestart != null) {
+            final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.graceful
+                    .restart.Config config = gracefulRestart.getConfig();
+            if (config != null) {
+                return config.getRestartTime();
             }
         }
-        return afiSafis;
+        return null;
     }
 
-    static AfiSafi toGlobalAfiSafiAddPath(final AfiSafi afiSafi, final BgpTableType tableType,
-        final Map<TablesKey, PathSelectionMode> multiPathTables) {
-        final PathSelectionMode pathSelection = multiPathTables.get(new TablesKey(tableType.getAfi(), tableType.getSafi()));
-        if (pathSelection == null) {
-            return afiSafi;
+    @Nonnull
+    static AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009
+            .bgp.neighbor.group.Config config, final PeerGroup peerGroup, final AsNumber localAs) {
+        AsNumber neighborAs = null;
+        if (peerGroup != null) {
+            neighborAs = getRemotePeerAs(peerGroup.getConfig());
         }
-        final long maxPaths;
-        if (pathSelection instanceof AddPathBestNPathSelection) {
-            maxPaths = ((AddPathBestNPathSelection) pathSelection).getNBestPaths();
-        } else {
-            maxPaths = 0L;
+
+        if (neighborAs == null) {
+            neighborAs = getRemotePeerAs(config);
+        }
+
+        if (neighborAs == null) {
+            return localAs;
         }
-        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2 addPath = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2Builder()
-            .setReceive(true)
-            .setSendMax(Shorts.checkedCast(maxPaths))
-            .build();
-        return new AfiSafiBuilder(afiSafi)
-            .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2.class,
-                addPath).build();
+        return neighborAs;
     }
 
-    static AfiSafi toNeighborAfiSafiAddPath(final AfiSafi afiSafi, final BgpTableType tableType, final List<AddressFamilies> capabilities) {
-        final Optional<AddressFamilies> capability = capabilities.stream()
-            .filter(af -> af.getAfi().equals(tableType.getAfi()) && af.getSafi().equals(tableType.getSafi()))
-            .findFirst();
-        if (!capability.isPresent()) {
-            return afiSafi;
+    @Nonnull
+    static AsNumber getLocalPeerAs(@Nullable final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
+            .rev151009.bgp.neighbor.group.Config config, @Nonnull final AsNumber globalAs) {
+        if (config != null) {
+            final AsNumber peerAs = config.getLocalAs();
+            if (peerAs != null) {
+                return peerAs;
+            }
         }
-        return new AfiSafiBuilder(afiSafi)
-            .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1.class,
-                fromSendReceiveMode(capability.get().getSendReceive())).build();
+        return globalAs;
     }
 
-    private static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1 fromSendReceiveMode(final SendReceive mode) {
-        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1Builder builder =
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1Builder();
-        switch (mode) {
-        case Both:
-            builder.setReceive(true).setSendMax((short) 0);
-            break;
-        case Receive:
-            builder.setReceive(true);
-            break;
-        case Send:
-            builder.setReceive(false).setSendMax((short) 0);
-            break;
-        default:
-            break;
+    static int getRetryTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
+        Integer retryTimer = null;
+        if (peerGroup != null) {
+            retryTimer = getRetryTimer(peerGroup.getTimers());
         }
-        return builder.build();
+
+        if (retryTimer == null) {
+            retryTimer = getRetryTimer(neighbor.getTimers());
+        }
+
+        if (retryTimer == null) {
+            return CONNECT_RETRY;
+        }
+
+        return retryTimer;
     }
 
-    public static Optional<AfiSafi> toAfiSafi(final BgpTableType tableType, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
-        final Optional<Class<? extends AfiSafiType>> afiSafi = tableTypeRegistry.getAfiSafiType(tableType);
-        if (afiSafi.isPresent()) {
-            return Optional.of(new AfiSafiBuilder().setAfiSafiName(afiSafi.get()).build());
+    @Nonnull
+    static PortNumber getPort(final Neighbor neighbor, final PeerGroup peerGroup) {
+        PortNumber port = null;
+        if (peerGroup != null) {
+            port = getPort(peerGroup.getTransport(), PeerGroupTransportConfig.class);
+        }
+
+        if (port == null) {
+            port = getPort(neighbor.getTransport(), NeighborTransportConfig.class);
         }
-        return Optional.empty();
+
+        if (port == null) {
+            return PORT;
+        }
+
+        return port;
     }
 
-    public static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
-        return afiSafis.stream()
-            .map(afiSafi -> tableTypeRegistry.getTableType(afiSafi.getAfiSafiName()))
-            .filter(Optional::isPresent)
-            .map(Optional::get)
-            .collect(Collectors.toList());
+    @Nullable
+    static IpAddress getLocalAddress(@Nullable final Transport transport) {
+        if (transport != null && transport.getConfig() != null) {
+            final BgpNeighborTransportConfig.LocalAddress localAddress = transport.getConfig().getLocalAddress();
+            if (localAddress != null ) {
+                return localAddress.getIpAddress();
+            }
+        }
+        return null;
     }
 
-    public static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
-        tableTypeRegistry) {
-        return afiSafis.stream()
-            .map(afiSafi -> tableTypeRegistry.getTableKey(afiSafi.getAfiSafiName()))
-            .filter(Optional::isPresent)
-            .map(Optional::get)
-            .collect(Collectors.toSet());
+    @Nullable
+    static RevisedErrorHandlingSupport getRevisedErrorHandling(final PeerRole role,final PeerGroup peerGroup,
+            final Neighbor neighbor) {
+        Boolean enabled = getRevisedErrorHandling(neighbor);
+        if (enabled == null) {
+            enabled = getRevisedErrorHandling(peerGroup);
+        }
+        if (!Boolean.TRUE.equals(enabled)) {
+            return null;
+        }
+        switch (role) {
+            case Ebgp:
+                return RevisedErrorHandlingSupportImpl.forExternalPeer();
+            case Ibgp:
+            case Internal:
+            case RrClient:
+                return RevisedErrorHandlingSupportImpl.forInternalPeer();
+            default:
+                throw new IllegalStateException("Unhandled role " + role);
+        }
+    }
+
+    @Nullable
+    private static @org.eclipse.jdt.annotation.Nullable Boolean getRevisedErrorHandling(final BgpNeighborGroup group) {
+        if (group == null) {
+            return null;
+        }
+        final ErrorHandling errorHandling = group.getErrorHandling();
+        if (errorHandling == null) {
+            return null;
+        }
+        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.error.handling
+            .Config config = errorHandling.getConfig();
+        return config == null ? null : config.isTreatAsWithdraw();
     }
 }