BGPCEP-754: PeerTracker Impl
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / config / OpenConfigMappingUtil.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.protocol.bgp.rib.impl.config;
10
11 import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil.INSTANCE;
12
13 import com.google.common.collect.ImmutableList;
14 import com.google.common.primitives.Shorts;
15 import java.math.BigDecimal;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Optional;
22 import java.util.Set;
23 import java.util.function.BiFunction;
24 import java.util.stream.Collectors;
25 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
26 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
27 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
28 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
29 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
30 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
31 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
32 import org.opendaylight.protocol.concepts.KeyMapping;
33 import org.opendaylight.protocol.util.Ipv4Util;
34 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.BgpCommonAfiSafiList;
35 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
36 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
37 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborAddPathsConfig;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.AfiSafisBuilder;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.ConfigBuilder;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflector;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflectorBuilder;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TimersBuilder;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TransportBuilder;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.Config;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborBuilder;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
51 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.GlobalBuilder;
52 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
53 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
54 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.CommunityType;
55 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
56 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.PeerType;
57 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.RrClusterIdType;
58 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.BgpTableType;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.SendReceive;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamilies;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamiliesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config2;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config2Builder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.GlobalConfigAugmentation;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.GlobalConfigAugmentationBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.NeighborConfigAugmentation;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.NeighborConfigAugmentationBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.ApplicationRibId;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.RibId;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.SimpleRoutingPolicy;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
84 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
85
86 public final class OpenConfigMappingUtil {
87
88     static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
89     private static final AfiSafi IPV4_AFISAFI = new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build();
90     private static final List<AfiSafi> DEFAULT_AFISAFI = ImmutableList.of(IPV4_AFISAFI);
91     private static final int HOLDTIMER = 90;
92     private static final int CONNECT_RETRY = 30;
93     private static final PortNumber PORT = new PortNumber(179);
94     private static final BigDecimal DEFAULT_KEEP_ALIVE = BigDecimal.valueOf(30);
95     private static final BigDecimal DEFAULT_MINIMUM_ADV_INTERVAL = BigDecimal.valueOf(30);
96
97     private OpenConfigMappingUtil() {
98         throw new UnsupportedOperationException();
99     }
100
101     public static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
102         return rootIdentifier.firstKeyOf(Protocol.class).getName();
103     }
104
105     public static int getHoldTimer(final Neighbor neighbor) {
106         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.Config config =
107             getTimersConfig(neighbor);
108         if (config != null && config.getHoldTime() != null) {
109             return config.getHoldTime().intValue();
110         }
111         return HOLDTIMER;
112     }
113
114     public static AsNumber getPeerAs(final Neighbor neighbor, final RIB rib) {
115         if (neighbor.getConfig() != null) {
116             final AsNumber peerAs = neighbor.getConfig().getPeerAs();
117             if (peerAs != null) {
118                 return peerAs;
119             }
120         }
121         return rib.getLocalAs();
122     }
123
124     public static boolean isActive(final Neighbor neighbor) {
125         if (neighbor.getTransport() != null) {
126             final Config config = neighbor.getTransport().getConfig();
127             if (config != null && config.isPassiveMode() != null) {
128                 return !config.isPassiveMode();
129             }
130         }
131         return true;
132     }
133
134     public static int getRetryTimer(final Neighbor neighbor) {
135         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.Config config =
136             getTimersConfig(neighbor);
137         if (config != null && config.getConnectRetry() != null) {
138             return config.getConnectRetry().intValue();
139         }
140         return CONNECT_RETRY;
141     }
142
143     public static KeyMapping getNeighborKey(final Neighbor neighbor) {
144         if (neighbor.getConfig() != null) {
145             final String authPassword = neighbor.getConfig().getAuthPassword();
146             if (authPassword != null) {
147                 return KeyMapping.getKeyMapping(INSTANCE.inetAddressFor(neighbor.getNeighborAddress()), authPassword);
148             }
149         }
150         return null;
151     }
152
153     public static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(final InstanceIdentifier<Bgp> rootIdentifier,
154         final NeighborKey neighborKey) {
155         return rootIdentifier.child(Neighbors.class).child(Neighbor.class, neighborKey);
156     }
157
158     public static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
159         return Ipv4Util.toStringIP(rootIdentifier.firstKeyOf(Neighbor.class).getNeighborAddress());
160     }
161
162     public static PortNumber getPort(final Neighbor neighbor) {
163         if (neighbor.getTransport() != null) {
164             final Config config = neighbor.getTransport().getConfig();
165             if (config != null && config.getAugmentation(Config1.class) != null) {
166                 final PortNumber remotePort = config.getAugmentation(Config1.class).getRemotePort();
167                 if (remotePort != null) {
168                     return remotePort;
169                 }
170             }
171         }
172         return PORT;
173     }
174
175     //make sure IPv4 Unicast (RFC 4271) when required
176     public static List<AfiSafi> getAfiSafiWithDefault(final BgpCommonAfiSafiList afiSAfis, final boolean setDeafultIPv4) {
177         if (afiSAfis == null || afiSAfis.getAfiSafi() == null) {
178             return setDeafultIPv4 ? DEFAULT_AFISAFI : Collections.emptyList();
179         }
180         final List<AfiSafi> afiSafi = afiSAfis.getAfiSafi();
181         if (setDeafultIPv4) {
182             final boolean anyMatch = afiSafi.stream().anyMatch(input -> input.getAfiSafiName().equals(IPV4UNICAST.class));
183             if (!anyMatch) {
184                 afiSafi.add(IPV4_AFISAFI);
185             }
186         }
187         return afiSafi;
188     }
189
190     public static ClusterIdentifier getClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config globalConfig) {
191         final GlobalConfigAugmentation globalConfigAugmentation = globalConfig.getAugmentation(GlobalConfigAugmentation.class);
192         if (globalConfigAugmentation != null && globalConfigAugmentation.getRouteReflectorClusterId() != null) {
193             return new ClusterIdentifier(globalConfigAugmentation.getRouteReflectorClusterId().getIpv4Address());
194         }
195         return new ClusterIdentifier(globalConfig.getRouterId());
196     }
197
198     public static SimpleRoutingPolicy getSimpleRoutingPolicy(final Neighbor neighbor) {
199         if (neighbor.getConfig() != null) {
200             final NeighborConfigAugmentation augmentation = neighbor.getConfig().getAugmentation(NeighborConfigAugmentation.class);
201             if (augmentation != null) {
202                 return augmentation.getSimpleRoutingPolicy();
203             }
204         }
205         return null;
206     }
207
208     private static org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.Config getTimersConfig(final Neighbor neighbor) {
209         final Timers timers = neighbor.getTimers();
210         return timers != null ? timers.getConfig() : null;
211     }
212
213     public static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
214             final BGPTableTypeRegistryConsumer tableTypeRegistry, final BGPPeerTracker peerTracker) {
215         final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
216         for (final AfiSafi afiSafi : afiSafis) {
217             final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.getAugmentation(AfiSafi2.class);
218             if (afiSafi2 != null) {
219                 final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
220                 if (bgpTableType.isPresent()) {
221                     final Short sendMax = afiSafi2.getSendMax();
222                     final PathSelectionMode selectionMode;
223                     if (sendMax > 1) {
224                         selectionMode = new AddPathBestNPathSelection(sendMax.longValue(), peerTracker);
225                     } else {
226                         selectionMode = new AllPathSelection(peerTracker);
227                     }
228                     pathSelectionModes.put(bgpTableType.get(), selectionMode);
229                 }
230             }
231         }
232         return pathSelectionModes;
233     }
234
235     public static boolean isApplicationPeer(final Neighbor neighbor) {
236         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Config config = neighbor.getConfig();
237         if (config != null) {
238             final Config2 config1 = config.getAugmentation(Config2.class);
239             if (config1 != null) {
240                 final String peerGroup = config1.getPeerGroup();
241                 return peerGroup != null && peerGroup.equals(APPLICATION_PEER_GROUP_NAME);
242             }
243         }
244         return false;
245     }
246
247     public static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
248         final List<AddressFamilies> addPathCapability = new ArrayList<>();
249         for (final AfiSafi afiSafi : afiSafis) {
250             final BgpNeighborAddPathsConfig afiSafi1 = afiSafi.getAugmentation(AfiSafi1.class);
251             final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
252             if (afiSafi1 != null && bgpTableType.isPresent()) {
253                 final AddressFamiliesBuilder builder = new AddressFamiliesBuilder(bgpTableType.get());
254                 builder.setSendReceive(toSendReceiveMode(afiSafi1));
255                 addPathCapability.add(builder.build());
256             }
257         }
258         return addPathCapability;
259     }
260
261     private static SendReceive toSendReceiveMode(final BgpNeighborAddPathsConfig addPath) {
262         if (addPath.isReceive() && addPath.getSendMax() != null) {
263             return SendReceive.Both;
264         }
265         if (addPath.getSendMax() != null) {
266             return SendReceive.Send;
267         }
268         return SendReceive.Receive;
269     }
270
271     public static Global fromRib(final BgpId bgpId, final ClusterIdentifier clusterIdentifier, final RibId ribId,
272         final AsNumber localAs, final List<BgpTableType> localTables,
273         final Map<TablesKey, PathSelectionMode> pathSelectionStrategies, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
274         return toGlobalConfiguration(bgpId, clusterIdentifier, localAs, localTables, pathSelectionStrategies, bgpTableTypeRegistryConsumer);
275     }
276
277     private static Global toGlobalConfiguration(final BgpId bgpId, final ClusterIdentifier clusterIdentifier,
278         final AsNumber localAs, final List<BgpTableType> localTables,
279         final Map<TablesKey, PathSelectionMode> pathSelectionStrategies, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
280         final ConfigBuilder configBuilder = new ConfigBuilder();
281         configBuilder.setAs(localAs);
282         configBuilder.setRouterId(bgpId);
283         if (clusterIdentifier != null) {
284             configBuilder.addAugmentation(GlobalConfigAugmentation.class,
285                 new GlobalConfigAugmentationBuilder().setRouteReflectorClusterId(new RrClusterIdType(clusterIdentifier)).build());
286         }
287         return new GlobalBuilder().setAfiSafis(new AfiSafisBuilder().setAfiSafi(toAfiSafis(localTables,
288             (afiSafi, tableType) -> toGlobalAfiSafiAddPath(afiSafi, tableType, pathSelectionStrategies), bgpTableTypeRegistryConsumer)).build())
289             .setConfig(configBuilder.build()).build();
290     }
291
292     public static Neighbor fromBgpPeer(final List<AddressFamilies> addPathCapabilities,
293         final List<BgpTableType> advertisedTables, final Integer holdTimer, final IpAddress ipAddress,
294         final Boolean isActive, final Rfc2385Key password, final PortNumber portNumber, final Integer retryTimer,
295         final AsNumber remoteAs, final PeerRole peerRole, final SimpleRoutingPolicy simpleRoutingPolicy, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
296         final NeighborBuilder neighborBuilder = new NeighborBuilder();
297         neighborBuilder.setNeighborAddress(ipAddress);
298         neighborBuilder.setKey(new NeighborKey(ipAddress));
299         neighborBuilder.setAfiSafis(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder().setAfiSafi(toAfiSafis(advertisedTables,
300             (afiSafi, tableType) -> toNeighborAfiSafiAddPath(afiSafi, tableType, addPathCapabilities), bgpTableTypeRegistryConsumer)).build());
301         neighborBuilder.setTransport(new TransportBuilder().setConfig(
302             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.ConfigBuilder()
303                 .setPassiveMode(!isActive)
304                 .setMtuDiscovery(Boolean.FALSE)
305                 .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1.class,
306                     new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1Builder()
307                         .setRemotePort(portNumber).build())
308                 .build()).build());
309         neighborBuilder.setConfig(
310             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
311                 .setAuthPassword(password != null ? password.getValue() : null)
312                 .setPeerAs(remoteAs)
313                 .setPeerType(toPeerType(peerRole))
314                 .setSendCommunity(CommunityType.NONE)
315                 .setRouteFlapDamping(Boolean.FALSE)
316                 .addAugmentation(NeighborConfigAugmentation.class, setNeighborAugmentation(simpleRoutingPolicy))
317                 .build());
318         neighborBuilder.setTimers(new TimersBuilder().setConfig(
319             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.ConfigBuilder()
320                 .setHoldTime(BigDecimal.valueOf(holdTimer))
321                 .setConnectRetry(BigDecimal.valueOf(retryTimer))
322                 .setKeepaliveInterval(DEFAULT_KEEP_ALIVE)
323                 .setMinimumAdvertisementInterval(DEFAULT_MINIMUM_ADV_INTERVAL)
324                 .build()).build());
325         neighborBuilder.setRouteReflector(new RouteReflectorBuilder().setConfig(
326             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.route.reflector.ConfigBuilder()
327                 .setRouteReflectorClient(peerRole == PeerRole.RrClient).build()).build());
328         return neighborBuilder.build();
329     }
330
331
332     public static Neighbor fromApplicationPeer(final ApplicationRibId applicationRibId, final BgpId bgpId) {
333         final NeighborBuilder neighborBuilder = new NeighborBuilder();
334         neighborBuilder.setNeighborAddress(new IpAddress(new Ipv4Address(bgpId.getValue())));
335         neighborBuilder.setKey(new NeighborKey(neighborBuilder.getNeighborAddress()));
336         neighborBuilder.setConfig(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
337             .setDescription(applicationRibId.getValue())
338             .addAugmentation(Config2.class, new Config2Builder().setPeerGroup(APPLICATION_PEER_GROUP_NAME).build())
339             .build());
340
341         return neighborBuilder.build();
342     }
343
344     private static NeighborConfigAugmentation setNeighborAugmentation(final SimpleRoutingPolicy simpleRoutingPolicy) {
345         if (simpleRoutingPolicy != null) {
346             return new NeighborConfigAugmentationBuilder().setSimpleRoutingPolicy(simpleRoutingPolicy).build();
347         }
348         return null;
349     }
350
351     public static PeerRole toPeerRole(final Neighbor neighbor) {
352         if (isRrClient(neighbor)) {
353             return PeerRole.RrClient;
354         }
355
356         if (neighbor.getConfig() != null) {
357             final PeerType peerType = neighbor.getConfig().getPeerType();
358             if (peerType == PeerType.EXTERNAL) {
359                 return PeerRole.Ebgp;
360             }
361         }
362         return PeerRole.Ibgp;
363     }
364
365     static PeerType toPeerType(final PeerRole peerRole) {
366         switch (peerRole) {
367         case Ibgp:
368         case RrClient:
369             return PeerType.INTERNAL;
370         case Ebgp:
371             return PeerType.EXTERNAL;
372         case Internal:
373             break;
374         default:
375             break;
376         }
377         return null;
378     }
379
380     private static boolean isRrClient(final Neighbor neighbor) {
381         final RouteReflector routeReflector = neighbor.getRouteReflector();
382         if (routeReflector != null && routeReflector.getConfig() != null) {
383             return routeReflector.getConfig().isRouteReflectorClient();
384         }
385         return false;
386     }
387
388     static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables, final BiFunction<AfiSafi, BgpTableType, AfiSafi> function,
389         final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
390         final List<AfiSafi> afiSafis = new ArrayList<>(advertizedTables.size());
391         for (final BgpTableType tableType : advertizedTables) {
392             final Optional<AfiSafi> afiSafiMaybe = toAfiSafi(new BgpTableTypeImpl(tableType.getAfi(), tableType.getSafi()), bgpTableTypeRegistryConsumer);
393             if (afiSafiMaybe.isPresent()) {
394                 final AfiSafi afiSafi = function.apply(afiSafiMaybe.get(), tableType);
395                 afiSafis.add(afiSafi);
396             }
397         }
398         return afiSafis;
399     }
400
401     static AfiSafi toGlobalAfiSafiAddPath(final AfiSafi afiSafi, final BgpTableType tableType,
402         final Map<TablesKey, PathSelectionMode> multiPathTables) {
403         final PathSelectionMode pathSelection = multiPathTables.get(new TablesKey(tableType.getAfi(), tableType.getSafi()));
404         if (pathSelection == null) {
405             return afiSafi;
406         }
407         final long maxPaths;
408         if (pathSelection instanceof AddPathBestNPathSelection) {
409             maxPaths = ((AddPathBestNPathSelection) pathSelection).getNBestPaths();
410         } else {
411             maxPaths = 0L;
412         }
413         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()
414             .setReceive(true)
415             .setSendMax(Shorts.checkedCast(maxPaths))
416             .build();
417         return new AfiSafiBuilder(afiSafi)
418             .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2.class,
419                 addPath).build();
420     }
421
422     static AfiSafi toNeighborAfiSafiAddPath(final AfiSafi afiSafi, final BgpTableType tableType, final List<AddressFamilies> capabilities) {
423         final Optional<AddressFamilies> capability = capabilities.stream()
424             .filter(af -> af.getAfi().equals(tableType.getAfi()) && af.getSafi().equals(tableType.getSafi()))
425             .findFirst();
426         if (!capability.isPresent()) {
427             return afiSafi;
428         }
429         return new AfiSafiBuilder(afiSafi)
430             .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1.class,
431                 fromSendReceiveMode(capability.get().getSendReceive())).build();
432     }
433
434     private static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1 fromSendReceiveMode(final SendReceive mode) {
435         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1Builder builder =
436             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1Builder();
437         switch (mode) {
438         case Both:
439             builder.setReceive(true).setSendMax((short) 0);
440             break;
441         case Receive:
442             builder.setReceive(true);
443             break;
444         case Send:
445             builder.setReceive(false).setSendMax((short) 0);
446             break;
447         default:
448             break;
449         }
450         return builder.build();
451     }
452
453     public static Optional<AfiSafi> toAfiSafi(final BgpTableType tableType, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
454         final Optional<Class<? extends AfiSafiType>> afiSafi = tableTypeRegistry.getAfiSafiType(tableType);
455         if (afiSafi.isPresent()) {
456             return Optional.of(new AfiSafiBuilder().setAfiSafiName(afiSafi.get()).build());
457         }
458         return Optional.empty();
459     }
460
461     public static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
462         return afiSafis.stream()
463             .map(afiSafi -> tableTypeRegistry.getTableType(afiSafi.getAfiSafiName()))
464             .filter(Optional::isPresent)
465             .map(Optional::get)
466             .collect(Collectors.toList());
467     }
468
469     public static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
470         tableTypeRegistry) {
471         return afiSafis.stream()
472             .map(afiSafi -> tableTypeRegistry.getTableKey(afiSafi.getAfiSafiName()))
473             .filter(Optional::isPresent)
474             .map(Optional::get)
475             .collect(Collectors.toSet());
476     }
477 }