NETCONF-557: Add support for URL capability
[netconf.git] / netconf / mdsal-netconf-connector / src / test / java / org / opendaylight / netconf / mdsal / connector / ops / NetconfMDSalMappingTest.java
1 /*
2  * Copyright (c) 2015 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.mdsal.connector.ops;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14
15 import java.io.StringWriter;
16 import java.net.URI;
17 import javax.xml.transform.OutputKeys;
18 import javax.xml.transform.Transformer;
19 import javax.xml.transform.TransformerFactory;
20 import javax.xml.transform.dom.DOMSource;
21 import javax.xml.transform.stream.StreamResult;
22 import org.junit.Assert;
23 import org.junit.Test;
24 import org.mockito.Mockito;
25 import org.opendaylight.netconf.api.DocumentedException;
26 import org.opendaylight.netconf.api.DocumentedException.ErrorSeverity;
27 import org.opendaylight.netconf.api.DocumentedException.ErrorTag;
28 import org.opendaylight.netconf.api.DocumentedException.ErrorType;
29 import org.opendaylight.netconf.api.xml.XmlElement;
30 import org.opendaylight.netconf.api.xml.XmlUtil;
31 import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
32 import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
33 import org.opendaylight.netconf.mdsal.connector.ops.get.GetConfig;
34 import org.opendaylight.netconf.util.test.XmlFileLoader;
35 import org.opendaylight.yangtools.yang.common.QName;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
37 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
38 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.w3c.dom.Document;
42 import org.w3c.dom.Element;
43 import org.w3c.dom.NodeList;
44
45 public class NetconfMDSalMappingTest extends AbstractNetconfOperationTest {
46     private static final Logger LOG = LoggerFactory.getLogger(NetconfMDSalMappingTest.class);
47
48     private static final String TARGET_KEY = "target";
49     private static final String FILTER_NODE = "filter";
50     private static final String GET_CONFIG = "get-config";
51     private static final QName TOP = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "top");
52     private static final QName USERS = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "users");
53     private static final QName USER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "user");
54     private static final QName MODULES = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "modules");
55     private static final QName AUGMENTED_CONTAINER = QName.create("urn:opendaylight:mdsal:mapping:test",
56             "2015-02-26", "augmented-container");
57     private static final QName AUGMENTED_STRING_IN_CONT = QName.create("urn:opendaylight:mdsal:mapping:test",
58             "2015-02-26", "identifier");
59     private static final QName CHOICE_NODE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26",
60             "choice-node");
61     private static final QName AUGMENTED_CASE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26",
62             "augmented-case");
63     private static final QName CHOICE_WRAPPER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26",
64             "choice-wrapper");
65     private static final QName INNER_CHOICE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26",
66             "inner-choice");
67     private static final QName INNER_CHOICE_TEXT = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26",
68             "text");
69
70     private static final YangInstanceIdentifier AUGMENTED_CONTAINER_IN_MODULES =
71             YangInstanceIdentifier.builder().node(TOP).node(MODULES).build();
72
73     @Override
74     protected SchemaContext getSchemaContext() {
75         return YangParserTestUtils.parseYangResources(NetconfMDSalMappingTest.class,
76             "/yang/mdsal-netconf-mapping-test.yang");
77     }
78
79     @Test
80     public void testEmptyDatastore() throws Exception {
81         assertEmptyDatastore(get());
82         assertEmptyDatastore(getConfigCandidate());
83         assertEmptyDatastore(getConfigRunning());
84     }
85
86     @Test
87     public void testIncorrectGet() throws Exception {
88         try {
89             executeOperation(new GetConfig(SESSION_ID_FOR_REPORTING, getCurrentSchemaContext(),
90                     getTransactionProvider()), "messages/mapping/bad_getConfig.xml");
91             fail("Should have failed, this is an incorrect request");
92         } catch (final DocumentedException e) {
93             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
94             assertTrue(e.getErrorTag() == ErrorTag.OPERATION_FAILED);
95             assertTrue(e.getErrorType() == ErrorType.APPLICATION);
96         }
97
98         try {
99             executeOperation(new GetConfig(SESSION_ID_FOR_REPORTING, getCurrentSchemaContext(),
100                     getTransactionProvider()), "messages/mapping/bad_namespace_getConfig.xml");
101             fail("Should have failed, this is an incorrect request");
102         } catch (final DocumentedException e) {
103             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
104             assertTrue(e.getErrorTag() == ErrorTag.OPERATION_FAILED);
105             assertTrue(e.getErrorType() == ErrorType.APPLICATION);
106         }
107     }
108
109     @Test
110     public void testConfigMissing() throws Exception {
111         try {
112             edit("messages/mapping/editConfigs/editConfig_no_config.xml");
113             fail("Should have failed - neither <config> nor <url> element is present");
114         } catch (final DocumentedException e) {
115             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
116             assertTrue(e.getErrorTag() == ErrorTag.MISSING_ELEMENT);
117             assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
118         }
119     }
120
121     @Test
122     public void testEditRunning() throws Exception {
123         try {
124             edit("messages/mapping/editConfigs/editConfig_running.xml");
125             fail("Should have failed - edit config on running datastore is not supported");
126         } catch (final DocumentedException e) {
127             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
128             assertTrue(e.getErrorTag() == ErrorTag.OPERATION_NOT_SUPPORTED);
129             assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
130         }
131     }
132
133     @Test
134     public void testCommitWithoutOpenTransaction() throws Exception {
135         verifyResponse(commit(), RPC_REPLY_OK);
136         assertEmptyDatastore(getConfigCandidate());
137     }
138
139     @Test
140     public void testCandidateTransaction() throws Exception {
141         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_n1.xml"), RPC_REPLY_OK);
142         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
143                 "messages/mapping/editConfigs/editConfig_merge_n1_control.xml"));
144         assertEmptyDatastore(getConfigRunning());
145
146         verifyResponse(discardChanges(), RPC_REPLY_OK);
147         assertEmptyDatastore(getConfigCandidate());
148     }
149
150     @Test
151     public void testEditWithCommit() throws Exception {
152         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_n1.xml"), RPC_REPLY_OK);
153         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
154                 "messages/mapping/editConfigs/editConfig_merge_n1_control.xml"));
155
156         verifyResponse(commit(), RPC_REPLY_OK);
157         verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
158                 "messages/mapping/editConfigs/editConfig_merge_n1_control.xml"));
159
160         deleteDatastore();
161     }
162
163     @Test
164     public void testKeyOrder() throws Exception {
165         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_keys_1.xml"), RPC_REPLY_OK);
166         verifyResponse(commit(), RPC_REPLY_OK);
167         final Document configRunning = getConfigRunning();
168         final String responseAsString = XmlUtil.toString(configRunning);
169         verifyResponse(configRunning, XmlFileLoader.xmlFileToDocument(
170                 "messages/mapping/editConfigs/editConfig_merge_multiple_keys_1_control.xml"));
171
172         final int key3 = responseAsString.indexOf("key3");
173         final int key1 = responseAsString.indexOf("key1");
174         final int key2 = responseAsString.indexOf("key2");
175
176         assertTrue(String.format("Key ordering invalid, should be key3(%d) < key1(%d) < key2(%d)", key3, key1, key2),
177                 key3 < key1 && key1 < key2);
178
179         deleteDatastore();
180     }
181
182
183     @Test
184     public void testMultipleEditsWithMerge() throws Exception {
185         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK);
186         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
187                 "messages/mapping/editConfigs/editConfig_merge_multiple_control_1.xml"));
188         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_single_1.xml"), RPC_REPLY_OK);
189         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
190                 "messages/mapping/editConfigs/editConfig_merge_multiple_control_2.xml"));
191         assertEmptyDatastore(getConfigRunning());
192
193         verifyResponse(commit(), RPC_REPLY_OK);
194         verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
195                 "messages/mapping/editConfigs/editConfig_merge_multiple_control_2.xml"));
196
197         deleteDatastore();
198     }
199
200     @Test
201     public void testMoreComplexEditConfigs() throws Exception {
202         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK);
203         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_single_1.xml"), RPC_REPLY_OK);
204
205         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_2.xml"), RPC_REPLY_OK);
206         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
207                 "messages/mapping/editConfigs/editConfig_merge_multiple_after_more_complex_merge.xml"));
208
209         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_3.xml"), RPC_REPLY_OK);
210         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
211                 "messages/mapping/editConfigs/editConfig_merge_multiple_after_more_complex_merge_2.xml"));
212
213         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_4_replace.xml"), RPC_REPLY_OK);
214         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
215                 "messages/mapping/editConfigs/editConfig_merge_multiple_after_replace.xml"));
216         verifyResponse(commit(), RPC_REPLY_OK);
217
218         verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
219                 "messages/mapping/editConfigs/editConfig_merge_multiple_after_replace.xml"));
220
221         verifyResponse(edit("messages/mapping/editConfigs/editConfig_replace_default.xml"), RPC_REPLY_OK);
222         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
223                 "messages/mapping/editConfigs/editConfig_replace_default_control.xml"));
224         verifyResponse(commit(), RPC_REPLY_OK);
225
226         verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
227                 "messages/mapping/editConfigs/editConfig_replace_default_control.xml"));
228
229         deleteDatastore();
230     }
231
232     @Test
233     public void testOrderedListEdits() throws Exception {
234
235         verifyResponse(edit("messages/mapping/editConfigs/editConfig_ordered_list_create.xml"), RPC_REPLY_OK);
236         verifyResponse(commit(), RPC_REPLY_OK);
237
238         verifyResponse(edit("messages/mapping/editConfigs/editConfig_ordered_list_replace.xml"), RPC_REPLY_OK);
239         verifyResponse(commit(), RPC_REPLY_OK);
240
241         deleteDatastore();
242
243     }
244
245     @Test
246     public void testAugmentedOrderedListEdits() throws Exception {
247
248         verifyResponse(edit("messages/mapping/editConfigs/editConfig_augmented_ordered_list_create.xml"),
249                 RPC_REPLY_OK);
250         verifyResponse(commit(), RPC_REPLY_OK);
251
252         verifyResponse(edit("messages/mapping/editConfigs/editConfig_augmented_ordered_list_replace.xml"),
253                 RPC_REPLY_OK);
254         verifyResponse(commit(), RPC_REPLY_OK);
255
256         deleteDatastore();
257
258     }
259
260     @Test
261     public void testAugmentedContainerReplace() throws Exception {
262         verifyResponse(edit("messages/mapping/editConfigs/editConfig_empty_modules_create.xml"),
263                 RPC_REPLY_OK);
264         verifyResponse(commit(), RPC_REPLY_OK);
265
266         verifyResponse(edit("messages/mapping/editConfigs/editConfig_augmented_container_replace.xml"),
267                 RPC_REPLY_OK);
268         verifyResponse(commit(), RPC_REPLY_OK);
269
270         deleteDatastore();
271     }
272
273     @Test
274     public void testLeafFromAugmentReplace() throws Exception {
275         verifyResponse(edit("messages/mapping/editConfigs/editConfig_empty_modules_create.xml"),
276                 RPC_REPLY_OK);
277         verifyResponse(commit(), RPC_REPLY_OK);
278
279         verifyResponse(edit("messages/mapping/editConfigs/editConfig_leaf_from_augment_replace.xml"),
280                 RPC_REPLY_OK);
281         verifyResponse(commit(), RPC_REPLY_OK);
282
283         deleteDatastore();
284     }
285
286     @Test
287     public void testLock() throws Exception {
288         verifyResponse(lockCandidate(), RPC_REPLY_OK);
289
290         try {
291             lock();
292             fail("Should have failed - locking of running datastore is not supported");
293         } catch (final DocumentedException e) {
294             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
295             assertTrue(e.getErrorTag() == ErrorTag.OPERATION_NOT_SUPPORTED);
296             assertTrue(e.getErrorType() == ErrorType.APPLICATION);
297         }
298
299         try {
300             lockWithoutTarget();
301             fail("Should have failed, target is missing");
302         } catch (final DocumentedException e) {
303             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
304             assertTrue(e.getErrorTag() == ErrorTag.INVALID_VALUE);
305             assertTrue(e.getErrorType() == ErrorType.APPLICATION);
306         }
307     }
308
309     @Test
310     public void testUnlock() throws Exception {
311         verifyResponse(unlockCandidate(), RPC_REPLY_OK);
312
313         try {
314             unlock();
315             fail("Should have failed - unlocking of running datastore is not supported");
316         } catch (final DocumentedException e) {
317             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
318             assertTrue(e.getErrorTag() == ErrorTag.OPERATION_NOT_SUPPORTED);
319             assertTrue(e.getErrorType() == ErrorType.APPLICATION);
320         }
321
322         try {
323             unlockWithoutTarget();
324             fail("Should have failed, target is missing");
325         } catch (final DocumentedException e) {
326             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
327             assertTrue(e.getErrorTag() == ErrorTag.INVALID_VALUE);
328             assertTrue(e.getErrorType() == ErrorType.APPLICATION);
329         }
330     }
331
332     @Test
333     public void testEditWithCreate() throws Exception {
334         verifyResponse(edit("messages/mapping/editConfigs/editConfig_create.xml"), RPC_REPLY_OK);
335         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
336                 "messages/mapping/editConfig_create_n1_control.xml"));
337
338         try {
339             edit("messages/mapping/editConfigs/editConfig_create.xml");
340             fail("Create should have failed - data already exists");
341         } catch (final DocumentedException e) {
342             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
343             assertTrue(e.getErrorTag() == ErrorTag.DATA_EXISTS);
344             assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
345         }
346
347         verifyResponse(discardChanges(), RPC_REPLY_OK);
348     }
349
350     @Test
351     public void testDeleteNonExisting() throws Exception {
352         assertEmptyDatastore(getConfigCandidate());
353         assertEmptyDatastore(getConfigRunning());
354
355         try {
356             edit("messages/mapping/editConfigs/editConfig_delete-top.xml");
357             fail("Delete should have failed - data is missing");
358         } catch (final DocumentedException e) {
359             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
360             assertTrue(e.getErrorTag() == ErrorTag.DATA_MISSING);
361             assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
362         }
363     }
364
365     @Test
366     public void testEditMissingDefaultOperation() throws Exception {
367         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_1.xml"),
368                 RPC_REPLY_OK);
369         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_2.xml"),
370                 RPC_REPLY_OK);
371         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
372                 "messages/mapping/editConfigs/editConfig_merge_missing_default-operation_control.xml"));
373
374         verifyResponse(commit(), RPC_REPLY_OK);
375         verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument(
376                 "messages/mapping/editConfigs/editConfig_merge_missing_default-operation_control.xml"));
377
378         deleteDatastore();
379     }
380
381     private static void printDocument(final Document doc) throws Exception {
382         final TransformerFactory tf = TransformerFactory.newInstance();
383         final Transformer transformer = tf.newTransformer();
384         transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
385         transformer.setOutputProperty(OutputKeys.METHOD, "xml");
386         transformer.setOutputProperty(OutputKeys.INDENT, "yes");
387         transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
388         transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
389
390         final StringWriter writer = new StringWriter();
391         transformer.transform(new DOMSource(doc),
392                 new StreamResult(writer));
393         LOG.warn(writer.getBuffer().toString());
394     }
395
396     @Test
397     public void testEditConfigWithMultipleOperations() throws Exception {
398         deleteDatastore();
399
400         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_setup.xml"),
401                 RPC_REPLY_OK);
402         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_1.xml"),
403                 RPC_REPLY_OK);
404
405         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_2.xml"),
406                 RPC_REPLY_OK);
407         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
408                 "messages/mapping/editConfigs/editConfig_merge_multiple_operations_2_control.xml"));
409
410         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_3_leaf_operations.xml"),
411                 RPC_REPLY_OK);
412         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
413                 "messages/mapping/editConfigs/editConfig_merge_multiple_operations_3_control.xml"));
414
415         deleteDatastore();
416
417         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_setup.xml"),
418                 RPC_REPLY_OK);
419         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_default-replace.xml"),
420                 RPC_REPLY_OK);
421
422         try {
423             edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_create_existing.xml");
424             fail();
425         } catch (final DocumentedException e) {
426             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
427             assertTrue(e.getErrorTag() == ErrorTag.DATA_EXISTS);
428             assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
429         }
430
431         verifyResponse(edit(
432                 "messages/mapping/editConfigs/"
433                         + "editConfig_merge_multiple_operations_4_delete_children_operations.xml"),
434                 RPC_REPLY_OK);
435         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
436                 "messages/mapping/editConfigs/"
437                         + "editConfig_merge_multiple_operations_4_delete_children_operations_control.xml"));
438         verifyResponse(edit(
439                 "messages/mapping/editConfigs/"
440                         + "editConfig_merge_multiple_operations_4_remove-non-existing.xml"),
441                 RPC_REPLY_OK);
442         try {
443             edit("messages/mapping/editConfigs/"
444                     + "editConfig_merge_multiple_operations_4_delete-non-existing.xml");
445             fail();
446         } catch (final DocumentedException e) {
447             assertTrue(e.getErrorSeverity() == ErrorSeverity.ERROR);
448             assertTrue(e.getErrorTag() == ErrorTag.DATA_MISSING);
449             assertTrue(e.getErrorType() == ErrorType.PROTOCOL);
450         }
451
452         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup.xml"),
453                 RPC_REPLY_OK);
454         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
455                 "messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup-control.xml"));
456
457         // Test files have been modified. RFC6020 requires that at most once case inside a choice is present at any time
458         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup2.xml"),
459                 RPC_REPLY_OK);
460         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
461                 "messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup2-control.xml"));
462
463         verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_delete.xml"),
464                 RPC_REPLY_OK);
465         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
466                 "messages/mapping/editConfigs"
467                         + "/editConfig_merge_multiple_operations_4_delete_children_operations_control.xml"));
468
469         deleteDatastore();
470     }
471
472     @Test
473     public void testEditConfigGetElementByTagName() throws Exception {
474         EditConfig editConfig = new EditConfig("test_edit-config", Mockito.mock(CurrentSchemaContext.class),
475                 Mockito.mock(TransactionProvider.class));
476
477         String stringWithoutPrefix =
478                 "<rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"0\">\n"
479                         + "  <edit-config>\n"
480                         + "    <target>\n"
481                         + "      <candidate/>\n"
482                         + "    </target>\n"
483                         + "  </edit-config>\n"
484                         + "</rpc>";
485         XmlElement xe = getXmlElement(stringWithoutPrefix);
486         NodeList nodeList = EditConfig.getElementsByTagName(xe, TARGET_KEY);
487         Assert.assertEquals(1, nodeList.getLength());
488
489         String stringWithPrefix =
490                 "<nc:rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"0\">\n"
491                         + "  <nc:edit-config>\n"
492                         + "    <nc:target>\n"
493                         + "      <nc:candidate/>\n"
494                         + "    </nc:target>\n"
495                         + "  </nc:edit-config>\n"
496                         + "</nc:rpc>";
497
498         xe = getXmlElement(stringWithPrefix);
499         nodeList = EditConfig.getElementsByTagName(xe, TARGET_KEY);
500         Assert.assertEquals(1, nodeList.getLength());
501
502         String stringWithoutTarget =
503                 "<nc:rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"0\">\n"
504                         + "  <nc:edit-config>\n"
505                         + "    <nc:target>\n"
506                         + "    </nc:target>\n"
507                         + "  </nc:edit-config>\n"
508                         + "</nc:rpc>";
509         xe = getXmlElement(stringWithoutTarget);
510
511         try {
512             nodeList = EditConfig.getElementsByTagName(xe, TARGET_KEY);
513             XmlElement.fromDomElement((Element) nodeList.item(0)).getOnlyChildElement();
514             Assert.fail("Not specified target, we should fail");
515         } catch (DocumentedException documentedException) {
516             // Ignore
517         }
518
519     }
520
521     private static XmlElement getXmlElement(final String elementAsString) throws Exception {
522         Document document = XmlUtil.readXmlToDocument(elementAsString);
523         Element element = document.getDocumentElement();
524         return XmlElement.fromDomElement(element);
525     }
526
527     @Test
528     public void testReplaceMapEntry() throws Exception {
529         verifyResponse(edit("messages/mapping/editConfigs/edit-config-replace-map-entry.xml"), RPC_REPLY_OK);
530         verifyResponse(commit(), RPC_REPLY_OK);
531         verifyResponse(getConfigRunning(),
532                 XmlFileLoader.xmlFileToDocument("messages/mapping/get-config-map-entry.xml"));
533     }
534
535     @Test
536     public void testMergeMapEntry() throws Exception {
537         verifyResponse(edit("messages/mapping/editConfigs/edit-config-merge-map-entry.xml"), RPC_REPLY_OK);
538         verifyResponse(commit(), RPC_REPLY_OK);
539         verifyResponse(getConfigRunning(),
540                 XmlFileLoader.xmlFileToDocument("messages/mapping/get-config-map-entry.xml"));
541     }
542
543     @Test
544     public void testFiltering() throws Exception {
545         assertEmptyDatastore(getConfigCandidate());
546         assertEmptyDatastore(getConfigRunning());
547
548         verifyResponse(getConfigWithFilter("messages/mapping/filters/get-config-empty-filter.xml"),
549                 XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
550         verifyResponse(getWithFilter("messages/mapping/filters/get-empty-filter.xml"),
551                 XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
552
553         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response"
554                 + ".xml"));
555         verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
556         verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-users.xml"),
557                 XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
558
559         verifyResponse(edit("messages/mapping/editConfigs/editConfig-filtering-setup.xml"), RPC_REPLY_OK);
560         verifyResponse(commit(), RPC_REPLY_OK);
561
562         verifyFilterIdentifier("messages/mapping/filters/get-filter-alluser.xml",
563                 YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
564         verifyFilterIdentifier("messages/mapping/filters/get-filter-company-info.xml",
565                 YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
566         verifyFilterIdentifier("messages/mapping/filters/get-filter-modules-and-admin.xml",
567                 YangInstanceIdentifier.builder().node(TOP).build());
568         verifyFilterIdentifier("messages/mapping/filters/get-filter-only-names-types.xml",
569                 YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
570         verifyFilterIdentifier("messages/mapping/filters/get-filter-specific-module-type-and-user.xml",
571                 YangInstanceIdentifier.builder().node(TOP).build());
572         verifyFilterIdentifier("messages/mapping/filters/get-filter-superuser.xml",
573                 YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
574         verifyFilterIdentifier("messages/mapping/filters/get-filter-users.xml",
575                 YangInstanceIdentifier.builder().node(TOP).node(USERS).build());
576
577         final YangInstanceIdentifier ident = YangInstanceIdentifier
578                 .builder(AUGMENTED_CONTAINER_IN_MODULES)
579                 .node(AUGMENTED_CONTAINER)
580                 .node(AUGMENTED_STRING_IN_CONT).build();
581
582         verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-string.xml", ident);
583         verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case.xml",
584                 YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(AUGMENTED_CASE).build());
585
586         verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case.xml"),
587                 XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case.xml"));
588
589         /*
590          *  RFC6020 requires that at most once case inside a choice is present at any time.
591          *  Therefore
592          *  <augmented-case>augmented case</augmented-case>
593          *  from
594          *  messages/mapping/editConfigs/editConfig-filtering-setup.xml
595          *  cannot exists together with
596          *  <text>augmented nested choice text1</text>
597          *  from
598          *  messages/mapping/editConfigs/editConfig-filtering-setup2.xml
599          */
600         //verifyResponse(edit("messages/mapping/editConfigs/editConfig-filtering-setup2.xml"), RPC_REPLY_OK);
601         //verifyResponse(commit(), RPC_REPLY_OK);
602
603         verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case-inner-choice.xml",
604                 YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(CHOICE_WRAPPER).build());
605         verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case-inner-case.xml",
606                 YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(CHOICE_WRAPPER).node(INNER_CHOICE)
607                         .node(INNER_CHOICE_TEXT).build());
608
609 //        verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-string.xml"),
610 //                XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-string.xml"));
611 //        verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case-inner-choice.xml"),
612 //                XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case-inner-choice.xml"));
613 //        verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case-inner-case.xml"),
614 //                XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case-inner-choice.xml"));
615
616         verifyResponse(edit("messages/mapping/editConfigs/editConfig_delete-top.xml"), RPC_REPLY_OK);
617         verifyResponse(commit(), RPC_REPLY_OK);
618
619     }
620
621     private void verifyFilterIdentifier(final String resource, final YangInstanceIdentifier identifier)
622             throws Exception {
623         final TestingGetConfig getConfig = new TestingGetConfig(SESSION_ID_FOR_REPORTING, getCurrentSchemaContext(),
624                 getTransactionProvider());
625         final Document request = XmlFileLoader.xmlFileToDocument(resource);
626         final YangInstanceIdentifier iid = getConfig.getInstanceIdentifierFromDocument(request);
627         assertEquals(identifier, iid);
628     }
629
630     private class TestingGetConfig extends GetConfig {
631         TestingGetConfig(final String sessionId, final CurrentSchemaContext schemaContext,
632                          final TransactionProvider transactionProvider) {
633             super(sessionId, schemaContext, transactionProvider);
634         }
635
636         YangInstanceIdentifier getInstanceIdentifierFromDocument(final Document request) throws DocumentedException {
637             final XmlElement filterElement = XmlElement.fromDomDocument(request).getOnlyChildElement(GET_CONFIG)
638                     .getOnlyChildElement(FILTER_NODE);
639             return getInstanceIdentifierFromFilter(filterElement);
640         }
641     }
642
643     private void deleteDatastore() throws Exception {
644         verifyResponse(edit("messages/mapping/editConfigs/editConfig_delete-root.xml"), RPC_REPLY_OK);
645         assertEmptyDatastore(getConfigCandidate());
646
647         verifyResponse(commit(), RPC_REPLY_OK);
648         assertEmptyDatastore(getConfigRunning());
649     }
650
651     @Test
652     public void testEditUsingConfigFromFile() throws Exception {
653         // Ask class loader for URI of config file and use it as <url> in <edit-config> RPC:
654         final String template = XmlFileLoader.fileToString("messages/mapping/editConfigs/editConfig_from_file.xml");
655         final URI uri = getClass().getClassLoader().getResource("messages/mapping/editConfigs/config_file.xml").toURI();
656         final String copyConfig = template.replaceFirst("URL", uri.toString());
657         final Document request = XmlUtil.readXmlToDocument(copyConfig);
658
659         verifyResponse(edit(request), RPC_REPLY_OK);
660         verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument(
661             "messages/mapping/editConfigs/editConfig_from_file_control.xml"));
662     }
663 }