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