2 * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netconf.client.mdsal;
10 import static org.hamcrest.CoreMatchers.instanceOf;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertEquals;
13 import static org.mockito.ArgumentMatchers.any;
14 import static org.mockito.ArgumentMatchers.anyCollection;
15 import static org.mockito.ArgumentMatchers.eq;
16 import static org.mockito.Mockito.after;
17 import static org.mockito.Mockito.doAnswer;
18 import static org.mockito.Mockito.doNothing;
19 import static org.mockito.Mockito.doReturn;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.spy;
22 import static org.mockito.Mockito.timeout;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
26 import com.google.common.util.concurrent.Futures;
27 import com.google.common.util.concurrent.MoreExecutors;
28 import com.google.common.util.concurrent.SettableFuture;
29 import java.net.InetSocketAddress;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.List;
36 import org.junit.BeforeClass;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.mockito.ArgumentCaptor;
40 import org.mockito.Mock;
41 import org.mockito.junit.MockitoJUnitRunner;
42 import org.opendaylight.mdsal.dom.api.DOMNotification;
43 import org.opendaylight.netconf.api.CapabilityURN;
44 import org.opendaylight.netconf.api.messages.NetconfMessage;
45 import org.opendaylight.netconf.api.xml.XmlUtil;
46 import org.opendaylight.netconf.client.mdsal.NetconfDevice.EmptySchemaContextException;
47 import org.opendaylight.netconf.client.mdsal.api.NetconfDeviceSchemasResolver;
48 import org.opendaylight.netconf.client.mdsal.api.NetconfSessionPreferences;
49 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceHandler;
50 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceId;
51 import org.opendaylight.netconf.client.mdsal.api.RemoteDeviceServices;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.connection.oper.available.capabilities.AvailableCapability.CapabilityOrigin;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.connection.oper.available.capabilities.AvailableCapabilityBuilder;
55 import org.opendaylight.yangtools.concepts.Registration;
56 import org.opendaylight.yangtools.yang.common.QName;
57 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
58 import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
59 import org.opendaylight.yangtools.yang.model.api.source.YangTextSource;
60 import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFactory;
61 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
62 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
63 import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
64 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
66 @RunWith(MockitoJUnitRunner.StrictStubs.class)
67 public class NetconfDeviceTest extends AbstractTestModelTest {
68 public static final String TEST_NAMESPACE = "test:namespace";
69 public static final String TEST_MODULE = "test-module";
70 public static final String TEST_REVISION = "2013-07-22";
71 public static final SourceIdentifier TEST_SID = new SourceIdentifier(TEST_MODULE, TEST_REVISION);
72 public static final String TEST_CAPABILITY =
73 TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION;
75 public static final SourceIdentifier TEST_SID2 = new SourceIdentifier(TEST_MODULE + "2", TEST_REVISION);
76 public static final String TEST_CAPABILITY2 =
77 TEST_NAMESPACE + "?module=" + TEST_MODULE + "2" + "&revision=" + TEST_REVISION;
79 private static final NetconfDeviceSchemasResolver STATE_SCHEMAS_RESOLVER =
80 (deviceRpc, remoteSessionCapabilities, id, schemaContext) -> Futures.immediateFuture(NetconfStateSchemas.EMPTY);
82 private static NetconfMessage NOTIFICATION;
85 private SchemaSourceRegistry schemaRegistry;
88 public static final void setupNotification() throws Exception {
89 NOTIFICATION = new NetconfMessage(XmlUtil.readXmlToDocument(
90 NetconfDeviceTest.class.getResourceAsStream("/notification-payload.xml")));
94 public void testNetconfDeviceFlawedModelFailedResolution() throws Exception {
95 final RemoteDeviceHandler facade = getFacade();
96 final NetconfDeviceCommunicator listener = getListener();
98 final EffectiveModelContextFactory schemaFactory = getSchemaFactory();
99 final SchemaRepository schemaRepository = getSchemaRepository();
101 final SchemaResolutionException schemaResolutionException =
102 new SchemaResolutionException("fail first", TEST_SID, new Throwable("YangTools parser fail"));
103 doAnswer(invocation -> {
104 if (invocation.getArgument(0, Collection.class).size() == 2) {
105 return Futures.immediateFailedFuture(schemaResolutionException);
107 return Futures.immediateFuture(SCHEMA_CONTEXT);
109 }).when(schemaFactory).createEffectiveModelContext(anyCollection());
111 final NetconfDeviceSchemasResolver stateSchemasResolver =
112 (deviceRpc, remoteSessionCapabilities, id, schemaContext) -> {
113 final var first = SCHEMA_CONTEXT.getModules().iterator().next();
114 final var qName = QName.create(first.getQNameModule(), first.getName());
115 return Futures.immediateFuture(new NetconfStateSchemas(
116 Set.of(qName, QName.create(first.getQNameModule(), "test-module2"))));
119 doReturn(mock(Registration.class)).when(schemaRegistry).registerSchemaSource(any(), any());
120 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice
121 .SchemaResourcesDTO(schemaRegistry, schemaRepository, schemaFactory, stateSchemasResolver);
123 final NetconfDevice device = new NetconfDeviceBuilder()
124 .setReconnectOnSchemasChange(true)
125 .setSchemaResourcesDTO(schemaResourcesDTO)
126 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
128 .setSalFacade(facade)
129 .setBaseSchemas(BASE_SCHEMAS)
131 // Monitoring supported
132 final NetconfSessionPreferences sessionCaps = getSessionCaps(true, List.of(TEST_CAPABILITY, TEST_CAPABILITY2));
133 device.onRemoteSessionUp(sessionCaps, listener);
135 verify(facade, timeout(5000)).onDeviceConnected(any(NetconfDeviceSchema.class),
136 any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class));
137 verify(schemaFactory, times(2)).createEffectiveModelContext(anyCollection());
141 public void testNetconfDeviceFailFirstSchemaFailSecondEmpty() throws Exception {
142 final RemoteDeviceHandler facade = getFacade();
143 final NetconfDeviceCommunicator listener = getListener();
145 final EffectiveModelContextFactory schemaFactory = getSchemaFactory();
146 final SchemaRepository schemaRepository = getSchemaRepository();
148 // Make fallback attempt to fail due to empty resolved sources
149 final SchemaResolutionException schemaResolutionException = new SchemaResolutionException("fail first",
150 new SourceIdentifier("test-module", "2013-07-22"), new Throwable());
151 doReturn(Futures.immediateFailedFuture(schemaResolutionException))
152 .when(schemaFactory).createEffectiveModelContext(anyCollection());
154 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice
155 .SchemaResourcesDTO(schemaRegistry, schemaRepository, schemaFactory, STATE_SCHEMAS_RESOLVER);
156 final NetconfDevice device = new NetconfDeviceBuilder()
157 .setReconnectOnSchemasChange(true)
158 .setSchemaResourcesDTO(schemaResourcesDTO)
159 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
161 .setSalFacade(facade)
162 .setBaseSchemas(BASE_SCHEMAS)
165 // Monitoring not supported
166 final NetconfSessionPreferences sessionCaps = getSessionCaps(false, List.of(TEST_CAPABILITY));
167 device.onRemoteSessionUp(sessionCaps, listener);
169 final var captor = ArgumentCaptor.forClass(Throwable.class);
170 verify(facade, timeout(5000)).onDeviceFailed(captor.capture());
171 assertThat(captor.getValue(), instanceOf(EmptySchemaContextException.class));
173 verify(listener, timeout(5000)).close();
174 verify(schemaFactory, times(1)).createEffectiveModelContext(anyCollection());
178 public void testNetconfDeviceMissingSource() throws Exception {
179 final RemoteDeviceHandler facade = getFacade();
180 final NetconfDeviceCommunicator listener = getListener();
182 final EffectiveModelContextFactory schemaFactory = getSchemaFactory();
183 final SchemaRepository schemaRepository = getSchemaRepository();
185 // Make fallback attempt to fail due to empty resolved sources
186 final MissingSchemaSourceException schemaResolutionException =
187 new MissingSchemaSourceException(TEST_SID, "fail first");
188 doReturn(Futures.immediateFailedFuture(schemaResolutionException))
189 .when(schemaRepository).getSchemaSource(eq(TEST_SID), eq(YangTextSource.class));
190 doAnswer(invocation -> {
191 if (invocation.getArgument(0, Collection.class).size() == 2) {
192 return Futures.immediateFailedFuture(schemaResolutionException);
194 return Futures.immediateFuture(SCHEMA_CONTEXT);
196 }).when(schemaFactory).createEffectiveModelContext(anyCollection());
198 final NetconfDeviceSchemasResolver stateSchemasResolver =
199 (deviceRpc, remoteSessionCapabilities, id, schemaContext) -> {
200 final var first = SCHEMA_CONTEXT.getModules().iterator().next();
201 final var qName = QName.create(first.getQNameModule(), first.getName());
202 return Futures.immediateFuture(new NetconfStateSchemas(
203 Set.of(qName, QName.create(first.getQNameModule(), "test-module2"))));
206 doReturn(mock(Registration.class)).when(schemaRegistry).registerSchemaSource(any(), any());
207 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice
208 .SchemaResourcesDTO(schemaRegistry, schemaRepository, schemaFactory, stateSchemasResolver);
210 final NetconfDevice device = new NetconfDeviceBuilder()
211 .setReconnectOnSchemasChange(true)
212 .setSchemaResourcesDTO(schemaResourcesDTO)
213 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
214 .setBaseSchemas(BASE_SCHEMAS)
216 .setSalFacade(facade)
218 // Monitoring supported
219 final NetconfSessionPreferences sessionCaps =
220 getSessionCaps(true, List.of(TEST_CAPABILITY, TEST_CAPABILITY2));
221 device.onRemoteSessionUp(sessionCaps, listener);
223 verify(facade, timeout(5000)).onDeviceConnected(any(NetconfDeviceSchema.class),
224 any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class));
225 verify(schemaFactory, times(1)).createEffectiveModelContext(anyCollection());
228 private static SchemaRepository getSchemaRepository() {
229 final SchemaRepository mock = mock(SchemaRepository.class);
230 final YangTextSource mockRep = mock(YangTextSource.class);
231 doReturn(Futures.immediateFuture(mockRep))
232 .when(mock).getSchemaSource(any(SourceIdentifier.class), eq(YangTextSource.class));
237 public void testNotificationBeforeSchema() throws Exception {
238 final RemoteDeviceHandler facade = getFacade();
239 final NetconfDeviceCommunicator listener = getListener();
240 final EffectiveModelContextFactory schemaContextProviderFactory = mock(EffectiveModelContextFactory.class);
241 final SettableFuture<SchemaContext> schemaFuture = SettableFuture.create();
242 doReturn(schemaFuture).when(schemaContextProviderFactory).createEffectiveModelContext(anyCollection());
243 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(schemaRegistry,
244 getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
245 final NetconfDevice device = new NetconfDeviceBuilder()
246 .setReconnectOnSchemasChange(true)
247 .setSchemaResourcesDTO(schemaResourcesDTO)
248 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
250 .setSalFacade(facade)
251 .setBaseSchemas(BASE_SCHEMAS)
254 final NetconfSessionPreferences sessionCaps = getSessionCaps(true, List.of(TEST_CAPABILITY));
255 device.onRemoteSessionUp(sessionCaps, listener);
257 device.onNotification(NOTIFICATION);
258 device.onNotification(NOTIFICATION);
259 verify(facade, times(0)).onNotification(any(DOMNotification.class));
261 verify(facade, times(0)).onNotification(any(DOMNotification.class));
262 schemaFuture.set(NetconfToNotificationTest.getNotificationSchemaContext(getClass(), false));
263 verify(facade, timeout(10000).times(2)).onNotification(any(DOMNotification.class));
265 device.onNotification(NOTIFICATION);
266 verify(facade, timeout(10000).times(3)).onNotification(any(DOMNotification.class));
270 public void testNetconfDeviceReconnect() throws Exception {
271 final RemoteDeviceHandler facade = getFacade();
272 final NetconfDeviceCommunicator listener = getListener();
274 final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory();
276 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(
277 schemaRegistry, getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
278 final NetconfDevice device = new NetconfDeviceBuilder()
279 .setReconnectOnSchemasChange(true)
280 .setSchemaResourcesDTO(schemaResourcesDTO)
281 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
283 .setSalFacade(facade)
284 .setBaseSchemas(BASE_SCHEMAS)
286 final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
287 List.of(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION));
288 device.onRemoteSessionUp(sessionCaps, listener);
290 verify(schemaContextProviderFactory, timeout(5000)).createEffectiveModelContext(anyCollection());
291 verify(facade, timeout(5000)).onDeviceConnected(
292 any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class));
294 device.onRemoteSessionDown();
295 verify(facade, timeout(5000)).onDeviceDisconnected();
297 device.onRemoteSessionUp(sessionCaps, listener);
299 verify(schemaContextProviderFactory, timeout(5000).times(2)).createEffectiveModelContext(anyCollection());
300 verify(facade, timeout(5000).times(2)).onDeviceConnected(
301 any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class));
305 public void testNetconfDeviceDisconnectListenerCallCancellation() throws Exception {
306 final RemoteDeviceHandler facade = getFacade();
307 final NetconfDeviceCommunicator listener = getListener();
308 final EffectiveModelContextFactory schemaContextProviderFactory = mock(EffectiveModelContextFactory.class);
309 final SettableFuture<SchemaContext> schemaFuture = SettableFuture.create();
310 doReturn(schemaFuture).when(schemaContextProviderFactory).createEffectiveModelContext(anyCollection());
311 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(schemaRegistry,
312 getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
313 final NetconfDevice device = new NetconfDeviceBuilder()
314 .setReconnectOnSchemasChange(true)
315 .setSchemaResourcesDTO(schemaResourcesDTO)
316 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
318 .setSalFacade(facade)
319 .setBaseSchemas(BASE_SCHEMAS)
321 final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
322 List.of(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION));
323 //session up, start schema resolution
324 device.onRemoteSessionUp(sessionCaps, listener);
326 device.onRemoteSessionDown();
327 verify(facade, timeout(5000)).onDeviceDisconnected();
328 //complete schema setup
329 schemaFuture.set(SCHEMA_CONTEXT);
330 //facade.onDeviceDisconnected() was called, so facade.onDeviceConnected() shouldn't be called anymore
331 verify(facade, after(1000).never()).onDeviceConnected(any(), any(), any(RemoteDeviceServices.class));
335 public void testNetconfDeviceReconnectBeforeSchemaSetup() throws Exception {
336 final RemoteDeviceHandler facade = getFacade();
338 final EffectiveModelContextFactory schemaContextProviderFactory = mock(EffectiveModelContextFactory.class);
339 final SettableFuture<SchemaContext> schemaFuture = SettableFuture.create();
340 doReturn(schemaFuture).when(schemaContextProviderFactory).createEffectiveModelContext(anyCollection());
342 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(
343 schemaRegistry, getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
344 final NetconfDevice device = new NetconfDeviceBuilder()
345 .setReconnectOnSchemasChange(true)
346 .setSchemaResourcesDTO(schemaResourcesDTO)
347 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
349 .setSalFacade(facade)
350 .setBaseSchemas(BASE_SCHEMAS)
352 final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
353 List.of(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION));
355 final NetconfDeviceCommunicator listener = getListener();
356 // session up, start schema resolution
357 device.onRemoteSessionUp(sessionCaps, listener);
359 device.onRemoteSessionDown();
360 verify(facade, timeout(5000)).onDeviceDisconnected();
361 // session back up, start another schema resolution
362 device.onRemoteSessionUp(sessionCaps, listener);
363 // complete schema setup
364 schemaFuture.set(SCHEMA_CONTEXT);
365 // schema setup performed twice
366 verify(schemaContextProviderFactory, timeout(5000).times(2)).createEffectiveModelContext(anyCollection());
367 // onDeviceConnected called once
368 verify(facade, timeout(5000)).onDeviceConnected(
369 any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class));
373 public void testNetconfDeviceAvailableCapabilitiesBuilding() throws Exception {
374 final RemoteDeviceHandler facade = getFacade();
375 final NetconfDeviceCommunicator listener = getListener();
377 final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory();
379 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(schemaRegistry,
380 getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
381 final NetconfDevice device = new NetconfDeviceBuilder()
382 .setReconnectOnSchemasChange(true)
383 .setSchemaResourcesDTO(schemaResourcesDTO)
384 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
386 .setSalFacade(facade)
387 .setBaseSchemas(BASE_SCHEMAS)
389 final NetconfDevice netconfSpy = spy(device);
391 final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
392 List.of(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION));
393 final Map<QName, CapabilityOrigin> moduleBasedCaps = new HashMap<>();
394 moduleBasedCaps.putAll(sessionCaps.moduleBasedCaps());
396 .put(QName.create("(test:qname:side:loading)test"), CapabilityOrigin.UserDefined);
398 netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener);
400 final var argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class);
401 verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class),
402 any(RemoteDeviceServices.class));
405 new AvailableCapabilityBuilder()
406 .setCapability("(test:namespace?revision=2013-07-22)test-module")
407 .setCapabilityOrigin(CapabilityOrigin.DeviceAdvertised)
409 new AvailableCapabilityBuilder()
410 .setCapability("(test:qname:side:loading)test")
411 .setCapabilityOrigin(CapabilityOrigin.UserDefined)
412 .build()), argument.getValue().capabilities().resolvedCapabilities());
416 public void testNetconfDeviceNotificationsModelNotPresentWithCapability() throws Exception {
417 final RemoteDeviceHandler facade = getFacade();
418 final NetconfDeviceCommunicator listener = getListener();
419 final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory();
421 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(schemaRegistry,
422 getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
423 final NetconfDevice device = new NetconfDeviceBuilder()
424 .setSchemaResourcesDTO(schemaResourcesDTO)
425 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
427 .setSalFacade(facade)
428 .setBaseSchemas(BASE_SCHEMAS)
430 final NetconfDevice netconfSpy = spy(device);
432 netconfSpy.onRemoteSessionUp(getSessionCaps(false, List.of(CapabilityURN.NOTIFICATION)), listener);
434 final var argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class);
435 verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class),
436 any(RemoteDeviceServices.class));
439 new AvailableCapabilityBuilder()
440 .setCapability("(urn:ietf:params:xml:ns:yang:ietf-yang-types?revision=2013-07-15)ietf-yang-types")
442 new AvailableCapabilityBuilder()
443 .setCapability("(urn:ietf:params:xml:ns:netconf:notification:1.0?revision=2008-07-14)notifications")
444 .build()), argument.getValue().capabilities().resolvedCapabilities());
448 public void testNetconfDeviceNotificationsCapabilityIsNotPresent() throws Exception {
449 final RemoteDeviceHandler facade = getFacade();
450 final NetconfDeviceCommunicator listener = getListener();
451 final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory();
453 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(schemaRegistry,
454 getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
455 final NetconfDevice device = new NetconfDeviceBuilder()
456 .setSchemaResourcesDTO(schemaResourcesDTO)
457 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
459 .setSalFacade(facade)
460 .setBaseSchemas(BASE_SCHEMAS)
462 final NetconfDevice netconfSpy = spy(device);
464 final NetconfSessionPreferences sessionCaps = getSessionCaps(false,
465 List.of(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION));
467 netconfSpy.onRemoteSessionUp(sessionCaps, listener);
469 final var argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class);
470 verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class),
471 any(RemoteDeviceServices.class));
473 assertEquals(Set.of(new AvailableCapabilityBuilder()
474 .setCapability("(test:namespace?revision=2013-07-22)test-module")
475 .setCapabilityOrigin(CapabilityOrigin.DeviceAdvertised)
476 .build()), argument.getValue().capabilities().resolvedCapabilities());
480 public void testNetconfDeviceNotificationsModelIsPresent() throws Exception {
481 final RemoteDeviceHandler facade = getFacade();
482 final NetconfDeviceCommunicator listener = getListener();
483 final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory();
485 final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(schemaRegistry,
486 getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER);
487 final NetconfDevice device = new NetconfDeviceBuilder()
488 .setSchemaResourcesDTO(schemaResourcesDTO)
489 .setGlobalProcessingExecutor(MoreExecutors.directExecutor())
491 .setSalFacade(facade)
492 .setBaseSchemas(BASE_SCHEMAS)
494 final NetconfDevice netconfSpy = spy(device);
496 netconfSpy.onRemoteSessionUp(getSessionCaps(false, List.of()).replaceModuleCaps(Map.of(
497 org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714
498 .YangModuleInfoImpl.getInstance().getName(), CapabilityOrigin.DeviceAdvertised,
499 org.opendaylight.yang.svc.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715
500 .YangModuleInfoImpl.getInstance().getName(), CapabilityOrigin.DeviceAdvertised
503 final var argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class);
504 verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class),
505 any(RemoteDeviceServices.class));
508 new AvailableCapabilityBuilder()
509 .setCapability("(urn:ietf:params:xml:ns:yang:ietf-yang-types?revision=2013-07-15)ietf-yang-types")
510 .setCapabilityOrigin(CapabilityOrigin.DeviceAdvertised)
512 new AvailableCapabilityBuilder()
513 .setCapability("(urn:ietf:params:xml:ns:netconf:notification:1.0?revision=2008-07-14)notifications")
514 .setCapabilityOrigin(CapabilityOrigin.DeviceAdvertised)
515 .build()), argument.getValue().capabilities().resolvedCapabilities());
518 private static EffectiveModelContextFactory getSchemaFactory() throws Exception {
519 final EffectiveModelContextFactory schemaFactory = mock(EffectiveModelContextFactory.class);
520 doReturn(Futures.immediateFuture(SCHEMA_CONTEXT))
521 .when(schemaFactory).createEffectiveModelContext(anyCollection());
522 return schemaFactory;
525 private static RemoteDeviceHandler getFacade() throws Exception {
526 final RemoteDeviceHandler remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class);
527 doNothing().when(remoteDeviceHandler).onDeviceConnected(
528 any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class));
529 doNothing().when(remoteDeviceHandler).onDeviceDisconnected();
530 doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class));
531 return remoteDeviceHandler;
534 private static <T extends AutoCloseable> T mockCloseableClass(final Class<T> remoteDeviceHandlerClass)
536 final T mock = mock(remoteDeviceHandlerClass);
537 doNothing().when(mock).close();
541 public RemoteDeviceId getId() {
542 return new RemoteDeviceId("test-D", InetSocketAddress.createUnresolved("localhost", 22));
545 public NetconfSessionPreferences getSessionCaps(final boolean addMonitor,
546 final Collection<String> additionalCapabilities) {
547 final var capabilities = new ArrayList<String>();
548 capabilities.add(CapabilityURN.BASE);
549 capabilities.add(CapabilityURN.BASE_1_1);
551 capabilities.add(NetconfState.QNAME.getNamespace().toString());
553 capabilities.addAll(additionalCapabilities);
554 return NetconfSessionPreferences.fromStrings(capabilities);
557 public NetconfDeviceCommunicator getListener() throws Exception {
558 return mockCloseableClass(NetconfDeviceCommunicator.class);