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=a5e774265d3924869b2342ce82848729abe0aa71;hb=9ea4622349b8f1e149e9d8339334c450607e3f48;hp=b74f5f52b0e71b565cf43dab5006af311e395f43;hpb=df283f75ef7de5ed90e47bf03c2f0c7183d11b0f;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 b74f5f52b0..a5e774265d 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,16 +5,13 @@ * 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.ToStringHelper; +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.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; @@ -22,12 +19,14 @@ 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.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; @@ -35,18 +34,19 @@ 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.keyprovider.KeyPairProvider; -import org.apache.sshd.common.util.threads.ThreadUtils; 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.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.monitoring.NetconfMonitoringService; +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; @@ -59,51 +59,49 @@ 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.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.rfc7950.repo.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(final Configuration configuration) { this.configuration = configuration; - this.nettyThreadgroup = new NioEventLoopGroup(); - this.hashedWheelTimer = new HashedWheelTimer(); - this.minaTimerExecutor = Executors.newScheduledThreadPool(configuration.getThreadPoolSize(), + nettyThreadgroup = new NioEventLoopGroup(); + hashedWheelTimer = new HashedWheelTimer(); + minaTimerExecutor = Executors.newScheduledThreadPool(configuration.getThreadPoolSize(), new ThreadFactoryBuilder().setNameFormat("netconf-ssh-server-mina-timers-%d").build()); - this.nioExecutor = ThreadUtils - .newFixedThreadPool("netconf-ssh-server-nio-group", configuration.getThreadPoolSize()); + nioExecutor = ThreadUtils.newFixedThreadPool("netconf-ssh-server-nio-group", configuration.getThreadPoolSize()); } 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); @@ -113,7 +111,7 @@ 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, transformedCapabilities, monitoringService1, idProvider); @@ -147,14 +145,18 @@ public class NetconfDeviceSimulator implements Closeable { 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.ofNullable(configuration.getNotificationFile()), + Optional.empty()); } else { LOG.info("using OperationsProvider."); operationProvider = new OperationsProvider(idProvider, transformedCapabilities, - configuration.getOperationsCreator() != null ? configuration.getOperationsCreator() - : DefaultOperationsCreator.getDefaultOperationServiceCreator(idProvider.getCurrentSessionId())); + requireNonNullElseGet(configuration.getOperationsCreator(), + () -> new DefaultOperationsCreator(idProvider.getCurrentSessionId()))); } - final NetconfMonitoringOperationServiceFactory monitoringService = new NetconfMonitoringOperationServiceFactory( new NetconfMonitoringOperationService(monitoringService1)); @@ -173,8 +175,9 @@ public class NetconfDeviceSimulator implements Closeable { } public List start() { + final var proto = configuration.isSsh() ? "SSH" : "TCP"; LOG.info("Starting {}, {} simulated devices starting on port {}", - configuration.getDeviceCount(), configuration.isSsh() ? "SSH" : "TCP", configuration.getStartingPort()); + configuration.getDeviceCount(), proto, configuration.getStartingPort()); final SharedSchemaRepository schemaRepo = new SharedSchemaRepository("netconf-simulator"); final Set capabilities = parseSchemasToModuleCapabilities(schemaRepo); @@ -184,7 +187,7 @@ 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 KeyPairProvider keyPairProvider = new VirtualKeyPairProvider(); @@ -232,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; @@ -247,7 +250,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 tcp simulated device on {}, skipping", address, e); continue; @@ -285,8 +288,8 @@ public class NetconfDeviceSimulator implements Closeable { } 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) { @@ -321,23 +324,23 @@ public class NetconfDeviceSimulator implements Closeable { } configuration.getDefaultYangResources().forEach(r -> { - final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create(r.getModuleName(), - Revision.ofNullable(r.getRevision())); + 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.createEffectiveModelContextFactory() + schemaContext = consumer.createEffectiveModelContextFactory() .createEffectiveModelContext(loadedSources).get(); } catch (final InterruptedException | ExecutionException e) { - throw new RuntimeException("Cannot parse schema context", 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); @@ -346,41 +349,35 @@ public class NetconfDeviceSimulator implements Closeable { } private static void addModuleCapability(final SharedSchemaRepository consumer, final Set capabilities, - final Module module) { - final SourceIdentifier moduleSourceIdentifier = RevisionSourceIdentifier.create(module.getName(), - module.getRevision()); + 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).get().read()); - capabilities.add(new YangModuleCapability(module, moduleContent)); - //IOException would be thrown in creating SchemaContext already - } catch (final ExecutionException | InterruptedException | 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); } + + capabilities.add(new YangModuleCapability(module, moduleContent)); } private static void registerSource(final SharedSchemaRepository consumer, final String resource, - final SourceIdentifier sourceId) { - consumer.registerSchemaSource(sourceIdentifier -> Futures.immediateFuture(new YangTextSchemaSource(sourceId) { - @Override - protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) { - return toStringHelper; - } - - @Override - public InputStream openStream() { - return getClass().getResourceAsStream(resource); - } - }), PotentialSchemaSource.create(sourceId, YangTextSchemaSource.class, - PotentialSchemaSource.Costs.IMMEDIATE.getValue())); + 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); } } @@ -400,5 +397,4 @@ public class NetconfDeviceSimulator implements Closeable { minaTimerExecutor.shutdownNow(); nioExecutor.shutdownNow(); } - }