Use minimal ietf-topology
[netconf.git] / netconf / netconf-it / src / test / java / org / opendaylight / netconf / it / NetconfITTest.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
9 package org.opendaylight.netconf.it;
10
11 import static org.hamcrest.CoreMatchers.containsString;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertThat;
15 import static org.junit.Assert.fail;
16 import static org.mockito.Mockito.doReturn;
17
18 import com.google.common.base.Throwables;
19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Sets;
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Set;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.TimeoutException;
28 import javax.management.ObjectName;
29 import javax.xml.parsers.ParserConfigurationException;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
33 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
34 import org.opendaylight.controller.config.util.xml.DocumentedException;
35 import org.opendaylight.controller.config.util.xml.XmlElement;
36 import org.opendaylight.controller.config.util.xml.XmlUtil;
37 import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
38 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
39 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean;
40 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
41 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
42 import org.opendaylight.netconf.api.NetconfMessage;
43 import org.opendaylight.netconf.client.NetconfClientDispatcher;
44 import org.opendaylight.netconf.client.TestingNetconfClient;
45 import org.opendaylight.netconf.util.test.XmlFileLoader;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
48 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Element;
51 import org.w3c.dom.NamedNodeMap;
52 import org.w3c.dom.Node;
53 import org.xml.sax.SAXException;
54
55 public class NetconfITTest extends AbstractNetconfConfigTest {
56
57     public static final int PORT = 12023;
58     public static final InetSocketAddress TCP_ADDRESS = new InetSocketAddress(LOOPBACK_ADDRESS, PORT);
59
60     private NetconfMessage getConfigCandidate, editConfig, closeSession;
61     private NetconfClientDispatcher clientDispatcher;
62
63     @Before
64     public void setUp() throws Exception {
65         loadMessages();
66         clientDispatcher = getClientDispatcher();
67     }
68
69     @Override
70     protected InetSocketAddress getTcpServerAddress() {
71         return TCP_ADDRESS;
72     }
73
74     private void loadMessages() throws IOException, SAXException, ParserConfigurationException {
75         this.editConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/edit_config.xml");
76         this.getConfigCandidate = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig_candidate.xml");
77         this.closeSession = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/closeSession.xml");
78     }
79
80     @Test
81     public void testNetconfClientDemonstration() throws Exception {
82         try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 4000))) {
83
84             final Set<String> capabilitiesFromNetconfServer = netconfClient.getCapabilities();
85             final long sessionId = netconfClient.getSessionId();
86
87             // NetconfMessage can be created :
88             // new NetconfMessage(XmlUtil.readXmlToDocument("<xml/>"));
89
90             final NetconfMessage response = netconfClient.sendMessage(getGetConfig());
91             response.getDocument();
92         }
93     }
94
95     @Test
96     public void testTwoSessions() throws Exception {
97         try (TestingNetconfClient netconfClient = new TestingNetconfClient("1", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 10000)))  {
98             try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("2", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 10000))) {
99                 assertNotNull(netconfClient2.getCapabilities());
100             }
101         }
102     }
103
104     @Test
105     public void rpcReplyContainsAllAttributesTest() throws Exception {
106         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
107             final String rpc = "<rpc message-id=\"5\" a=\"a\" b=\"44\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><get/>" + "</rpc>";
108             final Document doc = XmlUtil.readXmlToDocument(rpc);
109             final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc));
110             assertNotNull(message);
111             final NamedNodeMap expectedAttributes = doc.getDocumentElement().getAttributes();
112             final NamedNodeMap returnedAttributes = message.getDocument().getDocumentElement().getAttributes();
113
114             assertSameAttributes(expectedAttributes, returnedAttributes);
115         }
116     }
117
118     private void assertSameAttributes(final NamedNodeMap expectedAttributes, final NamedNodeMap returnedAttributes) {
119         assertNotNull("Expecting 4 attributes", returnedAttributes);
120         assertEquals(expectedAttributes.getLength(), returnedAttributes.getLength());
121
122         for (int i = 0; i < expectedAttributes.getLength(); i++) {
123             final Node expAttr = expectedAttributes.item(i);
124             final Node attr = returnedAttributes.item(i);
125             assertEquals(expAttr.getNodeName(), attr.getNodeName());
126             assertEquals(expAttr.getNamespaceURI(), attr.getNamespaceURI());
127             assertEquals(expAttr.getTextContent(), attr.getTextContent());
128         }
129     }
130
131     @Test
132     public void rpcReplyErrorContainsAllAttributesTest() throws Exception {
133         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
134             final String rpc = "<rpc message-id=\"1\" a=\"adada\" b=\"4\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><commit/>" + "</rpc>";
135             final Document doc = XmlUtil.readXmlToDocument(rpc);
136             final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc));
137             final NamedNodeMap expectedAttributes = doc.getDocumentElement().getAttributes();
138             final NamedNodeMap returnedAttributes = message.getDocument().getDocumentElement().getAttributes();
139
140             assertSameAttributes(expectedAttributes, returnedAttributes);
141         }
142     }
143
144     @Test
145     public void rpcOutputContainsCorrectNamespace() throws Exception {
146         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
147         final ObjectName dep = transaction.createModule(DepTestImplModuleFactory.NAME, "instanceD");
148         final ObjectName impl = transaction.createModule(NetconfTestImplModuleFactory.NAME, "instance");
149         final NetconfTestImplModuleMXBean proxy = configRegistryClient
150                 .newMXBeanProxy(impl, NetconfTestImplModuleMXBean.class);
151         proxy.setTestingDep(dep);
152         proxy.setSimpleShort((short) 0);
153
154         transaction.commit();
155
156         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
157             final String expectedNamespace = "urn:opendaylight:params:xml:ns:yang:controller:test:impl";
158
159             final String rpc = "<rpc message-id=\"5\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
160                     + "<no-arg xmlns=\""
161                     + expectedNamespace
162                     + "\">    "
163                     + "<context-instance>/modules/module[type='impl-netconf'][name='instance']</context-instance>"
164                     + "<arg1>argument1</arg1>" + "</no-arg>" + "</rpc>";
165             final Document doc = XmlUtil.readXmlToDocument(rpc);
166             final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc));
167
168             final Element rpcReply = message.getDocument().getDocumentElement();
169             final XmlElement resultElement = XmlElement.fromDomElement(rpcReply).getOnlyChildElement();
170             assertEquals("result", resultElement.getName());
171
172             final String namespace = resultElement.getNamespaceAttribute();
173             assertEquals(expectedNamespace, namespace);
174         }
175     }
176
177     @Test
178     public void testCloseSession() throws Exception {
179         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
180
181             // edit config
182             Document rpcReply = netconfClient.sendMessage(this.editConfig)
183                     .getDocument();
184             assertIsOK(rpcReply);
185
186             rpcReply = netconfClient.sendMessage(this.closeSession)
187                     .getDocument();
188
189             assertIsOK(rpcReply);
190         }
191     }
192
193     @Test
194     public void testEditConfig() throws Exception {
195         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
196             // send edit_config.xml
197             final Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument();
198             assertIsOK(rpcReply);
199         }
200     }
201
202     @Test
203     public void testValidate() throws Exception {
204         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
205             // begin transaction
206             Document rpcReply = netconfClient.sendMessage(getConfigCandidate).getDocument();
207             assertEquals("data", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName());
208
209             // operations empty
210             rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/validate.xml"))
211                     .getDocument();
212             assertIsOK(rpcReply);
213         }
214     }
215
216     private void assertIsOK(final Document rpcReply) throws DocumentedException {
217         assertEquals("rpc-reply", rpcReply.getDocumentElement().getLocalName());
218         assertEquals("ok", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName());
219     }
220
221     private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException, DocumentedException {
222         return assertGetConfigWorks(netconfClient, getGetConfig());
223     }
224
225     private Document assertGetConfigWorks(final TestingNetconfClient netconfClient, final NetconfMessage getConfigMessage)
226             throws InterruptedException, ExecutionException, TimeoutException, DocumentedException {
227         final NetconfMessage rpcReply = netconfClient.sendMessage(getConfigMessage);
228         assertNotNull(rpcReply);
229         assertEquals("data", XmlElement.fromDomDocument(rpcReply.getDocument()).getOnlyChildElement().getName());
230         return rpcReply.getDocument();
231     }
232
233     @Test
234     public void testGetConfig() throws Exception {
235         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
236             assertGetConfigWorks(netconfClient);
237         }
238     }
239
240     @Test
241     public void createYangTestBasedOnYuma() throws Exception {
242         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
243             Document rpcReply = netconfClient.sendMessage(
244                     XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_yang-test.xml"))
245                     .getDocument();
246             assertEquals("rpc-reply", rpcReply.getDocumentElement().getTagName());
247             assertIsOK(rpcReply);
248             assertGetConfigWorks(netconfClient, this.getConfigCandidate);
249             rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml"))
250                     .getDocument();
251             assertIsOK(rpcReply);
252
253             final ObjectName on = new ObjectName(
254                     "org.opendaylight.controller:instanceName=impl-dep-instance,type=Module,moduleFactoryName=impl-dep");
255             final Set<ObjectName> cfgBeans = configRegistryClient.lookupConfigBeans();
256             assertEquals(cfgBeans, Sets.newHashSet(on));
257         }
258     }
259
260     private TestingNetconfClient createSession(final InetSocketAddress address, final String expected) throws Exception {
261         final TestingNetconfClient netconfClient = new TestingNetconfClient("test " + address.toString(), clientDispatcher, getClientConfiguration(address, 5000));
262         assertEquals(expected, Long.toString(netconfClient.getSessionId()));
263         return netconfClient;
264     }
265
266     @Test
267     public void testIdRef() throws Exception {
268         final NetconfMessage editId = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
269         final NetconfMessage commit = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
270
271         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
272             assertIsOK(netconfClient.sendMessage(editId).getDocument());
273             assertIsOK(netconfClient.sendMessage(commit).getDocument());
274
275             final NetconfMessage response = netconfClient.sendMessage(getGetConfig());
276
277             assertThat(XmlUtil.toString(response.getDocument()), containsString("<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>"));
278             assertThat(XmlUtil.toString(response.getDocument()), containsString("<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>"));
279             assertThat(XmlUtil.toString(response.getDocument()), containsString("<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>"));
280             assertThat(XmlUtil.toString(response.getDocument()), containsString("<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>"));
281
282         } catch (final Exception e) {
283             fail(Throwables.getStackTraceAsString(e));
284         }
285     }
286
287     @Override
288     protected BindingRuntimeContext getBindingRuntimeContext() {
289         final BindingRuntimeContext ret = super.getBindingRuntimeContext();
290         doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
291         doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
292         return ret;
293     }
294
295     @Test
296     public void testMultipleDependencies() throws Exception {
297         // push first xml, should add parent and d1,d2 dependencies
298         try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
299             final Document rpcReply = netconfClient.sendMessage(
300                     XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps1.xml"))
301                     .getDocument();
302             assertIsOK(rpcReply);
303             commit(netconfClient);
304         }
305         // verify that parent.getTestingDeps == d1,d2
306         final MultipleDependenciesModuleMXBean parentProxy = configRegistryClient.newMXBeanProxy(
307                 configRegistryClient.lookupConfigBean(MultipleDependenciesModuleFactory.NAME, "parent"),
308                 MultipleDependenciesModuleMXBean.class);
309         {
310             final List<ObjectName> testingDeps = parentProxy.getTestingDeps();
311             assertEquals(2, testingDeps.size());
312             final Set<String> actualRefs = getServiceReferences(testingDeps);
313             assertEquals(Sets.newHashSet("ref_d1", "ref_d2"), actualRefs);
314         }
315
316         // push second xml, should add d3 to parent's dependencies
317         mergeD3(parentProxy);
318         // push second xml again, to test that d3 is not added again
319         mergeD3(parentProxy);
320     }
321
322     public void mergeD3(final MultipleDependenciesModuleMXBean parentProxy) throws Exception {
323         try (TestingNetconfClient netconfClient = new TestingNetconfClient(
324                 "test " + TCP_ADDRESS.toString(), clientDispatcher, getClientConfiguration(TCP_ADDRESS, 5000))) {
325
326             final Document rpcReply = netconfClient.sendMessage(
327                     XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps2.xml"))
328                     .getDocument();
329             assertIsOK(rpcReply);
330             commit(netconfClient);
331         }
332         {
333             final List<ObjectName> testingDeps = parentProxy.getTestingDeps();
334             assertEquals(3, testingDeps.size());
335             final Set<String> actualRefs = getServiceReferences(testingDeps);
336             assertEquals(Sets.newHashSet("ref_d1", "ref_d2", "ref_d3"), actualRefs);
337         }
338     }
339
340     public Set<String> getServiceReferences(final List<ObjectName> testingDeps) {
341         return new HashSet<>(Lists.transform(testingDeps, ObjectNameUtil::getReferenceName));
342     }
343
344     public void commit(final TestingNetconfClient netconfClient) throws Exception {
345         final Document rpcReply;
346         rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml"))
347                 .getDocument();
348         assertIsOK(rpcReply);
349     }
350 }