Update MRI projects for Aluminium
[bgpcep.git] / pcep / topology / topology-provider / src / test / java / org / opendaylight / bgpcep / pcep / topology / provider / Stateful07TopologySessionListenerTest.java
1 /*
2  * Copyright (c) 2014 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.bgpcep.pcep.topology.provider;
9
10 import static java.lang.Boolean.FALSE;
11 import static java.lang.Boolean.TRUE;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.assertNull;
16 import static org.junit.Assert.assertTrue;
17 import static org.junit.Assert.fail;
18 import static org.opendaylight.protocol.pcep.pcc.mock.spi.MsgBuilderUtil.createLspTlvs;
19 import static org.opendaylight.protocol.util.CheckTestUtil.checkEquals;
20 import static org.opendaylight.protocol.util.CheckTestUtil.checkNotPresentOperational;
21 import static org.opendaylight.protocol.util.CheckTestUtil.readDataOperational;
22
23 import com.google.common.collect.Lists;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Optional;
27 import java.util.concurrent.ExecutionException;
28 import java.util.concurrent.Future;
29 import java.util.concurrent.TimeUnit;
30 import java.util.concurrent.TimeoutException;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.opendaylight.protocol.pcep.PCEPCloseTermination;
34 import org.opendaylight.protocol.pcep.TerminationReason;
35 import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
36 import org.opendaylight.protocol.pcep.pcc.mock.spi.MsgBuilderUtil;
37 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
38 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
39 import org.opendaylight.protocol.util.CheckTestUtil;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyRef;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.Pcinitiate;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.Stateful1;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.Stateful1Builder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.pcinitiate.message.pcinitiate.message.Requests;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments1;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments1Builder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments2;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments2Builder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments3;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments3Builder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.OperationalStatus;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Pcrpt;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.PcrptBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Pcupd;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.PlspId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.SymbolicPathName;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Tlvs1;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Tlvs1Builder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.identifiers.tlv.LspIdentifiersBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.object.LspBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.object.lsp.Tlvs;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.PcrptMessageBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.pcrpt.message.Reports;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.pcrpt.message.ReportsBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.pcrpt.message.reports.PathBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcupd.message.pcupd.message.Updates;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.stateful.capability.tlv.StatefulBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.symbolic.path.name.tlv.SymbolicPathNameBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Close;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulCapabilitiesStatsAug;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesStatsAug;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.reply.time.grouping.ReplyTime;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv4CaseBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.ipv4._case.Ipv4Builder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObjBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.Open;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.OpenBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.open.TlvsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObject;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspInput;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspInputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspOutput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.EnsureLspOperationalInput;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.EnsureLspOperationalInputBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.FailureType;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.OperationResult;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.RemoveLspInput;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.RemoveLspInputBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspInput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspInputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspOutput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.add.lsp.args.ArgumentsBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.pcep.client.attributes.path.computation.client.ReportedLsp;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.pcep.client.attributes.path.computation.client.reported.lsp.Path;
102 import org.opendaylight.yangtools.yang.common.RpcResult;
103 import org.opendaylight.yangtools.yang.common.Uint32;
104
105 public class Stateful07TopologySessionListenerTest
106         extends AbstractPCEPSessionTest<Stateful07TopologySessionListenerFactory> {
107
108     private final String tunnelName = "pcc_" + this.testAddress + "_tunnel_0";
109
110     private Stateful07TopologySessionListener listener;
111
112     private PCEPSessionImpl session;
113
114     @Override
115     @Before
116     public void setUp() throws Exception {
117         super.setUp();
118         this.listener = (Stateful07TopologySessionListener) getSessionListener();
119         this.session = getPCEPSession(getLocalPref(), getRemotePref());
120     }
121
122     @Test
123     public void testStateful07TopologySessionListener() throws Exception {
124         this.listener.onSessionUp(this.session);
125         final PcepSessionState listenerState = this.listener.listenerState;
126         assertEquals(this.testAddress, listenerState.getPeerPref().getIpAddress());
127         final LocalPref state = this.listener.listenerState.getLocalPref();
128         assertNotNull(state);
129         assertEquals(DEAD_TIMER, state.getDeadtimer().shortValue());
130         assertEquals(KEEP_ALIVE, state.getKeepalive().shortValue());
131         assertEquals(0, state.getSessionId().intValue());
132         assertEquals(this.testAddress, state.getIpAddress());
133
134         final PeerPref peerState = listenerState.getPeerPref();
135
136         assertEquals(DEAD_TIMER, peerState.getDeadtimer().shortValue());
137         assertEquals(KEEP_ALIVE, peerState.getKeepalive().shortValue());
138         assertEquals(0, peerState.getSessionId().intValue());
139         assertEquals(this.testAddress, peerState.getIpAddress());
140
141         // add-lsp
142         this.topologyRpcs.addLsp(createAddLspInput());
143         assertEquals(1, this.receivedMsgs.size());
144         assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
145         final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
146         final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
147         final Uint32 srpId = req.getSrp().getOperationId().getValue();
148         final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
149                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
150         final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp())
151                         .setTlvs(tlvs).setPlspId(new PlspId(Uint32.ONE)).setSync(FALSE).setRemove(FALSE)
152                         .setOperational(OperationalStatus.Active).build(), Optional.of(MsgBuilderUtil.createSrp(srpId)),
153                 MsgBuilderUtil.createPath(req.getEro().getSubobject()));
154         final Pcrpt esm = MsgBuilderUtil.createPcRtpMessage(new LspBuilder().setSync(FALSE).build(),
155                 Optional.of(MsgBuilderUtil.createSrp(Uint32.ZERO)), null);
156         this.listener.onMessage(this.session, esm);
157         readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
158             assertEquals(this.testAddress, pcc.getIpAddress().getIpv4AddressNoZone().getValue());
159             // reported lsp so far empty, has not received response (PcRpt) yet
160             assertNull(pcc.getReportedLsp());
161             return pcc;
162         });
163
164         this.listener.onMessage(this.session, pcRpt);
165         // check created lsp
166         readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
167             assertEquals(1, pcc.nonnullReportedLsp().size());
168             final ReportedLsp reportedLsp = pcc.getReportedLsp().values().iterator().next();
169             assertEquals(this.tunnelName, reportedLsp.getName());
170             assertEquals(1, reportedLsp.nonnullPath().size());
171             final Path path = reportedLsp.nonnullPath().values().iterator().next();
172             assertEquals(1, path.getEro().getSubobject().size());
173             assertEquals(this.eroIpPrefix, getLastEroIpPrefix(path.getEro()));
174             return pcc;
175         });
176
177         // check stats
178         checkEquals(() -> assertEquals(1, listenerState.getDelegatedLspsCount().intValue()));
179         checkEquals(() -> assertTrue(this.listener.isSessionSynchronized()));
180         checkEquals(() -> assertTrue(listenerState.getMessages()
181                 .augmentation(StatefulMessagesStatsAug.class).getLastReceivedRptMsgTimestamp().toJava() > 0));
182         checkEquals(() -> assertEquals(2, listenerState.getMessages()
183                 .augmentation(StatefulMessagesStatsAug.class).getReceivedRptMsgCount().intValue()));
184         checkEquals(() -> assertEquals(1, listenerState.getMessages()
185                 .augmentation(StatefulMessagesStatsAug.class).getSentInitMsgCount().intValue()));
186         checkEquals(() -> assertEquals(0, listenerState.getMessages()
187                 .augmentation(StatefulMessagesStatsAug.class).getSentUpdMsgCount().intValue()));
188
189         // update-lsp
190         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.update.lsp.args
191                 .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
192                 .topology.pcep.rev200120.update.lsp.args.ArgumentsBuilder();
193         updArgsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix, this.dstIpPrefix)));
194         updArgsBuilder.addAugmentation(new Arguments3Builder().setLsp(new LspBuilder()
195                 .setDelegate(TRUE).setAdministrative(FALSE).build()).build());
196         final UpdateLspInput update = new UpdateLspInputBuilder().setArguments(updArgsBuilder.build())
197                 .setName(this.tunnelName).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
198                 .setNode(this.nodeId).build();
199         this.topologyRpcs.updateLsp(update);
200         assertEquals(2, this.receivedMsgs.size());
201         assertTrue(this.receivedMsgs.get(1) instanceof Pcupd);
202         final Pcupd updateMsg = (Pcupd) this.receivedMsgs.get(1);
203         final Updates upd = updateMsg.getPcupdMessage().getUpdates().get(0);
204         final Uint32 srpId2 = upd.getSrp().getOperationId().getValue();
205         final Tlvs tlvs2 = createLspTlvs(upd.getLsp().getPlspId().getValue(), false,
206                 this.newDestinationAddress, this.testAddress, this.testAddress, Optional.empty());
207         final Pcrpt pcRpt2 = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(upd.getLsp()).setTlvs(tlvs2)
208                         .setSync(TRUE).setRemove(FALSE).setOperational(OperationalStatus.Active).build(),
209                 Optional.of(MsgBuilderUtil.createSrp(srpId2)), MsgBuilderUtil.createPath(upd.getPath()
210                         .getEro().getSubobject()));
211         this.listener.onMessage(this.session, pcRpt2);
212
213         //check updated lsp
214         readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
215             assertEquals(1, pcc.getReportedLsp().size());
216             final ReportedLsp reportedLsp = pcc.getReportedLsp().values().iterator().next();
217             assertEquals(this.tunnelName, reportedLsp.getName());
218             assertEquals(1, reportedLsp.getPath().size());
219             final Path path = reportedLsp.getPath().values().iterator().next();
220             assertEquals(2, path.getEro().getSubobject().size());
221             assertEquals(this.dstIpPrefix, getLastEroIpPrefix(path.getEro()));
222             assertEquals(1, listenerState.getDelegatedLspsCount().intValue());
223             assertTrue(this.listener.isSessionSynchronized());
224             final StatefulMessagesStatsAug statefulstate = listenerState.getMessages()
225                     .augmentation(StatefulMessagesStatsAug.class);
226             assertTrue(statefulstate.getLastReceivedRptMsgTimestamp().toJava() > 0);
227             assertEquals(3, statefulstate.getReceivedRptMsgCount().intValue());
228             assertEquals(1, statefulstate.getSentInitMsgCount().intValue());
229             assertEquals(1, statefulstate.getSentUpdMsgCount().intValue());
230             final ReplyTime replyTime = listenerState.getMessages().getReplyTime();
231             assertTrue(replyTime.getAverageTime().toJava() > 0);
232             assertTrue(replyTime.getMaxTime().toJava() > 0);
233             final StatefulCapabilitiesStatsAug statefulCapabilities = listenerState
234                     .getPeerCapabilities().augmentation(StatefulCapabilitiesStatsAug.class);
235             assertFalse(statefulCapabilities.isActive());
236             assertTrue(statefulCapabilities.isInstantiation());
237             assertTrue(statefulCapabilities.isStateful());
238             return pcc;
239         });
240
241         // ensure-operational
242         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.ensure.lsp
243                 .operational.args.ArgumentsBuilder ensureArgs = new org.opendaylight.yang.gen.v1.urn.opendaylight.params
244                 .xml.ns.yang.topology.pcep.rev200120.ensure.lsp.operational.args.ArgumentsBuilder();
245         ensureArgs.addAugmentation(Arguments1.class, new Arguments1Builder().setOperational(OperationalStatus.Active)
246                 .build());
247         final EnsureLspOperationalInput ensure = new EnsureLspOperationalInputBuilder().setArguments(ensureArgs.build())
248                 .setName(this.tunnelName).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
249                 .setNode(this.nodeId).build();
250         final OperationResult result = this.topologyRpcs.ensureLspOperational(ensure).get().getResult();
251         //check result
252         assertNull(result.getFailure());
253
254         // remove-lsp
255         final RemoveLspInput remove = new RemoveLspInputBuilder().setName(this.tunnelName)
256                 .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
257         this.topologyRpcs.removeLsp(remove);
258         assertEquals(3, this.receivedMsgs.size());
259         assertTrue(this.receivedMsgs.get(2) instanceof Pcinitiate);
260         final Pcinitiate pcinitiate2 = (Pcinitiate) this.receivedMsgs.get(2);
261         final Requests req2 = pcinitiate2.getPcinitiateMessage().getRequests().get(0);
262         final Uint32 srpId3 = req2.getSrp().getOperationId().getValue();
263         final Tlvs tlvs3 = createLspTlvs(req2.getLsp().getPlspId().getValue(), false,
264                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
265         final Pcrpt pcRpt3 = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req2.getLsp()).setTlvs(tlvs3)
266                         .setRemove(TRUE).setSync(TRUE).setOperational(OperationalStatus.Down).build(),
267                 Optional.of(MsgBuilderUtil.createSrp(srpId3)), MsgBuilderUtil.createPath(Collections.emptyList()));
268         this.listener.onMessage(this.session, pcRpt3);
269
270         // check if lsp was removed
271         readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
272             assertNull(pcc.getReportedLsp());
273             return pcc;
274         });
275         // check stats
276         checkEquals(() -> assertEquals(0, listenerState.getDelegatedLspsCount().intValue()));
277         checkEquals(() -> assertTrue(this.listener.isSessionSynchronized()));
278         checkEquals(() -> assertTrue(listenerState.getMessages()
279                 .augmentation(StatefulMessagesStatsAug.class).getLastReceivedRptMsgTimestamp().toJava() > 0));
280         checkEquals(() -> assertEquals(4, listenerState.getMessages()
281                 .augmentation(StatefulMessagesStatsAug.class).getReceivedRptMsgCount().intValue()));
282         checkEquals(() -> assertEquals(2, listenerState.getMessages()
283                 .augmentation(StatefulMessagesStatsAug.class).getSentInitMsgCount().intValue()));
284         checkEquals(() -> assertEquals(1, listenerState.getMessages()
285                 .augmentation(StatefulMessagesStatsAug.class).getSentUpdMsgCount().intValue()));
286     }
287
288     @Test
289     public void testOnUnhandledErrorMessage() {
290         final Message errorMsg = AbstractMessageParser.createErrorMsg(PCEPErrors.NON_ZERO_PLSPID, Optional.empty());
291         this.listener.onSessionUp(this.session);
292         assertTrue(this.listener.onMessage(Optional.<AbstractTopologySessionListener.MessageContext>empty()
293                 .orElse(null),
294             errorMsg));
295     }
296
297     @Test
298     public void testOnErrorMessage() throws InterruptedException, ExecutionException {
299         final Message errorMsg = MsgBuilderUtil.createErrorMsg(PCEPErrors.NON_ZERO_PLSPID, Uint32.ONE);
300         this.listener.onSessionUp(this.session);
301         final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
302         this.listener.onMessage(this.session, errorMsg);
303
304         final AddLspOutput output = futureOutput.get().getResult();
305         assertEquals(FailureType.Failed, output.getFailure());
306         assertEquals(1, output.getError().size());
307         final ErrorObject err = output.getError().get(0).getErrorObject();
308         assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorType(), err.getType());
309         assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorValue(), err.getValue());
310     }
311
312     @Test
313     public void testOnSessionDown() throws InterruptedException, ExecutionException {
314         this.listener.onSessionUp(this.session);
315         // send request
316         final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
317         assertFalse(this.session.isClosed());
318         this.listener.onSessionDown(this.session, new IllegalArgumentException());
319         assertTrue(this.session.isClosed());
320         final AddLspOutput output = futureOutput.get().getResult();
321         // deal with unsent request after session down
322         assertEquals(FailureType.Unsent, output.getFailure());
323     }
324
325     /**
326      * All the pcep session registration should be closed when the session manager is closed.
327      */
328     @Test
329     public void testOnServerSessionManagerDown() throws InterruptedException, ExecutionException {
330         this.listener.onSessionUp(this.session);
331         // the session should not be closed when session manager is up
332         assertFalse(this.session.isClosed());
333         // send request
334         final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
335         stopSessionManager();
336         final AddLspOutput output = futureOutput.get().getResult();
337         // deal with unsent request after session down
338         assertEquals(FailureType.Unsent, output.getFailure());
339         // verify the session is closed after server session manager is closed
340         assertTrue(this.session.isClosed());
341     }
342
343     /**
344      * Verify the PCEP session should not be up when server session manager is down,
345      * otherwise it would be a problem when the session is up while it's not registered with session manager.
346      */
347     @Test
348     public void testOnServerSessionManagerUnstarted() throws InterruptedException, ExecutionException {
349         stopSessionManager();
350         assertFalse(this.session.isClosed());
351         this.listener.onSessionUp(this.session);
352         // verify the session was NOT added to topology
353         checkNotPresentOperational(getDataBroker(), TOPO_IID);
354         // verify the session is closed due to server session manager is closed
355         assertTrue(this.session.isClosed());
356         // send request
357         final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
358         final AddLspOutput output = futureOutput.get().getResult();
359         // deal with unsent request after session down
360         assertEquals(FailureType.Unsent, output.getFailure());
361     }
362
363     @Test
364     public void testOnServerSessionManagerRestartAndSessionRecovery() throws Exception {
365         // close server session manager first
366         stopSessionManager();
367         assertFalse(this.session.isClosed());
368         this.listener.onSessionUp(this.session);
369         // verify the session was NOT added to topology
370         checkNotPresentOperational(getDataBroker(), TOPO_IID);
371         // verify the session is closed due to server session manager is closed
372         assertTrue(this.session.isClosed());
373         // send request
374         final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
375         final AddLspOutput output = futureOutput.get().getResult();
376         // deal with unsent request after session down
377         assertEquals(FailureType.Unsent, output.getFailure());
378         // PCC client is not there
379         checkNotPresentOperational(getDataBroker(), this.pathComputationClientIId);
380
381         // reset received message queue
382         this.receivedMsgs.clear();
383         // now we restart the session manager
384         startSessionManager();
385         // try to start the session again
386         // notice since the session was terminated before, it is not usable anymore.
387         // we need to get a new session instance. the new session will have the same local / remote preference
388         this.session = getPCEPSession(getLocalPref(), getRemotePref());
389         assertFalse(this.session.isClosed());
390         this.listener.onSessionUp(this.session);
391         assertFalse(this.session.isClosed());
392
393         // create node
394         this.topologyRpcs.addLsp(createAddLspInput());
395         final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
396         final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
397         final Uint32 srpId = req.getSrp().getOperationId().getValue();
398         final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
399                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
400         final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(TRUE)
401                         .setRemove(FALSE).setOperational(OperationalStatus.Active).build(),
402                 Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
403         this.listener.onMessage(this.session, pcRpt);
404         readDataOperational(getDataBroker(), TOPO_IID, topology -> {
405             assertEquals(1, topology.getNode().size());
406             return topology;
407         });
408     }
409
410     /**
411      * When a session is somehow duplicated in controller, the controller should drop existing session.
412      */
413     @Test
414     public void testDuplicatedSession() throws ExecutionException, InterruptedException {
415         this.listener.onSessionUp(this.session);
416
417         // create node
418         this.topologyRpcs.addLsp(createAddLspInput());
419         final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
420         final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
421         final Uint32 srpId = req.getSrp().getOperationId().getValue();
422         final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
423                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
424         final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(TRUE)
425                         .setRemove(FALSE).setOperational(OperationalStatus.Active).build(),
426                 Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
427         this.listener.onMessage(this.session, pcRpt);
428         readDataOperational(getDataBroker(), TOPO_IID, topology -> {
429             assertEquals(1, topology.getNode().size());
430             return topology;
431         });
432
433         // now we do session up again
434         this.listener.onSessionUp(this.session);
435         assertTrue(this.session.isClosed());
436         // node should be removed after termination
437         checkNotPresentOperational(getDataBroker(), this.pathComputationClientIId);
438         assertFalse(this.receivedMsgs.isEmpty());
439         // the last message should be a Close message
440         assertTrue(this.receivedMsgs.get(this.receivedMsgs.size() - 1) instanceof Close);
441     }
442
443     @Test
444     public void testConflictingListeners() {
445         this.listener.onSessionUp(this.session);
446         assertFalse(this.session.isClosed());
447         Stateful07TopologySessionListener conflictingListener =
448                 (Stateful07TopologySessionListener) getSessionListener();
449         conflictingListener.onSessionUp(this.session);
450         assertTrue(this.session.isClosed());
451     }
452
453     @Test
454     public void testOnSessionTermination() throws Exception {
455         this.listener.onSessionUp(this.session);
456         // create node
457         this.topologyRpcs.addLsp(createAddLspInput());
458         final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
459         final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
460         final Uint32 srpId = req.getSrp().getOperationId().getValue();
461         final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
462                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
463         final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(TRUE)
464                         .setRemove(FALSE).setOperational(OperationalStatus.Active).build(),
465                 Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
466         this.listener.onMessage(this.session, pcRpt);
467         readDataOperational(getDataBroker(), TOPO_IID, topology -> {
468             assertEquals(1, topology.getNode().size());
469             return topology;
470         });
471
472         assertFalse(this.session.isClosed());
473         // node should be removed after termination
474         this.listener.onSessionTerminated(this.session, new PCEPCloseTermination(TerminationReason.UNKNOWN));
475         assertTrue(this.session.isClosed());
476         checkNotPresentOperational(getDataBroker(), this.pathComputationClientIId);
477     }
478
479     @Test
480     public void testUnknownLsp() throws Exception {
481         final List<Reports> reports = Lists.newArrayList(new ReportsBuilder()
482             .setPath(new PathBuilder()
483                 .setEro(new EroBuilder().build())
484                 .build())
485             .setLsp(new LspBuilder()
486                 .setPlspId(new PlspId(Uint32.valueOf(5)))
487                 .setSync(FALSE).setRemove(FALSE)
488                 .setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful
489                     .rev181109.lsp.object.lsp.TlvsBuilder().setLspIdentifiers(new LspIdentifiersBuilder()
490                         .setLspId(new LspId(Uint32.ONE))
491                         .build())
492                     .setSymbolicPathName(new SymbolicPathNameBuilder()
493                         .setPathName(new SymbolicPathName(new byte[]{22, 34}))
494                         .build())
495                     .build())
496                 .build())
497             .build());
498         final Pcrpt rptmsg = new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build())
499                 .build();
500         this.listener.onSessionUp(this.session);
501         this.listener.onMessage(this.session, rptmsg);
502         readDataOperational(getDataBroker(), TOPO_IID, node -> {
503             assertFalse(node.getNode().isEmpty());
504             return node;
505         });
506     }
507
508     @Test
509     public void testUpdateUnknownLsp() throws InterruptedException, ExecutionException {
510         this.listener.onSessionUp(this.session);
511         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.update.lsp.args
512                 .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
513                 .topology.pcep.rev200120.update.lsp.args.ArgumentsBuilder();
514         updArgsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix, this.dstIpPrefix)));
515         updArgsBuilder.addAugmentation(Arguments3.class, new Arguments3Builder().setLsp(new LspBuilder()
516                 .setDelegate(TRUE).setAdministrative(TRUE).build()).build());
517         final UpdateLspInput update = new UpdateLspInputBuilder().setArguments(updArgsBuilder.build())
518                 .setName(this.tunnelName).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId)
519                 .build();
520         final UpdateLspOutput result = this.topologyRpcs.updateLsp(update).get().getResult();
521         assertEquals(FailureType.Unsent, result.getFailure());
522         assertEquals(1, result.getError().size());
523         final ErrorObject errorObject = result.getError().get(0).getErrorObject();
524         assertNotNull(errorObject);
525         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, PCEPErrors.forValue(errorObject.getType(), errorObject.getValue()));
526     }
527
528     @Test
529     public void testRemoveUnknownLsp() throws InterruptedException, ExecutionException {
530         this.listener.onSessionUp(this.session);
531         final RemoveLspInput remove = new RemoveLspInputBuilder().setName(this.tunnelName).setNetworkTopologyRef(
532                 new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
533         final OperationResult result = this.topologyRpcs.removeLsp(remove).get().getResult();
534         assertEquals(FailureType.Unsent, result.getFailure());
535         assertEquals(1, result.getError().size());
536         final ErrorObject errorObject = result.getError().get(0).getErrorObject();
537         assertNotNull(errorObject);
538         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, PCEPErrors.forValue(errorObject.getType(), errorObject.getValue()));
539     }
540
541     @Test
542     public void testAddAlreadyExistingLsp() throws InterruptedException, ExecutionException {
543         this.listener.onSessionUp(this.session);
544         this.topologyRpcs.addLsp(createAddLspInput());
545         assertEquals(1, this.receivedMsgs.size());
546         assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
547         final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
548         final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
549         final Uint32 srpId = req.getSrp().getOperationId().getValue();
550         final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
551                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
552         final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
553                 .setPlspId(new PlspId(Uint32.ONE))
554                 .setSync(FALSE)
555                 .setRemove(FALSE)
556                 .setOperational(OperationalStatus.Active)
557                 .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro()
558                 .getSubobject()));
559         this.listener.onMessage(this.session, pcRpt);
560
561         //try to add already existing LSP
562         final AddLspOutput result = this.topologyRpcs.addLsp(createAddLspInput()).get().getResult();
563         assertEquals(FailureType.Unsent, result.getFailure());
564         assertEquals(1, result.getError().size());
565         final ErrorObject errorObject = result.getError().get(0).getErrorObject();
566         assertNotNull(errorObject);
567         assertEquals(PCEPErrors.USED_SYMBOLIC_PATH_NAME, PCEPErrors.forValue(errorObject.getType(),
568                 errorObject.getValue()));
569     }
570
571     @Test
572     @SuppressWarnings("checkstyle:IllegalCatch")
573     public void testPccResponseTimeout() throws Exception {
574         this.listener.onSessionUp(this.session);
575         final Future<RpcResult<AddLspOutput>> addLspResult = this.topologyRpcs.addLsp(createAddLspInput());
576         try {
577             addLspResult.get(2, TimeUnit.SECONDS);
578             fail();
579         } catch (final Exception e) {
580             assertTrue(e instanceof TimeoutException);
581         }
582         Thread.sleep(AbstractPCEPSessionTest.RPC_TIMEOUT);
583         CheckTestUtil.checkEquals(() -> {
584             final RpcResult<AddLspOutput> rpcResult = addLspResult.get();
585             assertNotNull(rpcResult);
586             assertEquals(rpcResult.getResult().getFailure(), FailureType.Unsent);
587         });
588     }
589
590     @Test
591     public void testDelegatedLspsCountWithDelegation() throws Exception {
592         this.listener.onSessionUp(this.session);
593         this.topologyRpcs.addLsp(createAddLspInput());
594         assertEquals(1, this.receivedMsgs.size());
595         assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
596         final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
597         final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
598         final Uint32 srpId = req.getSrp().getOperationId().getValue();
599         final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
600                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
601         //delegate set to true
602         final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
603                 .setPlspId(new PlspId(Uint32.ONE))
604                 .setSync(FALSE)
605                 .setRemove(FALSE)
606                 .setOperational(OperationalStatus.Active)
607                 .setDelegate(TRUE)
608                 .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(
609                 req.getEro().getSubobject()));
610         this.listener.onMessage(this.session, pcRpt);
611         checkEquals(() -> assertEquals(1, this.listener.listenerState.getDelegatedLspsCount().intValue()));
612     }
613
614     @Test
615     public void testDelegatedLspsCountWithoutDelegation() throws Exception {
616         this.listener.onSessionUp(this.session);
617         this.topologyRpcs.addLsp(createAddLspInput());
618         assertEquals(1, this.receivedMsgs.size());
619         assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
620         final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
621         final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
622         final Uint32 srpId = req.getSrp().getOperationId().getValue();
623         final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
624                 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
625         //delegate set to false
626         final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
627                         .setPlspId(new PlspId(Uint32.ONE))
628                         .setSync(FALSE)
629                         .setRemove(FALSE)
630                         .setOperational(OperationalStatus.Active)
631                         .setDelegate(FALSE)
632                         .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)),
633                 MsgBuilderUtil.createPath(req.getEro().getSubobject()));
634         this.listener.onMessage(this.session, pcRpt);
635         checkEquals(() -> assertEquals(0, this.listener.listenerState.getDelegatedLspsCount().intValue()));
636     }
637
638     @Override
639     protected Open getLocalPref() {
640         return new OpenBuilder(super.getLocalPref()).setTlvs(new TlvsBuilder().addAugmentation(Tlvs1.class,
641                 new Tlvs1Builder().setStateful(new StatefulBuilder()
642                         .addAugmentation(Stateful1.class, new Stateful1Builder().setInitiation(TRUE).build())
643                         .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller
644                                 .pcep.sync.optimizations.rev181109.Stateful1.class, new org.opendaylight.yang.gen.v1
645                                 .urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev181109
646                                 .Stateful1Builder().setTriggeredInitialSync(TRUE).build())
647                         .build()).build()).build()).build();
648     }
649
650     @Override
651     protected Open getRemotePref() {
652         return getLocalPref();
653     }
654
655     private AddLspInput createAddLspInput() {
656         final ArgumentsBuilder argsBuilder = new ArgumentsBuilder();
657         final Ipv4CaseBuilder ipv4Builder = new Ipv4CaseBuilder();
658         ipv4Builder.setIpv4(new Ipv4Builder().setSourceIpv4Address(new Ipv4AddressNoZone(this.testAddress))
659                 .setDestinationIpv4Address(new Ipv4AddressNoZone(this.testAddress)).build());
660         argsBuilder.setEndpointsObj(new EndpointsObjBuilder().setAddressFamily(ipv4Builder.build()).build());
661         argsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix)));
662         argsBuilder.addAugmentation(Arguments2.class, new Arguments2Builder().setLsp(new LspBuilder()
663                 .setDelegate(TRUE).setAdministrative(TRUE).build()).build());
664         return new AddLspInputBuilder().setName(this.tunnelName).setArguments(argsBuilder.build())
665                 .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
666     }
667 }