X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Ftools%2Fnetconf-testtool%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Ftest%2Ftool%2FNetconfDeviceSimulator.java;h=8c69562995691df44146e26168b5f98ec140bb8a;hb=aafa2fb9d206df54b7088f449f6e3cfc7bcae50d;hp=53ca53ab70ab4eabfdeeb8011d80e6119c31c87b;hpb=a018b4d571be537fea1cfbe0e882c4c55a0a9e9d;p=netconf.git diff --git a/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/NetconfDeviceSimulator.java b/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/NetconfDeviceSimulator.java index 53ca53ab70..8c69562995 100644 --- a/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/NetconfDeviceSimulator.java +++ b/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/NetconfDeviceSimulator.java @@ -5,15 +5,11 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netconf.test.tool; -import com.google.common.base.MoreObjects; -import com.google.common.base.Optional; +import static java.util.Objects.requireNonNullElseGet; + import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.netty.channel.Channel; @@ -23,89 +19,89 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; import java.io.Closeable; import java.io.IOException; -import java.io.InputStream; import java.net.BindException; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.UnknownHostException; -import java.nio.file.Files; -import java.nio.file.Path; +import java.nio.channels.AsynchronousChannelGroup; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import org.apache.sshd.common.util.ThreadUtils; -import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider; -import org.opendaylight.controller.config.util.capability.BasicCapability; -import org.opendaylight.controller.config.util.capability.Capability; -import org.opendaylight.controller.config.util.capability.YangModuleCapability; +import org.opendaylight.netconf.api.capability.BasicCapability; +import org.opendaylight.netconf.api.capability.Capability; +import org.opendaylight.netconf.api.capability.YangModuleCapability; import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService; -import org.opendaylight.netconf.api.xml.XmlNetconfConstants; -import org.opendaylight.netconf.impl.NetconfServerDispatcherImpl; -import org.opendaylight.netconf.impl.NetconfServerSessionNegotiatorFactory; -import org.opendaylight.netconf.impl.SessionIdProvider; -import org.opendaylight.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory; -import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory; -import org.opendaylight.netconf.monitoring.osgi.NetconfMonitoringActivator; -import org.opendaylight.netconf.monitoring.osgi.NetconfMonitoringOperationService; +import org.opendaylight.netconf.server.NetconfServerDispatcherImpl; +import org.opendaylight.netconf.server.NetconfServerSessionNegotiatorFactory; +import org.opendaylight.netconf.server.ServerChannelInitializer; +import org.opendaylight.netconf.server.api.SessionIdProvider; +import org.opendaylight.netconf.server.api.operations.NetconfOperationServiceFactory; +import org.opendaylight.netconf.server.impl.DefaultSessionIdProvider; +import org.opendaylight.netconf.server.osgi.AggregatedNetconfOperationServiceFactory; +import org.opendaylight.netconf.shaded.sshd.common.keyprovider.KeyPairProvider; +import org.opendaylight.netconf.shaded.sshd.common.util.threads.ThreadUtils; import org.opendaylight.netconf.ssh.SshProxyServer; import org.opendaylight.netconf.ssh.SshProxyServerConfiguration; import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder; +import org.opendaylight.netconf.test.tool.config.Configuration; import org.opendaylight.netconf.test.tool.customrpc.SettableOperationProvider; -import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import org.opendaylight.netconf.test.tool.monitoring.NetconfMonitoringOperationService; +import org.opendaylight.netconf.test.tool.monitoring.NetconfMonitoringOperationServiceFactory; +import org.opendaylight.netconf.test.tool.operations.DefaultOperationsCreator; +import org.opendaylight.netconf.test.tool.operations.OperationsProvider; +import org.opendaylight.netconf.test.tool.rpchandler.SettableOperationRpcProvider; +import org.opendaylight.netconf.test.tool.schemacache.SchemaSourceCache; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter; +import org.opendaylight.yangtools.yang.model.api.ModuleLike; +import org.opendaylight.yangtools.yang.model.api.Submodule; import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.fs.FilesystemSchemaSourceCache; import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource; import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceListener; import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; -import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache; import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository; -import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer; +import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class NetconfDeviceSimulator implements Closeable { - private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceSimulator.class); private final NioEventLoopGroup nettyThreadgroup; private final HashedWheelTimer hashedWheelTimer; - private final List devicesChannels = Lists.newArrayList(); - private final List sshWrappers = Lists.newArrayList(); + private final List devicesChannels = new ArrayList<>(); + private final List sshWrappers = new ArrayList<>(); private final ScheduledExecutorService minaTimerExecutor; private final ExecutorService nioExecutor; - private SchemaContext schemaContext; + private final Configuration configuration; + private EffectiveModelContext schemaContext; private boolean sendFakeSchema = false; - public NetconfDeviceSimulator(final int threadPoolSize) { - this(new NioEventLoopGroup(), new HashedWheelTimer(), - Executors.newScheduledThreadPool(threadPoolSize, - new ThreadFactoryBuilder().setNameFormat("netconf-ssh-server-mina-timers-%d").build()), - ThreadUtils.newFixedThreadPool("netconf-ssh-server-nio-group", threadPoolSize)); - } - - private NetconfDeviceSimulator(final NioEventLoopGroup eventExecutors, final HashedWheelTimer hashedWheelTimer, - final ScheduledExecutorService minaTimerExecutor, final ExecutorService nioExecutor) { - this.nettyThreadgroup = eventExecutors; - this.hashedWheelTimer = hashedWheelTimer; - this.minaTimerExecutor = minaTimerExecutor; - this.nioExecutor = nioExecutor; + public NetconfDeviceSimulator(final Configuration configuration) { + this.configuration = configuration; + nettyThreadgroup = new NioEventLoopGroup(); + hashedWheelTimer = new HashedWheelTimer(); + minaTimerExecutor = Executors.newScheduledThreadPool(configuration.getThreadPoolSize(), + new ThreadFactoryBuilder().setNameFormat("netconf-ssh-server-mina-timers-%d").build()); + nioExecutor = ThreadUtils.newFixedThreadPool("netconf-ssh-server-nio-group", configuration.getThreadPoolSize()); } private NetconfServerDispatcherImpl createDispatcher(final Set capabilities, - final SchemaSourceProvider sourceProvider, final TesttoolParameters params) { + final SchemaSourceProvider sourceProvider) { - final Set transformedCapabilities = Sets.newHashSet(Collections2.transform(capabilities, input -> { + final Set transformedCapabilities = new HashSet<>(Collections2.transform(capabilities, input -> { if (sendFakeSchema) { sendFakeSchema = false; return new FakeCapability((YangModuleCapability) input); @@ -115,88 +111,110 @@ public class NetconfDeviceSimulator implements Closeable { })); transformedCapabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0")); final NetconfMonitoringService monitoringService1 = new DummyMonitoringService(transformedCapabilities); - final SessionIdProvider idProvider = new SessionIdProvider(); + final SessionIdProvider idProvider = new DefaultSessionIdProvider(); final NetconfOperationServiceFactory aggregatedNetconfOperationServiceFactory = createOperationServiceFactory( - sourceProvider, params, transformedCapabilities, monitoringService1, idProvider); + sourceProvider, transformedCapabilities, monitoringService1, idProvider); - final Set serverCapabilities = params.exi - ? NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES - : Sets.newHashSet(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, - XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1); + final Set serverCapabilities = configuration.getCapabilities(); final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new TesttoolNegotiationFactory( - hashedWheelTimer, aggregatedNetconfOperationServiceFactory, idProvider, params.generateConfigsTimeout, + hashedWheelTimer, aggregatedNetconfOperationServiceFactory, idProvider, + configuration.getGenerateConfigsTimeout(), monitoringService1, serverCapabilities); - final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = - new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory); + final ServerChannelInitializer serverChannelInitializer = + new ServerChannelInitializer(serverNegotiatorFactory); return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup); } private NetconfOperationServiceFactory createOperationServiceFactory( - final SchemaSourceProvider sourceProvider, final TesttoolParameters params, + final SchemaSourceProvider sourceProvider, final Set transformedCapabilities, final NetconfMonitoringService monitoringService1, final SessionIdProvider idProvider) { final AggregatedNetconfOperationServiceFactory aggregatedNetconfOperationServiceFactory = new AggregatedNetconfOperationServiceFactory(); final NetconfOperationServiceFactory operationProvider; - if (params.mdSal) { + if (configuration.isMdSal()) { + LOG.info("using MdsalOperationProvider."); operationProvider = new MdsalOperationProvider( idProvider, transformedCapabilities, schemaContext, sourceProvider); - } else { + } else if (configuration.isXmlConfigurationProvided()) { + LOG.info("using SimulatedOperationProvider."); + operationProvider = new SimulatedOperationProvider(idProvider, transformedCapabilities, + Optional.ofNullable(configuration.getNotificationFile()), + Optional.ofNullable(configuration.getInitialConfigXMLFile())); + } else if (configuration.isNotificationsSupported()) { + LOG.info("using SimulatedOperationProvider."); operationProvider = new SimulatedOperationProvider(idProvider, transformedCapabilities, - Optional.fromNullable(params.notificationFile), - Optional.fromNullable(params.initialConfigXMLFile)); + Optional.ofNullable(configuration.getNotificationFile()), + Optional.empty()); + } else { + LOG.info("using OperationsProvider."); + operationProvider = new OperationsProvider(idProvider, transformedCapabilities, + requireNonNullElseGet(configuration.getOperationsCreator(), + () -> new DefaultOperationsCreator(idProvider.getCurrentSessionId()))); } - - final NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory monitoringService = - new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory( + final NetconfMonitoringOperationServiceFactory monitoringService = + new NetconfMonitoringOperationServiceFactory( new NetconfMonitoringOperationService(monitoringService1)); aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(operationProvider); aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(monitoringService); - if (params.rpcConfig != null) { - final SettableOperationProvider settableService = new SettableOperationProvider(params.rpcConfig); + if (configuration.getRpcConfigFile() != null) { + final SettableOperationProvider settableService = + new SettableOperationProvider(configuration.getRpcConfigFile()); + aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(settableService); + } else { + final SettableOperationRpcProvider settableService = + new SettableOperationRpcProvider(configuration.getRpcHandler()); aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(settableService); } return aggregatedNetconfOperationServiceFactory; } - public List start(final TesttoolParameters params) { + public List start() { + final var proto = configuration.isSsh() ? "SSH" : "TCP"; LOG.info("Starting {}, {} simulated devices starting on port {}", - params.deviceCount, params.ssh ? "SSH" : "TCP", params.startingPort); + configuration.getDeviceCount(), proto, configuration.getStartingPort()); final SharedSchemaRepository schemaRepo = new SharedSchemaRepository("netconf-simulator"); - final Set capabilities = parseSchemasToModuleCapabilities(params, schemaRepo); + final Set capabilities = parseSchemasToModuleCapabilities(schemaRepo); final NetconfServerDispatcherImpl dispatcher = createDispatcher(capabilities, - sourceIdentifier -> schemaRepo.getSchemaSource(sourceIdentifier, YangTextSchemaSource.class), params); + sourceIdentifier -> schemaRepo.getSchemaSource(sourceIdentifier, YangTextSchemaSource.class)); - int currentPort = params.startingPort; + int currentPort = configuration.getStartingPort(); - final List openDevices = Lists.newArrayList(); + final List openDevices = new ArrayList<>(); // Generate key to temp folder - final PEMGeneratorHostKeyProvider keyPairProvider = getPemGeneratorHostKeyProvider(); + final KeyPairProvider keyPairProvider = new VirtualKeyPairProvider(); + + final AsynchronousChannelGroup group; + try { + group = AsynchronousChannelGroup.withThreadPool(nioExecutor); + } catch (final IOException e) { + throw new IllegalStateException("Failed to create group", e); + } - for (int i = 0; i < params.deviceCount; i++) { + for (int i = 0; i < configuration.getDeviceCount(); i++) { if (currentPort > 65535) { LOG.warn("Port cannot be greater than 65535, stopping further attempts."); break; } - final InetSocketAddress address = getAddress(params.ip, currentPort); + final InetSocketAddress address = getAddress(configuration.getIp(), currentPort); final ChannelFuture server; - if (params.ssh) { + if (configuration.isSsh()) { final InetSocketAddress bindingAddress = InetSocketAddress.createUnresolved("0.0.0.0", currentPort); final LocalAddress tcpLocalAddress = new LocalAddress(address.toString()); server = dispatcher.createLocalServer(tcpLocalAddress); try { final SshProxyServer sshServer = new SshProxyServer( - minaTimerExecutor, nettyThreadgroup, nioExecutor); + minaTimerExecutor, nettyThreadgroup, group); sshServer.bind(getSshConfiguration(bindingAddress, tcpLocalAddress, keyPairProvider)); sshWrappers.add(sshServer); } catch (final BindException e) { @@ -217,7 +235,7 @@ public class NetconfDeviceSimulator implements Closeable { try { server.get(); } catch (final InterruptedException e) { - throw new RuntimeException(e); + throw new IllegalStateException("Interrupted while waiting for server", e); } catch (final ExecutionException e) { LOG.warn("Cannot start ssh simulated device on {}, skipping", address, e); continue; @@ -232,22 +250,22 @@ public class NetconfDeviceSimulator implements Closeable { try { server.get(); } catch (final InterruptedException e) { - throw new RuntimeException(e); + throw new IllegalStateException("Interrupted while waiting for server", e); } catch (final ExecutionException e) { LOG.warn("Cannot start tcp simulated device on {}, skipping", address, e); continue; } - LOG.debug("Simulated TCP device started on {}", address); + LOG.debug("Simulated TCP device started on {}", server.channel().localAddress()); } devicesChannels.add(server.channel()); openDevices.add(currentPort - 1); } - if (openDevices.size() == params.deviceCount) { + if (openDevices.size() == configuration.getDeviceCount()) { LOG.info("All simulated devices started successfully from port {} to {}", - params.startingPort, currentPort - 1); + configuration.getStartingPort(), currentPort - 1); } else if (openDevices.size() == 0) { LOG.warn("No simulated devices started."); } else { @@ -258,35 +276,25 @@ public class NetconfDeviceSimulator implements Closeable { } private SshProxyServerConfiguration getSshConfiguration(final InetSocketAddress bindingAddress, - final LocalAddress tcpLocalAddress, final PEMGeneratorHostKeyProvider keyPairProvider) throws IOException { + final LocalAddress tcpLocalAddress, final KeyPairProvider keyPairProvider) { return new SshProxyServerConfigurationBuilder() .setBindingAddress(bindingAddress) .setLocalAddress(tcpLocalAddress) - .setAuthenticator((username, password) -> true) + .setAuthenticator(configuration.getAuthProvider()) + .setPublickeyAuthenticator(configuration.getPublickeyAuthenticator()) .setKeyPairProvider(keyPairProvider) .setIdleTimeout(Integer.MAX_VALUE) .createSshProxyServerConfiguration(); } - private PEMGeneratorHostKeyProvider getPemGeneratorHostKeyProvider() { - try { - final Path tempFile = Files.createTempFile("tempKeyNetconfTest", "suffix"); - return new PEMGeneratorHostKeyProvider(tempFile.toAbsolutePath().toString(), "RSA", 4096); - } catch (final IOException e) { - LOG.error("Unable to generate PEM key", e); - throw new RuntimeException(e); - } - } - - private Set parseSchemasToModuleCapabilities(final TesttoolParameters params, - final SharedSchemaRepository consumer) { - final Set loadedSources = Sets.newHashSet(); - - consumer.registerSchemaSourceListener(TextToASTTransformer.create(consumer, consumer)); - + private Set parseSchemasToModuleCapabilities(final SharedSchemaRepository consumer) { + final Set loadedSources = new HashSet<>(); + consumer.registerSchemaSourceListener(TextToIRTransformer.create(consumer, consumer)); consumer.registerSchemaSourceListener(new SchemaSourceListener() { @Override - public void schemaSourceEncountered(final SchemaSourceRepresentation schemaSourceRepresentation) {} + public void schemaSourceEncountered(final SchemaSourceRepresentation schemaSourceRepresentation) { + + } @Override public void schemaSourceRegistered(final Iterable> potentialSchemaSources) { @@ -296,30 +304,43 @@ public class NetconfDeviceSimulator implements Closeable { } @Override - public void schemaSourceUnregistered(final PotentialSchemaSource potentialSchemaSource) {} + public void schemaSourceUnregistered(final PotentialSchemaSource potentialSchemaSource) { + + } }); - if (params.schemasDir != null) { + if (configuration.getSchemasDir() != null) { + LOG.info("Loading models from directory."); final FilesystemSchemaSourceCache cache = new FilesystemSchemaSourceCache<>( - consumer, YangTextSchemaSource.class, params.schemasDir); + consumer, YangTextSchemaSource.class, configuration.getSchemasDir()); + consumer.registerSchemaSourceListener(cache); + } else if (configuration.getModels() != null) { + LOG.info("Loading models from classpath."); + final SchemaSourceCache cache = new SchemaSourceCache<>( + consumer, YangTextSchemaSource.class, configuration.getModels()); consumer.registerSchemaSourceListener(cache); + } else { + LOG.info("Custom module loading skipped."); } - addDefaultSchemas(consumer); + configuration.getDefaultYangResources().forEach(r -> { + final SourceIdentifier sourceIdentifier = new SourceIdentifier(r.getModuleName(), r.getRevision()); + registerSource(consumer, r.getResourcePath(), sourceIdentifier); + }); try { //necessary for creating mdsal data stores and operations - this.schemaContext = consumer.createSchemaContextFactory( - SchemaSourceFilter.ALWAYS_ACCEPT) - .createSchemaContext(loadedSources).checkedGet(); - } catch (final SchemaResolutionException e) { - throw new RuntimeException("Cannot parse schema context", e); + schemaContext = consumer.createEffectiveModelContextFactory() + .createEffectiveModelContext(loadedSources).get(); + } catch (final InterruptedException | ExecutionException e) { + throw new IllegalStateException( + "Cannot parse schema context. Please read stack trace and check YANG files in schema directory.", e); } - final Set capabilities = Sets.newHashSet(); + final Set capabilities = new HashSet<>(); for (final Module module : schemaContext.getModules()) { - for (final Module subModule : module.getSubmodules()) { + for (final Submodule subModule : module.getSubmodules()) { addModuleCapability(consumer, capabilities, subModule); } addModuleCapability(consumer, capabilities, module); @@ -327,71 +348,47 @@ public class NetconfDeviceSimulator implements Closeable { return capabilities; } - private void addModuleCapability(final SharedSchemaRepository consumer, final Set capabilities, - final Module module) { - final SourceIdentifier moduleSourceIdentifier = SourceIdentifier.create(module.getName(), - (SimpleDateFormatUtil.DEFAULT_DATE_REV == module.getRevision() ? Optional.absent() : - Optional.of(module.getQNameModule().getFormattedRevision()))); + private static void addModuleCapability(final SharedSchemaRepository consumer, final Set capabilities, + final ModuleLike module) { + final var sourceId = new SourceIdentifier(module.getName(), + module.getRevision().map(Revision::toString).orElse(null)); + + final String moduleContent; try { - final String moduleContent = new String( - consumer.getSchemaSource(moduleSourceIdentifier, YangTextSchemaSource.class).checkedGet().read()); - capabilities.add(new YangModuleCapability(module, moduleContent)); - //IOException would be thrown in creating SchemaContext already - } catch (SchemaSourceException | IOException e) { - throw new RuntimeException("Cannot retrieve schema source for module " - + moduleSourceIdentifier.toString() + " from schema repository", e); + moduleContent = consumer.getSchemaSource(sourceId, YangTextSchemaSource.class).get() + .asCharSource(StandardCharsets.UTF_8).read(); + } catch (ExecutionException | InterruptedException | IOException e) { + throw new IllegalStateException( + "Cannot retrieve schema source for module " + sourceId + " from schema repository", e); } - } - - private void addDefaultSchemas(final SharedSchemaRepository consumer) { - SourceIdentifier srcId = RevisionSourceIdentifier.create("ietf-netconf-monitoring", "2010-10-04"); - registerSource(consumer, "/META-INF/yang/ietf-netconf-monitoring.yang", srcId); - - srcId = RevisionSourceIdentifier.create("ietf-netconf-monitoring-extension", "2013-12-10"); - registerSource(consumer, "/META-INF/yang/ietf-netconf-monitoring-extension.yang", srcId); - srcId = RevisionSourceIdentifier.create("ietf-yang-types", "2013-07-15"); - registerSource(consumer, "/META-INF/yang/ietf-yang-types@2013-07-15.yang", srcId); - - srcId = RevisionSourceIdentifier.create("ietf-inet-types", "2013-07-15"); - registerSource(consumer, "/META-INF/yang/ietf-inet-types@2013-07-15.yang", srcId); + capabilities.add(new YangModuleCapability(module, moduleContent)); } - private void registerSource(final SharedSchemaRepository consumer, final String resource, - final SourceIdentifier sourceId) { - consumer.registerSchemaSource(new SchemaSourceProvider() { - @Override - public CheckedFuture getSource( - final SourceIdentifier sourceIdentifier) { - return Futures.immediateCheckedFuture(new YangTextSchemaSource(sourceId) { - @Override - protected MoreObjects.ToStringHelper addToStringAttributes( - final MoreObjects.ToStringHelper toStringHelper) { - return toStringHelper; - } - - @Override - public InputStream openStream() throws IOException { - return getClass().getResourceAsStream(resource); - } - }); - } - }, PotentialSchemaSource.create( - sourceId, YangTextSchemaSource.class, PotentialSchemaSource.Costs.IMMEDIATE.getValue())); + private static void registerSource(final SharedSchemaRepository consumer, final String resource, + final SourceIdentifier sourceId) { + consumer.registerSchemaSource(sourceIdentifier -> Futures.immediateFuture( + YangTextSchemaSource.forResource(NetconfDeviceSimulator.class, resource)), + PotentialSchemaSource.create(sourceId, YangTextSchemaSource.class, + PotentialSchemaSource.Costs.IMMEDIATE.getValue())); } private static InetSocketAddress getAddress(final String ip, final int port) { try { return new InetSocketAddress(Inet4Address.getByName(ip), port); } catch (final UnknownHostException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException("Cannot resolve address " + ip, e); } } @Override public void close() { for (final SshProxyServer sshWrapper : sshWrappers) { - sshWrapper.close(); + try { + sshWrapper.close(); + } catch (final IOException e) { + LOG.debug("Wrapper {} failed to close", sshWrapper, e); + } } for (final Channel deviceCh : devicesChannels) { deviceCh.close(); @@ -399,6 +396,5 @@ public class NetconfDeviceSimulator implements Closeable { nettyThreadgroup.shutdownGracefully(); minaTimerExecutor.shutdownNow(); nioExecutor.shutdownNow(); - // close Everything } }