+ when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(answerFromGet);
+ }
+
+ private NormalizedNode prepareCnDataForSlashesBehindMountPointTest() throws ParseException {
+ return ImmutableMapEntryNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ TestUtils.getNodeIdentifierPredicate("lst1", "test:module", "2014-01-09", "lf11",
+ "GigabitEthernet0/0/0/0"))
+ .withChild(
+ ImmutableLeafNodeBuilder.create()
+ .withNodeIdentifier(TestUtils.getNodeIdentifier("lf11", "test:module", "2014-01-09"))
+ .withValue("GigabitEthernet0/0/0/0").build()).build();
+
+ }
+
+ /**
+ * If includeWhiteChars URI parameter is set to false then no white characters can be included in returned output
+ *
+ * @throws UnsupportedEncodingException
+ */
+ @Test
+ public void getDataWithUriIncludeWhiteCharsParameterTest() throws UnsupportedEncodingException {
+ getDataWithUriIncludeWhiteCharsParameter("config");
+ getDataWithUriIncludeWhiteCharsParameter("operational");
+ }
+
+ private void getDataWithUriIncludeWhiteCharsParameter(final String target) throws UnsupportedEncodingException {
+ mockReadConfigurationDataMethod();
+ mockReadOperationalDataMethod();
+ String uri = "/" + target + "/ietf-interfaces:interfaces/interface/eth0";
+ Response response = target(uri).queryParam("prettyPrint", "false").request("application/xml").get();
+ String xmlData = response.readEntity(String.class);
+
+ Pattern pattern = Pattern.compile(".*(>\\s+|\\s+<).*", Pattern.DOTALL);
+ Matcher matcher = pattern.matcher(xmlData);
+ // XML element can't surrounded with white character (e.g "> " or
+ // " <")
+ assertFalse(matcher.matches());
+
+ response = target(uri).queryParam("prettyPrint", "false").request("application/json").get();
+ String jsonData = response.readEntity(String.class);
+ pattern = Pattern.compile(".*(\\}\\s+|\\s+\\{|\\]\\s+|\\s+\\[|\\s+:|:\\s+).*", Pattern.DOTALL);
+ matcher = pattern.matcher(jsonData);
+ // JSON element can't surrounded with white character (e.g "} ", " {",
+ // "] ", " [", " :" or ": ")
+ assertFalse(matcher.matches());
+ }
+
+ @Test
+ public void getDataWithUriDepthParameterTest() throws UnsupportedEncodingException {
+
+ ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
+
+ CompositeNode depth1Cont = toCompositeNode(toCompositeNodeData(
+ toNestedQName("depth1-cont"),
+ toCompositeNodeData(
+ toNestedQName("depth2-cont1"),
+ toCompositeNodeData(
+ toNestedQName("depth3-cont1"),
+ toCompositeNodeData(toNestedQName("depth4-cont1"),
+ toSimpleNodeData(toNestedQName("depth5-leaf1"), "depth5-leaf1-value")),
+ toSimpleNodeData(toNestedQName("depth4-leaf1"), "depth4-leaf1-value")),
+ toSimpleNodeData(toNestedQName("depth3-leaf1"), "depth3-leaf1-value")),
+ toCompositeNodeData(
+ toNestedQName("depth2-cont2"),
+ toCompositeNodeData(
+ toNestedQName("depth3-cont2"),
+ toCompositeNodeData(toNestedQName("depth4-cont2"),
+ toSimpleNodeData(toNestedQName("depth5-leaf2"), "depth5-leaf2-value")),
+ toSimpleNodeData(toNestedQName("depth4-leaf2"), "depth4-leaf2-value")),
+ toSimpleNodeData(toNestedQName("depth3-leaf2"), "depth3-leaf2-value")),
+ toSimpleNodeData(toNestedQName("depth2-leaf1"), "depth2-leaf1-value")));
+
+ Module module = TestUtils.findModule(schemaContextModules.getModules(), "nested-module");
+ assertNotNull(module);
+
+ DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode("depth1-cont", module);
+ assertNotNull(dataSchemaNode);
+
+ when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(
+ TestUtils.compositeNodeToDatastoreNormalizedNode(depth1Cont, dataSchemaNode));
+
+ // Test config with depth 1
+
+ Response response = target("/config/nested-module:depth1-cont").queryParam("depth", "1")
+ .request("application/xml").get();
+
+ verifyXMLResponse(response, expectEmptyContainer("depth1-cont"));
+
+ // Test config with depth 2
+
+ response = target("/config/nested-module:depth1-cont").queryParam("depth", "2").request("application/xml")
+ .get();
+
+ // String
+ // xml="<depth1-cont><depth2-cont1/><depth2-cont2/><depth2-leaf1>depth2-leaf1-value</depth2-leaf1></depth1-cont>";
+ // Response mr=mock(Response.class);
+ // when(mr.getEntity()).thenReturn( new
+ // java.io.StringBufferInputStream(xml) );
+
+ verifyXMLResponse(
+ response,
+ expectContainer("depth1-cont", expectEmptyContainer("depth2-cont1"),
+ expectEmptyContainer("depth2-cont2"), expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
+
+ // Test config with depth 3
+
+ response = target("/config/nested-module:depth1-cont").queryParam("depth", "3").request("application/xml")
+ .get();
+
+ verifyXMLResponse(
+ response,
+ expectContainer(
+ "depth1-cont",
+ expectContainer("depth2-cont1", expectEmptyContainer("depth3-cont1"),
+ expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+ expectContainer("depth2-cont2", expectEmptyContainer("depth3-cont2"),
+ expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+ expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
+
+ // Test config with depth 4
+
+ response = target("/config/nested-module:depth1-cont").queryParam("depth", "4").request("application/xml")
+ .get();
+
+ verifyXMLResponse(
+ response,
+ expectContainer(
+ "depth1-cont",
+ expectContainer(
+ "depth2-cont1",
+ expectContainer("depth3-cont1", expectEmptyContainer("depth4-cont1"),
+ expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+ expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+ expectContainer(
+ "depth2-cont2",
+ expectContainer("depth3-cont2", expectEmptyContainer("depth4-cont2"),
+ expectLeaf("depth4-leaf2", "depth4-leaf2-value")),
+ expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+ expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
+
+ // Test config with depth 5
+
+ response = target("/config/nested-module:depth1-cont").queryParam("depth", "5").request("application/xml")
+ .get();
+
+ verifyXMLResponse(
+ response,
+ expectContainer(
+ "depth1-cont",
+ expectContainer(
+ "depth2-cont1",
+ expectContainer(
+ "depth3-cont1",
+ expectContainer("depth4-cont1",
+ expectLeaf("depth5-leaf1", "depth5-leaf1-value")),
+ expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+ expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+ expectContainer(
+ "depth2-cont2",
+ expectContainer(
+ "depth3-cont2",
+ expectContainer("depth4-cont2",
+ expectLeaf("depth5-leaf2", "depth5-leaf2-value")),
+ expectLeaf("depth4-leaf2", "depth4-leaf2-value")),
+ expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+ expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
+
+ // Test config with depth unbounded
+
+ response = target("/config/nested-module:depth1-cont").queryParam("depth", "unbounded")
+ .request("application/xml").get();
+
+ verifyXMLResponse(
+ response,
+ expectContainer(
+ "depth1-cont",
+ expectContainer(
+ "depth2-cont1",
+ expectContainer(
+ "depth3-cont1",
+ expectContainer("depth4-cont1",
+ expectLeaf("depth5-leaf1", "depth5-leaf1-value")),
+ expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+ expectLeaf("depth3-leaf1", "depth3-leaf1-value")),
+ expectContainer(
+ "depth2-cont2",
+ expectContainer(
+ "depth3-cont2",
+ expectContainer("depth4-cont2",
+ expectLeaf("depth5-leaf2", "depth5-leaf2-value")),
+ expectLeaf("depth4-leaf2", "depth4-leaf2-value")),
+ expectLeaf("depth3-leaf2", "depth3-leaf2-value")),
+ expectLeaf("depth2-leaf1", "depth2-leaf1-value")));
+
+ // Test operational
+
+ CompositeNode depth2Cont1 = toCompositeNode(toCompositeNodeData(
+ toNestedQName("depth2-cont1"),
+ toCompositeNodeData(
+ toNestedQName("depth3-cont1"),
+ toCompositeNodeData(toNestedQName("depth4-cont1"),
+ toSimpleNodeData(toNestedQName("depth5-leaf1"), "depth5-leaf1-value")),
+ toSimpleNodeData(toNestedQName("depth4-leaf1"), "depth4-leaf1-value")),
+ toSimpleNodeData(toNestedQName("depth3-leaf1"), "depth3-leaf1-value")));
+
+ assertTrue(dataSchemaNode instanceof DataNodeContainer);
+ DataSchemaNode depth2cont1Schema = null;
+ for (DataSchemaNode childNode : ((DataNodeContainer) dataSchemaNode).getChildNodes()) {
+ if (childNode.getQName().getLocalName().equals("depth2-cont1")) {
+ depth2cont1Schema = childNode;
+ break;
+ }
+ }
+ assertNotNull(depth2Cont1);
+
+ when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(
+ TestUtils.compositeNodeToDatastoreNormalizedNode(depth2Cont1, depth2cont1Schema));
+
+ response = target("/operational/nested-module:depth1-cont/depth2-cont1").queryParam("depth", "3")
+ .request("application/xml").get();
+
+ verifyXMLResponse(
+ response,
+ expectContainer(
+ "depth2-cont1",
+ expectContainer("depth3-cont1", expectEmptyContainer("depth4-cont1"),
+ expectLeaf("depth4-leaf1", "depth4-leaf1-value")),
+ expectLeaf("depth3-leaf1", "depth3-leaf1-value")));
+ }
+
+ /**
+ * Tests behavior when invalid value of depth URI parameter
+ */
+ @Test
+ public void getDataWithInvalidDepthParameterTest() {
+
+ ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
+
+ final MultivaluedMap<String, String> paramMap = new MultivaluedHashMap<>();
+ paramMap.putSingle("depth", "1o");
+ UriInfo mockInfo = mock(UriInfo.class);
+ when(mockInfo.getQueryParameters(false)).thenAnswer(new Answer<MultivaluedMap<String, String>>() {
+ @Override
+ public MultivaluedMap<String, String> answer(InvocationOnMock invocation) {
+ return paramMap;
+ }
+ });
+
+ getDataWithInvalidDepthParameterTest(mockInfo);
+
+ paramMap.putSingle("depth", "0");
+ getDataWithInvalidDepthParameterTest(mockInfo);
+
+ paramMap.putSingle("depth", "-1");
+ getDataWithInvalidDepthParameterTest(mockInfo);