Fix calculation and roll-over of BGP operational neighbor uptime value.
[bgpcep.git] / bgp / openconfig-state / src / main / java / org / opendaylight / protocol / bgp / state / NeighborUtil.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.state;
10
11 import com.google.common.primitives.UnsignedInteger;
12 import com.google.common.primitives.UnsignedLong;
13 import java.math.BigDecimal;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Objects;
19 import java.util.Optional;
20 import java.util.Set;
21 import java.util.stream.Collectors;
22 import javax.annotation.Nonnull;
23 import javax.annotation.Nullable;
24 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
25 import org.opendaylight.protocol.bgp.rib.spi.state.BGPAfiSafiState;
26 import org.opendaylight.protocol.bgp.rib.spi.state.BGPErrorHandlingState;
27 import org.opendaylight.protocol.bgp.rib.spi.state.BGPGracelfulRestartState;
28 import org.opendaylight.protocol.bgp.rib.spi.state.BGPPeerMessagesState;
29 import org.opendaylight.protocol.bgp.rib.spi.state.BGPPeerState;
30 import org.opendaylight.protocol.bgp.rib.spi.state.BGPSessionState;
31 import org.opendaylight.protocol.bgp.rib.spi.state.BGPTimersState;
32 import org.opendaylight.protocol.bgp.rib.spi.state.BGPTransportState;
33 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
34 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
35 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.operational.rev151009.BgpNeighborState.SessionState;
36 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.operational.rev151009.bgp.neighbor.prefix.counters_state.PrefixesBuilder;
37 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.GracefulRestart;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.GracefulRestartBuilder;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafis;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandling;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandlingBuilder;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.State;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.StateBuilder;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TimersBuilder;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TransportBuilder;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborBuilder;
51 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
52 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.NeighborsBuilder;
53 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.ADDPATHS;
54 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.ASN32;
55 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
56 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.BgpCapability;
57 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.GRACEFULRESTART;
58 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.MPBGP;
59 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.ROUTEREFRESH;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Timeticks;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.BgpNeighborStateAugmentation;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.BgpNeighborStateAugmentationBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiGracefulRestartStateAugmentation;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiGracefulRestartStateAugmentationBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiStateAugmentation;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiStateAugmentationBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborErrorHandlingStateAugmentation;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborErrorHandlingStateAugmentationBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborGracefulRestartStateAugmentation;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborGracefulRestartStateAugmentationBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborStateAugmentation;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborStateAugmentationBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTimersStateAugmentation;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTimersStateAugmentationBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTransportStateAugmentation;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTransportStateAugmentationBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.MessagesBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.messages.Received;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.messages.ReceivedBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.messages.Sent;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.messages.SentBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
83
84 /**
85  * Util for create OpenConfig Neighbor with corresponding openConfig state.
86  */
87 public final class NeighborUtil {
88     private static final long TIMETICK_ROLLOVER_VALUE = (UnsignedInteger.MAX_VALUE.longValue() + 1);
89
90     private NeighborUtil() {
91         throw new UnsupportedOperationException();
92     }
93
94     /**
95      * Build a Openconfig Neighbors container with all Neighbors Stats from a list of
96      * BGPPeerGroupState.
97      *
98      * @param peerStats            List of BGPPeerState containing Neighbor state counters
99      * @param bgpTableTypeRegistry BGP TableType Registry
100      * @return Openconfig Neighbors Stats
101      */
102     @Nullable
103     public static Neighbors buildNeighbors(@Nonnull final List<BGPPeerState> peerStats,
104             @Nonnull final BGPTableTypeRegistryConsumer bgpTableTypeRegistry) {
105         if (peerStats.isEmpty()) {
106             return null;
107         }
108         return new NeighborsBuilder().setNeighbor(peerStats.stream()
109                 .filter(Objects::nonNull)
110                 .map(neighbor -> buildNeighbor(neighbor, bgpTableTypeRegistry))
111                 .collect(Collectors.toList())).build();
112     }
113
114     /**
115      * Build a list of neighbors containing Operational State from a list of BGPPeerState.
116      *
117      * @param neighbor containing Neighbor state counters
118      * @return neighbor containing Neighbor State
119      */
120     @Nullable
121     public static Neighbor buildNeighbor(@Nonnull final BGPPeerState neighbor,
122             @Nonnull final BGPTableTypeRegistryConsumer bgpTableTypeRegistry) {
123         return new NeighborBuilder()
124                 .setNeighborAddress(neighbor.getNeighborAddress())
125                 .setState(buildNeighborState(neighbor.getBGPSessionState(), neighbor.getBGPPeerMessagesState()))
126                 .setTimers(buildTimer(neighbor.getBGPTimersState()))
127                 .setTransport(buildTransport(neighbor.getBGPTransportState()))
128                 .setErrorHandling(buildErrorHandling(neighbor.getBGPErrorHandlingState()))
129                 .setGracefulRestart(buildGracefulRestart(neighbor.getBGPGracelfulRestart()))
130                 .setAfiSafis(buildAfisSafis(neighbor, bgpTableTypeRegistry))
131                 .build();
132     }
133
134     /**
135      * Builds Neighbor State from BGPPeerState counters.
136      *
137      * @param sessionState         BGPPeerState containing Operational state counters
138      * @param bgpPeerMessagesState message state
139      * @return Neighbor State
140      */
141     @Nullable
142     public static State buildNeighborState(@Nullable final BGPSessionState sessionState,
143             final BGPPeerMessagesState bgpPeerMessagesState) {
144         if (sessionState == null && bgpPeerMessagesState == null) {
145             return null;
146         }
147         final StateBuilder builder = new StateBuilder();
148         if (sessionState != null) {
149             builder.addAugmentation(NeighborStateAugmentation.class, buildCapabilityState(sessionState));
150         }
151         if (bgpPeerMessagesState != null) {
152             builder.addAugmentation(BgpNeighborStateAugmentation.class, buildMessageState(bgpPeerMessagesState));
153         }
154         return builder.build();
155     }
156
157     /**
158      * Builds Neighbor State from BGPPeerState counters.
159      *
160      * @param neighbor BGPPeerState containing Operational state counters
161      * @return Timer State
162      */
163     @Nullable
164     public static Timers buildTimer(@Nullable final BGPTimersState neighbor) {
165         if (neighbor == null) {
166             return null;
167         }
168         // convert neighbor uptime which is in milliseconds to time-ticks which is
169         // hundredth of a second, and handle roll-over scenario
170         final long uptimeTicks = ((neighbor.getUpTime() / 10) % TIMETICK_ROLLOVER_VALUE);
171         final NeighborTimersStateAugmentation timerState = new NeighborTimersStateAugmentationBuilder()
172                 .setNegotiatedHoldTime(BigDecimal.valueOf(neighbor.getNegotiatedHoldTime()))
173                 .setUptime(new Timeticks(uptimeTicks)).build();
174
175         return new TimersBuilder().setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp
176                 .neighbor.group.timers.StateBuilder()
177                 .addAugmentation(NeighborTimersStateAugmentation.class, timerState).build()).build();
178     }
179
180     /**
181      * Builds Transport State from BGPTransportState counters.
182      *
183      * @param neighbor BGPPeerState containing Operational state counters
184      * @return Transport State
185      */
186     @Nullable
187     public static Transport buildTransport(@Nullable final BGPTransportState neighbor) {
188         if (neighbor == null) {
189             return null;
190         }
191         final NeighborTransportStateAugmentation transportState = new NeighborTransportStateAugmentationBuilder()
192                 .setLocalPort(neighbor.getLocalPort()).setRemoteAddress(neighbor.getRemoteAddress())
193                 .setRemotePort(neighbor.getRemotePort()).build();
194
195         return new TransportBuilder().setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009
196                 .bgp.neighbor.group.transport.StateBuilder()
197                 .addAugmentation(NeighborTransportStateAugmentation.class, transportState).build()).build();
198     }
199
200     /**
201      * Builds Error Handling State from BGPPeerState counters.
202      *
203      * @param errorHandlingState BGPErrorHandlingState containing ErrorHandlingState Operational state counters
204      * @return Error Handling State
205      */
206     public static ErrorHandling buildErrorHandling(@Nullable final BGPErrorHandlingState errorHandlingState) {
207         if (errorHandlingState == null) {
208             return null;
209         }
210         return new ErrorHandlingBuilder().setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
211                 .rev151009.bgp.neighbor.group.error.handling.StateBuilder()
212                 .addAugmentation(NeighborErrorHandlingStateAugmentation.class,
213                         buildErrorHandlingState(errorHandlingState.getErroneousUpdateReceivedCount())).build()).build();
214     }
215
216     /**
217      * Builds Graceful Restart containing Graceful Restart State from BGPGracelfulRestartState counters.
218      *
219      * @param neighbor BGPPeerState containing Operational state counters
220      * @return Graceful Restart
221      */
222     @Nonnull
223     public static GracefulRestart buildGracefulRestart(@Nonnull final BGPGracelfulRestartState neighbor) {
224         final NeighborGracefulRestartStateAugmentation gracefulRestartState =
225                 new NeighborGracefulRestartStateAugmentationBuilder()
226                         .setLocalRestarting(neighbor.isLocalRestarting())
227                         .setPeerRestartTime(neighbor.getPeerRestartTime())
228                         //.setMode(mode) TBD once implemented
229                         .setPeerRestarting(neighbor.isPeerRestarting()).build();
230
231         return new GracefulRestartBuilder().setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
232                 .rev151009.bgp.graceful.restart.graceful.restart.StateBuilder()
233                 .addAugmentation(NeighborGracefulRestartStateAugmentation.class, gracefulRestartState).build()).build();
234     }
235
236     /**
237      * Builds  Neighbor Afi Safi containing AfiSafi State.
238      *
239      * @param neighbor BGPPeerState containing Operational state counters
240      * @return Afi Safis
241      */
242     public static AfiSafis buildAfisSafis(@Nonnull final BGPPeerState neighbor,
243             @Nonnull final BGPTableTypeRegistryConsumer bgpTableTypeRegistry) {
244         return new AfiSafisBuilder().setAfiSafi(buildAfisSafisState(neighbor.getBGPAfiSafiState(),
245                 bgpTableTypeRegistry)).build();
246     }
247
248     /**
249      * Builds  Neighbor State containing Capabilities State, session State.
250      *
251      * @return Neighbor State
252      */
253     public static NeighborStateAugmentation buildCapabilityState(@Nonnull final BGPSessionState neighbor) {
254
255         final List<Class<? extends BgpCapability>> supportedCapabilities = buildSupportedCapabilities(neighbor);
256         SessionState sessionState = null;
257         switch (neighbor.getSessionState()) {
258             case IDLE:
259                 sessionState = SessionState.IDLE;
260                 break;
261             case UP:
262                 sessionState = SessionState.ESTABLISHED;
263                 break;
264             case OPEN_CONFIRM:
265                 sessionState = SessionState.OPENCONFIRM;
266                 break;
267             default:
268         }
269         return new NeighborStateAugmentationBuilder().setSupportedCapabilities(supportedCapabilities)
270                 .setSessionState(sessionState).build();
271     }
272
273     /**
274      * Builds Bgp Neighbor State containing Message State.
275      *
276      * @return BgpNeighborState containing Message State
277      */
278     @Nonnull
279     public static BgpNeighborStateAugmentation buildMessageState(@Nonnull final BGPPeerMessagesState neighbor) {
280         return new BgpNeighborStateAugmentationBuilder()
281                 .setMessages(new MessagesBuilder()
282                         .setReceived(buildMessagesReceived(neighbor))
283                         .setSent(buildMessagesSent(neighbor)).build()).build();
284     }
285
286     private static Received buildMessagesReceived(@Nonnull final BGPPeerMessagesState neighbor) {
287         return new ReceivedBuilder()
288                 .setUPDATE(toBigInteger(neighbor.getUpdateMessagesReceivedCount()))
289                 .setNOTIFICATION(toBigInteger(neighbor.getNotificationMessagesReceivedCount()))
290                 .build();
291     }
292
293     public static BigInteger toBigInteger(final long updateReceivedCounter) {
294         return UnsignedLong.valueOf(updateReceivedCounter).bigIntegerValue();
295     }
296
297     private static Sent buildMessagesSent(@Nonnull final BGPPeerMessagesState neighbor) {
298         return new SentBuilder()
299                 .setUPDATE(toBigInteger(neighbor.getUpdateMessagesSentCount()))
300                 .setNOTIFICATION(toBigInteger(neighbor.getNotificationMessagesSentCount()))
301                 .build();
302     }
303
304     /**
305      * Builds Neighbor Error Handling State.
306      *
307      * @param erroneousUpdateCount erroneous Update Count
308      * @return Error Handling State
309      */
310     @Nonnull
311     public static NeighborErrorHandlingStateAugmentation buildErrorHandlingState(final long erroneousUpdateCount) {
312         return new NeighborErrorHandlingStateAugmentationBuilder()
313                 .setErroneousUpdateMessages(erroneousUpdateCount).build();
314     }
315
316     /**
317      * Build List of afi safi containing State per Afi Safi.
318      *
319      * @return AfiSafi List
320      */
321     @Nonnull
322     public static List<AfiSafi> buildAfisSafisState(@Nonnull final BGPAfiSafiState neighbor,
323             @Nonnull final BGPTableTypeRegistryConsumer bgpTableTypeRegistry) {
324         final Set<TablesKey> afiSafiJoin = new HashSet<>(neighbor.getAfiSafisAdvertized());
325         afiSafiJoin.addAll(neighbor.getAfiSafisReceived());
326         return afiSafiJoin.stream().map(tableKey -> buildAfiSafi(neighbor, tableKey, bgpTableTypeRegistry))
327                 .filter(Objects::nonNull)
328                 .collect(Collectors.toList());
329     }
330
331     private static AfiSafi buildAfiSafi(@Nonnull final BGPAfiSafiState neighbor,
332             @Nonnull final TablesKey tablesKey, @Nonnull final BGPTableTypeRegistryConsumer bgpTableTypeRegistry) {
333         final Optional<Class<? extends AfiSafiType>> afiSafi = bgpTableTypeRegistry.getAfiSafiType(tablesKey);
334         return afiSafi.map(aClass -> new AfiSafiBuilder().setAfiSafiName(aClass)
335                 .setState(buildAfiSafiState(neighbor, tablesKey, neighbor.isAfiSafiSupported(tablesKey)))
336                 .setGracefulRestart(buildAfiSafiGracefulRestartState(neighbor, tablesKey)).build()).orElse(null);
337
338     }
339
340     private static org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi
341             .safi.list.afi.safi.State buildAfiSafiState(@Nonnull final BGPAfiSafiState neighbor,
342             @Nonnull final TablesKey tablesKey, final boolean afiSafiSupported) {
343         final NeighborAfiSafiStateAugmentationBuilder builder = new NeighborAfiSafiStateAugmentationBuilder();
344         builder.setActive(afiSafiSupported);
345         if (afiSafiSupported) {
346             builder.setPrefixes(new PrefixesBuilder()
347                     .setInstalled(neighbor.getPrefixesInstalledCount(tablesKey))
348                     .setReceived(neighbor.getPrefixesReceivedCount(tablesKey))
349                     .setSent(neighbor.getPrefixesSentCount(tablesKey)).build());
350         }
351         return new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi
352                 .safi.list.afi.safi.StateBuilder().addAugmentation(NeighborAfiSafiStateAugmentation.class,
353                 builder.build()).build();
354     }
355
356     private static org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi
357             .safi.list.afi.safi.GracefulRestart buildAfiSafiGracefulRestartState(
358             @Nonnull final BGPGracelfulRestartState neighbor, @Nonnull final TablesKey tablesKey) {
359         final NeighborAfiSafiGracefulRestartStateAugmentation builder =
360                 new NeighborAfiSafiGracefulRestartStateAugmentationBuilder()
361                         .setAdvertised(neighbor.isGracefulRestartAdvertized(tablesKey))
362                         .setReceived(neighbor.isGracefulRestartReceived(tablesKey)).build();
363         return new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi
364                 .safi.list.afi.safi.GracefulRestartBuilder().setState(new org.opendaylight.yang.gen.v1.http.openconfig
365                 .net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.afi.safi.graceful.restart.StateBuilder()
366                 .addAugmentation(NeighborAfiSafiGracefulRestartStateAugmentation.class, builder).build()).build();
367     }
368
369     /**
370      * Builds List of BgpCapability supported capabilities.
371      *
372      * @return List containing supported capabilities
373      */
374     @Nonnull
375     public static List<Class<? extends BgpCapability>> buildSupportedCapabilities(
376             @Nonnull final BGPSessionState neighbor) {
377         final List<Class<? extends BgpCapability>> supportedCapabilities = new ArrayList<>();
378         if (neighbor.isAddPathCapabilitySupported()) {
379             supportedCapabilities.add(ADDPATHS.class);
380         }
381         if (neighbor.isAsn32CapabilitySupported()) {
382             supportedCapabilities.add(ASN32.class);
383         }
384         if (neighbor.isGracefulRestartCapabilitySupported()) {
385             supportedCapabilities.add(GRACEFULRESTART.class);
386         }
387         if (neighbor.isMultiProtocolCapabilitySupported()) {
388             supportedCapabilities.add(MPBGP.class);
389         }
390         if (neighbor.isRouterRefreshCapabilitySupported()) {
391             supportedCapabilities.add(ROUTEREFRESH.class);
392         }
393         return supportedCapabilities;
394     }
395 }