Cleanup AbstractStatementRegistryConsumerTest
[bgpcep.git] / bgp / rib-impl / src / test / java / org / opendaylight / protocol / bgp / rib / impl / AbstractAddPathTest.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 package org.opendaylight.protocol.bgp.rib.impl;
9
10 import static org.mockito.ArgumentMatchers.any;
11 import static org.mockito.Mockito.doReturn;
12 import static org.opendaylight.protocol.util.CheckUtil.readDataOperational;
13 import static org.opendaylight.protocol.util.CheckUtil.waitFutureSuccess;
14
15 import com.google.common.collect.ImmutableList;
16 import com.google.common.collect.Lists;
17 import io.netty.channel.epoll.Epoll;
18 import io.netty.channel.nio.NioEventLoopGroup;
19 import io.netty.util.concurrent.Future;
20 import java.net.InetSocketAddress;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Optional;
26 import java.util.Set;
27 import java.util.concurrent.TimeUnit;
28 import org.junit.After;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.mockito.Mock;
32 import org.mockito.Mockito;
33 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
34 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
35 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
36 import org.opendaylight.protocol.bgp.inet.RIBActivator;
37 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
38 import org.opendaylight.protocol.bgp.parser.BGPError;
39 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
40 import org.opendaylight.protocol.bgp.parser.impl.BGPActivator;
41 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
42 import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext;
43 import org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer;
44 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
45 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
46 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
47 import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
48 import org.opendaylight.protocol.util.InetSocketAddressUtil;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.prefixes.DestinationIpv4Builder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.prefixes.destination.ipv4.Ipv4PrefixesBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.routes.Ipv4Routes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.routes.ipv4.routes.Ipv4Route;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.routes.ipv4.routes.Ipv4RouteKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4CaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.NotifyBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Open;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.OpenBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.UpdateBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.open.message.BgpParameters;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.AsPathBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.ClusterIdBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.LocalPrefBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.MultiExitDiscBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.OriginBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.OriginatorIdBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.as.path.SegmentsBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.update.message.WithdrawnRoutesBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.BgpRib;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpId;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpOrigin;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.ClusterIdentifier;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv6AddressFamily;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
92 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
93 import org.opendaylight.yangtools.yang.binding.Notification;
94 import org.opendaylight.yangtools.yang.common.Uint16;
95 import org.opendaylight.yangtools.yang.common.Uint32;
96
97 public abstract class AbstractAddPathTest extends DefaultRibPoliciesMockTest {
98     private static final int RETRY_TIMER = 10;
99     static final String RIB_ID = "127.0.0.1";
100     static final BgpId BGP_ID = new BgpId(RIB_ID);
101     static final Ipv4AddressNoZone PEER1 = new Ipv4AddressNoZone("127.0.0.2");
102     static final Ipv4AddressNoZone PEER2 = new Ipv4AddressNoZone("127.0.0.3");
103     static final Ipv4AddressNoZone PEER3 = new Ipv4AddressNoZone("127.0.0.4");
104     static final Ipv4AddressNoZone PEER4 = new Ipv4AddressNoZone("127.0.0.5");
105     static final Ipv4AddressNoZone PEER5 = new Ipv4AddressNoZone("127.0.0.6");
106     static final Ipv4AddressNoZone PEER6 = new Ipv4AddressNoZone("127.0.0.7");
107     static final AsNumber AS_NUMBER = new AsNumber(Uint32.valueOf(AS));
108     static final Uint16 PORT = Uint16.valueOf(InetSocketAddressUtil.getRandomPort());
109     static final Ipv4Prefix PREFIX1 = new Ipv4Prefix("1.1.1.1/32");
110     private static final ClusterIdentifier CLUSTER_ID = new ClusterIdentifier(RIB_ID);
111     static final int HOLDTIMER = 2180;
112     private static final Ipv4AddressNoZone NH1 = new Ipv4AddressNoZone("2.2.2.2");
113     static final Update UPD_100 = createSimpleUpdate(PREFIX1, new PathId(Uint32.ONE), CLUSTER_ID, 100);
114     static final Update UPD_50 = createSimpleUpdate(PREFIX1, new PathId(Uint32.TWO), CLUSTER_ID, 50);
115     static final Update UPD_200 = createSimpleUpdate(PREFIX1, new PathId(Uint32.valueOf(3)), CLUSTER_ID, 200);
116     static final Update UPD_20 = createSimpleUpdate(PREFIX1, new PathId(Uint32.ONE), CLUSTER_ID, 20);
117     static final Update UPD_NA_100 = createSimpleUpdate(PREFIX1, null, CLUSTER_ID, 100);
118     static final Update UPD_NA_100_EBGP = createSimpleUpdateEbgp(PREFIX1);
119     static final Update UPD_NA_200 = createSimpleUpdate(PREFIX1, null, CLUSTER_ID, 200);
120     static final Update UPD_NA_200_EBGP = createSimpleUpdateEbgp(PREFIX1);
121     static final TablesKey TABLES_KEY = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
122     static final List<BgpTableType> TABLES_TYPE = ImmutableList.of(new BgpTableTypeImpl(TABLES_KEY.getAfi(),
123         TABLES_KEY.getSafi()));
124     static final Set<TablesKey> AFI_SAFIS_ADVERTIZED = Collections.singleton(TABLES_KEY);
125     private BGPExtensionProviderContext context;
126     static final InstanceIdentifier<BgpRib> BGP_IID = InstanceIdentifier.create(BgpRib.class);
127     static final int GRACEFUL_RESTART_TIME = 5;
128     @Mock
129     protected ClusterSingletonServiceProvider clusterSingletonServiceProvider;
130     BGPDispatcherImpl serverDispatcher;
131     final RIBExtensionProviderContext ribExtension = new SimpleRIBExtensionProviderContext();
132     private final RIBActivator ribActivator = new RIBActivator();
133     private BGPActivator bgpActivator;
134     private NioEventLoopGroup worker;
135     private NioEventLoopGroup boss;
136     private org.opendaylight.protocol.bgp.inet.BGPActivator inetActivator;
137     protected StrictBGPPeerRegistry serverRegistry;
138     protected ConstantCodecsRegistry codecsRegistry;
139
140     private List<BGPDispatcherImpl> clientDispatchers;
141
142     @Override
143     @Before
144     public void setUp() throws Exception {
145         super.setUp();
146
147         this.ribActivator.startRIBExtensionProvider(this.ribExtension, this.mappingService.currentSerializer());
148
149         this.bgpActivator = new BGPActivator();
150         this.inetActivator = new org.opendaylight.protocol.bgp.inet.BGPActivator();
151         this.context = new SimpleBGPExtensionProviderContext();
152         this.bgpActivator.start(this.context);
153         this.inetActivator.start(this.context);
154         if (!Epoll.isAvailable()) {
155             this.worker = new NioEventLoopGroup();
156             this.boss = new NioEventLoopGroup();
157         }
158         this.serverRegistry = new StrictBGPPeerRegistry();
159         this.serverDispatcher = new BGPDispatcherImpl(this.context.getMessageRegistry(), this.boss, this.worker,
160             this.serverRegistry);
161         doReturn(Mockito.mock(ClusterSingletonServiceRegistration.class)).when(this.clusterSingletonServiceProvider)
162             .registerClusterSingletonService(any(ClusterSingletonService.class));
163
164         this.codecsRegistry = new ConstantCodecsRegistry(mappingService.currentSerializer());
165         this.clientDispatchers = new ArrayList<>();
166     }
167
168     @Override
169     @After
170     public void tearDown() throws Exception {
171         this.serverDispatcher.close();
172         if (!Epoll.isAvailable()) {
173             this.worker.shutdownGracefully(0, 0, TimeUnit.SECONDS);
174             this.boss.shutdownGracefully(0, 0, TimeUnit.SECONDS);
175         }
176         this.bgpActivator.close();
177         this.clientDispatchers.forEach(BGPDispatcherImpl::close);
178         this.clientDispatchers = null;
179
180         super.tearDown();
181     }
182
183     void sendRouteAndCheckIsOnLocRib(final BGPSessionImpl session, final Ipv4Prefix prefix, final long localPreference,
184         final int expectedRoutesOnDS) throws Exception {
185         waitFutureSuccess(session.writeAndFlush(createSimpleUpdate(prefix, null, null, localPreference)));
186         checkLocRib(expectedRoutesOnDS);
187     }
188
189     void sendWithdrawalRouteAndCheckIsOnLocRib(final BGPSessionImpl session, final Ipv4Prefix prefix,
190         final long localPreference, final int expectedRoutesOnDS) throws Exception {
191         waitFutureSuccess(session.writeAndFlush(createSimpleWithdrawalUpdate(prefix, localPreference)));
192         checkLocRib(expectedRoutesOnDS);
193     }
194
195     void sendNotification(final BGPSessionImpl session) {
196         final Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode())
197             .setErrorSubcode(BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
198         waitFutureSuccess(session.writeAndFlush(notMsg));
199     }
200
201     void causeBGPError(final BGPSessionImpl session) {
202         final Open openObj = new OpenBuilder().setBgpIdentifier(new Ipv4AddressNoZone("1.1.1.1"))
203             .setHoldTimer(Uint16.valueOf(50)).setMyAsNumber(Uint16.valueOf(72)).build();
204         waitFutureSuccess(session.writeAndFlush(openObj));
205     }
206
207     private void checkLocRib(final int expectedRoutesOnDS) throws Exception {
208         // FIXME: remove this sleep
209         Thread.sleep(100);
210         readDataOperational(getDataBroker(), BGP_IID, bgpRib -> {
211             final Ipv4RoutesCase routes = (Ipv4RoutesCase) bgpRib.getRib().values().iterator().next().getLocRib()
212                     .getTables().values().iterator().next().getRoutes();
213             final int size;
214             if (routes != null) {
215                 final Ipv4Routes routesCase = routes.getIpv4Routes();
216                 if (routesCase != null) {
217                     final Map<Ipv4RouteKey, Ipv4Route> routeList = routesCase.getIpv4Route();
218                     size = routeList == null ? 0 : routeList.size();
219                 } else {
220                     size = 0;
221                 }
222             } else {
223                 size = 0;
224             }
225
226             Assert.assertEquals(expectedRoutesOnDS, size);
227             return bgpRib;
228         });
229     }
230
231     void checkPeersPresentOnDataStore(final int numberOfPeers) throws Exception {
232         readDataOperational(getDataBroker(), BGP_IID, bgpRib -> {
233             Assert.assertEquals(numberOfPeers, bgpRib.getRib().values().iterator().next().getPeer().size());
234             return bgpRib;
235         });
236     }
237
238     BGPSessionImpl createPeerSession(final Ipv4AddressNoZone peer, final BgpParameters bgpParameters,
239         final SimpleSessionListener sessionListener) throws InterruptedException {
240         return createPeerSession(peer, bgpParameters, sessionListener, AS_NUMBER);
241     }
242
243     BGPSessionImpl createPeerSession(final Ipv4AddressNoZone peer, final BgpParameters bgpParameters,
244                                      final SimpleSessionListener sessionListener,
245                                      final AsNumber remoteAsNumber) throws InterruptedException {
246         final StrictBGPPeerRegistry clientRegistry = new StrictBGPPeerRegistry();
247         final BGPDispatcherImpl clientDispatcher = new BGPDispatcherImpl(this.context.getMessageRegistry(), this.boss,
248                 this.worker, clientRegistry);
249
250         clientDispatchers.add(clientDispatcher);
251         clientRegistry.addPeer(new IpAddressNoZone(new Ipv4AddressNoZone(RIB_ID)), sessionListener,
252                 new BGPSessionPreferences(remoteAsNumber, HOLDTIMER, new BgpId(peer),
253                         AS_NUMBER, Lists.newArrayList(bgpParameters)));
254
255         return connectPeer(peer, clientDispatcher);
256     }
257
258     static BGPPeer configurePeer(final BGPTableTypeRegistryConsumer tableRegistry, final Ipv4AddressNoZone peerAddress,
259             final RIBImpl ribImpl, final BgpParameters bgpParameters, final PeerRole peerRole,
260             final BGPPeerRegistry bgpPeerRegistry) {
261         return configurePeer(tableRegistry, peerAddress, ribImpl, bgpParameters, peerRole, bgpPeerRegistry,
262                 AFI_SAFIS_ADVERTIZED, Collections.emptySet());
263     }
264
265     static BGPPeer configurePeer(final BGPTableTypeRegistryConsumer tableRegistry,
266             final Ipv4AddressNoZone peerAddress, final RIBImpl ribImpl, final BgpParameters bgpParameters,
267             final PeerRole peerRole, final BGPPeerRegistry bgpPeerRegistry, final Set<TablesKey> afiSafiAdvertised,
268             final Set<TablesKey> gracefulAfiSafiAdvertised) {
269         final BgpPeer bgpPeer = Mockito.mock(BgpPeer.class);
270         doReturn(Optional.empty()).when(bgpPeer).getErrorHandling();
271         return configurePeer(tableRegistry, peerAddress, ribImpl, bgpParameters, peerRole, bgpPeerRegistry,
272                 afiSafiAdvertised, gracefulAfiSafiAdvertised, Collections.emptyMap(), bgpPeer);
273     }
274
275     static BGPPeer configurePeer(final BGPTableTypeRegistryConsumer tableRegistry, final Ipv4AddressNoZone peerAddress,
276             final RIBImpl ribImpl, final BgpParameters bgpParameters, final PeerRole peerRole,
277             final BGPPeerRegistry bgpPeerRegistry, final Set<TablesKey> afiSafiAdvertised,
278             final Set<TablesKey> gracefulAfiSafiAdvertised, final Map<TablesKey, Integer> llGracefulTimersAdvertised,
279             final BgpPeer peer) {
280         final IpAddressNoZone ipAddress = new IpAddressNoZone(peerAddress);
281
282         final BGPPeer bgpPeer = new BGPPeer(tableRegistry, new IpAddressNoZone(peerAddress), null, ribImpl, peerRole,
283                 null, null, null, afiSafiAdvertised, gracefulAfiSafiAdvertised, llGracefulTimersAdvertised, peer);
284         final List<BgpParameters> tlvs = Lists.newArrayList(bgpParameters);
285         bgpPeerRegistry.addPeer(ipAddress, bgpPeer,
286                 new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(RIB_ID), AS_NUMBER, tlvs));
287         bgpPeer.instantiateServiceInstance();
288         return bgpPeer;
289     }
290
291     private static BGPSessionImpl connectPeer(final Ipv4Address localAddress, final BGPDispatcherImpl dispatcherImpl)
292             throws InterruptedException {
293         final Future<BGPSessionImpl> future = dispatcherImpl
294                 .createClient(new InetSocketAddress(localAddress.getValue(), PORT.toJava()),
295                         new InetSocketAddress(RIB_ID, PORT.toJava()), RETRY_TIMER, true);
296         Thread.sleep(200);
297         waitFutureSuccess(future);
298         Thread.sleep(100);
299         return future.getNow();
300     }
301
302     static BgpParameters createParameter(final boolean addPath) {
303         return createParameter(addPath, false, null);
304     }
305
306     static BgpParameters createParameter(final boolean addPath,
307                                          final boolean addIpv6,
308                                          final Map<TablesKey, Boolean> gracefulTables) {
309         final TablesKey ipv4Key = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
310         final List<TablesKey> advertisedTables = Lists.newArrayList(ipv4Key);
311         if (addIpv6) {
312             final TablesKey ipv6Key = new TablesKey(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class);
313             advertisedTables.add(ipv6Key);
314         }
315         final List<TablesKey> addPathTables = new ArrayList<>();
316         if (addPath) {
317             addPathTables.add(ipv4Key);
318         }
319         return PeerUtil.createBgpParameters(advertisedTables, addPathTables, gracefulTables, GRACEFUL_RESTART_TIME);
320     }
321
322     private static Update createSimpleUpdate(final Ipv4Prefix prefix, final PathId pathId,
323             final ClusterIdentifier clusterId, final long localPreference) {
324         final AttributesBuilder attBuilder = new AttributesBuilder();
325         attBuilder.setLocalPref(new LocalPrefBuilder().setPref(Uint32.valueOf(localPreference)).build());
326         attBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
327         attBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.emptyList()).build());
328         attBuilder.setMultiExitDisc(new MultiExitDiscBuilder().setMed(Uint32.ZERO).build());
329         if (clusterId != null) {
330             attBuilder.setClusterId(new ClusterIdBuilder().setCluster(Collections.singletonList(clusterId)).build());
331             attBuilder.setOriginatorId(new OriginatorIdBuilder()
332                 .setOriginator(new Ipv4AddressNoZone(clusterId))
333                 .build());
334         }
335         addAttributeAugmentation(attBuilder, prefix, pathId);
336         return new UpdateBuilder().setAttributes(attBuilder.build()).build();
337     }
338
339     private static Update createSimpleUpdateEbgp(final Ipv4Prefix prefix) {
340         final AttributesBuilder attBuilder = new AttributesBuilder();
341         attBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
342         attBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.singletonList(
343             new SegmentsBuilder().setAsSequence(Collections.singletonList(AS_NUMBER)).build())).build());
344         addAttributeAugmentation(attBuilder, prefix, null);
345
346         return new UpdateBuilder().setAttributes(attBuilder.build()).build();
347     }
348
349     private static void addAttributeAugmentation(final AttributesBuilder attBuilder, final Ipv4Prefix prefix,
350         final PathId pathId) {
351         attBuilder.setUnrecognizedAttributes(Collections.emptyMap());
352         attBuilder.addAugmentation(new Attributes1Builder()
353             .setMpReachNlri(new MpReachNlriBuilder()
354                 .setCNextHop(new Ipv4NextHopCaseBuilder()
355                     .setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(NH1).build())
356                     .build())
357                 .setAfi(Ipv4AddressFamily.class)
358                 .setSafi(UnicastSubsequentAddressFamily.class)
359                 .setAdvertizedRoutes(new AdvertizedRoutesBuilder()
360                     .setDestinationType(new DestinationIpv4CaseBuilder()
361                         .setDestinationIpv4(new DestinationIpv4Builder()
362                             .setIpv4Prefixes(Collections.singletonList(new Ipv4PrefixesBuilder()
363                                 .setPathId(pathId)
364                                 .setPrefix(new Ipv4Prefix(prefix))
365                                 .build()))
366                             .build())
367                         .build())
368                     .build())
369                 .build())
370             .build());
371     }
372
373     private static Update createSimpleWithdrawalUpdate(final Ipv4Prefix prefix, final long localPreference) {
374         final AttributesBuilder attBuilder = new AttributesBuilder();
375         attBuilder.setLocalPref(new LocalPrefBuilder().setPref(Uint32.valueOf(localPreference)).build());
376         attBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
377         attBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.emptyList()).build());
378         attBuilder.setUnrecognizedAttributes(Collections.emptyMap());
379         return new UpdateBuilder()
380                 .setWithdrawnRoutes(Collections.singletonList(new WithdrawnRoutesBuilder().setPrefix(prefix).build()))
381                 .build();
382     }
383 }