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