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