X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-it%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fit%2FNetconfITTest.java;h=c61dab7f643ebd119544cb12d76c0b420435d6af;hb=03abf047ba966c53f4901d36ae5198156d66dc05;hp=d7f96a876148299d5a09ab765de1e558fbf8cb8e;hpb=448dfd40cfe9279abc9bf7de27a3c25caed3547b;p=controller.git diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index d7f96a8761..c61dab7f64 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -8,91 +8,102 @@ package org.opendaylight.controller.netconf.it; +import static java.util.Collections.emptyList; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; +import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.internal.util.Checks.checkNotNull; import io.netty.channel.ChannelFuture; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; import java.io.IOException; import java.io.InputStream; import java.lang.management.ManagementFactory; import java.net.InetSocketAddress; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.management.ObjectName; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; import javax.xml.parsers.ParserConfigurationException; +import junit.framework.Assert; + import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.opendaylight.controller.config.api.ModuleIdentifier; import org.opendaylight.controller.config.manager.impl.AbstractConfigTest; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; -import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator; -import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegistratorImpl; -import org.opendaylight.controller.config.persist.api.Persister; import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.opendaylight.controller.config.yang.store.api.YangStoreException; import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService; -import org.opendaylight.controller.config.yang.test.impl.Asdf; import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory; import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory; import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean; -import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplRuntimeMXBean; -import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplRuntimeRegistrator; import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.client.NetconfClient; +import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory; import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory; import org.opendaylight.controller.netconf.impl.SessionIdProvider; +import org.opendaylight.controller.netconf.impl.mapping.ExiDecoderHandler; +import org.opendaylight.controller.netconf.impl.mapping.ExiEncoderHandler; +import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; -import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.controller.netconf.ssh.NetconfSSHServer; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; +import org.opendaylight.controller.netconf.util.xml.ExiParameters; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.opendaylight.protocol.util.SSLUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; -import com.google.common.base.Optional; +import ch.ethz.ssh2.Connection; +import ch.ethz.ssh2.Session; + import com.google.common.collect.Lists; import com.google.common.collect.Sets; public class NetconfITTest extends AbstractConfigTest { - // private static final Logger logger = - // LoggerFactory.getLogger(NetconfITTest.class); - // + // TODO refactor, pull common code up to AbstractNetconfITTest + + private static final Logger logger = LoggerFactory.getLogger(NetconfITTest.class); + private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023); - private static final InetSocketAddress tlsAddress = new InetSocketAddress("127.0.0.1", 12024); + private static final InetSocketAddress sshAddress = new InetSocketAddress("127.0.0.1", 10830); + private static final String USERNAME = "netconf"; + private static final String PASSWORD = "netconf"; - private NetconfMessage getConfig, getConfigCandidate, editConfig, closeSession; + private NetconfMessage getConfig, getConfigCandidate, editConfig, + closeSession, startExi, stopExi; private DefaultCommitNotificationProducer commitNot; - private NetconfServerDispatcher dispatch, dispatchS; + private NetconfServerDispatcher dispatch; + private EventLoopGroup nettyThreadgroup; + + private NetconfClientDispatcher clientDispatcher; @Before public void setUp() throws Exception { @@ -104,50 +115,53 @@ public class NetconfITTest extends AbstractConfigTest { NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore())); + nettyThreadgroup = new NioEventLoopGroup(); + commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer()); - dispatch = createDispatcher(Optional. absent(), factoriesListener); + dispatch = createDispatcher(factoriesListener); ChannelFuture s = dispatch.createServer(tcpAddress); s.await(); - dispatchS = createDispatcher(Optional.of(getSslContext()), factoriesListener); - s = dispatchS.createServer(tlsAddress); - s.await(); + clientDispatcher = new NetconfClientDispatcher( nettyThreadgroup, nettyThreadgroup); } - private NetconfServerDispatcher createDispatcher(Optional sslC, - NetconfOperationServiceFactoryListenerImpl factoriesListener) { + private NetconfServerDispatcher createDispatcher(NetconfOperationServiceFactoryListenerImpl factoriesListener) { SessionIdProvider idProvider = new SessionIdProvider(); NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider); NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory( - factoriesListener, commitNot, idProvider); + factoriesListener, commitNot, idProvider, getNetconfMonitoringListenerService()); + + NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer( + serverNegotiatorFactory, listenerFactory); + return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup); + } - return new NetconfServerDispatcher(sslC, serverNegotiatorFactory, listenerFactory); + static NetconfMonitoringServiceImpl getNetconfMonitoringListenerService() { + NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class); + NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class); + doReturn(Collections.emptySet()).when(snap).getServices(); + doReturn(snap).when(factoriesListener).getSnapshot(anyLong()); + return new NetconfMonitoringServiceImpl(factoriesListener); } @After public void tearDown() throws Exception { commitNot.close(); - dispatch.close(); - dispatchS.close(); - } - - private SSLContext getSslContext() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, - IOException, UnrecoverableKeyException, KeyManagementException { - final InputStream keyStore = getClass().getResourceAsStream("/keystore.jks"); - final InputStream trustStore = getClass().getResourceAsStream("/keystore.jks"); - SSLContext sslContext = SSLUtil.initializeSecureContext("password", keyStore, trustStore, KeyManagerFactory.getDefaultAlgorithm()); - keyStore.close(); - trustStore.close(); - return sslContext; + nettyThreadgroup.shutdownGracefully(); + clientDispatcher.close(); } private void loadMessages() throws IOException, SAXException, ParserConfigurationException { this.editConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/edit_config.xml"); this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml"); this.getConfigCandidate = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig_candidate.xml"); + this.startExi = XmlFileLoader + .xmlFileToNetconfMessage("netconfMessages/startExi.xml"); + this.stopExi = XmlFileLoader + .xmlFileToNetconfMessage("netconfMessages/stopExi.xml"); this.closeSession = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/closeSession.xml"); } @@ -156,49 +170,67 @@ public class NetconfITTest extends AbstractConfigTest { return new HardcodedYangStoreService(yangDependencies); } - private Collection getBasicYangs() throws IOException { + static Collection getBasicYangs() throws IOException { List paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang", - "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang", + "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang", "/META-INF/yang/test-types.yang", "/META-INF/yang/ietf-inet-types.yang"); final Collection yangDependencies = new ArrayList<>(); + List failedToFind = new ArrayList<>(); for (String path : paths) { - final InputStream is = checkNotNull(getClass().getResourceAsStream(path), path + " not found"); - yangDependencies.add(is); + InputStream resourceAsStream = NetconfITTest.class.getResourceAsStream(path); + if (resourceAsStream == null) { + failedToFind.add(path); + } else { + yangDependencies.add(resourceAsStream); + } } + assertEquals("Some yang files were not found",emptyList(), failedToFind); return yangDependencies; } protected List getModuleFactories() { return getModuleFactoriesS(); } - static List getModuleFactoriesS() { return Lists.newArrayList(new TestImplModuleFactory(), new DepTestImplModuleFactory(), new NetconfTestImplModuleFactory()); } + @Test + public void testNetconfClientDemonstration() throws Exception { + try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) { + + Set capabilitiesFromNetconfServer = netconfClient.getCapabilities(); + long sessionId = netconfClient.getSessionId(); + + // NetconfMessage can be created : + // new NetconfMessage(XmlUtil.readXmlToDocument("")); + + NetconfMessage response = netconfClient.sendMessage(getConfig); + response.getDocument(); + } + } + @Test public void testTwoSessions() throws Exception { - try (NetconfClient netconfClient = new NetconfClient("1", tcpAddress, 4000)) { - try (NetconfClient netconfClient2 = new NetconfClient("2", tcpAddress, 4000)) { + try (NetconfClient netconfClient = new NetconfClient("1", tcpAddress, 10000, clientDispatcher)) { + try (NetconfClient netconfClient2 = new NetconfClient("2", tcpAddress, 10000, clientDispatcher)) { } } } + + //TODO: test persister actually + @Ignore @Test(timeout = 10000) public void testPersister() throws Exception { - Persister persister = mock(Persister.class); - doReturn("mockPersister").when(persister).toString(); - doReturn(Optional.absent()).when(persister).loadLastConfig(); - ConfigPersisterNotificationHandler h = new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer()); - h.init(); - } - - @Test - public void testSecure() throws Exception { - try (NetconfClient netconfClient = new NetconfClient("1", tlsAddress, 4000, Optional.of(getSslContext()))) { - - } +// Persister persister = mock(Persister.class); +// doReturn("mockPersister").when(persister).toString(); +// doReturn(Collections.emptyList()).when(persister).loadLastConfigs(); +// ConfigPersisterNotificationHandler h = +// new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer(), +// Pattern.compile(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX)); +// h.init(); } @Ignore @@ -260,7 +292,7 @@ public class NetconfITTest extends AbstractConfigTest { NetconfTestImplModuleMXBean proxy = configRegistryClient .newMXBeanProxy(impl, NetconfTestImplModuleMXBean.class); proxy.setTestingDep(dep); - registerRuntimeBean(); + proxy.setSimpleShort((short)0); transaction.commit(); @@ -271,7 +303,7 @@ public class NetconfITTest extends AbstractConfigTest { + " " - + "/data/modules/module[name='impl-netconf']/instance[name='instance']" + + "/modules/module[type='impl-netconf'][name='instance']" + "argument1" + "" + ""; final Document doc = XmlUtil.readXmlToDocument(rpc); final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc)); @@ -279,32 +311,37 @@ public class NetconfITTest extends AbstractConfigTest { final Element rpcReply = message.getDocument().getDocumentElement(); final XmlElement resultElement = XmlElement.fromDomElement(rpcReply).getOnlyChildElement(); assertEquals("result", resultElement.getName()); + final String namespace = resultElement.getNamespaceAttribute(); assertEquals(expectedNamespace, namespace); } } - private void registerRuntimeBean() { - BaseJMXRegistrator baseJMXRegistrator = new BaseJMXRegistrator(ManagementFactory.getPlatformMBeanServer()); - RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = baseJMXRegistrator - .createRuntimeBeanRegistrator(new ModuleIdentifier(NetconfTestImplModuleFactory.NAME, "instance")); - NetconfTestImplRuntimeRegistrator reg = new NetconfTestImplRuntimeRegistrator(runtimeBeanRegistrator); - reg.register(new NetconfTestImplRuntimeMXBean() { - @Override - public Asdf getAsdf() { - return null; - } + @Test +// @Ignore + public void testStartExi() throws Exception { + try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { - @Override - public Long getCreatedSessions() { - return null; - } - @Override - public String noArg(String arg1) { - return "from no arg"; - } - }); + Document rpcReply = netconfClient.sendMessage(this.startExi) + .getDocument(); + assertIsOK(rpcReply); + + ExiParameters exiParams = new ExiParameters(); + exiParams.setParametersFromXmlElement(XmlElement.fromDomDocument(this.startExi.getDocument())); + + netconfClient.getClientSession().addExiDecoder(ExiDecoderHandler.HANDLER_NAME, new ExiDecoderHandler(exiParams)); + netconfClient.getClientSession().addExiEncoder(ExiEncoderHandler.HANDLER_NAME, new ExiEncoderHandler(exiParams)); + + rpcReply = netconfClient.sendMessage(this.editConfig) + .getDocument(); + assertIsOK(rpcReply); + + rpcReply = netconfClient.sendMessage(this.stopExi) + .getDocument(); + assertIsOK(rpcReply); + + } } @Test @@ -312,10 +349,12 @@ public class NetconfITTest extends AbstractConfigTest { try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { // edit config - Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument(); + Document rpcReply = netconfClient.sendMessage(this.editConfig) + .getDocument(); assertIsOK(rpcReply); - rpcReply = netconfClient.sendMessage(this.closeSession).getDocument(); + rpcReply = netconfClient.sendMessage(this.closeSession) + .getDocument(); assertIsOK(rpcReply); } @@ -345,27 +384,10 @@ public class NetconfITTest extends AbstractConfigTest { } private void assertIsOK(final Document rpcReply) { - assertEquals("rpc-reply", rpcReply.getDocumentElement().getTagName()); + assertEquals("rpc-reply", rpcReply.getDocumentElement().getLocalName()); assertEquals("ok", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName()); } - @Ignore - @Test - // TODO can only send NetconfMessage - it must be valid xml - public void testClientHelloWithAuth() throws Exception { - final String fileName = "netconfMessages/client_hello_with_auth.xml"; - // final InputStream resourceAsStream = - // AbstractListenerTest.class.getResourceAsStream(fileName); - // assertNotNull(resourceAsStream); - try (NetconfClient netconfClient = new NetconfClient("test", tcpAddress, 5000)) { - // IOUtils.copy(resourceAsStream, netconfClient.getStream()); - // netconfClient.getOutputStream().write(NetconfMessageFactory.endOfMessage); - // server should not write anything back - // assertEquals(null, netconfClient.readMessage()); - assertGetConfigWorks(netconfClient); - } - } - private Document assertGetConfigWorks(final NetconfClient netconfClient) throws InterruptedException { return assertGetConfigWorks(netconfClient, this.getConfig); } @@ -406,11 +428,51 @@ public class NetconfITTest extends AbstractConfigTest { } private NetconfClient createSession(final InetSocketAddress address, final String expected) throws Exception { - final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000); - + final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000, clientDispatcher); assertEquals(expected, Long.toString(netconfClient.getSessionId())); - return netconfClient; } + private void startSSHServer() throws Exception{ + logger.info("Creating SSH server"); + Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress)); + sshServerThread.setDaemon(true); + sshServerThread.start(); + logger.info("SSH server on"); + } + + @Test + public void sshTest() throws Exception { + startSSHServer(); + logger.info("creating connection"); + Connection conn = new Connection(sshAddress.getHostName(),sshAddress.getPort()); + Assert.assertNotNull(conn); + logger.info("connection created"); + conn.connect(); + boolean isAuthenticated = conn.authenticateWithPassword(USERNAME,PASSWORD); + assertTrue(isAuthenticated); + logger.info("user authenticated"); + final Session sess = conn.openSession(); + sess.startSubSystem("netconf"); + logger.info("user authenticated"); + sess.getStdin().write(XmlUtil.toString(this.getConfig.getDocument()).getBytes()); + + new Thread(){ + public void run(){ + while (true){ + byte[] bytes = new byte[1024]; + int c = 0; + try { + c = sess.getStdout().read(bytes); + } catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + logger.info("got data:"+bytes); + if (c == 0) break; + } + } + }.join(); + } + + }