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 static org.junit.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.doReturn;
15 import static org.mockito.Mockito.mock;
16 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithName;
17 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertElementsCount;
18 import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToDocument;
20 import com.google.common.collect.Lists;
21 import com.google.common.collect.Sets;
22 import java.io.IOException;
23 import java.lang.management.ManagementFactory;
24 import java.net.InetSocketAddress;
25 import java.net.SocketAddress;
26 import java.util.Collections;
27 import java.util.List;
29 import javax.management.InstanceNotFoundException;
30 import javax.management.Notification;
31 import javax.management.NotificationListener;
32 import org.junit.Test;
33 import org.mockito.invocation.InvocationOnMock;
34 import org.mockito.stubbing.Answer;
35 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
36 import org.opendaylight.controller.config.persist.api.Persister;
37 import org.opendaylight.controller.netconf.api.NetconfMessage;
38 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
39 import org.opendaylight.controller.netconf.client.TestingNetconfClient;
40 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
41 import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
42 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl;
43 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
44 import org.opendaylight.controller.netconf.mapping.api.Capability;
45 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider;
46 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
47 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
48 import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
49 import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
50 import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
51 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
52 import org.w3c.dom.Document;
53 import org.w3c.dom.Element;
54 import org.xml.sax.SAXException;
56 public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
58 public static final int PORT = 12026;
59 private static final InetSocketAddress TCP_ADDRESS = new InetSocketAddress(LOOPBACK_ADDRESS, PORT);
61 private NetconfMonitoringServiceImpl netconfMonitoringService;
64 protected void setUpTestInitial() {
65 netconfMonitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
69 protected SessionMonitoringService getNetconfMonitoringService() throws Exception {
70 return netconfMonitoringService;
74 protected SocketAddress getTcpServerAddress() {
79 protected Iterable<NetconfOperationServiceFactory> getAdditionalServiceFactories() {
80 return Collections.<NetconfOperationServiceFactory>singletonList(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
81 new NetconfMonitoringOperationService(netconfMonitoringService)));
85 protected DefaultCommitNotificationProducer getNotificationProducer() {
86 return new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
90 public void testNetconfCommitNotifications() throws Exception {
91 final VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
92 final VerifyingPersister mockedAggregator = mockAggregator();
94 try (TestingNetconfClient persisterClient = new TestingNetconfClient("persister", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 4000))) {
95 try (ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
96 platformMBeanServer, mockedAggregator)) {
99 try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 4000))) {
100 NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
101 assertContainsElementWithName(response.getDocument(), "modules");
102 assertContainsElementWithName(response.getDocument(), "services");
103 response = netconfClient.sendMessage(loadCommitMessage());
104 assertContainsElementWithName(response.getDocument(), "ok");
106 response = netconfClient.sendMessage(loadEditConfigMessage());
107 assertContainsElementWithName(response.getDocument(), "ok");
108 response = netconfClient.sendMessage(loadCommitMessage());
109 assertContainsElementWithName(response.getDocument(), "ok");
114 notificationVerifier.assertNotificationCount(2);
115 notificationVerifier.assertNotificationContent(0, 0, 0, 8);
116 notificationVerifier.assertNotificationContent(1, 4, 3, 8);
118 mockedAggregator.assertSnapshotCount(2);
119 // Capabilities are stripped for persister
120 mockedAggregator.assertSnapshotContent(0, 0, 0, 1);
121 mockedAggregator.assertSnapshotContent(1, 4, 3, 3);
124 private VerifyingPersister mockAggregator() throws IOException {
125 return new VerifyingPersister();
128 private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
129 final VerifyingNotificationListener listener = new VerifyingNotificationListener();
130 platformMBeanServer.addNotificationListener(DefaultCommitNotificationProducer.OBJECT_NAME, listener, null, null);
134 private NetconfMessage loadGetConfigMessage() throws Exception {
135 return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
138 private NetconfMessage loadEditConfigMessage() throws Exception {
139 return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig.xml");
142 private NetconfMessage loadCommitMessage() throws Exception {
143 return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
147 public NetconfOperationProvider getNetconfOperationProvider() {
148 final NetconfOperationProvider factoriesListener = mock(NetconfOperationProvider.class);
149 final NetconfOperationServiceSnapshotImpl snap = mock(NetconfOperationServiceSnapshotImpl.class);
150 final NetconfOperationService service = mock(NetconfOperationService.class);
151 final Set<Capability> caps = Sets.newHashSet();
152 doReturn(caps).when(service).getCapabilities();
153 final Set<NetconfOperationService> services = Sets.newHashSet(service);
154 doReturn(services).when(snap).getServices();
155 doReturn(snap).when(factoriesListener).openSnapshot(anyString());
157 return factoriesListener;
160 private static class VerifyingNotificationListener implements NotificationListener {
161 public List<Notification> notifications = Lists.newArrayList();
164 public void handleNotification(final Notification notification, final Object handback) {
165 this.notifications.add(notification);
168 void assertNotificationCount(final Object size) {
169 assertEquals(size, notifications.size());
172 void assertNotificationContent(final int notificationIndex, final int expectedModulesSize, final int expectedServicesSize, final int expectedCapsSize) {
173 final Notification notification = notifications.get(notificationIndex);
174 assertEquals(CommitJMXNotification.class, notification.getClass());
175 final int capsSize = ((CommitJMXNotification) notification).getCapabilities().size();
176 assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
177 final Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot();
178 final int modulesSize = configSnapshot.getElementsByTagName("module").getLength();
179 assertEquals("Expected modules count", expectedModulesSize, modulesSize);
180 final int servicesSize = configSnapshot.getElementsByTagName("instance").getLength();
181 assertEquals("Expected services count", expectedServicesSize, servicesSize);
185 private static class VerifyingPersister implements Persister {
187 public List<ConfigSnapshotHolder> snapshots = Lists.newArrayList();
188 private Persister mockedPersister;
190 public VerifyingPersister() throws IOException {
191 final Persister mockedAggregator = mock(Persister.class);
193 doAnswer(new Answer<Object>() {
195 public Object answer(final InvocationOnMock invocation) throws Throwable {
196 final ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0];
197 snapshots.add(configSnapshot);
200 }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class));
202 this.mockedPersister = mockedAggregator;
205 void assertSnapshotCount(final Object size) {
206 assertEquals(size, snapshots.size());
209 void assertSnapshotContent(final int notificationIndex, final int expectedModulesSize, final int expectedServicesSize, final int expectedCapsSize)
210 throws SAXException, IOException {
211 final ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
212 final int capsSize = snapshot.getCapabilities().size();
213 assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
214 final Document configSnapshot = readXmlToDocument(snapshot.getConfigSnapshot());
215 assertElementsCount(configSnapshot, "module", expectedModulesSize);
216 assertElementsCount(configSnapshot, "instance", expectedServicesSize);
220 public void persistConfig(final ConfigSnapshotHolder configSnapshotHolder) throws IOException {
221 mockedPersister.persistConfig(configSnapshotHolder);
225 public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
226 return mockedPersister.loadLastConfigs();
230 public void close() {
231 mockedPersister.close();