From 25563418e1867be44ab8d829db30360df60ee1c9 Mon Sep 17 00:00:00 2001 From: msunal Date: Fri, 25 Oct 2013 11:18:30 +0200 Subject: [PATCH] Solved bugs and added tests in sal-rest-connector - solved bugs in ControllerContext - added tests - formatting Change-Id: Ia552ec3aa6a8e4949aedfc01f8386dbc6875a73f Signed-off-by: Martin Sunal --- .../md-sal/sal-rest-connector/pom.xml | 34 +++++ .../sal/restconf/impl/BrokerFacade.xtend | 12 +- .../sal/restconf/impl/ControllerContext.xtend | 63 ++++++---- .../impl/InstanceIdWithSchemaNode.java | 6 +- .../sal/restconf/impl/RestconfImpl.xtend | 34 +++-- .../sal/restconf/impl/RestconfService.java | 21 ++-- .../impl/test/ControllerContextTest.java | 35 ++++++ .../restconf/impl/test/JsonMapperTest.java | 39 ++++++ .../restconf/impl/test/RestconfImplTest.java | 43 +++++++ .../sal/restconf/impl/test/TestUtils.java | 116 ++++++++++++++++++ .../{ => full-versions}/testData.json | 0 .../{ => full-versions}/testData.xml | 0 .../{ => full-versions/yangs}/ex-vlan.yang | 0 .../yangs}/iana-if-type.yang | 0 .../yangs}/ietf-interfaces@2013-07-04.yang | 0 .../yangs}/ietf-yang-types@2013-05-16.yang | 0 .../parts/ietf-interfaces_interfaces.xml | 6 + 17 files changed, 346 insertions(+), 63 deletions(-) create mode 100644 opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java create mode 100644 opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonMapperTest.java create mode 100644 opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java create mode 100644 opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java rename opendaylight/md-sal/sal-rest-connector/src/test/resources/{ => full-versions}/testData.json (100%) rename opendaylight/md-sal/sal-rest-connector/src/test/resources/{ => full-versions}/testData.xml (100%) rename opendaylight/md-sal/sal-rest-connector/src/test/resources/{ => full-versions/yangs}/ex-vlan.yang (100%) rename opendaylight/md-sal/sal-rest-connector/src/test/resources/{ => full-versions/yangs}/iana-if-type.yang (100%) rename opendaylight/md-sal/sal-rest-connector/src/test/resources/{ => full-versions/yangs}/ietf-interfaces@2013-07-04.yang (100%) rename opendaylight/md-sal/sal-rest-connector/src/test/resources/{ => full-versions/yangs}/ietf-yang-types@2013-05-16.yang (100%) create mode 100644 opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.xml diff --git a/opendaylight/md-sal/sal-rest-connector/pom.xml b/opendaylight/md-sal/sal-rest-connector/pom.xml index b28e9677b6..24ac2467f0 100644 --- a/opendaylight/md-sal/sal-rest-connector/pom.xml +++ b/opendaylight/md-sal/sal-rest-connector/pom.xml @@ -27,12 +27,46 @@ org.eclipse.xtend org.eclipse.xtend.lib + + org.slf4j + slf4j-api + org.jboss.resteasy jaxrs-api 3.0.4.Final provided + + + + junit + junit + test + + + org.mockito + mockito-all + test + + + ch.qos.logback + logback-classic + 1.0.9 + test + + + org.opendaylight.yangtools + yang-parser-impl + ${yang.version} + test + + + org.opendaylight.yangtools + yang-data-impl + ${yang.version} + test + diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend index e4cff4d6b1..07cd4a846b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend @@ -12,10 +12,10 @@ class BrokerFacade implements DataReader { @Property private ConsumerSession context; - + @Property private DataBrokerService dataService; - + override readConfigurationData(InstanceIdentifier path) { return dataService.readConfigurationData(path); } @@ -23,22 +23,22 @@ class BrokerFacade implements DataReader { override readOperationalData(InstanceIdentifier path) { return dataService.readOperationalData(path); } - + def RpcResult invokeRpc(QName type, CompositeNode payload) { val future = context.rpc(type, payload); return future.get; } - + def commitConfigurationDataUpdate(InstanceIdentifier path, CompositeNode payload) { val transaction = dataService.beginTransaction; transaction.putConfigurationData(path, payload); return transaction.commit() } - + def commitConfigurationDataCreate(InstanceIdentifier path, CompositeNode payload) { val transaction = dataService.beginTransaction; transaction.putConfigurationData(path, payload); return transaction.commit() } - + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index 49b997fa50..419ca50ee9 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -24,6 +24,7 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode import org.opendaylight.yangtools.yang.model.api.SchemaContext import static com.google.common.base.Preconditions.* +import java.util.Date class ControllerContext { @@ -36,17 +37,35 @@ class ControllerContext { public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) { val ret = InstanceIdentifier.builder(); val pathArgs = restconfInstance.split("/"); + if (pathArgs.empty) { + return null; + } val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule); new InstanceIdWithSchemaNode(ret.toInstance, schemaNode) } - + def findModule(String restconfInstance) { + checkNotNull(restconfInstance); val pathArgs = restconfInstance.split("/"); - val first = pathArgs.get(0); - val startModule = first.toModuleName(); - val module = schemas.findModuleByNamespace(moduleNameToUri.get(startModule)); - checkArgument(module.size == 1); // Only one version supported now - module.iterator.next + if (pathArgs.empty) { + return null; + } + val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head + val startModule = modulWithFirstYangStatement.toModuleName(); + schemas.getLatestModule(startModule) + } + + private def getLatestModule(SchemaContext schema, String moduleName) { + checkNotNull(schema) + checkArgument(moduleName != null && !moduleName.empty) + val modules = schema.modules.filter[m|m.name == moduleName] + var latestModule = modules.head + for (module : modules) { + if (module.revision.after(latestModule.revision)) { + latestModule = module + } + } + return latestModule } def String toFullRestconfIdentifier(InstanceIdentifier path) { @@ -137,30 +156,27 @@ class ControllerContext { return URLEncoder.encode(object.toString) } - def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List strings, DataNodeContainer parentNode) { + def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List strings, + DataNodeContainer parentNode) { checkNotNull(strings) - if (strings.length == 0) { - return null; + if (strings.empty) { + return parentNode as DataSchemaNode; } - val nodeRef = strings.get(0); + val nodeRef = strings.head; //val moduleName = nodeRef.toModuleName(); val nodeName = nodeRef.toNodeName(); - val naiveTargetNode = parentNode.getDataChildByName(nodeName); - - //var URI namespace; - var DataSchemaNode targetNode = naiveTargetNode; + val targetNode = parentNode.getDataChildByName(nodeName); + if (targetNode == null) { + return null + } - /*if(moduleName !== null) { - namespace = moduleNameToUri.get(moduleName); - - }*/ // Number of consumed elements var consumed = 1; if (targetNode instanceof ListSchemaNode) { val listNode = targetNode as ListSchemaNode; val keysSize = listNode.keyDefinition.size - val uriKeyValues = strings.subList(1, keysSize); + val uriKeyValues = strings.subList(consumed, consumed + keysSize); val keyValues = new HashMap(); var i = 0; for (key : listNode.keyDefinition) { @@ -176,11 +192,11 @@ class ControllerContext { builder.node(targetNode.QName); } if (targetNode instanceof DataNodeContainer) { - val remaining = strings.subList(consumed, strings.length - 1); + val remaining = strings.subList(consumed, strings.length); val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer); return result } - + return targetNode } @@ -193,6 +209,7 @@ class ControllerContext { } def String toModuleName(String str) { + checkNotNull(str) if (str.contains(":")) { val args = str.split(":"); checkArgument(args.size === 2); @@ -211,9 +228,7 @@ class ControllerContext { return str; } } - + public def QName toRpcQName(String name) { - - } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java index dd03b78462..ad0654af78 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java @@ -4,10 +4,10 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; public class InstanceIdWithSchemaNode { - + private final InstanceIdentifier instanceIdentifier; private final DataSchemaNode schemaNode; - + public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode) { this.instanceIdentifier = instanceIdentifier; this.schemaNode = schemaNode; @@ -20,5 +20,5 @@ public class InstanceIdWithSchemaNode { public DataSchemaNode getSchemaNode() { return schemaNode; } - + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend index f75c12dc7e..0b0ebc5922 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend @@ -6,58 +6,56 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode import static com.google.common.base.Preconditions.* class RestconfImpl implements RestconfService { - + @Property BrokerFacade broker - + @Property extension ControllerContext controllerContext - + val JsonMapper jsonMapper = new JsonMapper; - + def init(SchemaService schemaService) { checkState(broker !== null) checkState(controllerContext !== null) checkState(schemaService !== null) controllerContext.schemas = schemaService.globalContext } - + override readAllData() { return broker.readOperationalData("".removePrefixes.toInstanceIdentifier.getInstanceIdentifier); } - - + override getModules() { throw new UnsupportedOperationException("TODO: auto-generated method stub") } - + override getRoot() { throw new UnsupportedOperationException("TODO: auto-generated method stub") - + } - + override readData(String identifier) { val instanceIdentifierWithSchemaNode = identifier.removePrefixes.toInstanceIdentifier - val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier); + val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier); jsonMapper.convert(instanceIdentifierWithSchemaNode.getSchemaNode, data) } - + override createConfigurationData(String identifier, CompositeNode payload) { return broker.commitConfigurationDataCreate(identifier.removePrefixes.toInstanceIdentifier.getInstanceIdentifier, payload); } - - + override updateConfigurationData(String identifier, CompositeNode payload) { return broker.commitConfigurationDataCreate(identifier.removePrefixes.toInstanceIdentifier.getInstanceIdentifier, payload); } - + override invokeRpc(String identifier, CompositeNode payload) { val rpcResult = broker.invokeRpc(identifier.removePrefixes.toRpcQName, payload); jsonMapper.convert(identifier.removePrefixes.toInstanceIdentifier.getSchemaNode, rpcResult.result); } - + private def String removePrefixes(String path) { return path; } - -} \ No newline at end of file + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfService.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfService.java index 3dc181b826..8f821410c6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfService.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfService.java @@ -7,6 +7,8 @@ */ package org.opendaylight.controller.sal.restconf.impl; +import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API; + import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -14,11 +16,8 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.*; - /** * The URI hierarchy for the RESTCONF resources consists of an entry * point container, 3 top-level resources, and 1 field. Refer to @@ -49,37 +48,35 @@ public interface RestconfService { public static final String XML = "+xml"; public static final String JSON = "+json"; - + @GET public Object getRoot(); - + @GET @Path("/datastore") @Produces({API+JSON,API+XML}) public Object readAllData(); - + @GET @Path("/datastore/{identifier}") @Produces({API+XML}) public Object readData(@PathParam("identifier") String identifier); - + @PUT @Path("/datastore/{identifier}") @Produces({API+XML}) public Object createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload); - + @POST @Path("/datastore/{identifier}") @Produces({API+XML}) public Object updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload); - - - + @GET @Path("/modules") @Produces(API+XML) public Object getModules(); - + @POST @Path("/operations/{identifier}") @Produces(API+XML) diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java new file mode 100644 index 0000000000..9916278dfe --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java @@ -0,0 +1,35 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import static org.junit.Assert.assertEquals; + +import java.io.FileNotFoundException; +import java.util.Set; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +public class ControllerContextTest { + + private static final ControllerContext controllerContext = new ControllerContext(); + + @BeforeClass + public static void init() throws FileNotFoundException { + Set allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath()); + assertEquals(4, allModules.size()); + SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); + controllerContext.setSchemas(schemaContext); + } + + @Test + public void testToInstanceIdentifierList() throws FileNotFoundException { + InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("ietf-interfaces:interfaces/interface/foo"); + DataSchemaNode schemaNode = instanceIdentifier.getSchemaNode(); + assertEquals(schemaNode.getQName().getLocalName(), "interface"); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonMapperTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonMapperTest.java new file mode 100644 index 0000000000..b1d7d2281c --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JsonMapperTest.java @@ -0,0 +1,39 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import static org.junit.Assert.*; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.Set; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.controller.sal.restconf.impl.JsonMapper; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +public class JsonMapperTest { + + private static final ControllerContext controllerContext = new ControllerContext(); + + @BeforeClass + public static void init() throws FileNotFoundException { + Set allModules = TestUtils.loadModules(JsonMapperTest.class.getResource("/full-versions/yangs").getPath()); + assertEquals(4, allModules.size()); + SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); + controllerContext.setSchemas(schemaContext); + } + + @Test + public void test() throws FileNotFoundException { + InputStream xmlStream = JsonMapperTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml"); + CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream); + DataSchemaNode loadedSchemaNode = controllerContext.toInstanceIdentifier("ietf-interfaces:interfaces/interface/eth0").getSchemaNode(); + JsonMapper jsonMapper = new JsonMapper(); + String json = jsonMapper.convert(loadedSchemaNode, loadedCompositeNode); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java new file mode 100644 index 0000000000..8263c467b0 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java @@ -0,0 +1,43 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import static org.mockito.Mockito.*; +import static org.junit.Assert.*; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.Set; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; +import org.opendaylight.controller.sal.restconf.impl.ControllerContext; +import org.opendaylight.controller.sal.restconf.impl.RestconfImpl; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +public class RestconfImplTest { + + private static final RestconfImpl restconfImpl = new RestconfImpl(); + + @BeforeClass + public static void init() throws FileNotFoundException { + Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs").getPath()); + assertEquals(4, allModules.size()); + SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); + ControllerContext controllerContext = new ControllerContext(); + controllerContext.setSchemas(schemaContext); + restconfImpl.setControllerContext(controllerContext); + } + + @Test + public void testExample() throws FileNotFoundException { + InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml"); + CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream); + BrokerFacade brokerFacade = mock(BrokerFacade.class); + when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); + assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null)); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java new file mode 100644 index 0000000000..c32e350509 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java @@ -0,0 +1,116 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; +import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + +final class TestUtils { + + private static final Logger logger = LoggerFactory.getLogger(TestUtils.class); + + private final static YangModelParser parser = new YangParserImpl(); + + public static Set loadModules(String resourceDirectory) throws FileNotFoundException { + final File testDir = new File(resourceDirectory); + final String[] fileList = testDir.list(); + final List testFiles = new ArrayList(); + if (fileList == null) { + throw new FileNotFoundException(resourceDirectory); + } + for (int i = 0; i < fileList.length; i++) { + String fileName = fileList[i]; + testFiles.add(new File(testDir, fileName)); + } + return parser.parseYangModels(testFiles); + } + + public static SchemaContext loadSchemaContext(Set modules) { + return parser.resolveSchemaContext(modules); + } + + public static SchemaContext loadSchemaContext(String resourceDirectory) throws FileNotFoundException { + return parser.resolveSchemaContext(loadModules(resourceDirectory)); + } + + public static Module findModule(Set modules, String moduleName) { + Module result = null; + for (Module module : modules) { + if (module.getName().equals(moduleName)) { + result = module; + break; + } + } + return result; + } + + public static CompositeNode loadCompositeNode(InputStream xmlInputStream) throws FileNotFoundException { + if (xmlInputStream == null) { + throw new IllegalArgumentException(); + } + Node dataTree; + try { + dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream); + } catch (XMLStreamException e) { + logger.error("Error during building data tree from XML", e); + return null; + } + if (dataTree == null) { + logger.error("data tree is null"); + return null; + } + if (dataTree instanceof SimpleNode) { + logger.error("RPC XML was resolved as SimpleNode"); + return null; + } + return (CompositeNode) dataTree; + } + + public static String getDocumentInPrintableForm(Document doc) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + + transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, "UTF-8"))); + byte[] charData = out.toByteArray(); + return new String(charData, "UTF-8"); + } catch (IOException | TransformerException e) { + String msg = "Error during transformation of Document into String"; + logger.error(msg, e); + return msg; + } + + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/testData.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/testData.json similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/testData.json rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/testData.json diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/testData.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/testData.xml similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/testData.xml rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/testData.xml diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/ex-vlan.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/ex-vlan.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/ex-vlan.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/ex-vlan.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/iana-if-type.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/iana-if-type.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/iana-if-type.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/iana-if-type.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/ietf-interfaces@2013-07-04.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/ietf-interfaces@2013-07-04.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/ietf-interfaces@2013-07-04.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/ietf-interfaces@2013-07-04.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/ietf-yang-types@2013-05-16.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/ietf-yang-types@2013-05-16.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/ietf-yang-types@2013-05-16.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/ietf-yang-types@2013-05-16.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.xml new file mode 100644 index 0000000000..988ba7aa27 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/parts/ietf-interfaces_interfaces.xml @@ -0,0 +1,6 @@ + + eth0 + ethernetCsmacd + false + some interface + -- 2.36.6