From: Ed Warnicke Date: Wed, 18 Jun 2014 12:59:05 +0000 (+0000) Subject: Merge "BUG-1140: inPort disappeared from match" X-Git-Tag: release/helium~644 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=013138732400ae603193db8900371f1df79931a3;hp=a1bb72c42cbbd5779782b8bfd9104f936a252258 Merge "BUG-1140: inPort disappeared from match" --- diff --git a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java index ebc56928a2..d76c094851 100644 --- a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java +++ b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java @@ -261,7 +261,7 @@ public class ConnectionManager implements IConnectionManager, Map params) { if (connectionService == null) return null; - Node node = connectionService.connect(connectionIdentifier, params); + Node node = connectionService.connect(type, connectionIdentifier, params); AbstractScheme scheme = schemes.get(activeScheme); if (scheme != null && node != null) scheme.addNode(node); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java index 4d9b198795..056be72d4e 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java @@ -107,13 +107,15 @@ public interface RestconfService { @Path("/config/{identifier:.+}") @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - public StructuredData readConfigurationData(@Encoded @PathParam("identifier") String identifier); + public StructuredData readConfigurationData(@Encoded @PathParam("identifier") String identifier, + @Context UriInfo depth); @GET @Path("/operational/{identifier:.+}") @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - public StructuredData readOperationalData(@Encoded @PathParam("identifier") String identifier); + public StructuredData readOperationalData(@Encoded @PathParam("identifier") String identifier, + @Context UriInfo depth); @PUT @Path("/config/{identifier:.+}") diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java index c0ce90e15d..7b6dcd57db 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java @@ -49,6 +49,7 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdent import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.api.SimpleNode; +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -71,6 +72,7 @@ import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -566,7 +568,7 @@ public class RestconfImpl implements RestconfService { } @Override - public StructuredData readConfigurationData(final String identifier) { + public StructuredData readConfigurationData(final String identifier, UriInfo info) { final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier); CompositeNode data = null; MountInstance mountPoint = iiWithData.getMountPoint(); @@ -577,11 +579,57 @@ public class RestconfImpl implements RestconfService { data = broker.readConfigurationData(iiWithData.getInstanceIdentifier()); } + data = pruneDataAtDepth( data, parseDepthParameter( info ) ); return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint()); } + @SuppressWarnings("unchecked") + private > T pruneDataAtDepth( T node, Integer depth ) { + if( depth == null ) { + return node; + } + + if( node instanceof CompositeNode ) { + ImmutableList.Builder> newChildNodes = ImmutableList.> builder(); + if( depth > 1 ) { + for( Node childNode: ((CompositeNode)node).getValue() ) { + newChildNodes.add( pruneDataAtDepth( childNode, depth - 1 ) ); + } + } + + return (T) ImmutableCompositeNode.create( node.getNodeType(), newChildNodes.build() ); + } + else { // SimpleNode + return node; + } + } + + private Integer parseDepthParameter( UriInfo info ) { + String param = info.getQueryParameters( false ).getFirst( "depth" ); + if( Strings.isNullOrEmpty( param ) || "unbounded".equals( param ) ) { + return null; + } + + try { + Integer depth = Integer.valueOf( param ); + if( depth < 1 ) { + throw new RestconfDocumentedException( new RestconfError( + ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + depth, + null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) ); + } + + return depth; + } + catch( NumberFormatException e ) { + throw new RestconfDocumentedException( new RestconfError( + ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, + "Invalid depth parameter: " + e.getMessage(), + null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) ); + } + } + @Override - public StructuredData readOperationalData(final String identifier) { + public StructuredData readOperationalData(final String identifier, UriInfo info) { final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier); CompositeNode data = null; MountInstance mountPoint = iiWithData.getMountPoint(); @@ -592,6 +640,7 @@ public class RestconfImpl implements RestconfService { data = broker.readOperationalData(iiWithData.getInstanceIdentifier()); } + data = pruneDataAtDepth( data, parseDepthParameter( info ) ); return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java index 2037fd4862..319603dfc1 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java @@ -23,6 +23,7 @@ import java.io.UnsupportedEncodingException; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; @@ -96,21 +97,21 @@ public class MediaTypesTest extends JerseyTest { String uriPrefix = "/config/"; String uriPath = "ietf-interfaces:interfaces"; String uri = uriPrefix + uriPath; - when(restconfService.readConfigurationData(uriPath)).thenReturn(null); + when(restconfService.readConfigurationData(eq(uriPath), any(UriInfo.class))).thenReturn(null); get(uri, Draft02.MediaTypes.DATA+JSON); - verify(restconfService, times(1)).readConfigurationData(uriPath); + verify(restconfService, times(1)).readConfigurationData(eq(uriPath), any(UriInfo.class)); get(uri, Draft02.MediaTypes.DATA+XML); - verify(restconfService, times(2)).readConfigurationData(uriPath); + verify(restconfService, times(2)).readConfigurationData(eq(uriPath), any(UriInfo.class)); get(uri, MediaType.APPLICATION_JSON); - verify(restconfService, times(3)).readConfigurationData(uriPath); + verify(restconfService, times(3)).readConfigurationData(eq(uriPath), any(UriInfo.class)); get(uri, MediaType.APPLICATION_XML); - verify(restconfService, times(4)).readConfigurationData(uriPath); + verify(restconfService, times(4)).readConfigurationData(eq(uriPath), any(UriInfo.class)); get(uri, MediaType.TEXT_XML); - verify(restconfService, times(5)).readConfigurationData(uriPath); + verify(restconfService, times(5)).readConfigurationData(eq(uriPath), any(UriInfo.class)); // negative tests get(uri, MediaType.TEXT_PLAIN); - verify(restconfService, times(5)).readConfigurationData(uriPath); + verify(restconfService, times(5)).readConfigurationData(eq(uriPath), any(UriInfo.class)); } @Test @@ -118,21 +119,21 @@ public class MediaTypesTest extends JerseyTest { String uriPrefix = "/operational/"; String uriPath = "ietf-interfaces:interfaces"; String uri = uriPrefix + uriPath; - when(restconfService.readOperationalData(uriPath)).thenReturn(null); + when(restconfService.readOperationalData(eq(uriPath), any(UriInfo.class))).thenReturn(null); get(uri, Draft02.MediaTypes.DATA+JSON); - verify(restconfService, times(1)).readOperationalData(uriPath); + verify(restconfService, times(1)).readOperationalData(eq(uriPath), any(UriInfo.class)); get(uri, Draft02.MediaTypes.DATA+XML); - verify(restconfService, times(2)).readOperationalData(uriPath); + verify(restconfService, times(2)).readOperationalData(eq(uriPath), any(UriInfo.class)); get(uri, MediaType.APPLICATION_JSON); - verify(restconfService, times(3)).readOperationalData(uriPath); + verify(restconfService, times(3)).readOperationalData(eq(uriPath), any(UriInfo.class)); get(uri, MediaType.APPLICATION_XML); - verify(restconfService, times(4)).readOperationalData(uriPath); + verify(restconfService, times(4)).readOperationalData(eq(uriPath), any(UriInfo.class)); get(uri, MediaType.TEXT_XML); - verify(restconfService, times(5)).readOperationalData(uriPath); + verify(restconfService, times(5)).readOperationalData(eq(uriPath), any(UriInfo.class)); // negative tests get(uri, MediaType.TEXT_PLAIN); - verify(restconfService, times(5)).readOperationalData(uriPath); + verify(restconfService, times(5)).readOperationalData(eq(uriPath), any(UriInfo.class)); } @Test diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java index 893622f60a..f0a232fba6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java @@ -7,15 +7,17 @@ */ package org.opendaylight.controller.sal.restconf.impl.test; -import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.FileNotFoundException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; @@ -24,17 +26,23 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.opendaylight.controller.sal.core.api.mount.MountInstance; import org.opendaylight.controller.sal.core.api.mount.MountService; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; @@ -45,6 +53,7 @@ import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException; import org.opendaylight.controller.sal.restconf.impl.RestconfImpl; import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper; import org.opendaylight.yangtools.yang.common.QName; @@ -52,10 +61,28 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; +import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; public class RestGetOperationTest extends JerseyTest { + static class NodeData { + Object key; + Object data; // List for a CompositeNode, value Object for a SimpleNode + + NodeData( Object key, Object data ) { + this.key = key; + this.data = data; + } + } + private static BrokerFacade brokerFacade; private static RestconfImpl restconfImpl; private static SchemaContext schemaContextYangsIetf; @@ -588,4 +615,314 @@ public class RestGetOperationTest extends JerseyTest { return null; } + @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" ) + ) ); + + when( brokerFacade.readConfigurationData( any( InstanceIdentifier.class ) ) ) + .thenReturn( depth1Cont ); + + // 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="depth2-leaf1-value"; +// 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" ) + ) ); + + when( brokerFacade.readOperationalData( any( InstanceIdentifier.class ) ) ) + .thenReturn( depth2Cont1 ); + + 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" ) + ) ); + } + + @Test + public void getDataWithInvalidDepthParameterTest() { + + ControllerContext.getInstance().setGlobalSchema( schemaContextModules ); + + final MultivaluedMap paramMap = new MultivaluedHashMap<>(); + paramMap.putSingle( "depth", "1o" ); + UriInfo mockInfo = mock( UriInfo.class ); + when( mockInfo.getQueryParameters( false ) ).thenAnswer( + new Answer>() { + @Override + public MultivaluedMap answer( InvocationOnMock invocation ) { + return paramMap; + } + } ); + + getDataWithInvalidDepthParameterTest( mockInfo ); + + paramMap.putSingle( "depth", "0" ); + getDataWithInvalidDepthParameterTest( mockInfo ); + + paramMap.putSingle( "depth", "-1" ); + getDataWithInvalidDepthParameterTest( mockInfo ); + } + + private void getDataWithInvalidDepthParameterTest( UriInfo uriInfo ) { + try { + restconfImpl.readConfigurationData( "nested-module:depth1-cont", uriInfo ); + fail( "Expected RestconfDocumentedException" ); + } + catch( RestconfDocumentedException e ) { + assertTrue( "Unexpected error message: " + e.getErrors().get( 0 ).getErrorMessage(), + e.getErrors().get( 0 ).getErrorMessage().contains( "depth" ) ); + } + } + + private void verifyXMLResponse( Response response, NodeData nodeData ) { + + Document doc = TestUtils.loadDocumentFrom( (InputStream) response.getEntity() ); + assertNotNull( "Could not parse XML document", doc ); + + //System.out.println(TestUtils.getDocumentInPrintableForm( doc )); + + verifyContainerElement( doc.getDocumentElement(), nodeData ); + } + + @SuppressWarnings("unchecked") + private void verifyContainerElement( Element element, NodeData nodeData ) { + + assertEquals( "Element local name", nodeData.key, element.getNodeName() ); + + NodeList childNodes = element.getChildNodes(); + if( nodeData.data == null ) { // empty container + assertTrue( "Expected no child elements for \"" + element.getNodeName() + "\"", + childNodes.getLength() == 0 ); + return; + } + + Map expChildMap = Maps.newHashMap(); + for( NodeData expChild: (List)nodeData.data ) { + expChildMap.put( expChild.key.toString(), expChild ); + } + + for( int i = 0; i < childNodes.getLength(); i++ ) { + org.w3c.dom.Node actualChild = childNodes.item( i ); + if( !( actualChild instanceof Element ) ) { + continue; + } + + Element actualElement = (Element)actualChild; + NodeData expChild = expChildMap.remove( actualElement.getNodeName() ); + assertNotNull( "Unexpected child element for parent \"" + element.getNodeName() + + "\": " + actualElement.getNodeName(), expChild ); + + if( expChild.data == null || expChild.data instanceof List ) { + verifyContainerElement( actualElement, expChild ); + } + else { + assertEquals( "Text content for element: " + actualElement.getNodeName(), + expChild.data, actualElement.getTextContent() ); + } + } + + if( !expChildMap.isEmpty() ) { + fail( "Missing elements for parent \"" + element.getNodeName() + + "\": " + expChildMap.keySet() ); + } + } + + private NodeData expectContainer( String name, NodeData... childData ) { + return new NodeData( name, Lists.newArrayList( childData ) ); + } + + private NodeData expectEmptyContainer( String name ) { + return new NodeData( name, null ); + } + + private NodeData expectLeaf( String name, Object value ) { + return new NodeData( name, value ); + } + + private QName toNestedQName( String localName ) { + return QName.create( "urn:nested:module", "2014-06-3", localName ); + } + + @SuppressWarnings("unchecked") + private CompositeNode toCompositeNode( NodeData nodeData ) { + CompositeNodeBuilder builder = ImmutableCompositeNode.builder(); + builder.setQName( (QName) nodeData.key ); + + for( NodeData child: (List)nodeData.data ) { + if( child.data instanceof List ) { + builder.add( toCompositeNode( child ) ); + } + else { + builder.addLeaf( (QName) child.key, child.data ); + } + } + + return builder.toInstance(); + } + + private NodeData toCompositeNodeData( QName key, NodeData... childData ) { + return new NodeData( key, Lists.newArrayList( childData ) ); + } + + private NodeData toSimpleNodeData( QName key, Object value ) { + return new NodeData( key, value ); + } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfDocumentedExceptionMapperTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfDocumentedExceptionMapperTest.java index 3f984c293b..e146cf8f4f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfDocumentedExceptionMapperTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfDocumentedExceptionMapperTest.java @@ -34,6 +34,7 @@ import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; @@ -220,7 +221,7 @@ public class RestconfDocumentedExceptionMapperTest extends JerseyTest { void stageMockEx( final RestconfDocumentedException ex ) { reset( mockRestConf ); - when( mockRestConf.readOperationalData( any( String.class ) ) ).thenThrow( ex ); + when( mockRestConf.readOperationalData( any( String.class ), any( UriInfo.class ) ) ).thenThrow( ex ); } void testJsonResponse( final RestconfDocumentedException ex, final Status expStatus, final ErrorType expErrorType, @@ -776,8 +777,8 @@ public class RestconfDocumentedExceptionMapperTest extends JerseyTest { // The StructuredDataToJsonProvider should throw a RestconfDocumentedException with no data - when( mockRestConf.readOperationalData( any( String.class ) ) ) - .thenReturn( new StructuredData( null, null, null ) ); + when( mockRestConf.readOperationalData( any( String.class ), any( UriInfo.class ) ) ) + .thenReturn( new StructuredData( null, null, null ) ); Response resp = target("/operational/foo").request( MediaType.APPLICATION_JSON ).get(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/modules/nested-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/modules/nested-module.yang new file mode 100644 index 0000000000..590743c9ca --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/modules/nested-module.yang @@ -0,0 +1,47 @@ +module nested-module { + namespace "urn:nested:module"; + prefix "nested"; + revision "2014-06-3"; + + container depth1-cont { + container depth2-cont1 { + container depth3-cont1 { + container depth4-cont1 { + leaf depth5-leaf1 { + type string; + } + } + + leaf depth4-leaf1 { + type string; + } + } + + leaf depth3-leaf1 { + type string; + } + } + + container depth2-cont2 { + container depth3-cont2 { + container depth4-cont2 { + leaf depth5-leaf2 { + type string; + } + } + + leaf depth4-leaf2 { + type string; + } + } + + leaf depth3-leaf2 { + type string; + } + } + + leaf depth2-leaf1 { + type string; + } + } +} \ No newline at end of file diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index 48b4bbc2a8..867ad60362 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -103,10 +103,7 @@ public class Get extends AbstractConfigNetconfOperation { xml.checkName(XmlNetconfConstants.GET); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); - // Filter option - unsupported - if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){ - throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " + XmlNetconfConstants.GET); - } + // Filter option: ignore for now, TODO only load modules specified by the filter } @Override diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java index 03e0176e32..bc059d345c 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java @@ -9,6 +9,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig; import com.google.common.base.Optional; +import java.util.Set; +import javax.management.ObjectName; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; @@ -30,9 +32,6 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import javax.management.ObjectName; -import java.util.Set; - public class GetConfig extends AbstractConfigNetconfOperation { public static final String GET_CONFIG = "get-config"; @@ -65,11 +64,7 @@ public class GetConfig extends AbstractConfigNetconfOperation { logger.debug("Setting source datastore to '{}'", sourceParsed); Datastore sourceDatastore = Datastore.valueOf(sourceParsed); - // Filter option - unsupported - if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){ - throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " - + GET_CONFIG); - } + // Filter option: ignore for now, TODO only load modules specified by the filter return sourceDatastore; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java index 75be1f8fe0..54ad18a1de 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java @@ -13,10 +13,10 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; import org.opendaylight.controller.netconf.api.NetconfSessionListener; import org.opendaylight.controller.netconf.api.NetconfTerminationReason; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; import org.opendaylight.controller.netconf.util.messages.SendErrorExceptionUtil; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -98,7 +98,7 @@ public class NetconfServerSessionListener implements NetconfSessionListenerrfc6241 for details. + */ +public class SubtreeFilter { + private static final Logger logger = LoggerFactory.getLogger(SubtreeFilter.class); + + static Document applySubtreeFilter(Document requestDocument, Document rpcReply) throws NetconfDocumentedException { + // FIXME: rpcReply document must be reread otherwise some nodes do not inherit namespaces. (services/service) + try { + rpcReply = XmlUtil.readXmlToDocument(XmlUtil.toString(rpcReply, true)); + } catch (SAXException | IOException e) { + logger.error("Cannot transform document", e); + throw new NetconfDocumentedException("Cannot transform document"); + } + + OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(requestDocument); + if (XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0.equals(operationNameAndNamespace.getNamespace()) && + XmlNetconfConstants.GET.equals(operationNameAndNamespace.getOperationName()) || + XmlNetconfConstants.GET_CONFIG.equals(operationNameAndNamespace.getOperationName())) { + // process subtree filtering here, in case registered netconf operations do + // not implement filtering. + Optional maybeFilter = operationNameAndNamespace.getOperationElement().getOnlyChildElementOptionally( + XmlNetconfConstants.FILTER, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + if (maybeFilter.isPresent() && ( + "subtree".equals(maybeFilter.get().getAttribute("type"))|| + "subtree".equals(maybeFilter.get().getAttribute("type", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0)) + )) { + + + // do + return filtered(maybeFilter.get(), rpcReply); + } + } + return rpcReply; // return identical document + } + + private static Document filtered(XmlElement filter, Document originalReplyDocument) throws NetconfDocumentedException { + Document result = XmlUtil.newDocument(); + // even if filter is empty, copy /rpc/data + Element rpcReply = originalReplyDocument.getDocumentElement(); + Node rpcReplyDst = result.importNode(rpcReply, false); + result.appendChild(rpcReplyDst); + XmlElement dataSrc = XmlElement.fromDomElement(rpcReply).getOnlyChildElement("data", XmlNetconfConstants.RFC4741_TARGET_NAMESPACE); + Element dataDst = (Element) result.importNode(dataSrc.getDomElement(), false); + rpcReplyDst.appendChild(dataDst); + addSubtree(filter, dataSrc, XmlElement.fromDomElement(dataDst)); + + return result; + } + + private static void addSubtree(XmlElement filter, XmlElement src, XmlElement dst) { + for (XmlElement srcChild : src.getChildElements()) { + for (XmlElement filterChild : filter.getChildElements()) { + addSubtree2(filterChild, srcChild, dst); + } + } + } + + private static MatchingResult addSubtree2(XmlElement filter, XmlElement src, XmlElement dstParent) { + Document document = dstParent.getDomElement().getOwnerDocument(); + MatchingResult matches = matches(src, filter); + if (matches != MatchingResult.NO_MATCH && matches != MatchingResult.CONTENT_MISMATCH) { + // copy srcChild to dst + boolean filterHasChildren = filter.getChildElements().isEmpty() == false; + // copy to depth if this is leaf of filter tree + Element copied = (Element) document.importNode(src.getDomElement(), filterHasChildren == false); + boolean shouldAppend = filterHasChildren == false; + if (filterHasChildren) { // this implies TAG_MATCH + // do the same recursively + int numberOfTextMatchingChildren = 0; + for (XmlElement srcChild : src.getChildElements()) { + for (XmlElement filterChild : filter.getChildElements()) { + MatchingResult childMatch = addSubtree2(filterChild, srcChild, XmlElement.fromDomElement(copied)); + if (childMatch == MatchingResult.CONTENT_MISMATCH) { + return MatchingResult.NO_MATCH; + } + if (childMatch == MatchingResult.CONTENT_MATCH) { + numberOfTextMatchingChildren++; + } + shouldAppend |= childMatch != MatchingResult.NO_MATCH; + } + } + // if only text matching child filters are specified.. + if (numberOfTextMatchingChildren == filter.getChildElements().size()) { + // force all children to be added (to depth). This is done by copying parent node to depth. + // implies shouldAppend == true + copied = (Element) document.importNode(src.getDomElement(), true); + } + } + if (shouldAppend) { + dstParent.getDomElement().appendChild(copied); + } + } + return matches; + } + + /** + * Shallow compare src node to filter: tag name and namespace must match. + * If filter node has no children and has text content, it also must match. + */ + private static MatchingResult matches(XmlElement src, XmlElement filter) { + boolean tagMatch = src.getName().equals(filter.getName()) && + src.getNamespaceOptionally().equals(filter.getNamespaceOptionally()); + MatchingResult result = null; + if (tagMatch) { + // match text content + Optional maybeText = filter.getOnlyTextContentOptionally(); + if (maybeText.isPresent()) { + if (maybeText.equals(src.getOnlyTextContentOptionally())) { + result = MatchingResult.CONTENT_MATCH; + } else { + result = MatchingResult.CONTENT_MISMATCH; + } + } + // match attributes, combination of content and tag is not supported + if (result == null) { + for (Attr attr : filter.getAttributes().values()) { + // ignore namespace declarations + if (XmlUtil.XMLNS_URI.equals(attr.getNamespaceURI()) == false ) { + // find attr with matching localName(), namespaceURI(), == value() in src + String found = src.getAttribute(attr.getLocalName(), attr.getNamespaceURI()); + if (attr.getValue().equals(found) && result != MatchingResult.NO_MATCH) { + result = MatchingResult.TAG_MATCH; + } else { + result = MatchingResult.NO_MATCH; + } + } + } + } + if (result == null) { + result = MatchingResult.TAG_MATCH; + } + } + if (result == null) { + result = MatchingResult.NO_MATCH; + } + logger.debug("Matching {} to {} resulted in {}", src, filter, tagMatch); + return result; + } + + enum MatchingResult { + NO_MATCH, TAG_MATCH, CONTENT_MATCH, CONTENT_MISMATCH + } +} diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java new file mode 100644 index 0000000000..b11834386e --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.netconf.impl; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.custommonkey.xmlunit.Diff; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +@RunWith(value = Parameterized.class) +public class SubtreeFilterTest { + private static final Logger logger = LoggerFactory.getLogger(SubtreeFilterTest.class); + + private final int directoryIndex; + + @Parameters + public static Collection data() { + List result = new ArrayList<>(); + for (int i = 0; i <= 8; i++) { + result.add(new Object[]{i}); + } + return result; + } + + public SubtreeFilterTest(int directoryIndex) { + this.directoryIndex = directoryIndex; + } + + @Before + public void setUp(){ + XMLUnit.setIgnoreWhitespace(true); + } + + @Test + public void test() throws Exception { + Document requestDocument = getDocument("request.xml"); + Document preFilterDocument = getDocument("pre-filter.xml"); + Document postFilterDocument = getDocument("post-filter.xml"); + Document actualPostFilterDocument = SubtreeFilter.applySubtreeFilter(requestDocument, preFilterDocument); + logger.info("Actual document: {}", XmlUtil.toString(actualPostFilterDocument)); + Diff diff = XMLUnit.compareXML(postFilterDocument, actualPostFilterDocument); + assertTrue(diff.toString(), diff.similar()); + + } + + public Document getDocument(String fileName) throws SAXException, IOException { + return XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/subtree/" + directoryIndex + "/" + + fileName)); + } +} diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/getConfig_reply_unfiltered.xml b/opendaylight/netconf/netconf-impl/src/test/resources/getConfig_reply_unfiltered.xml new file mode 100644 index 0000000000..3c2765ad1b --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/getConfig_reply_unfiltered.xml @@ -0,0 +1,439 @@ + + + + + + prefix:toaster-provider-impl + + toaster-provider-impl + + + prefix:binding-notification-service + + binding-notification-broker + + + + prefix:binding-rpc-registry + + binding-rpc-broker + + + + prefix:binding-data-broker + + binding-data-broker + + + + + prefix:sal-netconf-connector + + controller-config + 1830 + + 20000 + + 2000 + + 1.5 + admin + + + prefix:dom-broker-osgi-registry + + dom-broker + + + + prefix:netconf-client-dispatcher + + global-netconf-dispatcher + + admin +
127.0.0.1
+ + prefix:threadpool + global-netconf-processing-executor + + false + + + prefix:binding-broker-osgi-registry + + binding-osgi-broker + + 0 + + + prefix:netty-event-executor + global-event-executor + +
+ + + prefix:netconf-client-dispatcher + + global-netconf-dispatcher + + prefix:netty-threadgroup + global-worker-group + + + prefix:netty-timer + global-timer + + + prefix:netty-threadgroup + global-boss-group + + + + prefix:logback + singleton + + ERROR + STDOUT + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n + + + true + logs/audit.log + audit-file + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n + + + WARN + org.opendaylight.controller.logging.bridge + + + INFO + audit + audit-file + + + ERROR + ROOT + STDOUT + opendaylight.log + + + INFO + org.opendaylight + + + INFO + org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort + opendaylight.log + + + TRACE + org.opendaylight.controller.netconf + + + WARN + io.netty + + + true + 10MB + logs/opendaylight.log + opendaylight.log + logs/opendaylight.%d.log.zip + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n + false + 1 + TimeBasedRollingPolicy + + + + prefix:shutdown + shutdown + + + + + prefix:netty-hashed-wheel-timer + + global-timer + + + + prefix:netty-threadgroup-fixed + + global-boss-group + + + + prefix:netty-threadgroup-fixed + + global-worker-group + + + + prefix:schema-service-singleton + + yang-schema-service + + + prefix:dom-broker-impl + + inmemory-dom-broker + + prefix:dom-async-data-broker + + inmemory-data-broker + + + + + prefix:dom-inmemory-data-broker + + inmemory-data-broker + + prefix:schema-service + yang-schema-service + + + + + prefix:threadpool-flexible + + global-netconf-processing-executor + + prefix:threadfactory + global-netconf-processing-executor-threadfactory + + 1 + + 4 + + 600000 + + + + + prefix:netty-global-event-executor + + singleton + + + + prefix:binding-broker-impl + + binding-broker-impl + + + prefix:binding-notification-service + + binding-notification-broker + + + + prefix:binding-data-broker + + binding-data-broker + + + + + prefix:runtime-generated-mapping + + runtime-mapping-singleton + + + + prefix:binding-notification-broker + + binding-notification-broker + + + + prefix:binding-data-compatible-broker + + inmemory-binding-data-broker + + + prefix:dom-broker-osgi-registry + + dom-broker + + + + prefix:binding-dom-mapping-service + + runtime-mapping-singleton + + + + + prefix:threadfactory-naming + + global-netconf-processing-executor-threadfactory + + remote-connector-processing-executor + + + + + prefix:kitchen-service-impl + + kitchen-service-impl + + + prefix:binding-notification-service + + binding-notification-broker + + + + prefix:binding-rpc-registry + + binding-rpc-broker + + + + + prefix:remote-zeromq-rpc-server + + remoter + 5666 + + + prefix:dom-broker-osgi-registry + + dom-broker + + +
+ + + prefix:schema-service + + yang-schema-service + /modules/module[type='schema-service-singleton'][name='yang-schema-service'] + + + + prefix:dom-broker-osgi-registry + + + dom-broker + /modules/module[type='dom-broker-impl'][name='inmemory-dom-broker'] + + + + prefix:dom-async-data-broker + + + inmemory-data-broker + /modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker'] + + + + prefix:threadpool + + global-netconf-processing-executor + /modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor'] + + + + prefix:threadfactory + + global-netconf-processing-executor-threadfactory + + /modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory'] + + + + + + prefix:binding-dom-mapping-service + + + runtime-mapping-singleton + /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] + + + + prefix:netty-timer + + global-timer + /modules/module[type='netty-hashed-wheel-timer'][name='global-timer'] + + + + prefix:netty-threadgroup + + global-boss-group + /modules/module[type='netty-threadgroup-fixed'][name='global-boss-group'] + + + global-worker-group + /modules/module[type='netty-threadgroup-fixed'][name='global-worker-group'] + + + + prefix:netty-event-executor + + global-event-executor + /modules/module[type='netty-global-event-executor'][name='singleton'] + + + + prefix:binding-rpc-registry + + + binding-rpc-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + + prefix:binding-notification-service + + + binding-notification-broker + /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] + + + + + prefix:binding-broker-osgi-registry + + + binding-osgi-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + prefix:binding-data-broker + + + binding-data-broker + /modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker'] + + + + + + prefix:kitchen-service + + + kitchen-service + /modules/module[type='kitchen-service-impl'][name='kitchen-service-impl'] + + + + + prefix:netconf-client-dispatcher + + + global-netconf-dispatcher + /modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher'] + + + +
+
\ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/logback-test.xml b/opendaylight/netconf/netconf-impl/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..74714a0a24 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/logback-test.xml @@ -0,0 +1,13 @@ + + + + + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/post-filter.xml new file mode 100644 index 0000000000..4abe6a3947 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/post-filter.xml @@ -0,0 +1,48 @@ + + + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/pre-filter.xml new file mode 100644 index 0000000000..031409bdcf --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/pre-filter.xml @@ -0,0 +1,40 @@ + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/request.xml new file mode 100644 index 0000000000..8d49a7fcb2 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/0/request.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/post-filter.xml new file mode 100644 index 0000000000..1ad3f205e3 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/post-filter.xml @@ -0,0 +1,5 @@ + + + + diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/pre-filter.xml new file mode 100644 index 0000000000..8fd61e1b77 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/pre-filter.xml @@ -0,0 +1,40 @@ + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/request.xml new file mode 100644 index 0000000000..2579aa61e6 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/1/request.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/post-filter.xml new file mode 100644 index 0000000000..e974b59ea1 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/post-filter.xml @@ -0,0 +1,35 @@ + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/pre-filter.xml new file mode 100644 index 0000000000..a399e5772f --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/pre-filter.xml @@ -0,0 +1,48 @@ + + + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/request.xml new file mode 100644 index 0000000000..7b549b9c3e --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/2/request.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/post-filter.xml new file mode 100644 index 0000000000..e379d49a66 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/post-filter.xml @@ -0,0 +1,26 @@ + + + + + + + + root + + + fred + + + barney + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/pre-filter.xml new file mode 100644 index 0000000000..42f451bca1 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/pre-filter.xml @@ -0,0 +1,48 @@ + + + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/request.xml new file mode 100644 index 0000000000..771f1364b0 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/3/request.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/post-filter.xml new file mode 100644 index 0000000000..c701ba0a84 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/post-filter.xml @@ -0,0 +1,18 @@ + + + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/pre-filter.xml new file mode 100644 index 0000000000..f2f2cbb9b5 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/pre-filter.xml @@ -0,0 +1,48 @@ + + + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/request.xml new file mode 100644 index 0000000000..04c8149206 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/4/request.xml @@ -0,0 +1,17 @@ + + + + + + + + + + fred + + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/post-filter.xml new file mode 100644 index 0000000000..d6ffd008f3 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/post-filter.xml @@ -0,0 +1,14 @@ + + + + + + fred + admin + Fred Flintstone + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/pre-filter.xml new file mode 100644 index 0000000000..7e3f7218e3 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/pre-filter.xml @@ -0,0 +1,40 @@ + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/request.xml new file mode 100644 index 0000000000..35819887d9 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/5/request.xml @@ -0,0 +1,19 @@ + + + + + + + + + + fred + + + + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/post-filter.xml new file mode 100644 index 0000000000..05eb019726 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/post-filter.xml @@ -0,0 +1,22 @@ + + + + + + root + + 1 + 1 + + + + fred + + 2 + + + + + + diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/pre-filter.xml new file mode 100644 index 0000000000..71dd6282e7 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/pre-filter.xml @@ -0,0 +1,48 @@ + + + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/request.xml new file mode 100644 index 0000000000..c4a410dbb5 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/6/request.xml @@ -0,0 +1,32 @@ + + + + + + + + + + root + + + + fred + + + + + + barney + superuser + + + + + + + + + + diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/post-filter.xml new file mode 100644 index 0000000000..676ba22254 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/post-filter.xml @@ -0,0 +1,13 @@ + + + + + + 45621 + 774344 + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/pre-filter.xml new file mode 100644 index 0000000000..ef88283668 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/pre-filter.xml @@ -0,0 +1,52 @@ + + + + + + root + superuser + Charlie Root + + 1 + 1 + + + + fred + admin + Fred Flintstone + + 2 + 2 + + + + barney + admin + Barney Rubble + + 2 + 3 + + + + + + admin + + + + + + + 45621 + 774344 + + + 1 + 1 + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/request.xml new file mode 100644 index 0000000000..4bbbabaa50 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/7/request.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/post-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/post-filter.xml new file mode 100644 index 0000000000..3498b026e6 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/post-filter.xml @@ -0,0 +1,115 @@ + + + + + prefix:schema-service + + yang-schema-service + /modules/module[type='schema-service-singleton'][name='yang-schema-service'] + + + + prefix:dom-broker-osgi-registry + + dom-broker + /modules/module[type='dom-broker-impl'][name='inmemory-dom-broker'] + + + + prefix:dom-async-data-broker + + inmemory-data-broker + /modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker'] + + + + prefix:threadpool + + global-netconf-processing-executor + /modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor'] + + + + prefix:threadfactory + + global-netconf-processing-executor-threadfactory + /modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory'] + + + + prefix:binding-dom-mapping-service + + runtime-mapping-singleton + /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] + + + + prefix:netty-timer + + global-timer + /modules/module[type='netty-hashed-wheel-timer'][name='global-timer'] + + + + prefix:netty-threadgroup + + global-boss-group + /modules/module[type='netty-threadgroup-fixed'][name='global-boss-group'] + + + global-worker-group + /modules/module[type='netty-threadgroup-fixed'][name='global-worker-group'] + + + + prefix:netty-event-executor + + global-event-executor + /modules/module[type='netty-global-event-executor'][name='singleton'] + + + + prefix:binding-rpc-registry + + binding-rpc-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + prefix:binding-notification-service + + binding-notification-broker + /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] + + + + prefix:binding-broker-osgi-registry + + binding-osgi-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + prefix:binding-data-broker + + binding-data-broker + /modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker'] + + + + prefix:kitchen-service + + kitchen-service + /modules/module[type='kitchen-service-impl'][name='kitchen-service-impl'] + + + + prefix:netconf-client-dispatcher + + global-netconf-dispatcher + /modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher'] + + + + + diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/pre-filter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/pre-filter.xml new file mode 100644 index 0000000000..8a57b4cab0 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/pre-filter.xml @@ -0,0 +1,350 @@ + + + + + prefix:toaster-provider-impl + toaster-provider-impl + + prefix:binding-notification-service + binding-notification-broker + + + prefix:binding-rpc-registry + binding-rpc-broker + + + prefix:binding-data-broker + binding-data-broker + + + + prefix:sal-netconf-connector + controller-config + 1830 + 20000 + 2000 + 1.5 + admin + + prefix:dom-broker-osgi-registry + dom-broker + + + prefix:netconf-client-dispatcher + global-netconf-dispatcher + + admin +
127.0.0.1
+ + prefix:threadpool + global-netconf-processing-executor + + false + + prefix:binding-broker-osgi-registry + binding-osgi-broker + + 0 + + prefix:netty-event-executor + global-event-executor + +
+ + prefix:netconf-client-dispatcher + global-netconf-dispatcher + + prefix:netty-threadgroup + global-worker-group + + + prefix:netty-timer + global-timer + + + prefix:netty-threadgroup + global-boss-group + + + + prefix:logback + singleton + + ERROR + STDOUT + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n + + + true + logs/audit.log + audit-file + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n + + + WARN + org.opendaylight.controller.logging.bridge + + + INFO + audit + audit-file + + + ERROR + ROOT + STDOUT + opendaylight.log + + + INFO + org.opendaylight + + + INFO + org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort + opendaylight.log + + + TRACE + org.opendaylight.controller.netconf + + + WARN + io.netty + + + true + 10MB + logs/opendaylight.log + opendaylight.log + logs/opendaylight.%d.log.zip + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n + false + 1 + TimeBasedRollingPolicy + + + + prefix:shutdown + shutdown + + + + prefix:netty-hashed-wheel-timer + global-timer + + + prefix:netty-threadgroup-fixed + global-boss-group + + + prefix:netty-threadgroup-fixed + global-worker-group + + + prefix:schema-service-singleton + yang-schema-service + + + prefix:dom-broker-impl + inmemory-dom-broker + + prefix:dom-async-data-broker + inmemory-data-broker + + + + prefix:dom-inmemory-data-broker + inmemory-data-broker + + prefix:schema-service + yang-schema-service + + + + prefix:threadpool-flexible + global-netconf-processing-executor + + prefix:threadfactory + global-netconf-processing-executor-threadfactory + + 1 + 4 + 600000 + + + prefix:netty-global-event-executor + singleton + + + prefix:binding-broker-impl + binding-broker-impl + + prefix:binding-notification-service + binding-notification-broker + + + prefix:binding-data-broker + binding-data-broker + + + + prefix:runtime-generated-mapping + runtime-mapping-singleton + + + prefix:binding-notification-broker + binding-notification-broker + + + prefix:binding-data-compatible-broker + inmemory-binding-data-broker + + prefix:dom-broker-osgi-registry + dom-broker + + + prefix:binding-dom-mapping-service + runtime-mapping-singleton + + + + prefix:threadfactory-naming + global-netconf-processing-executor-threadfactory + remote-connector-processing-executor + + + prefix:kitchen-service-impl + kitchen-service-impl + + prefix:binding-notification-service + binding-notification-broker + + + prefix:binding-rpc-registry + binding-rpc-broker + + + + prefix:remote-zeromq-rpc-server + remoter + 5666 + + prefix:dom-broker-osgi-registry + dom-broker + + +
+ + + prefix:schema-service + + yang-schema-service + /modules/module[type='schema-service-singleton'][name='yang-schema-service'] + + + + prefix:dom-broker-osgi-registry + + dom-broker + /modules/module[type='dom-broker-impl'][name='inmemory-dom-broker'] + + + + prefix:dom-async-data-broker + + inmemory-data-broker + /modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker'] + + + + prefix:threadpool + + global-netconf-processing-executor + /modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor'] + + + + prefix:threadfactory + + global-netconf-processing-executor-threadfactory + /modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory'] + + + + prefix:binding-dom-mapping-service + + runtime-mapping-singleton + /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] + + + + prefix:netty-timer + + global-timer + /modules/module[type='netty-hashed-wheel-timer'][name='global-timer'] + + + + prefix:netty-threadgroup + + global-boss-group + /modules/module[type='netty-threadgroup-fixed'][name='global-boss-group'] + + + global-worker-group + /modules/module[type='netty-threadgroup-fixed'][name='global-worker-group'] + + + + prefix:netty-event-executor + + global-event-executor + /modules/module[type='netty-global-event-executor'][name='singleton'] + + + + prefix:binding-rpc-registry + + binding-rpc-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + prefix:binding-notification-service + + binding-notification-broker + /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] + + + + prefix:binding-broker-osgi-registry + + binding-osgi-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + prefix:binding-data-broker + + binding-data-broker + /modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker'] + + + + prefix:kitchen-service + + kitchen-service + /modules/module[type='kitchen-service-impl'][name='kitchen-service-impl'] + + + + prefix:netconf-client-dispatcher + + global-netconf-dispatcher + /modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher'] + + + +
+
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/request.xml b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/request.xml new file mode 100644 index 0000000000..4d71ba4ac9 --- /dev/null +++ b/opendaylight/netconf/netconf-impl/src/test/resources/subtree/8/request.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java index 731aad6d1a..e9e92d9202 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java @@ -20,7 +20,7 @@ import org.opendaylight.controller.netconf.monitoring.MonitoringConstants; public class NetconfMonitoringOperationService implements NetconfOperationService { - public static final Set CAPABILITIES = Sets.newHashSet(new Capability() { + private static final Set CAPABILITIES = Sets.newHashSet(new Capability() { @Override public String getCapabilityUri() { diff --git a/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java b/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java index 4e32e82e89..2bda51b495 100644 --- a/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java +++ b/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/netty/SSHTest.java @@ -30,7 +30,7 @@ public class SSHTest { AuthProvider authProvider = mock(AuthProvider.class); doReturn(PEMGenerator.generate().toCharArray()).when(authProvider).getPEMAsCharArray(); doReturn(true).when(authProvider).authenticated(anyString(), anyString()); - NetconfSSHServer thread = NetconfSSHServer.start(1831, NetconfConfigUtil.getNetconfLocalAddress(), authProvider, new NioEventLoopGroup()); + NetconfSSHServer thread = NetconfSSHServer.start(10831, NetconfConfigUtil.getNetconfLocalAddress(), authProvider, new NioEventLoopGroup()); Thread.sleep(2000); logger.info("Closing socket"); thread.close(); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java index 65ca1b7c4b..8837c74ff5 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java @@ -47,12 +47,12 @@ public abstract class AbstractNetconfOperation implements NetconfOperation { public static final class OperationNameAndNamespace { private final String operationName, namespace; + private final XmlElement operationElement; public OperationNameAndNamespace(Document message) throws NetconfDocumentedException { XmlElement requestElement = null; requestElement = getRequestElementWithCheck(message); - - XmlElement operationElement = requestElement.getOnlyChildElement(); + operationElement = requestElement.getOnlyChildElement(); operationName = operationElement.getName(); namespace = operationElement.getNamespace(); } @@ -64,6 +64,10 @@ public abstract class AbstractNetconfOperation implements NetconfOperation { public String getNamespace() { return namespace; } + + public XmlElement getOperationElement() { + return operationElement; + } } protected static XmlElement getRequestElementWithCheck(Document message) throws NetconfDocumentedException { diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java index ac200a0aa6..8780925eb1 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java @@ -338,6 +338,17 @@ public final class XmlElement { ); } + public Optional getOnlyTextContentOptionally() { + // only return text content if this node has exactly one Text child node + if (element.getChildNodes().getLength() == 1) { + Node item = element.getChildNodes().item(0); + if (item instanceof Text) { + return Optional.of(((Text) item).getWholeText()); + } + } + return Optional.absent(); + } + public String getNamespaceAttribute() throws MissingNameSpaceException { String attribute = element.getAttribute(XmlUtil.XMLNS_ATTRIBUTE_KEY); if (attribute == null || attribute.equals("")){ diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java index 708f17cadb..fa72284b98 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java @@ -56,4 +56,5 @@ public final class XmlNetconfConstants { // TODO where to store namespace of config ? public static final String URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG = "urn:opendaylight:params:xml:ns:yang:controller:config"; public static final String GET = "get"; + public static final String GET_CONFIG = "get-config"; } diff --git a/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java b/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java index b2cb414303..7bd15ff7f4 100644 --- a/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java +++ b/opendaylight/sal/connection/implementation/src/main/java/org/opendaylight/controller/sal/connection/implementation/internal/ConnectionService.java @@ -111,7 +111,9 @@ public class ConnectionService implements IPluginOutConnectionService, IConnecti @Override public Node connect (String type, String connectionIdentifier, Map params) { IPluginInConnectionService s = pluginService.get(type); - if (s != null) return s.connect(connectionIdentifier, params); + if (s != null) { + return s.connect(connectionIdentifier, params); + } return null; } @@ -121,7 +123,9 @@ public class ConnectionService implements IPluginOutConnectionService, IConnecti for (String pluginType : this.pluginService.keySet()) { IPluginInConnectionService s = pluginService.get(pluginType); Node node = s.connect(connectionIdentifier, params); - if (node != null) return node; + if (node != null) { + return node; + } } } return null;