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=3cb2e19222e530ca1976f9d00bbc1b5552e191ff;hb=8ccc23cd635ba39306fab956f2ba599b7922281e;hp=bbf8af73dba4d8e134799644a732e4223345c33e;hpb=083981362c3424cefa6752595fce82576ba43eb2;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 bbf8af73db..3cb2e19222 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,17 +5,12 @@ * 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 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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.local.LocalAddress; @@ -23,76 +18,78 @@ 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.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.impl.NetconfServerDispatcherImpl; import org.opendaylight.netconf.impl.NetconfServerSessionNegotiatorFactory; +import org.opendaylight.netconf.impl.ServerChannelInitializer; 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.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.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.SimpleDateFormatUtil; +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.api.ModuleLike; +import org.opendaylight.yangtools.yang.model.api.Submodule; 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.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; +@SuppressFBWarnings("DM_DEFAULT_ENCODING") 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 final Configuration configuration; - private SchemaContext schemaContext; + private EffectiveModelContext schemaContext; private boolean sendFakeSchema = false; - public NetconfDeviceSimulator(Configuration configuration) { + public NetconfDeviceSimulator(final Configuration configuration) { this.configuration = configuration; this.nettyThreadgroup = new NioEventLoopGroup(); this.hashedWheelTimer = new HashedWheelTimer(); @@ -105,7 +102,7 @@ public class NetconfDeviceSimulator implements Closeable { private NetconfServerDispatcherImpl createDispatcher(final Set capabilities, 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); @@ -127,8 +124,8 @@ public class NetconfDeviceSimulator implements Closeable { configuration.getGenerateConfigsTimeout(), monitoringService1, serverCapabilities); - final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = - new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory); + final ServerChannelInitializer serverChannelInitializer = + new ServerChannelInitializer(serverNegotiatorFactory); return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup); } @@ -147,8 +144,8 @@ public class NetconfDeviceSimulator implements Closeable { } else if (configuration.isXmlConfigurationProvided()) { LOG.info("using SimulatedOperationProvider."); operationProvider = new SimulatedOperationProvider(idProvider, transformedCapabilities, - Optional.fromNullable(configuration.getNotificationFile()), - Optional.fromNullable(configuration.getInitialConfigXMLFile())); + Optional.ofNullable(configuration.getNotificationFile()), + Optional.ofNullable(configuration.getInitialConfigXMLFile())); } else { LOG.info("using OperationsProvider."); operationProvider = new OperationsProvider(idProvider, transformedCapabilities, @@ -157,8 +154,8 @@ public class NetconfDeviceSimulator implements Closeable { } - final NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory monitoringService = - new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory( + final NetconfMonitoringOperationServiceFactory monitoringService = + new NetconfMonitoringOperationServiceFactory( new NetconfMonitoringOperationService(monitoringService1)); aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(operationProvider); aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(monitoringService); @@ -186,10 +183,17 @@ public class NetconfDeviceSimulator implements Closeable { 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 < configuration.getDeviceCount(); i++) { if (currentPort > 65535) { @@ -206,7 +210,7 @@ public class NetconfDeviceSimulator implements Closeable { 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) { @@ -248,7 +252,7 @@ public class NetconfDeviceSimulator implements Closeable { continue; } - LOG.debug("Simulated TCP device started on {}", address); + LOG.debug("Simulated TCP device started on {}", server.channel().localAddress()); } devicesChannels.add(server.channel()); @@ -268,36 +272,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) - .setPublickeyAuthenticator(((username, key, session) -> { - LOG.info("Auth with public key: {}", key); - return 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 SharedSchemaRepository consumer) { - final Set loadedSources = Sets.newHashSet(); - consumer.registerSchemaSourceListener(TextToASTTransformer.create(consumer, 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) { @@ -307,7 +300,9 @@ public class NetconfDeviceSimulator implements Closeable { } @Override - public void schemaSourceUnregistered(final PotentialSchemaSource potentialSchemaSource) {} + public void schemaSourceUnregistered(final PotentialSchemaSource potentialSchemaSource) { + + } }); if (configuration.getSchemasDir() != null) { @@ -324,21 +319,24 @@ public class NetconfDeviceSimulator implements Closeable { LOG.info("Custom module loading skipped."); } - addDefaultSchemas(consumer); + configuration.getDefaultYangResources().forEach(r -> { + final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create(r.getModuleName(), + Revision.ofNullable(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) { + this.schemaContext = consumer.createEffectiveModelContextFactory() + .createEffectiveModelContext(loadedSources).get(); + } catch (final InterruptedException | ExecutionException e) { throw new RuntimeException("Cannot parse schema context", 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); @@ -346,57 +344,27 @@ 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 SourceIdentifier moduleSourceIdentifier = RevisionSourceIdentifier.create(module.getName(), + module.getRevision()); try { final String moduleContent = new String( - consumer.getSchemaSource(moduleSourceIdentifier, YangTextSchemaSource.class).checkedGet().read()); + consumer.getSchemaSource(moduleSourceIdentifier, YangTextSchemaSource.class).get().read()); capabilities.add(new YangModuleCapability(module, moduleContent)); //IOException would be thrown in creating SchemaContext already - } catch (SchemaSourceException | IOException e) { + } catch (final ExecutionException | InterruptedException | IOException e) { throw new RuntimeException("Cannot retrieve schema source for module " + moduleSourceIdentifier.toString() + " 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); - } - - 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) { @@ -410,7 +378,11 @@ public class NetconfDeviceSimulator implements Closeable { @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();