Promote MessageRegistry to pcep-api
[bgpcep.git] / pcep / pcc-mock / src / test / java / org / opendaylight / protocol / pcep / pcc / mock / PCCMockCommon.java
1 /*
2  * Copyright (c) 2015 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.pcep.pcc.mock;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.opendaylight.protocol.util.CheckTestUtil.checkEquals;
15 import static org.opendaylight.protocol.util.CheckTestUtil.checkReceivedMessages;
16 import static org.opendaylight.protocol.util.CheckTestUtil.waitFutureSuccess;
17
18 import com.google.common.base.Stopwatch;
19 import com.google.common.net.InetAddresses;
20 import com.google.common.util.concurrent.Uninterruptibles;
21 import io.netty.channel.Channel;
22 import io.netty.channel.ChannelFuture;
23 import io.netty.channel.nio.NioEventLoopGroup;
24 import io.netty.util.HashedWheelTimer;
25 import io.netty.util.concurrent.Future;
26 import java.net.InetAddress;
27 import java.net.InetSocketAddress;
28 import java.util.List;
29 import java.util.Optional;
30 import java.util.ServiceLoader;
31 import java.util.concurrent.TimeUnit;
32 import org.junit.Before;
33 import org.opendaylight.protocol.concepts.KeyMapping;
34 import org.opendaylight.protocol.pcep.MessageRegistry;
35 import org.opendaylight.protocol.pcep.PCEPCapability;
36 import org.opendaylight.protocol.pcep.PCEPDispatcher;
37 import org.opendaylight.protocol.pcep.PCEPDispatcherDependencies;
38 import org.opendaylight.protocol.pcep.PCEPPeerProposal;
39 import org.opendaylight.protocol.pcep.PCEPSession;
40 import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
41 import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
42 import org.opendaylight.protocol.pcep.ietf.stateful.StatefulActivator;
43 import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
44 import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
45 import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl;
46 import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
47 import org.opendaylight.protocol.pcep.pcc.mock.protocol.MockPcepSessionErrorPolicy;
48 import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCDispatcherImpl;
49 import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCSessionListener;
50 import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderActivator;
51 import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
52 import org.opendaylight.protocol.pcep.spi.pojo.SimplePCEPExtensionProviderContext;
53 import org.opendaylight.protocol.pcep.sync.optimizations.SyncOptimizationsActivator;
54 import org.opendaylight.protocol.util.InetSocketAddressUtil;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev200720.Tlvs3;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.initiated.rev200720.Stateful1;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Pcrpt;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Tlvs1;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.lsp.object.Lsp;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.pcrpt.message.pcrpt.message.Reports;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
62 import org.opendaylight.yangtools.yang.common.Uint64;
63 import org.opendaylight.yangtools.yang.common.Uint8;
64
65 public abstract class PCCMockCommon {
66     private static final Uint8 KEEP_ALIVE = Uint8.valueOf(30);
67     private static final Uint8 DEAD_TIMER = Uint8.valueOf(120);
68     private static final long SLEEP_FOR = 50;
69     private final int port = InetSocketAddressUtil.getRandomPort();
70     final InetSocketAddress remoteAddress = InetSocketAddressUtil
71             .getRandomLoopbackInetSocketAddress(port);
72     final InetSocketAddress localAddress = InetSocketAddressUtil
73             .getRandomLoopbackInetSocketAddress(port);
74     PCCSessionListener pccSessionListener;
75     private PCEPDispatcher pceDispatcher;
76     private final PCEPExtensionProviderContext extensionProvider = new SimplePCEPExtensionProviderContext();
77     private MessageRegistry messageRegistry;
78
79     protected abstract List<PCEPCapability> getCapabilities();
80
81     @Before
82     public void setUp() {
83         final BasePCEPSessionProposalFactory proposal = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE,
84                 getCapabilities());
85         final DefaultPCEPSessionNegotiatorFactory nf = new DefaultPCEPSessionNegotiatorFactory(proposal,
86             MockPcepSessionErrorPolicy.ZERO);
87
88         ServiceLoader.load(PCEPExtensionProviderActivator.class).forEach(act -> act.start(extensionProvider));
89
90         messageRegistry = extensionProvider.getMessageHandlerRegistry();
91         pceDispatcher = new PCEPDispatcherImpl(messageRegistry, nf, new NioEventLoopGroup(),
92                 new NioEventLoopGroup());
93     }
94
95     static TestingSessionListener checkSessionListener(final int numMessages, final Channel channel,
96             final TestingSessionListenerFactory factory, final String localAddress) throws Exception {
97         final TestingSessionListener sessionListener = checkSessionListenerNotNull(factory, localAddress);
98         assertTrue(sessionListener.isUp());
99         checkReceivedMessages(sessionListener, numMessages);
100         assertEquals(numMessages, sessionListener.messages().size());
101         channel.close().get();
102         return sessionListener;
103     }
104
105     static TestingSessionListener checkSessionListenerNotNull(final TestingSessionListenerFactory factory,
106             final String localAddress) {
107         final Stopwatch sw = Stopwatch.createStarted();
108         TestingSessionListener listener;
109         final InetAddress address = InetAddresses.forString(localAddress);
110         while (sw.elapsed(TimeUnit.SECONDS) <= 60) {
111             listener = factory.getSessionListenerByRemoteAddress(address);
112             if (listener == null) {
113                 Uninterruptibles.sleepUninterruptibly(SLEEP_FOR, TimeUnit.MILLISECONDS);
114             } else {
115                 return listener;
116             }
117         }
118         throw new NullPointerException();
119     }
120
121     Channel createServer(final TestingSessionListenerFactory factory,
122             final InetSocketAddress serverAddress2) {
123         return createServer(factory, serverAddress2, null);
124     }
125
126     Channel createServer(final TestingSessionListenerFactory factory, final InetSocketAddress
127             serverAddress2, final PCEPPeerProposal peerProposal) {
128         final StatefulActivator activator07 = new StatefulActivator();
129         final SyncOptimizationsActivator optimizationsActivator = new SyncOptimizationsActivator();
130         activator07.start(extensionProvider);
131         optimizationsActivator.start(extensionProvider);
132
133         final ChannelFuture future = pceDispatcher
134                 .createServer(new DispatcherDependencies(serverAddress2, factory, peerProposal));
135         waitFutureSuccess(future);
136         return future.channel();
137     }
138
139     static void checkSynchronizedSession(final int numberOfLsp,
140             final TestingSessionListener pceSessionListener, final Uint64 expectedeInitialDb) throws Exception {
141         assertTrue(pceSessionListener.isUp());
142         //Send Open with LspDBV = 1
143         final int numberOfSyncMessage = 1;
144         int numberOfLspExpected = numberOfLsp;
145         if (!expectedeInitialDb.equals(Uint64.ZERO)) {
146             checkEquals(() -> checkSequequenceDBVersionSync(pceSessionListener, expectedeInitialDb));
147             numberOfLspExpected += numberOfSyncMessage;
148         }
149         checkReceivedMessages(pceSessionListener, numberOfLspExpected);
150         final PCEPSession session = pceSessionListener.getSession();
151         checkSession(session, DEAD_TIMER, KEEP_ALIVE);
152
153         assertTrue(session.getRemoteTlvs().augmentation(Tlvs1.class).getStateful()
154                 .augmentation(Stateful1.class).getInitiation());
155         assertNull(session.getLocalTlvs().augmentation(Tlvs3.class)
156                 .getLspDbVersion().getLspDbVersionValue());
157     }
158
159     static void checkResyncSession(final Optional<Integer> startAtNumberLsp, final int expectedNumberOfLsp,
160             final int expectedTotalMessages, final Uint64 startingDBVersion, final Uint64 expectedDBVersion,
161             final TestingSessionListener pceSessionListener) throws Exception {
162         assertNotNull(pceSessionListener.getSession());
163         assertTrue(pceSessionListener.isUp());
164         final List<Message> messages;
165         checkReceivedMessages(pceSessionListener, expectedTotalMessages);
166         if (startAtNumberLsp.isPresent()) {
167             messages = pceSessionListener.messages().subList(startAtNumberLsp.get(),
168                     startAtNumberLsp.get() + expectedNumberOfLsp);
169         } else {
170             messages = pceSessionListener.messages();
171         }
172         checkEquals(() -> checkSequequenceDBVersionSync(pceSessionListener, expectedDBVersion));
173         assertEquals(expectedNumberOfLsp, messages.size());
174         final PCEPSession session = pceSessionListener.getSession();
175
176         checkSession(session, DEAD_TIMER, KEEP_ALIVE);
177
178         assertTrue(session.getRemoteTlvs().augmentation(Tlvs1.class).getStateful()
179                 .augmentation(Stateful1.class).getInitiation());
180         final Uint64 pceDBVersion = session.getLocalTlvs().augmentation(Tlvs3.class)
181                 .getLspDbVersion().getLspDbVersionValue();
182         assertEquals(startingDBVersion, pceDBVersion);
183     }
184
185     static void checkSession(final PCEPSession session, final Uint8 expectedDeadTimer,
186             final Uint8 expectedKeepAlive) {
187         assertNotNull(session);
188         assertEquals(expectedDeadTimer, session.getPeerPref().getDeadtimer());
189         assertEquals(expectedKeepAlive, session.getPeerPref().getKeepalive());
190         final Stateful1 stateful = session.getRemoteTlvs().augmentation(Tlvs1.class)
191                 .getStateful().augmentation(Stateful1.class);
192         assertTrue(stateful.getInitiation());
193     }
194
195     protected static void checkSequequenceDBVersionSync(final TestingSessionListener pceSessionListener,
196             final Uint64 expectedDbVersion) {
197         for (final Message msg : pceSessionListener.messages()) {
198             final List<Reports> pcrt = ((Pcrpt) msg).getPcrptMessage().getReports();
199             for (final Reports report : pcrt) {
200                 final Lsp lsp = report.getLsp();
201                 if (lsp.getPlspId().getValue().toJava() == 0) {
202                     assertEquals(false, lsp.getSync());
203                 } else {
204                     assertEquals(true, lsp.getSync());
205                 }
206                 final Uint64 actuaLspDBVersion = lsp.getTlvs()
207                         .augmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep
208                             .sync.optimizations.rev200720.Tlvs1.class)
209                         .getLspDbVersion().getLspDbVersionValue();
210                 assertEquals(expectedDbVersion, actuaLspDBVersion);
211             }
212         }
213     }
214
215     Future<PCEPSession> createPCCSession(final Uint64 dbVersion) {
216         final PCCDispatcherImpl pccDispatcher = new PCCDispatcherImpl(messageRegistry);
217         final PCEPSessionNegotiatorFactory snf = getSessionNegotiatorFactory();
218         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(3, localAddress.getAddress(),
219                 0, -1, new HashedWheelTimer(), Optional.empty());
220
221         return pccDispatcher.createClient(remoteAddress, -1, () -> {
222             pccSessionListener = new PCCSessionListener(1, tunnelManager, false);
223             return pccSessionListener;
224         }, snf, KeyMapping.of(), localAddress, dbVersion);
225     }
226
227     private PCEPSessionNegotiatorFactory getSessionNegotiatorFactory() {
228         return new DefaultPCEPSessionNegotiatorFactory(new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE,
229                 getCapabilities()), MockPcepSessionErrorPolicy.ZERO);
230     }
231
232     TestingSessionListener getListener(final TestingSessionListenerFactory factory) {
233         return checkSessionListenerNotNull(factory, localAddress.getHostString());
234     }
235
236     private static class DispatcherDependencies implements PCEPDispatcherDependencies {
237         private final KeyMapping keys = KeyMapping.of();
238         private final InetSocketAddress address;
239         private final TestingSessionListenerFactory listenerFactory;
240         private final PCEPPeerProposal peerProposal;
241
242         DispatcherDependencies(
243                 final InetSocketAddress address,
244                 final TestingSessionListenerFactory listenerFactory,
245                 final PCEPPeerProposal peerProposal) {
246             this.address = address;
247             this.listenerFactory = listenerFactory;
248             this.peerProposal = peerProposal;
249         }
250
251         @Override
252         public InetSocketAddress getAddress() {
253             return address;
254         }
255
256         @Override
257         public KeyMapping getKeys() {
258             return keys;
259         }
260
261         @Override
262         public PCEPSessionListenerFactory getListenerFactory() {
263             return listenerFactory;
264         }
265
266         @Override
267         public PCEPPeerProposal getPeerProposal() {
268             return peerProposal;
269         }
270     }
271 }