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

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.