29afa93d373cb5e7a7b86c57b0f93b6cceeeb48e
[controller.git] / opendaylight / netconf / netconf-it / src / test / java / org / opendaylight / controller / netconf / it / NetconfConfigPersisterITTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.netconf.it;
9
10 import static junit.framework.Assert.assertEquals;
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Matchers.anyString;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.doNothing;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
17 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithName;
18 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertElementsCount;
19 import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToDocument;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.InetSocketAddress;
24 import java.util.Collection;
25 import java.util.List;
26 import java.util.Set;
27
28 import javax.management.InstanceNotFoundException;
29 import javax.management.Notification;
30 import javax.management.NotificationListener;
31
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.mockito.invocation.InvocationOnMock;
36 import org.mockito.stubbing.Answer;
37 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
38 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
39 import org.opendaylight.controller.config.persist.api.Persister;
40 import org.opendaylight.controller.config.spi.ModuleFactory;
41 import org.opendaylight.controller.netconf.api.NetconfMessage;
42 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
43 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
44 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
45 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
46 import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
47 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
48 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
49 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
50 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
51 import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
52 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
53 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl;
54 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
55 import org.opendaylight.controller.netconf.mapping.api.Capability;
56 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider;
57 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
58 import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
59 import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
60 import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
61 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
62 import org.w3c.dom.Document;
63 import org.w3c.dom.Element;
64 import org.xml.sax.SAXException;
65
66 import com.google.common.collect.Lists;
67 import com.google.common.collect.Sets;
68 import io.netty.channel.ChannelFuture;
69
70 public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
71
72     private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
73
74     private NetconfClientDispatcher clientDispatcher;
75     private DefaultCommitNotificationProducer commitNotifier;
76
77     @Before
78     public void setUp() throws Exception {
79         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,NetconfITTest.getModuleFactoriesS().toArray(
80                 new ModuleFactory[0])));
81
82         NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
83
84         NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
85         factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
86         factoriesListener
87                 .onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
88                         new NetconfMonitoringOperationService(monitoringService)));
89
90
91         commitNotifier = new DefaultCommitNotificationProducer(platformMBeanServer);
92         NetconfServerDispatcher dispatch = createDispatcher(factoriesListener, mockSessionMonitoringService(), commitNotifier);
93         ChannelFuture s = dispatch.createServer(tcpAddress);
94         s.await();
95
96         clientDispatcher = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
97     }
98
99     @After
100     public void cleanUp(){
101         commitNotifier.close();
102     }
103
104     private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
105         final Collection<InputStream> yangDependencies = NetconfITTest.getBasicYangs();
106         return new HardcodedYangStoreService(yangDependencies);
107     }
108
109
110     protected SessionMonitoringService mockSessionMonitoringService() {
111         SessionMonitoringService mockedSessionMonitor = mock(SessionMonitoringService.class);
112         doNothing().when(mockedSessionMonitor).onSessionUp(any(NetconfManagementSession.class));
113         doNothing().when(mockedSessionMonitor).onSessionDown(any(NetconfManagementSession.class));
114         return mockedSessionMonitor;
115     }
116
117
118
119     @Test
120     public void testNetconfCommitNotifications() throws Exception {
121
122         VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
123         VerifyingPersister mockedAggregator = mockAggregator();
124
125         try (TestingNetconfClient persisterClient = new TestingNetconfClient("persister", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) {
126             try (ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
127                     platformMBeanServer, mockedAggregator)) {
128
129
130                 try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) {
131                     NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
132                     assertContainsElementWithName(response.getDocument(), "modules");
133                     assertContainsElementWithName(response.getDocument(), "services");
134                     response = netconfClient.sendMessage(loadCommitMessage());
135                     assertContainsElementWithName(response.getDocument(), "ok");
136
137                     response = netconfClient.sendMessage(loadEditConfigMessage());
138                     assertContainsElementWithName(response.getDocument(), "ok");
139                     response = netconfClient.sendMessage(loadCommitMessage());
140                     assertContainsElementWithName(response.getDocument(), "ok");
141                 }
142             }
143         }
144
145         notificationVerifier.assertNotificationCount(2);
146         notificationVerifier.assertNotificationContent(0, 0, 0, 9);
147         notificationVerifier.assertNotificationContent(1, 4, 4, 9);
148
149         mockedAggregator.assertSnapshotCount(2);
150         // Capabilities are stripped for persister
151         mockedAggregator.assertSnapshotContent(0, 0, 0, 1);
152         mockedAggregator.assertSnapshotContent(1, 4, 4, 3);
153     }
154
155     private VerifyingPersister mockAggregator() throws IOException {
156         return new VerifyingPersister();
157     }
158
159     private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
160         VerifyingNotificationListener listener = new VerifyingNotificationListener();
161         platformMBeanServer.addNotificationListener(DefaultCommitNotificationProducer.OBJECT_NAME, listener, null, null);
162         return listener;
163     }
164
165     private NetconfMessage loadGetConfigMessage() throws Exception {
166         return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
167     }
168
169     private NetconfMessage loadEditConfigMessage() throws Exception {
170         return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig.xml");
171     }
172
173     private NetconfMessage loadCommitMessage() throws Exception {
174         return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
175     }
176
177
178     public NetconfOperationProvider getNetconfOperationProvider() {
179         NetconfOperationProvider factoriesListener = mock(NetconfOperationProvider.class);
180         NetconfOperationServiceSnapshotImpl snap = mock(NetconfOperationServiceSnapshotImpl.class);
181         NetconfOperationService service = mock(NetconfOperationService.class);
182         Set<Capability> caps = Sets.newHashSet();
183         doReturn(caps).when(service).getCapabilities();
184         Set<NetconfOperationService> services = Sets.newHashSet(service);
185         doReturn(services).when(snap).getServices();
186         doReturn(snap).when(factoriesListener).openSnapshot(anyString());
187
188         return factoriesListener;
189     }
190
191     private static class VerifyingNotificationListener implements NotificationListener {
192         public List<Notification> notifications = Lists.newArrayList();
193
194         @Override
195         public void handleNotification(Notification notification, Object handback) {
196             this.notifications.add(notification);
197         }
198
199         void assertNotificationCount(Object size) {
200             assertEquals(size, notifications.size());
201         }
202
203         void assertNotificationContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
204             Notification notification = notifications.get(notificationIndex);
205             assertEquals(CommitJMXNotification.class, notification.getClass());
206             int capsSize = ((CommitJMXNotification) notification).getCapabilities().size();
207             assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
208             Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot();
209             int modulesSize = configSnapshot.getElementsByTagName("module").getLength();
210             assertEquals("Expected modules count", expectedModulesSize, modulesSize);
211             int servicesSize = configSnapshot.getElementsByTagName("instance").getLength();
212             assertEquals("Expected services count", expectedServicesSize, servicesSize);
213         }
214     }
215
216     private static class VerifyingPersister implements Persister {
217
218         public List<ConfigSnapshotHolder> snapshots = Lists.newArrayList();
219         private Persister mockedPersister;
220
221         public VerifyingPersister() throws IOException {
222             Persister mockedAggregator = mock(Persister.class);
223
224             doAnswer(new Answer<Object>() {
225                 @Override
226                 public Object answer(InvocationOnMock invocation) throws Throwable {
227                     ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0];
228                     snapshots.add(configSnapshot);
229                     return null;
230                 }
231             }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class));
232
233             this.mockedPersister = mockedAggregator;
234         }
235
236         void assertSnapshotCount(Object size) {
237             assertEquals(size, snapshots.size());
238         }
239
240         void assertSnapshotContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize)
241                 throws SAXException, IOException {
242             ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
243             int capsSize = snapshot.getCapabilities().size();
244             assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
245             Document configSnapshot = readXmlToDocument(snapshot.getConfigSnapshot());
246             assertElementsCount(configSnapshot, "module", expectedModulesSize);
247             assertElementsCount(configSnapshot, "instance", expectedServicesSize);
248         }
249
250         @Override
251         public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException {
252             mockedPersister.persistConfig(configSnapshotHolder);
253         }
254
255         @Override
256         public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
257             return mockedPersister.loadLastConfigs();
258         }
259
260         @Override
261         public void close() {
262             mockedPersister.close();
263         }
264     }
265 }