2 * Copyright (c) 2013 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.controller.netconf.it;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Matchers.anySetOf;
14 import static org.mockito.Matchers.anyString;
15 import static org.mockito.Mockito.doNothing;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.mock;
19 import io.netty.channel.Channel;
20 import io.netty.channel.ChannelFuture;
21 import io.netty.channel.EventLoopGroup;
22 import io.netty.channel.local.LocalAddress;
23 import io.netty.channel.nio.NioEventLoopGroup;
24 import io.netty.util.HashedWheelTimer;
25 import io.netty.util.concurrent.GlobalEventExecutor;
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.net.InetSocketAddress;
30 import java.net.SocketAddress;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.concurrent.TimeUnit;
38 import org.apache.commons.io.IOUtils;
39 import org.junit.After;
40 import org.junit.Before;
41 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
42 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
43 import org.opendaylight.controller.config.spi.ModuleFactory;
44 import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
45 import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFactory;
46 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
47 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
48 import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
49 import org.opendaylight.controller.netconf.api.NetconfMessage;
50 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
51 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
52 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
53 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
54 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
55 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
56 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
57 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreServiceImpl;
58 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
59 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
60 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
61 import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
62 import org.opendaylight.controller.netconf.impl.SessionIdProvider;
63 import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
64 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
65 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl;
66 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
67 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider;
68 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
69 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
70 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
71 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
72 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
73 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
74 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
75 import org.w3c.dom.Element;
77 public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
79 public static final String LOOPBACK_ADDRESS = "127.0.0.1";
80 public static final int SERVER_CONNECTION_TIMEOUT_MILLIS = 5000;
81 private static final int RESOURCE_TIMEOUT_MINUTES = 2;
83 static ModuleFactory[] FACTORIES = {new TestImplModuleFactory(),
84 new DepTestImplModuleFactory(),
85 new NetconfTestImplModuleFactory(),
86 new IdentityTestModuleFactory(),
87 new MultipleDependenciesModuleFactory() };
89 private EventLoopGroup nettyThreadgroup;
90 private HashedWheelTimer hashedWheelTimer;
92 private NetconfClientDispatcherImpl clientDispatcher;
93 private Channel serverTcpChannel;
95 private NetconfMessage getConfig;
96 private NetconfMessage get;
99 * @Before in subclasses is called after this method.
102 public void setUpAbstractNetconfConfigTest() throws Exception {
103 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, FACTORIES));
105 nettyThreadgroup = new NioEventLoopGroup();
106 hashedWheelTimer = new HashedWheelTimer();
112 final NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
113 factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
115 for (final NetconfOperationServiceFactory netconfOperationServiceFactory : getAdditionalServiceFactories()) {
116 factoriesListener.onAddNetconfOperationServiceFactory(netconfOperationServiceFactory);
119 serverTcpChannel = startNetconfTcpServer(factoriesListener);
120 clientDispatcher = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
124 * Called before setUp method is executed, so test classes can set up resources before setUpAbstractNetconfConfigTest method is called.
126 protected void setUpTestInitial() throws Exception {}
128 private void loadMessages() throws Exception {
129 this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
130 this.get = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml");
133 public NetconfMessage getGetConfig() {
137 public NetconfMessage getGet() {
141 private Channel startNetconfTcpServer(final NetconfOperationServiceFactoryListenerImpl factoriesListener) throws Exception {
142 final NetconfServerDispatcher dispatch = createDispatcher(factoriesListener, getNetconfMonitoringService(), getNotificationProducer());
144 final ChannelFuture s;
145 if(getTcpServerAddress() instanceof LocalAddress) {
146 s = dispatch.createLocalServer(((LocalAddress) getTcpServerAddress()));
148 s = dispatch.createServer(((InetSocketAddress) getTcpServerAddress()));
150 s.await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
154 protected DefaultCommitNotificationProducer getNotificationProducer() {
155 final DefaultCommitNotificationProducer notificationProducer = mock(DefaultCommitNotificationProducer.class);
156 doNothing().when(notificationProducer).close();
157 doNothing().when(notificationProducer).sendCommitNotification(anyString(), any(Element.class), anySetOf(String.class));
158 return notificationProducer;
161 protected Iterable<NetconfOperationServiceFactory> getAdditionalServiceFactories() {
162 return Collections.emptySet();
165 protected SessionMonitoringService getNetconfMonitoringService() throws Exception {
166 final NetconfOperationProvider netconfOperationProvider = mock(NetconfOperationProvider.class);
167 final NetconfOperationServiceSnapshotImpl snap = mock(NetconfOperationServiceSnapshotImpl.class);
168 doReturn(Collections.<NetconfOperationService>emptySet()).when(snap).getServices();
169 doReturn(snap).when(netconfOperationProvider).openSnapshot(anyString());
170 return new NetconfMonitoringServiceImpl(netconfOperationProvider);
173 protected abstract SocketAddress getTcpServerAddress();
175 public NetconfClientDispatcherImpl getClientDispatcher() {
176 return clientDispatcher;
179 private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
180 final Collection<InputStream> yangDependencies = getBasicYangs();
181 return new HardcodedYangStoreService(yangDependencies);
184 static Collection<InputStream> getBasicYangs() throws IOException {
186 final List<String> paths = Arrays.asList(
187 "/META-INF/yang/config.yang",
188 "/META-INF/yang/rpc-context.yang",
189 "/META-INF/yang/config-test.yang",
190 "/META-INF/yang/config-test-impl.yang",
191 "/META-INF/yang/test-types.yang",
192 "/META-INF/yang/test-groups.yang",
193 "/META-INF/yang/ietf-inet-types.yang");
195 final Collection<InputStream> yangDependencies = new ArrayList<>();
196 final List<String> failedToFind = new ArrayList<>();
197 for (final String path : paths) {
198 final InputStream resourceAsStream = NetconfITTest.class.getResourceAsStream(path);
199 if (resourceAsStream == null) {
200 failedToFind.add(path);
202 yangDependencies.add(resourceAsStream);
205 assertEquals("Some yang files were not found", Collections.<String>emptyList(), failedToFind);
206 return yangDependencies;
209 protected NetconfServerDispatcher createDispatcher(
210 final NetconfOperationServiceFactoryListenerImpl factoriesListener, final SessionMonitoringService sessionMonitoringService,
211 final DefaultCommitNotificationProducer commitNotifier) {
212 final SessionIdProvider idProvider = new SessionIdProvider();
214 final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
215 hashedWheelTimer, factoriesListener, idProvider, SERVER_CONNECTION_TIMEOUT_MILLIS, commitNotifier, sessionMonitoringService);
217 final NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
218 serverNegotiatorFactory);
219 return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
222 protected HashedWheelTimer getHashedWheelTimer() {
223 return hashedWheelTimer;
226 protected EventLoopGroup getNettyThreadgroup() {
227 return nettyThreadgroup;
231 * @After in subclasses is be called before this.
234 public void cleanUpNetconf() throws Exception {
235 serverTcpChannel.close().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
236 hashedWheelTimer.stop();
237 nettyThreadgroup.shutdownGracefully().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
240 public NetconfClientConfiguration getClientConfiguration(final InetSocketAddress tcpAddress, final int timeout) {
241 final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
242 b.withAddress(tcpAddress);
243 b.withSessionListener(new SimpleNetconfClientSessionListener());
244 b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, timeout));
245 b.withConnectionTimeoutMillis(timeout);
249 public static final class HardcodedYangStoreService implements YangStoreService {
251 private final List<InputStream> byteArrayInputStreams;
253 public HardcodedYangStoreService(final Collection<? extends InputStream> inputStreams) throws YangStoreException, IOException {
254 byteArrayInputStreams = new ArrayList<>();
255 for (final InputStream inputStream : inputStreams) {
256 assertNotNull(inputStream);
257 final byte[] content = IOUtils.toByteArray(inputStream);
258 final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
259 byteArrayInputStreams.add(byteArrayInputStream);
264 public YangStoreSnapshot getYangStoreSnapshot() throws YangStoreException {
265 for (final InputStream inputStream : byteArrayInputStreams) {
268 } catch (final IOException e) {
269 throw new RuntimeException(e);
273 final YangParserImpl yangParser = new YangParserImpl();
274 final SchemaContext schemaContext = yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(byteArrayInputStreams).values()));
275 final YangStoreServiceImpl yangStoreService = new YangStoreServiceImpl(new SchemaContextProvider() {
277 public SchemaContext getSchemaContext() {
278 return schemaContext ;
281 return yangStoreService.getYangStoreSnapshot();