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 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.confignetconfconnector.osgi.YangStoreException;
26 import org.opendaylight.controller.netconf.api.NetconfMessage;
27 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
28 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
29 import org.opendaylight.controller.netconf.client.NetconfClient;
30 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
31 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
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.impl.osgi.NetconfOperationServiceFactoryListener;
36 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
37 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
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;
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;
57 import java.util.regex.Pattern;
59 import static junit.framework.Assert.assertEquals;
60 import static org.mockito.Matchers.any;
61 import static org.mockito.Matchers.anyLong;
62 import static org.mockito.Mockito.doAnswer;
63 import static org.mockito.Mockito.doNothing;
64 import static org.mockito.Mockito.doReturn;
65 import static org.mockito.Mockito.mock;
67 public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
69 private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
73 private NetconfClientDispatcher clientDispatcher;
75 DefaultCommitNotificationProducer commitNotifier;
78 public void setUp() throws Exception {
79 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
80 new ModuleFactory[0])));
82 NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener());
84 NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
85 factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
87 .onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
88 new NetconfMonitoringOperationService(monitoringService)));
91 commitNotifier = new DefaultCommitNotificationProducer(platformMBeanServer);
92 NetconfServerDispatcher dispatch = createDispatcher(factoriesListener, mockSessionMonitoringService(), commitNotifier);
93 ChannelFuture s = dispatch.createServer(tcpAddress);
96 clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000);
100 public void cleanUp(){
101 commitNotifier.close();
104 private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
105 final Collection<InputStream> yangDependencies = NetconfITTest.getBasicYangs();
106 return new HardcodedYangStoreService(yangDependencies);
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;
120 public void testNetconfCommitNotifications() throws Exception {
122 VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
123 VerifyingPersister mockedAggregator = mockAggregator();
125 try (NetconfClient persisterClient = new NetconfClient("persister", tcpAddress, 4000, clientDispatcher)) {
126 try (ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
127 platformMBeanServer, mockedAggregator, Pattern.compile(""))) {
130 try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) {
131 NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
132 assertResponse(response, "<modules");
133 assertResponse(response, "<services");
134 response = netconfClient.sendMessage(loadCommitMessage());
135 assertResponse(response, "ok");
137 response = netconfClient.sendMessage(loadEditConfigMessage());
138 assertResponse(response, "ok");
139 response = netconfClient.sendMessage(loadCommitMessage());
140 assertResponse(response, "ok");
145 notificationVerifier.assertNotificationCount(2);
146 notificationVerifier.assertNotificationContent(0, 0, 0, 9);
147 notificationVerifier.assertNotificationContent(1, 4, 4, 9);
149 mockedAggregator.assertSnapshotCount(2);
150 // Capabilities are stripped for persister
151 mockedAggregator.assertSnapshotContent(0, 0, 0, 1);
152 mockedAggregator.assertSnapshotContent(1, 4, 4, 3);
155 private VerifyingPersister mockAggregator() throws IOException {
156 return new VerifyingPersister();
159 private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
160 VerifyingNotificationListener listener = new VerifyingNotificationListener();
161 platformMBeanServer.addNotificationListener(DefaultCommitNotificationProducer.OBJECT_NAME, listener, null, null);
165 private void assertResponse(NetconfMessage response, String content) {
166 Assert.assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString(content));
169 private NetconfMessage loadGetConfigMessage() throws Exception {
170 return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
173 private NetconfMessage loadEditConfigMessage() throws Exception {
174 return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig.xml");
177 private NetconfMessage loadCommitMessage() throws Exception {
178 return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
182 public NetconfOperationServiceFactoryListener getFactoriesListener() {
183 NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
184 NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
185 NetconfOperationService service = mock(NetconfOperationService.class);
186 Set<Capability> caps = Sets.newHashSet();
187 doReturn(caps).when(service).getCapabilities();
188 Set<NetconfOperationService> services = Sets.newHashSet(service);
189 doReturn(services).when(snap).getServices();
190 doReturn(snap).when(factoriesListener).getSnapshot(anyLong());
192 return factoriesListener;
195 private static class VerifyingNotificationListener implements NotificationListener {
196 public List<Notification> notifications = Lists.newArrayList();
199 public void handleNotification(Notification notification, Object handback) {
200 this.notifications.add(notification);
203 void assertNotificationCount(Object size) {
204 assertEquals(size, notifications.size());
207 void assertNotificationContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
208 Notification notification = notifications.get(notificationIndex);
209 assertEquals(CommitJMXNotification.class, notification.getClass());
210 int capsSize = ((CommitJMXNotification) notification).getCapabilities().size();
211 assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
212 Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot();
213 int modulesSize = configSnapshot.getElementsByTagName("module").getLength();
214 assertEquals("Expected modules count", expectedModulesSize, modulesSize);
215 int servicesSize = configSnapshot.getElementsByTagName("instance").getLength();
216 assertEquals("Expected services count", expectedServicesSize, servicesSize);
220 private static class VerifyingPersister implements Persister {
222 public List<ConfigSnapshotHolder> snapshots = Lists.newArrayList();
223 private Persister mockedPersister;
225 public VerifyingPersister() throws IOException {
226 Persister mockedAggregator = mock(Persister.class);
228 doAnswer(new Answer<Object>() {
230 public Object answer(InvocationOnMock invocation) throws Throwable {
231 ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0];
232 snapshots.add(configSnapshot);
235 }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class));
237 this.mockedPersister = mockedAggregator;
240 void assertSnapshotCount(Object size) {
241 assertEquals(size, snapshots.size());
244 void assertSnapshotContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
245 ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
246 int capsSize = snapshot.getCapabilities().size();
247 assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
248 String configSnapshot = snapshot.getConfigSnapshot();
249 int modulesSize = StringUtils.countMatches(configSnapshot, "<module>");
250 assertEquals("Expected modules count", expectedModulesSize, modulesSize);
251 int servicesSize = StringUtils.countMatches(configSnapshot, "<instance>");
252 assertEquals("Expected services count", expectedServicesSize, servicesSize);
256 public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException {
257 mockedPersister.persistConfig(configSnapshotHolder);
261 public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
262 return mockedPersister.loadLastConfigs();
266 public void close() {
267 mockedPersister.close();