From: Ed Warnicke Date: Thu, 9 Jan 2014 07:25:47 +0000 (+0000) Subject: Merge "private key configurable in config.ini" X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~126 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=3fdb59d96aecf80c8e5b414f2c69fc2d521c0abd;hp=ebb776d215a9285d56ca5121f3e5fc6678253538;p=controller.git Merge "private key configurable in config.ini" --- diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java index 81b0921660..028d7d1f40 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java @@ -8,7 +8,6 @@ package org.opendaylight.controller.config.manager.impl; import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; import junit.framework.Assert; import org.junit.After; import org.mockito.Matchers; @@ -26,6 +25,8 @@ import org.opendaylight.controller.config.util.ConfigRegistryJMXClient; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanServer; @@ -38,7 +39,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Dictionary; import java.util.List; -import java.util.Map; import java.util.Set; import static org.junit.Assert.assertEquals; @@ -66,8 +66,16 @@ public abstract class AbstractConfigTest extends protected BundleContext mockedContext = mock(BundleContext.class); protected ServiceRegistration mockedServiceRegistration; - protected Map getBundleContextServiceRegistrationHandlers() { - return Maps.newHashMap(); + private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class); + + // Default handler for OSGi service registration + private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() { + @Override + public void handleServiceRegistration(Object serviceInstance) {} + }; + + protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class serviceType) { + return noopServiceRegHandler; } // this method should be called in @Before @@ -166,9 +174,8 @@ public abstract class AbstractConfigTest extends protected ObjectName createTestConfigBean( ConfigTransactionJMXClient transaction, String implementationName, String name) throws InstanceAlreadyExistsException { - ObjectName nameCreated = transaction.createModule(implementationName, + return transaction.createModule(implementationName, name); - return nameCreated; } protected void assertBeanCount(int i, String configMXBeanName) { @@ -204,26 +211,42 @@ public abstract class AbstractConfigTest extends } private class RegisterServiceAnswer implements Answer { + @Override public Object answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); - Preconditions.checkArgument(args.length == 3); + Preconditions.checkArgument(args.length == 3, "Unexpected arguments size (expected 3 was %s)", args.length); - Preconditions.checkArgument(args[0] instanceof Class); - Class serviceType = (Class) args[0]; + Object serviceTypeRaw = args[0]; Object serviceInstance = args[1]; - BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandlers() - .get(serviceType); + if (serviceTypeRaw instanceof Class) { + Class serviceType = (Class) serviceTypeRaw; + invokeServiceHandler(serviceInstance, serviceType); + + } else if(serviceTypeRaw instanceof String[]) { + for (String className : (String[]) serviceTypeRaw) { + try { + Class serviceType = Class.forName(className); + invokeServiceHandler(serviceInstance, serviceType); + } catch (ClassNotFoundException e) { + logger.warn("Not handling service registration of type {} ", className, e); + } + } - Preconditions.checkArgument(serviceType.isAssignableFrom(serviceInstance.getClass())); + } else + logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw); + + return mockedServiceRegistration; + } + + private void invokeServiceHandler(Object serviceInstance, Class serviceType) { + BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType); if (serviceRegistrationHandler != null) { serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance)); } - - return mockedServiceRegistration; } } } diff --git a/opendaylight/config/pom.xml b/opendaylight/config/pom.xml index eba5e07c0f..9f9bca9d98 100644 --- a/opendaylight/config/pom.xml +++ b/opendaylight/config/pom.xml @@ -61,7 +61,7 @@ 1.7 1.7 4.10 - 2.3.7 + 2.4.0 5.0.0 0.6.2.201302030002 1.7.2 diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java index 9356dd3752..0d704a8f6a 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java @@ -186,7 +186,15 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size()); return yangStoreSnapshot; } catch (RuntimeException e) { - throw new YangStoreException("Unable to parse yang files from following URLs: " + multimap, e); + StringBuffer causeStr = new StringBuffer(); + Throwable cause = e; + while (cause != null) { + causeStr.append(e.getMessage()); + causeStr.append("\n"); + cause = e.getCause(); + } + throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() + + "URLs: " + multimap, e); } } diff --git a/opendaylight/md-sal/model/pom.xml b/opendaylight/md-sal/model/pom.xml index 1fc9b50b3f..571e9d8df2 100644 --- a/opendaylight/md-sal/model/pom.xml +++ b/opendaylight/md-sal/model/pom.xml @@ -19,7 +19,7 @@ UTF-8 - 2.3.7 + 2.4.0 @@ -40,7 +40,7 @@ ${project.groupId}.${project.artifactId} - *,org.opendaylight.yangtools.yang.binding.annotations + org.opendaylight.yangtools.yang.binding.annotations, * diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java index fb7872f8bc..8b1bdef8ba 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java @@ -43,7 +43,7 @@ class JsonMapper { private final Set foundLeafLists = new HashSet<>(); private final Set foundLists = new HashSet<>(); - private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); + private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException { Preconditions.checkNotNull(writer); @@ -184,16 +184,23 @@ class JsonMapper { TypeDefinition baseType = RestUtil.resolveBaseTypeFrom(type); + if (node.getValue() == null && !(baseType instanceof EmptyTypeDefinition)) { + logger.debug("While generationg JSON output null value was found for type " + + baseType.getClass().getSimpleName() + "."); + } + // TODO check InstanceIdentifierTypeDefinition if (baseType instanceof IdentityrefTypeDefinition) { if (node.getValue() instanceof QName) { IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType).serialize(node.getValue()); IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0); - String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace())); + String moduleName = ControllerContext.getInstance().findModuleByNamespace( + URI.create(valueFromDTO.getNamespace())); writer.value(moduleName + ":" + valueFromDTO.getValue()); } else { logger.debug("Value of " + baseType.getQName().getNamespace() + ":" - + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass()); + + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + + node.getValue().getClass()); writer.value(String.valueOf(node.getValue())); } } else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java index 0e9bad046b..0dd4668a74 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java @@ -1,14 +1,60 @@ package org.opendaylight.controller.sal.rest.impl; import javax.activation.UnsupportedDataTypeException; + import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec; +import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; +import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.Leafref; import org.w3c.dom.Document; +import com.google.common.base.Optional; public class XmlMapper { + private static final LeafrefCodecImpl LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl( + Optional. absent()); + + private static class LeafrefCodecImpl extends TypeDefinitionAwareCodec implements + LeafrefCodec { + + protected LeafrefCodecImpl(Optional typeDef) { + super(typeDef, Object.class); + } + + @Override + public String serialize(Object data) { + return String.valueOf(data); + } + + @Override + public Object deserialize(String data) { + return data; + } + } + + private static class XmlCodecProviderImpl implements XmlCodecProvider { + @Override + public TypeDefinitionAwareCodec> codecFor(TypeDefinition baseType) { + TypeDefinitionAwareCodec> codec = TypeDefinitionAwareCodec + .from(baseType); + + if (codec == null) { + if (baseType instanceof Leafref) { + return LEAFREF_DEFAULT_CODEC; + } + } + return codec; + } + } + + private static final XmlCodecProvider XML_CODEC_PROVIDER_IMPL = new XmlCodecProviderImpl(); + public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException { - return XmlDocumentUtils.toDocument(data, schema, XmlDocumentUtils.defaultValueCodecProvider()); + return XmlDocumentUtils.toDocument(data, schema, XML_CODEC_PROVIDER_IMPL); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java index 450ba02b56..40fba88356 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java @@ -19,16 +19,16 @@ public class RestCodec { private RestCodec() { } - + public static final Codec from(TypeDefinition typeDefinition) { return new ObjectCodec(typeDefinition); } - + @SuppressWarnings("rawtypes") public static final class ObjectCodec implements Codec { private final Logger logger = LoggerFactory.getLogger(RestCodec.class); - + public static final Codec IDENTITYREF_DEFAULT_CODEC = new IdentityrefCodecImpl(); public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(); @@ -37,7 +37,7 @@ public class RestCodec { private ObjectCodec(TypeDefinition typeDefinition) { type = RestUtil.resolveBaseTypeFrom(typeDefinition); } - + @SuppressWarnings("unchecked") @Override public Object deserialize(Object input) { @@ -47,16 +47,21 @@ public class RestCodec { } else if (type instanceof LeafrefTypeDefinition) { return LEAFREF_DEFAULT_CODEC.deserialize(input); } else { - TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec.from(type); + TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec + .from(type); if (typeAwarecodec != null) { return typeAwarecodec.deserialize(String.valueOf(input)); } else { - logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet."); + logger.debug("Codec for type \"" + type.getQName().getLocalName() + + "\" is not implemented yet."); return null; } } - } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs - logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e); + } catch (ClassCastException e) { // TODO remove this catch when + // everyone use codecs + logger.error( + "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), + e); return input; } } @@ -70,22 +75,27 @@ public class RestCodec { } else if (type instanceof LeafrefTypeDefinition) { return LEAFREF_DEFAULT_CODEC.serialize(input); } else { - TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec.from(type); + TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec + .from(type); if (typeAwarecodec != null) { return typeAwarecodec.serialize(input); } else { - logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet."); + logger.debug("Codec for type \"" + type.getQName().getLocalName() + + "\" is not implemented yet."); return null; } } - } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs - logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e); + } catch (ClassCastException e) { // TODO remove this catch when + // everyone use codecs + logger.error( + "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), + e); return input; } } - + } - + public static class IdentityrefCodecImpl implements IdentityrefCodec { @Override @@ -105,7 +115,7 @@ public class RestCodec { } } - + public static class LeafrefCodecImpl implements LeafrefCodec { @Override @@ -117,7 +127,7 @@ public class RestCodec { public Object deserialize(String data) { return data; } - + } - + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java similarity index 90% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java index b01d4104b2..e754fdec5f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java @@ -1,22 +1,44 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.StringReader; import java.util.Map; import java.util.Set; +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.controller.sal.restconf.impl.test.structures.*; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.controller.sal.restconf.impl.test.structures.Cont; +import org.opendaylight.controller.sal.restconf.impl.test.structures.Lf; +import org.opendaylight.controller.sal.restconf.impl.test.structures.LfLst; +import org.opendaylight.controller.sal.restconf.impl.test.structures.Lst; +import org.opendaylight.controller.sal.restconf.impl.test.structures.LstItem; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; -public class ToJsonBasicYangTypesTest { +public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-yang-types", 1, "simple-yang-types", "cont1"); + } /** * Test of json output when as input are specified composite node with empty @@ -24,9 +46,16 @@ public class ToJsonBasicYangTypesTest { */ @Test public void compositeNodeAndYangWithJsonReaderEmptyDataTest() { - String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(), - "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1"); - verifyJsonOutputForEmpty(jsonOutput); + CompositeNode compositeNode = prepareCompositeNodeWithEmpties(); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + String jsonOutput = null; + try { + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + + verifyJsonOutputForEmptyData(jsonOutput); } /** @@ -35,13 +64,21 @@ public class ToJsonBasicYangTypesTest { */ @Test public void xmlAndYangTypesWithJsonReaderTest() { - String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/simple-yang-types/xml/data.xml"), - "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1"); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-yang-types/xml/data.xml", + XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + String jsonOutput = null; + try { + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + verifyJsonOutput(jsonOutput); } - private void verifyJsonOutputForEmpty(String jsonOutput) { + private void verifyJsonOutputForEmptyData(String jsonOutput) { + assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -60,6 +97,7 @@ public class ToJsonBasicYangTypesTest { } private void verifyJsonOutput(String jsonOutput) { + assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java similarity index 86% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java index b745411bf4..1eb3779730 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java @@ -8,11 +8,13 @@ import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { +public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialization() { @@ -111,10 +113,11 @@ public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader { } private void testWrapper(String xmlPath, String pathToSchemaNode) { - CompositeNode compNode = TestUtils.loadCompositeNode(xmlPath); - TestUtils.normalizeCompositeNode(compNode, modules, dataSchemaNode, pathToSchemaNode); + CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compNode, modules, pathToSchemaNode); try { - TestUtils.writeCompNodeWithSchemaContextToJson(compNode, modules, dataSchemaNode); + TestUtils.writeCompNodeWithSchemaContextToOutput(compNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); } catch (WebApplicationException | IOException e) { // shouldn't end here assertTrue(false); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java similarity index 56% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java index 73d0c82521..c45c0b3288 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java @@ -1,153 +1,57 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.StringReader; -import java.math.BigDecimal; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import javax.ws.rs.WebApplicationException; -import javax.xml.bind.DatatypeConverter; +import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.data.impl.NodeFactory; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; -public class ToJsonBasicDataTypesTest { +public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-data-types"); + } @Test public void simpleYangDataTest() { - String jsonOutput = ""; - CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/simple-data-types/xml/data.xml"); - Set modules = TestUtils.resolveModules("/cnsn-to-json/simple-data-types"); - assertEquals(1, modules.size()); - Module module = TestUtils.resolveModule(null, modules); - assertNotNull(module); - DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null); - assertNotNull(dataSchemaNode); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", + XmlToCompositeNodeProvider.INSTANCE); - TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "simple-data-types:cont"); + String jsonOutput = null; + + TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont"); try { - jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode); + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); } catch (WebApplicationException | IOException e) { - assertTrue(false); // shouldn't get here } + assertNotNull(jsonOutput); - System.out.println(jsonOutput); verifyJsonOutput(jsonOutput); } - private CompositeNode prepareData() { - MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, - ModifyAction.CREATE, null); - - List> childNodes = new ArrayList<>(); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Min"), cont, (byte) -128, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Max"), cont, (byte) 127, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Min"), cont, (short) -32768, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Max"), cont, (short) 32767, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Min"), cont, - (int) -2147483648, ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Max"), cont, (int) 2147483647, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Min"), cont, new Long( - "-9223372036854775807"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Max"), cont, new Long( - "9223372036854775807"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint8Max"), cont, (short) 255, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint16Max"), cont, (int) 65535, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint32Max"), cont, new Long( - "4294967295"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr"), cont, "lfstr", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr1"), cont, "", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool1"), cont, Boolean.TRUE, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool2"), cont, Boolean.FALSE, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal1"), cont, new BigDecimal( - "43.32"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal2"), cont, new BigDecimal( - "-0.43"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal3"), cont, new BigDecimal( - "43"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal4"), cont, new BigDecimal( - "43E3"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal6"), cont, new BigDecimal( - "33.12345"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfenum"), cont, "enum3", - ModifyAction.CREATE, null)); - - HashSet bits = new HashSet(); - bits.add("bit3"); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbits"), cont, bits, - ModifyAction.CREATE, null)); - - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbinary"), cont, DatatypeConverter - .parseBase64Binary("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"), - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfempty"), cont, null, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion1"), cont, (int) 324, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion2"), cont, new BigDecimal( - "33.3"), ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion3"), cont, "55", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion4"), cont, Boolean.TRUE, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion5"), cont, "true", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion6"), cont, "false", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion7"), cont, null, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion8"), cont, "", - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion9"), cont, "", - ModifyAction.CREATE, null)); - - HashSet bits2 = new HashSet(); - bits2.add("bt1"); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion10"), cont, bits2, - ModifyAction.CREATE, null)); - - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion11"), cont, (short) 33, - ModifyAction.CREATE, null)); - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion12"), cont, Boolean.FALSE, - ModifyAction.CREATE, null)); - try { - childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("identityref1"), cont, new QName( - new URI("simple:data:types"), "iden"), ModifyAction.CREATE, null)); - } catch (URISyntaxException e) { - } - - cont.getChildren().addAll(childNodes); - - cont.init(); - - return cont; - } - private void verifyJsonOutput(String jsonOutput) { StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -178,7 +82,6 @@ public class ToJsonBasicDataTypesTest { private void jsonReadContElements(JsonReader jReader) throws IOException { jReader.beginObject(); List loadedLfs = new ArrayList<>(); - boolean exceptForDecimal5Raised = false; boolean enumChecked = false; boolean bitsChecked = false; boolean lfdecimal6Checked = false; @@ -190,7 +93,6 @@ public class ToJsonBasicDataTypesTest { boolean lfbool2Checked = false; boolean lfstrChecked = false; boolean lfbinaryChecked = false; - // boolean lfref1Checked = false; boolean lfemptyChecked = false; boolean lfstr1Checked = false; boolean lfidentityrefChecked = false; @@ -201,11 +103,7 @@ public class ToJsonBasicDataTypesTest { try { peek = jReader.peek(); } catch (IOException e) { - if (keyName.equals("lfdecimal5")) { - exceptForDecimal5Raised = true; - } else { - assertTrue("Key " + keyName + " has incorrect value for specifed type", false); - } + assertTrue("Key " + keyName + " has incorrect value for specifed type", false); } if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java similarity index 56% rename from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java rename to opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java index 6d30559ccd..6920b0f1ff 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java @@ -11,12 +11,14 @@ import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.*; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; -public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { +public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialization() { @@ -27,7 +29,9 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { public void identityrefToJsonTest() { String json = null; try { - json = TestUtils.writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), modules, dataSchemaNode); + QName valueAsQname = TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"); + json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(valueAsQname), modules, + dataSchemaNode, StructuredDataToJsonProvider.INSTANCE); } catch (WebApplicationException | IOException e) { // shouldn't end here assertTrue(false); @@ -40,15 +44,35 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { assertTrue(mtch.matches()); } - private CompositeNode prepareCompositeNode() { + @Test + public void identityrefToJsonWithoutQNameTest() { + String json = null; + try { + String value = "not q name value"; + json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(value), modules, + dataSchemaNode, StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + // shouldn't end here + assertTrue(false); + } + System.out.println(json); + assertNotNull(json); + Pattern ptrn = Pattern.compile(".*\"lf1\"\\p{Space}*:\\p{Space}*\"not q name value\".*", Pattern.DOTALL); + Matcher mtch = ptrn.matcher(json); + + assertTrue(mtch.matches()); + } + + private CompositeNode prepareCompositeNode(Object value) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null, ModifyAction.CREATE, null); cont.getChildren().add(cont1); - MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, - TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"), ModifyAction.CREATE, null); + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, value, + ModifyAction.CREATE, null); + cont1.getChildren().add(lf1); cont1.init(); cont.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java new file mode 100644 index 0000000000..6b5776263c --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java @@ -0,0 +1,170 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +import javax.activation.UnsupportedDataTypeException; +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.api.YangNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CnSnToJsonIncorrectTopLevelTest extends YangAndXmlAndDataSchemaLoader { + + private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonIncorrectTopLevelTest.class); + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-data-types"); + } + + private class IncorrectDataSchema implements DataSchemaNode, DataNodeContainer { + + @Override + public String getDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + public SchemaPath getPath() { + // TODO Auto-generated method stub + return null; + } + + @Override + public QName getQName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getReference() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Status getStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getUnknownSchemaNodes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getChildNodes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public DataSchemaNode getDataChildByName(QName arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DataSchemaNode getDataChildByName(String arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getGroupings() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set> getTypeDefinitions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getUses() { + // TODO Auto-generated method stub + return null; + } + + @Override + public ConstraintDefinition getConstraints() { + // TODO Auto-generated method stub + return null; + } + + @Override + public YangNode getParent() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isAddedByUses() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isAugmenting() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isConfiguration() { + // TODO Auto-generated method stub + return false; + } + + } + + @Test + public void incorrectTopLevelElementTest() { + + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", XmlToCompositeNodeProvider.INSTANCE); + DataSchemaNode incorrectDataSchema = null; + incorrectDataSchema = new IncorrectDataSchema(); + + TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont"); + + boolean exceptionRaised = false; + try { + TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, incorrectDataSchema, + StructuredDataToJsonProvider.INSTANCE); + } catch (UnsupportedDataTypeException e) { + exceptionRaised = true; + } catch (WebApplicationException | IOException e) { + LOG.error("WebApplicationException or IOException was raised"); + } + + assertTrue(exceptionRaised); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java new file mode 100644 index 0000000000..3215e81719 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java @@ -0,0 +1,103 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; + +/** + * + * All tests are commented now because leafref isn't supported now + * + */ + +public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialization() { + dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont"); + } + + @Test + public void leafrefAbsolutePathToExistingLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"); + validateJson(".*\"lf3\":\\p{Blank}*\"true\".*", json); + } + + @Test + public void leafrefRelativePathToExistingLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"); + validateJson(".*\"lf2\":\\p{Blank}*\"121\".*", json); + } + + /** + * Tests case when reference to not existing element is present. In this + * case value from single node is printed as string. + */ + @Test + public void leafrefToNonExistingLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"); + validateJson(".*\"lf5\":\\p{Blank}*\"137\".*", json); + } + + /** + * Tests case when non leaf element is referenced. In this case value from + * single node is printed as string. + */ + @Test + public void leafrefToNotLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"); + validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*", json); + } + + /** + * Tests case when leaflist element is refers to leaf. + */ + @Test + public void leafrefFromLeafListToLeafTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"); + validateJson( + ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*\"345\",\\p{Space}*\"346\",\\p{Space}*\"347\".*", + json); + } + + /** + * Tests case when leaflist element is refers to leaf. + */ + @Test + public void leafrefFromLeafrefToLeafrefTest() { + String json = toJson("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"); + validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*\"200\".*", json); + } + + private void validateJson(String regex, String value) { + assertNotNull(value); + Pattern ptrn = Pattern.compile(regex, Pattern.DOTALL); + Matcher mtch = ptrn.matcher(value); + assertTrue(mtch.matches()); + } + + private String toJson(String xmlDataPath) { + try { + CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlDataPath, XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + return TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + return ""; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java new file mode 100644 index 0000000000..e5a317e2d5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java @@ -0,0 +1,72 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.restconf.impl.test.*; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLoader { + + private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonNotExistingLeafTypeTest.class); + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/simple-data-types"); + } + + @Test + public void incorrectTopLevelElementTest() { + + String jsonOutput = null; + try { + jsonOutput = TestUtils + .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), + (Set) Collections.EMPTY_SET, prepareDataSchemaNode(), + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + LOG.error("WebApplicationException or IOException was raised"); + } + assertNotNull(jsonOutput); + assertTrue(jsonOutput.contains("\"lf1\": \"\"")); + } + + private CompositeNode prepareCompositeNode() { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( + TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); + cont.getChildren().add(lf1); + cont.init(); + return cont; + } + + private DataSchemaNode prepareDataSchemaNode() { + ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont", + "simple:uri", "2012-12-17"), null); + LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1", + "simple:uri", "2012-12-17"), null); + leafBuild.setType(new DummyType()); + leafBuild.setConfiguration(true); + + contBuild.addChildNode(leafBuild); + return contBuild.build(null); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java new file mode 100644 index 0000000000..3c2325c0f3 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java @@ -0,0 +1,51 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; + +public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/cnsn-to-json/augmentation", 5, "yang", "cont"); + } + + /** + * Test of json output when as input are specified composite node with empty + * data + YANG file + */ + @Test + public void augmentedElementsToJson() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/augmentation/xml/data.xml", + XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + + String jsonOutput = null; + try { + jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + assertNotNull(jsonOutput); + + assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\"")); + assertTrue(jsonOutput.contains("\"augment-container:cont1\": {")); + assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\"")); + assertTrue(jsonOutput.contains("\"augment-list:lst1\": [")); + assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\"")); + assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\"")); + assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": [")); + } +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java deleted file mode 100644 index 1ac81a332f..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.regex.Matcher; - -import javax.ws.rs.WebApplicationException; - -import org.junit.*; -import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; - -/** - * - * All tests are commented now because leafref isn't supported now - * - */ - -public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader { - - @BeforeClass - public static void initialization() { - dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont"); - } - - @Ignore - @Test - public void leafrefAbsolutePathToExistingLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf3\":\\p{Blank}*true.*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - @Ignore - @Test - public void leafrefRelativePathToExistingLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf2\":\\p{Blank}*121.*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when reference to not existing element is present. In this - * case value from single node is printed as string. - */ - @Ignore - @Test - public void leafrefToNonExistingLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf5\":\\p{Blank}*\"137\".*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when non leaf element is referenced. In this case value from - * single node is printed as string. - */ - @Ignore - @Test - public void leafrefToNotLeafTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"), modules, - dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile( - ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when leaflist element is refers to leaf. - */ - @Ignore - @Test - public void leafrefFromLeafListToLeafTest() { - String json = null; - try { - json = TestUtils - .writeCompNodeWithSchemaContextToJson( - TestUtils - .loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"), - modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern - .compile( - ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*345,\\p{Space}*346,\\p{Space}*347.*", - java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - - /** - * Tests case when leaflist element is refers to leaf. - */ - @Ignore - @Test - public void leafrefFromLeafrefToLeafrefTest() { - String json = null; - try { - json = TestUtils.writeCompNodeWithSchemaContextToJson( - TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"), modules, - dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // shouldn't end here - assertTrue(false); - } - assertNotNull(json); - java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile( - ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*200.*", java.util.regex.Pattern.DOTALL); - Matcher mtch = ptrn.matcher(json); - assertTrue(mtch.matches()); - } - -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java deleted file mode 100644 index 73bd178ff3..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; - -public class ToJsonWithAugmentTest { - - /** - * Test of json output when as input are specified composite node with empty - * data + YANG file - */ - @Test - public void augmentedElementsToJson() { - - CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/augmentation/xml/data.xml"); - String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(compositeNode, - "/cnsn-to-json/augmentation", "/cnsn-to-json/augmentation/xml", "yang", "cont"); - - assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\"")); - assertTrue(jsonOutput.contains("\"augment-container:cont1\": {")); - assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\"")); - assertTrue(jsonOutput.contains("\"augment-list:lst1\": [")); - assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\"")); - assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\"")); - assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": [")); - } -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java new file mode 100644 index 0000000000..d779b5ce7b --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java @@ -0,0 +1,70 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import javax.ws.rs.WebApplicationException; + +import org.junit.Ignore; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; +import org.opendaylight.controller.sal.restconf.impl.test.DummyType; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CnSnToXmlNotExistingLeafTypeTest { + + private static final Logger LOG = LoggerFactory.getLogger(CnSnToXmlNotExistingLeafTypeTest.class); + + @Ignore + @Test + public void incorrectTopLevelElementTest() { + + boolean nullPointerExceptionRaised = false; + try { + TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), + (Set) Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + LOG.error("WebApplicationException or IOException was raised"); + } catch (NullPointerException e) { + nullPointerExceptionRaised = true; + } + assertTrue(nullPointerExceptionRaised); + + } + + private CompositeNode prepareCompositeNode() { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( + TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); + cont.getChildren().add(lf1); + cont.init(); + return cont; + } + + private DataSchemaNode prepareDataSchemaNode() { + ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont", + "simple:uri", "2012-12-17"), null); + LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1", + "simple:uri", "2012-12-17"), null); + leafBuild.setType(new DummyType()); + leafBuild.setConfiguration(true); + + contBuild.addChildNode(leafBuild); + return contBuild.build(null); + + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java index d04337865a..96e03a5a3c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java @@ -1,24 +1,21 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -import java.io.StringWriter; -import java.util.Set; +import java.io.IOException; -import javax.activation.UnsupportedDataTypeException; -import javax.xml.transform.*; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; +import javax.ws.rs.WebApplicationException; +import javax.xml.transform.TransformerFactoryConfigurationError; import org.junit.BeforeClass; import org.junit.Test; -import org.opendaylight.controller.sal.rest.impl.XmlMapper; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.data.api.*; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; -import org.opendaylight.yangtools.yang.model.api.*; -import org.w3c.dom.Document; /** * @@ -27,25 +24,31 @@ import org.w3c.dom.Document; * XML file * */ -public class CnSnToXmlTest { - - private static Set modules; - private static DataSchemaNode dataSchemaNode; - +public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialization() { - modules = TestUtils.resolveModules("/cnsn-to-xml/yang"); - assertEquals(2, modules.size()); - Module module = TestUtils.resolveModule("basic-module", modules); - assertNotNull(module); - dataSchemaNode = TestUtils.resolveDataSchemaNode(module, "cont"); - assertNotNull(dataSchemaNode); - + dataLoad("/cnsn-to-xml/yang", 2, "basic-module", "cont"); } @Test public void snAsYangIdentityrefToXMLTest() { - serializeToXml(prepareIdentityrefData(), "x:iden"); + serializeToXml(prepareIdentityrefData(null, true), "x:iden"); + } + + @Test + public void snAsYangIdentityrefWithQNamePrefixToXMLTest() { + serializeToXml(prepareIdentityrefData("prefix", true), + "prefix:iden"); + } + + @Test + public void snAsYangIdentityrefWithPrefixToXMLTest() { + serializeToXml(prepareIdentityrefData("prefix", false), "no qname value"); + } + + @Test + public void snAsYangLeafrefWithPrefixToXMLTest() { + serializeToXml(prepareLeafrefData(), "true", "true"); } @Test @@ -186,22 +189,13 @@ public class CnSnToXmlTest { private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation) throws TransformerFactoryConfigurationError { - XmlMapper xmlMapper = new XmlMapper(); - String xmlString = null; - if (dataSchemaNode instanceof DataNodeContainer) { - try { - Document doc = xmlMapper.write(compositeNode, (DataNodeContainer) dataSchemaNode); - DOMSource domSource = new DOMSource(doc); - StringWriter writer = new StringWriter(); - StreamResult result = new StreamResult(writer); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - transformer.transform(domSource, result); - xmlString = writer.toString(); - } catch (UnsupportedDataTypeException | TransformerException e) { - } + String xmlString = ""; + try { + xmlString = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { } - assertNotNull(xmlMapper); + assertNotNull(xmlString); boolean containSearchedStr = false; String strRepresentation = ""; for (String searchedStr : xmlRepresentation) { @@ -215,16 +209,21 @@ public class CnSnToXmlTest { } - private CompositeNode prepareIdentityrefData() { + private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null); cont.getChildren().add(cont1); + Object value = null; + if (valueAsQName) { + value = TestUtils.buildQName("iden", "referenced:module", "2013-12-2", prefix); + } else { + value = "no qname value"; + } MutableSimpleNode lf11 = NodeFactory.createMutableSimpleNode( - TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, - TestUtils.buildQName("iden", "referenced:module", "2013-12-2"), ModifyAction.CREATE, null); + TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null); cont1.getChildren().add(lf11); cont1.init(); cont.init(); @@ -244,4 +243,19 @@ public class CnSnToXmlTest { return cont; } + private CompositeNode prepareLeafrefData() { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, + ModifyAction.CREATE, null); + + MutableSimpleNode lfBoolean = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfBoolean"), + cont, Boolean.TRUE, ModifyAction.CREATE, null); + MutableSimpleNode lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont, + "true", ModifyAction.CREATE, null); + cont.getChildren().add(lfBoolean); + cont.getChildren().add(lfLfref); + cont.init(); + + return cont; + } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java new file mode 100644 index 0000000000..a23501cbe6 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java @@ -0,0 +1,64 @@ +package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; + +/** + * + * CnSn = Composite node and Simple node data structure Class contains test of + * serializing simple nodes data values according data types from YANG schema to + * XML file + * + */ +public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader { + @BeforeClass + public static void initialization() { + dataLoad("/cnsn-to-xml/choice", 1, "module-with-choice", "cont"); + } + + @Test + public void cnSnToXmlWithYangChoice() { + String xmlOutput = ""; + try { + xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput( + prepareCnStructForYangData("lf1", "String data1"), modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + + assertTrue(xmlOutput.contains("String data1")); + + try { + xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput( + prepareCnStructForYangData("lf2", "String data2"), modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + } catch (WebApplicationException | IOException e) { + } + assertTrue(xmlOutput.contains("String data2")); + + } + + private CompositeNode prepareCnStructForYangData(String lfName, Object data) { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, + ModifyAction.CREATE, null); + + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data, + ModifyAction.CREATE, null); + cont.getChildren().add(lf1); + cont.init(); + + return cont; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java new file mode 100644 index 0000000000..e9b1dbe1a5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java @@ -0,0 +1,74 @@ +package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; + +import static org.junit.Assert.*; + +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.*; + +public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/json-to-cnsn/identityref", 2, "identityref-module", "cont"); + } + + @Test + public void jsonIdentityrefToCompositeNode() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false, + JsonToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); + + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + + assertEquals("cont", compositeNode.getNodeType().getLocalName()); + + List> childs = compositeNode.getChildren(); + assertEquals(1, childs.size()); + Node nd = childs.iterator().next(); + assertTrue(nd instanceof CompositeNode); + assertEquals("cont1", nd.getNodeType().getLocalName()); + + childs = ((CompositeNode) nd).getChildren(); + assertEquals(4, childs.size()); + SimpleNode lf11 = null; + SimpleNode lf12 = null; + SimpleNode lf13 = null; + SimpleNode lf14 = null; + for (Node child : childs) { + assertTrue(child instanceof SimpleNode); + if (child.getNodeType().getLocalName().equals("lf11")) { + lf11 = (SimpleNode) child; + } else if (child.getNodeType().getLocalName().equals("lf12")) { + lf12 = (SimpleNode) child; + } else if (child.getNodeType().getLocalName().equals("lf13")) { + lf13 = (SimpleNode) child; + } else if (child.getNodeType().getLocalName().equals("lf14")) { + lf14 = (SimpleNode) child; + } + } + + assertTrue(lf11.getValue() instanceof QName); + assertEquals("iden", ((QName) lf11.getValue()).getLocalName()); + assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString()); + + assertTrue(lf12.getValue() instanceof QName); + assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName()); + assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString()); + + assertTrue(lf13.getValue() instanceof QName); + assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName()); + assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString()); + + assertTrue(lf14.getValue() instanceof QName); + assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName()); + assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString()); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java new file mode 100644 index 0000000000..2bb42d903a --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java @@ -0,0 +1,48 @@ +package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; + +import static org.junit.Assert.*; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.*; + +public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/json-to-cnsn/leafref"); + } + + /** + * JSON values which represents leafref are always loaded to simple node as + * string + */ + @Test + public void jsonIdentityrefToCompositeNode() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/leafref/json/data.json", false, + JsonToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); + TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName); + + assertEquals("cont", compositeNode.getNodeType().getLocalName()); + + SimpleNode lf2 = null; + for (Node childNode : compositeNode.getChildren()) { + if (childNode instanceof SimpleNode) { + if (childNode.getNodeType().getLocalName().equals("lf2")) { + lf2 = (SimpleNode) childNode; + break; + } + } + } + + assertNotNull(lf2); + assertTrue(lf2.getValue() instanceof String); + assertEquals("121", (String) lf2.getValue()); + + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java index b02ea9a3a2..f2c0c29bc4 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java @@ -1,9 +1,10 @@ package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -import java.io.*; -import java.net.URISyntaxException; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -12,10 +13,12 @@ import javax.ws.rs.WebApplicationException; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; +import org.opendaylight.controller.sal.restconf.impl.ResponseException; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +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.model.api.Module; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +31,7 @@ public class JsonToCnSnTest { @Test public void simpleListTest() { - simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1", + simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang/1", "lst", "simple:list:yang1", "simple-list-yang1"); } @@ -43,7 +46,8 @@ public class JsonToCnSnTest { */ @Test public void multipleItemsInLeafList() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); assertEquals(3, compositeNode.getChildren().size()); @@ -76,9 +80,10 @@ public class JsonToCnSnTest { */ @Test public void multipleItemsInListTest() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true); - assertNotNull(compositeNode); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true, + JsonToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); assertEquals("lst", compositeNode.getNodeType().getLocalName()); verityMultipleItemsInList(compositeNode); @@ -86,7 +91,8 @@ public class JsonToCnSnTest { @Test public void nullArrayToSimpleNodeWithNullValueTest() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); assertEquals("cont", compositeNode.getNodeType().getLocalName()); @@ -103,7 +109,8 @@ public class JsonToCnSnTest { public void incorrectTopLevelElementsTest() { Throwable cause1 = null; try { - compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true); + TestUtils + .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause1 = e; } @@ -117,7 +124,8 @@ public class JsonToCnSnTest { Throwable cause2 = null; try { - compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true); + TestUtils + .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause2 = e; } @@ -126,7 +134,8 @@ public class JsonToCnSnTest { Throwable cause3 = null; try { - compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true); + TestUtils + .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause3 = e; } @@ -145,7 +154,8 @@ public class JsonToCnSnTest { */ @Test public void emptyDataReadTest() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); @@ -158,7 +168,7 @@ public class JsonToCnSnTest { String reason = null; try { - compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true); + TestUtils.readInputToCnSn("/json-to-cnsn/empty-data1.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (JsonSyntaxException e) { reason = e.getMessage(); } @@ -176,24 +186,20 @@ public class JsonToCnSnTest { @Test public void notSupplyNamespaceIfAlreadySupplied() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json"); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - DataSchemaNode dataSchemaNode1 = null; - DataSchemaNode dataSchemaNode2 = null; - try { - dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang1"); - dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang2"); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - assertNotNull(dataSchemaNode1); - assertNotNull(dataSchemaNode2); - // supplement namespaces according to first data schema - // "simple:data:types1" - TestUtils.supplementNamespace(dataSchemaNode1, compositeNode); + Set modules1 = new HashSet<>(); + Set modules2 = new HashSet<>(); + modules1 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/1"); + modules2 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/2"); + assertNotNull(modules1); + assertNotNull(modules2); + + TestUtils.normalizeCompositeNode(compositeNode, modules1, "simple-list-yang1:lst"); assertTrue(compositeNode instanceof CompositeNodeWrapper); CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap(); @@ -201,26 +207,27 @@ public class JsonToCnSnTest { assertEquals("lst", compNode.getNodeType().getLocalName()); verifyCompositeNode(compNode, "simple:list:yang1"); - // dataSchemaNode2 should't be taken into account, because compNode - // isn't CompositeNodeWrapper - TestUtils.supplementNamespace(dataSchemaNode2, compNode); - verifyCompositeNode(compNode, "simple:list:yang1"); + String exceptionMessage = ""; + try { + TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst"); + } catch (ResponseException e) { + exceptionMessage = String.valueOf(e.getResponse().getEntity()); + } + assertTrue(exceptionMessage + .contains("Data has bad format\nIf data is in XML format then namespace for lst should be simple:list:yang2.\n If data is in Json format then module name for lst should be simple-list-yang2.")); } @Test public void jsonIdentityrefToCompositeNode() { - CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json"); + CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false, + JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - Set modules = TestUtils.resolveModules("/json-to-cnsn/identityref"); + Set modules = TestUtils.loadModulesFrom("/json-to-cnsn/identityref"); assertEquals(2, modules.size()); - Module module = TestUtils.resolveModule("identityref-module", modules); - assertNotNull(module); - DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null); - assertNotNull(dataSchemaNode); - TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "identityref-module:cont"); + TestUtils.normalizeCompositeNode(compositeNode, modules, "identityref-module:cont"); assertEquals("cont", compositeNode.getNodeType().getLocalName()); @@ -268,19 +275,14 @@ public class JsonToCnSnTest { private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace, String moduleName) { - CompositeNode compositeNode = compositeContainerFromJson(jsonPath); + CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - DataSchemaNode dataSchemaNode = null; - try { - dataSchemaNode = TestUtils.obtainSchemaFromYang(yangPath, moduleName); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - assertNotNull(dataSchemaNode); + Set modules = null; + modules = TestUtils.loadModulesFrom(yangPath); + assertNotNull(modules); - TestUtils.supplementNamespace(dataSchemaNode, compositeNode); + TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + topLevelElementName); assertTrue(compositeNode instanceof CompositeNodeWrapper); CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap(); @@ -331,7 +333,8 @@ public class JsonToCnSnTest { boolean lflst1_2Found = false; boolean lf1Found = false; - assertEquals(namespace, compositeNode.getNodeType().getNamespace().toString()); + // assertEquals(namespace, + // compositeNode.getNodeType().getNamespace().toString()); for (Node node : compositeNode.getChildren()) { if (node.getNodeType().getLocalName().equals("cont1")) { @@ -369,34 +372,16 @@ public class JsonToCnSnTest { assertTrue(lf1Found); } - private CompositeNode compositeContainerFromJson(String jsonPath) { - return compositeContainerFromJson(jsonPath, false); - } - - private CompositeNode compositeContainerFromJson(String jsonPath, boolean dummyNamespaces) - throws WebApplicationException { - - JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE; - InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath); + @Test + public void unsupportedDataFormatTest() { + String exceptionMessage = ""; try { - CompositeNode compositeNode = jsonToCompositeNodeProvider - .readFrom(null, null, null, null, null, jsonStream); - assertTrue(compositeNode instanceof CompositeNodeWrapper); - if (dummyNamespaces) { - try { - TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode); - return ((CompositeNodeWrapper) compositeNode).unwrap(); - } catch (URISyntaxException e) { - LOG.error(e.getMessage()); - assertTrue(e.getMessage(), false); - } - } - return compositeNode; - } catch (IOException e) { - LOG.error(e.getMessage()); - assertTrue(e.getMessage(), false); + TestUtils.readInputToCnSn("/json-to-cnsn/unsupported-json-format.json", true, + JsonToCompositeNodeProvider.INSTANCE); + } catch (WebApplicationException e) { + exceptionMessage = e.getCause().getMessage(); } - return null; + assertTrue(exceptionMessage.contains("Root element of Json has to be Object")); } } 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 index 08ec3f2b0c..c68fcb9071 100644 --- 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 @@ -1,21 +1,22 @@ package org.opendaylight.controller.sal.restconf.impl.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.io.FileNotFoundException; import java.util.Set; import org.junit.BeforeClass; import org.junit.Test; -import org.mockito.Mock; - -import static org.mockito.Mockito.*; - import org.opendaylight.controller.sal.core.api.mount.MountInstance; import org.opendaylight.controller.sal.core.api.mount.MountService; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -26,8 +27,8 @@ public class ControllerContextTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext.setSchemas(schemaContext); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java new file mode 100644 index 0000000000..0876584cab --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java @@ -0,0 +1,64 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import java.util.List; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.*; + +public class DummyType implements TypeDefinition { + QName dummyQName = TestUtils.buildQName("dummy type", "simple:uri", "2012-12-17"); + + @Override + public QName getQName() { + return dummyQName; + } + + @Override + public SchemaPath getPath() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getReference() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Status getStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getUnknownSchemaNodes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public DummyType getBaseType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getUnits() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object getDefaultValue() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index d58b7e9dab..2370035861 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -7,15 +7,25 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.net.*; -import java.util.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Set; -import org.junit.*; +import org.junit.BeforeClass; +import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.opendaylight.controller.sal.restconf.impl.*; -import org.opendaylight.yangtools.yang.common.*; -import org.opendaylight.yangtools.yang.data.api.*; +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.controller.sal.restconf.impl.StructuredData; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; +import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.Module; @@ -33,7 +43,7 @@ public class InvokeRpcMethodTest { @BeforeClass public static void initialization() { - modules = TestUtils.resolveModules("/invoke-rpc"); + modules = TestUtils.loadModulesFrom("/invoke-rpc"); assertEquals(1, modules.size()); Module module = TestUtils.resolveModule("invoke-rpc-module", modules); assertNotNull(module); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java index 0bb03cb0ad..f2eea9dbd2 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java @@ -1,6 +1,7 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -45,8 +46,8 @@ public class ReadConfAndOperDataTest extends JerseyTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext = ControllerContext.getInstance(); controllerContext.setSchemas(schemaContext); @@ -69,15 +70,16 @@ public class ReadConfAndOperDataTest extends JerseyTest { String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0"); - CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml"); + CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", true, + XmlToCompositeNodeProvider.INSTANCE); when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(200, response.getStatus()); - + uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example"); when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null); - + response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(404, response.getStatus()); } @@ -86,16 +88,17 @@ public class ReadConfAndOperDataTest extends JerseyTest { public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException { String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0"); - - CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml"); + CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", true, + XmlToCompositeNodeProvider.INSTANCE); + when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode); Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(200, response.getStatus()); - + uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example"); when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null); - + response = target(uri).request(MEDIA_TYPE_DRAFT02).get(); assertEquals(404, response.getStatus()); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java new file mode 100644 index 0000000000..fcc4c02a6f --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java @@ -0,0 +1,33 @@ +package org.opendaylight.controller.sal.restconf.impl.test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import org.junit.Test; +import org.opendaylight.controller.sal.restconf.impl.RestCodec; +import org.opendaylight.yangtools.concepts.Codec; +import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.BitsType; + +public class RestCodecExceptionsTest { + + @Test + public void serializeExceptionTest() { + Codec codec = RestCodec.from(new BitsType(null)); + String serializedValue = (String) codec.serialize("incorrect value"); // set + // expected + assertEquals("incorrect value", serializedValue); + } + + @Test + public void deserializeExceptionTest() { + IdentityrefTypeDefinition mockedIidentityrefType = mock(IdentityrefTypeDefinition.class); + + Codec codec = RestCodec.from(mockedIidentityrefType); + String serializedValue = (String) codec.deserialize("incorrect value"); // IdentityValuesDTO + // object + // expected + assertEquals("incorrect value", serializedValue); + } + +} 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 index 41cc0ddb51..c15cd53082 100644 --- 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 @@ -1,17 +1,20 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; 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.*; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +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; @@ -23,8 +26,8 @@ public class RestconfImplTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); ControllerContext controllerContext = ControllerContext.getInstance(); controllerContext.setSchemas(schemaContext); @@ -33,8 +36,7 @@ public class RestconfImplTest { @Test public void testExample() throws FileNotFoundException { - InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml"); - CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream); + CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", XmlToCompositeNodeProvider.INSTANCE); 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 index 366d99dbcb..4295c29a22 100644 --- 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 @@ -1,32 +1,50 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.io.*; +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.net.URI; import java.net.URISyntaxException; import java.sql.Date; -import java.util.*; -import java.util.concurrent.Future; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; import javax.ws.rs.WebApplicationException; -import javax.xml.parsers.*; -import javax.xml.stream.XMLStreamException; -import javax.xml.transform.*; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +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.controller.md.sal.common.api.TransactionStatus; -import org.opendaylight.controller.sal.rest.impl.*; -import org.opendaylight.controller.sal.restconf.impl.*; +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.NodeWrapper; +import org.opendaylight.controller.sal.restconf.impl.RestconfImpl; +import org.opendaylight.controller.sal.restconf.impl.StructuredData; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder; -import org.opendaylight.yangtools.yang.model.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +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; @@ -38,11 +56,11 @@ import com.google.common.base.Preconditions; public final class TestUtils { - private static final Logger logger = LoggerFactory.getLogger(TestUtils.class); + private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class); private final static YangModelParser parser = new YangParserImpl(); - public static Set loadModules(String resourceDirectory) throws FileNotFoundException { + private static Set loadModules(String resourceDirectory) throws FileNotFoundException { final File testDir = new File(resourceDirectory); final String[] fileList = testDir.list(); final List testFiles = new ArrayList(); @@ -58,34 +76,40 @@ public final class TestUtils { return parser.parseYangModels(testFiles); } + public static Set loadModulesFrom(String yangPath) { + try { + return TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath()); + } catch (FileNotFoundException e) { + LOG.error("Yang files at path: " + yangPath + " weren't loaded."); + } + + return null; + } + public static SchemaContext loadSchemaContext(Set modules) { return parser.resolveSchemaContext(modules); } public static SchemaContext loadSchemaContext(String resourceDirectory) throws FileNotFoundException { - return parser.resolveSchemaContext(loadModules(resourceDirectory)); + return parser.resolveSchemaContext(loadModulesFrom(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 module; } } - return result; + return null; } - - public static Document loadDocumentFrom(InputStream inputStream) { try { DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); return docBuilder.parse(inputStream); } catch (SAXException | IOException | ParserConfigurationException e) { - logger.error("Error during loading Document from XML", e); + LOG.error("Error during loading Document from XML", e); return null; } } @@ -107,288 +131,84 @@ public final class TestUtils { return new String(charData, "UTF-8"); } catch (IOException | TransformerException e) { String msg = "Error during transformation of Document into String"; - logger.error(msg, e); + LOG.error(msg, e); return msg; } } - public static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, - String outputPath, String searchedModuleName, String searchedDataSchemaName) { - Set modules = resolveModules(yangPath); - Module module = resolveModule(searchedModuleName, modules); - DataSchemaNode dataSchemaNode = resolveDataSchemaNode(module, searchedDataSchemaName); - - normalizeCompositeNode(compositeNode, modules, dataSchemaNode, searchedModuleName + ":" - + searchedDataSchemaName); - - try { - return writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode); - } catch (WebApplicationException | IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - - } - - public static void normalizeCompositeNode(CompositeNode compositeNode, Set modules, - DataSchemaNode dataSchemaNode, String schemaNodePath) { + /** + * + * Fill missing data (namespaces) and build correct data type in + * {@code compositeNode} according to {@code dataSchemaNode}. The method + * {@link RestconfImpl#createConfigurationData createConfigurationData} is + * used because it contains calling of method {code normalizeNode} + */ + public static void normalizeCompositeNode(CompositeNode compositeNode, Set modules, String schemaNodePath) { RestconfImpl restconf = RestconfImpl.getInstance(); ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules)); - TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf); + prepareMocksForRestconf(modules, restconf); restconf.createConfigurationData(schemaNodePath, compositeNode); } + /** + * Searches module with name {@code searchedModuleName} in {@code modules}. + * If module name isn't specified and module set has only one element then + * this element is returned. + * + */ public static Module resolveModule(String searchedModuleName, Set modules) { - assertNotNull("modules can't be null.", modules); - Module module = null; + assertNotNull("Modules can't be null.", modules); if (searchedModuleName != null) { for (Module m : modules) { if (m.getName().equals(searchedModuleName)) { - module = m; - break; + return m; } } } else if (modules.size() == 1) { - module = modules.iterator().next(); + return modules.iterator().next(); } - return module; - } - - public static Set resolveModules(String yangPath) { - Set modules = null; - - try { - modules = TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath()); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - return modules; + return null; } - public static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) { - assertNotNull("Module is missing", module); + public static DataSchemaNode resolveDataSchemaNode(String searchedDataSchemaName, Module module) { + assertNotNull("Module can't be null", module); - DataSchemaNode dataSchemaNode = null; if (searchedDataSchemaName != null) { for (DataSchemaNode dsn : module.getChildNodes()) { if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) { - dataSchemaNode = dsn; + return dsn; } } } else if (module.getChildNodes().size() == 1) { - dataSchemaNode = module.getChildNodes().iterator().next(); + return module.getChildNodes().iterator().next(); } - return dataSchemaNode; - } - - public static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, Set modules, - DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException { - String jsonResult; - - assertNotNull(dataSchemaNode); - assertNotNull("Composite node can't be null", compositeNode); - ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); - - ControllerContext.getInstance().setSchemas(loadSchemaContext(modules)); - - StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE; - structuredDataToJsonProvider.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null, - null, byteArrayOS); - - jsonResult = byteArrayOS.toString(); - - return jsonResult; - } - - public static CompositeNode loadCompositeNode(String xmlDataPath) { - InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath); - CompositeNode compositeNode = null; - try { - XmlReader xmlReader = new XmlReader(); - compositeNode = xmlReader.read(xmlStream); - - } catch (UnsupportedFormatException | XMLStreamException e) { - e.printStackTrace(); - } - return compositeNode; - } - - static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException { - FileOutputStream fileOS = null; - try { - String path = TestUtils.class.getResource(outputDir).getPath(); - File outFile = new File(path + "/data.json"); - fileOS = new FileOutputStream(outFile); - try { - fileOS.write(outputStream.toByteArray()); - } catch (IOException e) { - e.printStackTrace(); - } - fileOS.close(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } - } - - static String readJsonFromFile(String path, boolean removeWhiteChars) { - FileReader fileReader = getFileReader(path); - - StringBuilder strBuilder = new StringBuilder(); - char[] buffer = new char[1000]; - - while (true) { - int loadedCharNum; - try { - loadedCharNum = fileReader.read(buffer); - } catch (IOException e) { - break; - } - if (loadedCharNum == -1) { - break; - } - strBuilder.append(buffer, 0, loadedCharNum); - } - try { - fileReader.close(); - } catch (IOException e) { - System.out.println("The file wasn't closed"); - } - String rawStr = strBuilder.toString(); - if (removeWhiteChars) { - rawStr = rawStr.replace("\n", ""); - rawStr = rawStr.replace("\r", ""); - rawStr = rawStr.replace("\t", ""); - rawStr = removeSpaces(rawStr); - } - - return rawStr; - } - - private static FileReader getFileReader(String path) { - String fullPath = TestUtils.class.getResource(path).getPath(); - assertNotNull("Path to file can't be null.", fullPath); - File file = new File(fullPath); - assertNotNull("File can't be null", file); - FileReader fileReader = null; - try { - fileReader = new FileReader(file); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - assertNotNull("File reader can't be null.", fileReader); - return fileReader; - } - - private static String removeSpaces(String rawStr) { - StringBuilder strBuilder = new StringBuilder(); - int i = 0; - int quoteCount = 0; - while (i < rawStr.length()) { - if (rawStr.substring(i, i + 1).equals("\"")) { - quoteCount++; - } - - if (!rawStr.substring(i, i + 1).equals(" ") || (quoteCount % 2 == 1)) { - strBuilder.append(rawStr.charAt(i)); - } - i++; - } - - return strBuilder.toString(); + return null; } - public static QName buildQName(String name, String uri, String date) { + public static QName buildQName(String name, String uri, String date, String prefix) { try { URI u = new URI(uri); Date dt = null; if (date != null) { dt = Date.valueOf(date); } - return new QName(u, dt, name); + return new QName(u, dt, prefix, name); } catch (URISyntaxException e) { return null; } } - public static QName buildQName(String name) { - return buildQName(name, "", null); - } - - public static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) { - RestconfImpl restconf = RestconfImpl.getInstance(); - - InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class), - dataSchemaNode); - - ControllerContext controllerContext = mock(ControllerContext.class); - BrokerFacade broker = mock(BrokerFacade.class); - - RpcResult rpcResult = new DummyRpcResult.Builder().result( - TransactionStatus.COMMITED).build(); - Future> future = DummyFuture.builder().rpcResult(rpcResult).build(); - when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema); - when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn( - future); - - restconf.setControllerContext(controllerContext); - restconf.setBroker(broker); - - // method is called only because it contains call of method which - // supplement namespaces to compositeNode - restconf.createConfigurationData("something", compositeNode); - } - - public static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException { - return obtainSchemaFromYang(yangFolder, null); + public static QName buildQName(String name, String uri, String date) { + return buildQName(name, uri, date, null); } - public static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName) - throws FileNotFoundException { - Set modules = null; - modules = TestUtils.loadModules(TestUtils.class.getResource(yangFolder).getPath()); - - if (modules == null) { - return null; - } - if (modules.size() < 1) { - return null; - } - - Module moduleRes = null; - if (modules.size() > 1) { - if (moduleName == null) { - return null; - } else { - for (Module module : modules) { - if (module.getName().equals(moduleName)) { - moduleRes = module; - } - } - if (moduleRes == null) { - return null; - } - } - } else { - moduleRes = modules.iterator().next(); - } - - if (moduleRes.getChildNodes() == null) { - return null; - } - - if (moduleRes.getChildNodes().size() != 1) { - return null; - } - DataSchemaNode dataSchemaNode = moduleRes.getChildNodes().iterator().next(); - return dataSchemaNode; - + public static QName buildQName(String name) { + return buildQName(name, "", null); } - public static void addDummyNamespaceToAllNodes(NodeWrapper wrappedNode) throws URISyntaxException { + private static void addDummyNamespaceToAllNodes(NodeWrapper wrappedNode) throws URISyntaxException { wrappedNode.setNamespace(new URI("")); if (wrappedNode instanceof CompositeNodeWrapper) { for (NodeWrapper childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) { @@ -397,56 +217,63 @@ public final class TestUtils { } } - public static void prepareMockForRestconfBeforeNormalization(Set modules, DataSchemaNode dataSchemaNode, - RestconfImpl restconf) { - ControllerContext instance = ControllerContext.getInstance(); - instance.setSchemas(TestUtils.loadSchemaContext(modules)); - restconf.setControllerContext(ControllerContext.getInstance()); - + private static void prepareMocksForRestconf(Set modules, RestconfImpl restconf) { + ControllerContext controllerContext = ControllerContext.getInstance(); BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class); + + controllerContext.setSchemas(TestUtils.loadSchemaContext(modules)); + when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))) .thenReturn( new DummyFuture.Builder().rpcResult( new DummyRpcResult.Builder().result(TransactionStatus.COMMITED) .build()).build()); + + restconf.setControllerContext(controllerContext); restconf.setBroker(mockedBrokerFacade); } - - static CompositeNode loadCompositeNodeWithXmlTreeBuilder(String xmlDataPath) { - InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath); - CompositeNode compositeNode = null; + + public static CompositeNode readInputToCnSn(String path, boolean dummyNamespaces, + MessageBodyReader reader) throws WebApplicationException { + + InputStream inputStream = TestUtils.class.getResourceAsStream(path); try { - compositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream); - } catch (FileNotFoundException e) { - e.printStackTrace(); + CompositeNode compositeNode = reader.readFrom(null, null, null, null, null, inputStream); + assertTrue(compositeNode instanceof CompositeNodeWrapper); + if (dummyNamespaces) { + try { + TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode); + return ((CompositeNodeWrapper) compositeNode).unwrap(); + } catch (URISyntaxException e) { + LOG.error(e.getMessage()); + assertTrue(e.getMessage(), false); + } + } + return compositeNode; + } catch (IOException e) { + LOG.error(e.getMessage()); + assertTrue(e.getMessage(), false); } - return compositeNode; - - - + return null; } - - - public static CompositeNode loadCompositeNodeWithXmlTreeBuilder(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 CompositeNode readInputToCnSn(String path, MessageBodyReader reader) { + return readInputToCnSn(path, false, reader); + } + + public static String writeCompNodeWithSchemaContextToOutput(CompositeNode compositeNode, Set modules, + DataSchemaNode dataSchemaNode, MessageBodyWriter messageBodyWriter) throws IOException, + WebApplicationException { + + assertNotNull(dataSchemaNode); + assertNotNull("Composite node can't be null", compositeNode); + ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); + + ControllerContext.getInstance().setSchemas(loadSchemaContext(modules)); + + messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null, null, + byteArrayOS); + + return byteArrayOS.toString(); + } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java index 4cea120d4d..b18f526a23 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java @@ -1,6 +1,7 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -35,7 +36,6 @@ import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.*; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -51,8 +51,8 @@ public class XmlProvidersTest extends JerseyTest { @BeforeClass public static void init() throws FileNotFoundException { - Set allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs") - .getPath()); + Set allModules = TestUtils.loadModulesFrom("/full-versions/yangs"); + assertNotNull(allModules); SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules); controllerContext = ControllerContext.getInstance(); controllerContext.setSchemas(schemaContext); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java index 7e3da0e4b4..3d24c6ba67 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java @@ -4,24 +4,32 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Set; -import org.opendaylight.yangtools.yang.model.api.*; + +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; public abstract class YangAndXmlAndDataSchemaLoader { protected static Set modules; protected static DataSchemaNode dataSchemaNode; + protected static String searchedModuleName; + protected static String searchedDataSchemaName; + protected static String schemaNodePath; protected static void dataLoad(String yangPath) { dataLoad(yangPath, 1, null, null); } protected static void dataLoad(String yangPath, int modulesNumber, String moduleName, String dataSchemaName) { - modules = TestUtils.resolveModules(yangPath); + modules = TestUtils.loadModulesFrom(yangPath); assertEquals(modulesNumber, modules.size()); Module module = TestUtils.resolveModule(moduleName, modules); + searchedModuleName = module == null ? "" : module.getName(); assertNotNull(module); - dataSchemaNode = TestUtils.resolveDataSchemaNode(module, dataSchemaName); + dataSchemaNode = TestUtils.resolveDataSchemaNode(dataSchemaName, module); + searchedDataSchemaName = dataSchemaNode == null ? "" : dataSchemaNode.getQName().getLocalName(); assertNotNull(dataSchemaNode); + schemaNodePath = searchedModuleName + ":" + searchedDataSchemaName; } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java new file mode 100644 index 0000000000..beff5724eb --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java @@ -0,0 +1,351 @@ +package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test; + +import static org.junit.Assert.*; + +import java.util.List; +import java.util.Set; + +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XmlLeafrefToCnSnTest { + private static final Logger LOG = LoggerFactory.getLogger(XmlLeafrefToCnSnTest.class); + + /** + * top level element represents container. second level element is list with + * two elements. + */ + @Test + public void testXmlDataContainer() { + CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-container.xml", false, + XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compNode); + Set modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-container-yang"); + + assertNotNull(modules); + TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont"); + + String nameSpace = "data:container:yang"; + assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString()); + + verifyNullAndEmptyStringSingleNode(compNode, nameSpace); + verifyCommonPartAOfXml(compNode, "", nameSpace); + } + + private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) { + assertEquals("cont", compNode.getNodeType().getLocalName()); + + SimpleNode lf2 = null; + SimpleNode lf3 = null; + int found = 0; + for (Node child : compNode.getChildren()) { + if (found == 0x3) + break; + if (child instanceof SimpleNode) { + SimpleNode childSimple = (SimpleNode) child; + if (childSimple.getNodeType().getLocalName().equals("lf3")) { + lf3 = childSimple; + found = found | (1 << 0); + } else if (childSimple.getNodeType().getLocalName().equals("lf2")) { + lf2 = childSimple; + found = found | (1 << 1); + } + } + assertEquals(nameSpace, child.getNodeType().getNamespace().toString()); + } + + assertEquals("", lf2.getValue()); + assertEquals(null, lf3.getValue()); + } + + @Test + public void testXmlDataList() { + CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-list.xml", false, + XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compNode); + + Set modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-list-yang"); + assertNotNull(modules); + + TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont"); + + String nameSpaceList = "data:list:yang"; + String nameSpaceCont = "data:container:yang"; + assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); + assertEquals("cont", compNode.getNodeType().getLocalName()); + assertEquals(3, compNode.getChildren().size()); + CompositeNode lst1_1 = null; + CompositeNode lst1_2 = null; + int loopCount = 0; + for (Node node : compNode.getChildren()) { + if (node.getNodeType().getLocalName().equals("lf1")) { + assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString()); + assertTrue(node instanceof SimpleNode); + assertEquals("lf1", node.getValue()); + } else { + assertTrue(node instanceof CompositeNode); + switch (loopCount++) { + case 0: + lst1_1 = (CompositeNode) node; + break; + case 1: + lst1_2 = (CompositeNode) node; + break; + } + assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString()); + } + } + // lst1_1 + verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont); + // :lst1_1 + + // lst1_2 + SimpleNode lflst11 = null; + CompositeNode cont11 = null; + for (Node node : lst1_2.getChildren()) { + String nodeName = node.getNodeType().getLocalName(); + if (nodeName.equals("lflst11")) { + assertTrue(node instanceof SimpleNode); + lflst11 = (SimpleNode) node; + + } else if (nodeName.equals("cont11")) { + assertTrue(node instanceof CompositeNode); + cont11 = (CompositeNode) node; + } + assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); + } + assertEquals("221", lflst11.getValue()); + + assertEquals(1, cont11.getChildren().size()); + assertTrue(cont11.getChildren().get(0) instanceof SimpleNode); + SimpleNode cont11_lf111 = (SimpleNode) cont11.getChildren().get(0); + assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString()); + assertEquals("lf111", cont11_lf111.getNodeType().getLocalName()); + assertEquals((short) 100, cont11_lf111.getValue()); + // :lst1_2 + + } + + @Test + public void testXmlEmptyData() { + CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/empty-data.xml", true, + XmlToCompositeNodeProvider.INSTANCE); + assertEquals("cont", compNode.getNodeType().getLocalName()); + SimpleNode lf1 = null; + SimpleNode lflst1_1 = null; + SimpleNode lflst1_2 = null; + CompositeNode lst1 = null; + int lflst1Count = 0; + for (Node node : compNode.getChildren()) { + if (node.getNodeType().getLocalName().equals("lf1")) { + assertTrue(node instanceof SimpleNode); + lf1 = (SimpleNode) node; + } else if (node.getNodeType().getLocalName().equals("lflst1")) { + assertTrue(node instanceof SimpleNode); + + switch (lflst1Count++) { + case 0: + lflst1_1 = (SimpleNode) node; + break; + case 1: + lflst1_2 = (SimpleNode) node; + break; + } + } else if (node.getNodeType().getLocalName().equals("lst1")) { + assertTrue(node instanceof CompositeNode); + lst1 = (CompositeNode) node; + } + } + + assertNotNull(lf1); + assertNotNull(lflst1_1); + assertNotNull(lflst1_2); + assertNotNull(lst1); + + assertEquals("", lf1.getValue()); + assertEquals("", lflst1_1.getValue()); + assertEquals("", lflst1_2.getValue()); + assertEquals(1, lst1.getChildren().size()); + assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName()); + + assertTrue(lst1.getChildren().get(0) instanceof SimpleNode); + assertEquals("", lst1.getChildren().get(0).getValue()); + + } + + /** + * Test case like this x:identity + */ + @Test + public void testIdentityrefNmspcInElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref", + "identityref-module", "cont", 2, "iden", "identity:module"); + } + + /** + * + * Test case like identity + */ + + @Test + public void testIdentityrefDefaultNmspcInElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml", + "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module"); + } + + /** + * + * Test case like identity + */ + @Test + public void testIdentityrefDefaultNmspcInParrentElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); + } + + /** + * + * Test case like + * x:identity + */ + @Test + public void testIdentityrefNmspcInParrentElement() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace"); + + } + + /** + * + * Test case like (without namespace in xml) x:identity + * + */ + @Test + public void testIdentityrefNoNmspcValueWithPrefix() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module"); + } + + /** + * + * Test case like (without namespace in xml) identity + * + */ + @Test + public void testIdentityrefNoNmspcValueWithoutPrefix() { + testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml", + "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); + } + + private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) { + SimpleNode lf1suf = null; + SimpleNode lflst1suf_1 = null; + SimpleNode lflst1suf_2 = null; + SimpleNode lflst1suf_3 = null; + CompositeNode cont1suf = null; + CompositeNode lst1suf = null; + + int lflstCount = 0; + + for (Node node : compNode.getChildren()) { + String localName = node.getNodeType().getLocalName(); + if (localName.equals("lf1" + suf)) { + assertTrue(node instanceof SimpleNode); + lf1suf = (SimpleNode) node; + } else if (localName.equals("lflst1" + suf)) { + assertTrue(node instanceof SimpleNode); + switch (lflstCount++) { + case 0: + lflst1suf_1 = (SimpleNode) node; + break; + case 1: + lflst1suf_2 = (SimpleNode) node; + break; + case 2: + lflst1suf_3 = (SimpleNode) node; + break; + } + } else if (localName.equals("lst1" + suf)) { + assertTrue(node instanceof CompositeNode); + lst1suf = (CompositeNode) node; + } else if (localName.equals("cont1" + suf)) { + assertTrue(node instanceof CompositeNode); + cont1suf = (CompositeNode) node; + } + assertEquals(nameSpace, node.getNodeType().getNamespace().toString()); + } + + assertNotNull(lf1suf); + assertNotNull(lflst1suf_1); + assertNotNull(lflst1suf_2); + assertNotNull(lflst1suf_3); + assertNotNull(lst1suf); + assertNotNull(cont1suf); + + assertEquals("str0", lf1suf.getValue()); + assertEquals("121", lflst1suf_1.getValue()); + assertEquals("131", lflst1suf_2.getValue()); + assertEquals("str1", lflst1suf_3.getValue()); + + assertEquals(1, lst1suf.getChildren().size()); + + assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode); + SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getChildren().get(0); + assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString()); + assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName()); + assertEquals("str2", lst11_lf11.getValue()); + + assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode); + SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getChildren().get(0); + assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString()); + assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName()); + assertEquals((short) 100, cont1_lf11.getValue()); + } + + private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName, + int moduleCount, String resultLocalName, String resultNamespace) { + CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); + + Set modules = TestUtils.loadModulesFrom(yangPath); + assertEquals(moduleCount, modules.size()); + + TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + schemaName); + + SimpleNode lf11 = getLf11(compositeNode); + assertTrue(lf11.getValue() instanceof QName); + QName qName = (QName) lf11.getValue(); + assertEquals(resultLocalName, qName.getLocalName()); + assertEquals(resultNamespace, qName.getNamespace().toString()); + } + + private SimpleNode getLf11(CompositeNode compositeNode) { + assertEquals("cont", compositeNode.getNodeType().getLocalName()); + + List> childs = compositeNode.getChildren(); + assertEquals(1, childs.size()); + Node nd = childs.iterator().next(); + assertTrue(nd instanceof CompositeNode); + assertEquals("cont1", nd.getNodeType().getLocalName()); + + childs = ((CompositeNode) nd).getChildren(); + SimpleNode lf11 = null; + for (Node child : childs) { + assertTrue(child instanceof SimpleNode); + if (child.getNodeType().getLocalName().equals("lf11")) { + lf11 = (SimpleNode) child; + } + } + assertNotNull(lf11); + return lf11; + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java index 50ab0857b7..7c7df56133 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java @@ -2,391 +2,43 @@ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test; import static org.junit.Assert.*; -import java.io.*; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Set; - -import javax.ws.rs.WebApplicationException; - +import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; -import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; -import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.data.api.*; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class XmlToCnSnTest { - private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class); - - /** - * top level element represents container. second level element is list with - * two elements. - */ - @Test - public void testXmlDataContainer() { - CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false); - assertNotNull(compNode); - DataSchemaNode dataSchemaNode = null; - try { - dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang"); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - - assertNotNull(dataSchemaNode); - TestUtils.supplementNamespace(dataSchemaNode, compNode); - - String nameSpace = "data:container:yang"; - assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString()); - - verifyNullAndEmptyStringSingleNode(compNode, nameSpace); - verifyCommonPartAOfXml(compNode, "", nameSpace); - } - - private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) { - assertEquals("cont", compNode.getNodeType().getLocalName()); - SimpleNode lf2 = null; - SimpleNode lf3 = null; - int found = 0; - for (Node child : compNode.getChildren()) { - if (found == 0x3) - break; - if (child instanceof SimpleNode) { - SimpleNode childSimple = (SimpleNode) child; - if (childSimple.getNodeType().getLocalName().equals("lf3")) { - lf3 = childSimple; - found = found | (1 << 0); - } else if (childSimple.getNodeType().getLocalName().equals("lf2")) { - lf2 = childSimple; - found = found | (1 << 1); - } - } - assertEquals(nameSpace, child.getNodeType().getNamespace().toString()); - } +public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { - assertEquals("", lf2.getValue()); - assertEquals(null, lf3.getValue()); + @BeforeClass + public static void initialize() { + dataLoad("/xml-to-cnsn/leafref"); } @Test - public void testXmlDataList() { - CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false); - assertNotNull(compNode); - - DataSchemaNode dataSchemaNode = null; - try { - dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang"); - } catch (FileNotFoundException e) { - LOG.error(e.getMessage()); - } + public void testXmlLeafrefToCnSn() { + CompositeNode compositeNode = TestUtils.readInputToCnSn("/xml-to-cnsn/leafref/xml/data.xml", false, + XmlToCompositeNodeProvider.INSTANCE); + assertNotNull(compositeNode); assertNotNull(dataSchemaNode); - TestUtils.supplementNamespace(dataSchemaNode, compNode); - - String nameSpaceList = "data:list:yang"; - String nameSpaceCont = "data:container:yang"; - assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); - assertEquals("cont", compNode.getNodeType().getLocalName()); - assertEquals(3, compNode.getChildren().size()); - CompositeNode lst1_1 = null; - CompositeNode lst1_2 = null; - int loopCount = 0; - for (Node node : compNode.getChildren()) { - if (node.getNodeType().getLocalName().equals("lf1")) { - assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString()); - assertTrue(node instanceof SimpleNode); - assertEquals("lf1", node.getValue()); - } else { - assertTrue(node instanceof CompositeNode); - switch (loopCount++) { - case 0: - lst1_1 = (CompositeNode) node; - break; - case 1: - lst1_2 = (CompositeNode) node; - break; - } - assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString()); - } - } - // lst1_1 - verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont); - // :lst1_1 - - // lst1_2 - SimpleNode lflst11 = null; - CompositeNode cont11 = null; - for (Node node : lst1_2.getChildren()) { - String nodeName = node.getNodeType().getLocalName(); - if (nodeName.equals("lflst11")) { - assertTrue(node instanceof SimpleNode); - lflst11 = (SimpleNode) node; - - } else if (nodeName.equals("cont11")) { - assertTrue(node instanceof CompositeNode); - cont11 = (CompositeNode) node; - } - assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); - } - assertEquals("221", lflst11.getValue()); - - assertEquals(1, cont11.getChildren().size()); - assertTrue(cont11.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont11_lf111 = (SimpleNode) cont11.getChildren().get(0); - assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString()); - assertEquals("lf111", cont11_lf111.getNodeType().getLocalName()); - assertEquals((short) 100, cont11_lf111.getValue()); - // :lst1_2 - - } - - @Test - public void testXmlEmptyData() { - CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true); - assertEquals("cont", compNode.getNodeType().getLocalName()); - SimpleNode lf1 = null; - SimpleNode lflst1_1 = null; - SimpleNode lflst1_2 = null; - CompositeNode lst1 = null; - int lflst1Count = 0; - for (Node node : compNode.getChildren()) { - if (node.getNodeType().getLocalName().equals("lf1")) { - assertTrue(node instanceof SimpleNode); - lf1 = (SimpleNode) node; - } else if (node.getNodeType().getLocalName().equals("lflst1")) { - assertTrue(node instanceof SimpleNode); - - switch (lflst1Count++) { - case 0: - lflst1_1 = (SimpleNode) node; - break; - case 1: - lflst1_2 = (SimpleNode) node; - break; - } - } else if (node.getNodeType().getLocalName().equals("lst1")) { - assertTrue(node instanceof CompositeNode); - lst1 = (CompositeNode) node; - } - } - - assertNotNull(lf1); - assertNotNull(lflst1_1); - assertNotNull(lflst1_2); - assertNotNull(lst1); - - assertEquals("", lf1.getValue()); - assertEquals("", lflst1_1.getValue()); - assertEquals("", lflst1_2.getValue()); - assertEquals(1, lst1.getChildren().size()); - assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName()); - - assertTrue(lst1.getChildren().get(0) instanceof SimpleNode); - assertEquals("", lst1.getChildren().get(0).getValue()); - - } - - /** - * Test case like this x:identity - */ - @Test - public void testIdentityrefNmspcInElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref", - "identityref-module", "cont", 2, "iden", "identity:module"); - } + TestUtils.normalizeCompositeNode(compositeNode, modules, schemaNodePath); - /** - * - * Test case like identity - */ - - @Test - public void testIdentityrefDefaultNmspcInElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml", - "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module"); - } - - /** - * - * Test case like identity - */ - @Test - public void testIdentityrefDefaultNmspcInParrentElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); - } - - /** - * - * Test case like - * x:identity - */ - @Test - public void testIdentityrefNmspcInParrentElement() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace"); - - } - - /** - * - * Test case like (without namespace in xml) x:identity - * - */ - @Test - public void testIdentityrefNoNmspcValueWithPrefix() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module"); - } - - /** - * - * Test case like (without namespace in xml) identity - * - */ - @Test - public void testIdentityrefNoNmspcValueWithoutPrefix() { - testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml", - "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); - } - - private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) { - SimpleNode lf1suf = null; - SimpleNode lflst1suf_1 = null; - SimpleNode lflst1suf_2 = null; - SimpleNode lflst1suf_3 = null; - CompositeNode cont1suf = null; - CompositeNode lst1suf = null; - - int lflstCount = 0; + assertEquals("cont", compositeNode.getNodeType().getLocalName()); - for (Node node : compNode.getChildren()) { - String localName = node.getNodeType().getLocalName(); - if (localName.equals("lf1" + suf)) { - assertTrue(node instanceof SimpleNode); - lf1suf = (SimpleNode) node; - } else if (localName.equals("lflst1" + suf)) { - assertTrue(node instanceof SimpleNode); - switch (lflstCount++) { - case 0: - lflst1suf_1 = (SimpleNode) node; - break; - case 1: - lflst1suf_2 = (SimpleNode) node; - break; - case 2: - lflst1suf_3 = (SimpleNode) node; + SimpleNode lf2 = null; + for (Node childNode : compositeNode.getChildren()) { + if (childNode instanceof SimpleNode) { + if (childNode.getNodeType().getLocalName().equals("lf2")) { + lf2 = (SimpleNode) childNode; break; } - } else if (localName.equals("lst1" + suf)) { - assertTrue(node instanceof CompositeNode); - lst1suf = (CompositeNode) node; - } else if (localName.equals("cont1" + suf)) { - assertTrue(node instanceof CompositeNode); - cont1suf = (CompositeNode) node; } - assertEquals(nameSpace, node.getNodeType().getNamespace().toString()); } - assertNotNull(lf1suf); - assertNotNull(lflst1suf_1); - assertNotNull(lflst1suf_2); - assertNotNull(lflst1suf_3); - assertNotNull(lst1suf); - assertNotNull(cont1suf); - - assertEquals("str0", lf1suf.getValue()); - assertEquals("121", lflst1suf_1.getValue()); - assertEquals("131", lflst1suf_2.getValue()); - assertEquals("str1", lflst1suf_3.getValue()); - - assertEquals(1, lst1suf.getChildren().size()); - - assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getChildren().get(0); - assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString()); - assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName()); - assertEquals("str2", lst11_lf11.getValue()); - - assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getChildren().get(0); - assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString()); - assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName()); - assertEquals((short) 100, cont1_lf11.getValue()); - } - - private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) { - XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE; - try { - InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath); - CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream); - if (dummyNamespaces) { - try { - TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode); - return ((CompositeNodeWrapper) compositeNode).unwrap(); - } catch (URISyntaxException e) { - LOG.error(e.getMessage()); - assertTrue(e.getMessage(), false); - } - } - return compositeNode; - - } catch (WebApplicationException | IOException e) { - LOG.error(e.getMessage()); - assertTrue(false); - } - return null; - } - - private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName, - int moduleCount, String resultLocalName, String resultNamespace) { - CompositeNode compositeNode = compositeNodeFromXml(xmlPath, false); - assertNotNull(compositeNode); - - Set modules = TestUtils.resolveModules(yangPath); - assertEquals(moduleCount, modules.size()); - Module module = TestUtils.resolveModule(moduleName, modules); - assertNotNull(module); - DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null); - assertNotNull(dataSchemaNode); - - TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, moduleName + ":" + schemaName); - - SimpleNode lf11 = getLf11(compositeNode); - assertTrue(lf11.getValue() instanceof QName); - QName qName = (QName) lf11.getValue(); - assertEquals(resultLocalName, qName.getLocalName()); - assertEquals(resultNamespace, qName.getNamespace().toString()); - - } - - private SimpleNode getLf11(CompositeNode compositeNode) { - assertEquals("cont", compositeNode.getNodeType().getLocalName()); - - List> childs = compositeNode.getChildren(); - assertEquals(1, childs.size()); - Node nd = childs.iterator().next(); - assertTrue(nd instanceof CompositeNode); - assertEquals("cont1", nd.getNodeType().getLocalName()); - - childs = ((CompositeNode) nd).getChildren(); - SimpleNode lf11 = null; - for (Node child : childs) { - assertTrue(child instanceof SimpleNode); - if (child.getNodeType().getLocalName().equals("lf11")) { - lf11 = (SimpleNode) child; - } - } - assertNotNull(lf11); - return lf11; + assertNotNull(lf2); + assertTrue(lf2.getValue() instanceof String); + assertEquals("121", (String) lf2.getValue()); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang new file mode 100644 index 0000000000..a9df486b13 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang @@ -0,0 +1,13 @@ +module invalid-top-level-element { + namespace "invalid:top:level:element"; + + prefix "intoleel"; + revision 2013-12-17 { + } + + + leaf lf { + type string; + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module new file mode 100644 index 0000000000..9bdea81579 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module @@ -0,0 +1,274 @@ +module simple-data-types { + namespace "simple:data:types"; + + prefix "smpdtp"; + revision 2013-11-12 { + } + + identity iden { + } + + typedef tpdfempty { + type empty; + } + + typedef tpdfbit { + type bits { + bit b1; + bit b2; + bit b3; + } + } + + typedef tpdfun4 { + type boolean; + } + + typedef tpdfun3 { + type union { + type tpdfbit; + type tpdfempty; + } + } + + typedef tpdfun2 { + type union { + type tpdfun3; + type tpdfun4; + } + } + + typedef tpdfun1 { + type union { + type uint8; + type decimal64 { + fraction-digits 2; + } + } + } + + container cont { + leaf lfnint8Min { + type int8; + } + leaf lfnint8Max { + type int8; + } + leaf lfnint16Min { + type int16; + } + leaf lfnint16Max { + type int16; + } + leaf lfnint32Min { + type int32; + } + leaf lfnint32Max { + type int32; + } + leaf lfnint64Min { + type int64; + } + leaf lfnint64Max { + type int64; + } + + leaf lfnuint8Max { + type uint8; + } + leaf lfnuint16Max { + type uint16; + } + leaf lfnuint32Max { + type uint32; + } + leaf lfuint64Max { + type uint64; + } + leaf lfstr { + type string; + } + leaf lfstr1 { + type string; + } + leaf lfbool1 { + type boolean; + } + leaf lfbool2 { + type boolean; + } + leaf lfbool3 { + type boolean; + } + leaf lfdecimal1 { + type decimal64 { + fraction-digits 2; + } + } + leaf lfdecimal2 { + type decimal64 { + fraction-digits 2; + } + } + leaf lfdecimal3 { + type decimal64 { + fraction-digits 2; + } + } + + leaf lfdecimal4 { + type decimal64 { + fraction-digits 2; + } + } + + + leaf lfdecimal6 { + type decimal64 { + fraction-digits 2; + } + } + + leaf lfenum { + type enumeration { + enum enum1; + enum enum2; + enum enum3; + enum enum4; + } + } + + leaf lfbits { + type bits { + bit bit1; + bit bit2; + bit bit3; + bit bit4; + } + } + + leaf lfbinary { + type binary; + } + + leaf lfref1 { //reference to string type + type leafref { + path "../lfstr"; + } + } + + leaf lfref2 { //reference to number type + type leafref { + path "../lfnint8Max"; + } + } + + leaf lfempty { + type empty; + } + + leaf lfunion1 { + type union { + type uint16; + type string; + } + } + leaf lfunion2 { + type union { + type decimal64 { + fraction-digits 2; + } + type string; + } + } + + leaf lfunion3 { + type union { + type empty; + type string; + } + } + + leaf lfunion4 { + type union { + type boolean; + type string; + } + } + + leaf lfunion5 { + type union { + type uint16; + type string; + } + } + + leaf lfunion6 { + type union { + type uint16; + type empty; + } + } + + leaf lfunion7 { + type tpdfun3; + } + + leaf lfunion8 { + type union { + type uint16; + type string; + } + } + + leaf lfunion9 { + type union { + type uint16; + type boolean; + } + } + + leaf lfunion10 { + type union { + type bits { + bit bt1; + bit bt2; + } + type boolean; + } + } + + leaf lfunion11 { + type union { + type tpdfun1; + type tpdfun2; + } + } + + leaf lfunion12 { + type tpdfun2; + } + + leaf lfunion13 { + type tpdfbit; + } + + leaf lfunion14 { + type union { + type enumeration { + enum zero; + enum one; + } + type uint16; + } + } + + leaf identityref1 { + type identityref { + base iden; + } + } + + + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang new file mode 100644 index 0000000000..84547847ee --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang @@ -0,0 +1,25 @@ +module module-with-choice { + namespace "module:with:choice"; + + prefix "mowicho"; + + revision 2013-12-18 { + } + + + container cont { + choice choA { + case caA1 { + leaf lf1 { + type string; + } + } + case caA2 { + leaf lf2 { + type string; + } + } + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang index 7023c94f2f..81d77329c6 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang @@ -91,6 +91,12 @@ module basic-module { } } + leaf lfLfref { + type leafref { + path "/cont/lfBoolean"; + } + } + } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json new file mode 100644 index 0000000000..235666eed4 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json @@ -0,0 +1,6 @@ +{ + "cont":{ + "lf1":121, + "lf2":121 + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module new file mode 100644 index 0000000000..8ca9f09096 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module @@ -0,0 +1,19 @@ +module leafref-module { + namespace "leafref:module"; + + prefix "lfrfmo"; + revision 2013-11-18 { + } + + container cont { + leaf lf1 { + type int32; + } + leaf lf2 { + type leafref { + path "/cont/lf1"; + } + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang similarity index 100% rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json new file mode 100644 index 0000000000..abc626739e --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json @@ -0,0 +1 @@ +fffff \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module new file mode 100644 index 0000000000..8ca9f09096 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module @@ -0,0 +1,19 @@ +module leafref-module { + namespace "leafref:module"; + + prefix "lfrfmo"; + revision 2013-11-18 { + } + + container cont { + leaf lf1 { + type int32; + } + leaf lf2 { + type leafref { + path "/cont/lf1"; + } + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml new file mode 100644 index 0000000000..06200a69b5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml @@ -0,0 +1,4 @@ + + 121 + 121 + \ No newline at end of file diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java deleted file mode 100644 index 23cdabf69f..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2013 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.confignetconfconnector.mapping.attributes; - -public class AttributesConstants { - - /** - * Property placed into object names for dependencies to preserve reference name - */ - public static final String REF_NAME_ON_PROPERTY_KEY = "X-refName"; -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java index a1f46dde54..dbc1b48d4f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java @@ -43,7 +43,6 @@ public class AttributeConfigElement { resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value); Optional resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue); resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null; - } public static AttributeConfigElement create(Object nullableDefault, Object value) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java index fb385221c8..506d7d61c3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java @@ -16,7 +16,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; @@ -27,9 +27,9 @@ import java.util.Map.Entry; public class ObjectMapper extends AttributeIfcSwitchStatement>> { - private final Services dependencyTracker; + private final ServiceRegistryWrapper dependencyTracker; - public ObjectMapper(Services depTracker) { + public ObjectMapper(ServiceRegistryWrapper depTracker) { this.dependencyTracker = depTracker; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java index 8426341636..83e8086eef 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java @@ -10,8 +10,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import javax.management.ObjectName; @@ -20,11 +20,11 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeMappingStrategy extends AbstractAttributeMappingStrategy> { - private final Services tracker; + private final ServiceRegistryWrapper tracker; private final String serviceName; private final String namespace; - public ObjectNameAttributeMappingStrategy(SimpleType openType, Services dependencyTracker, String serviceName, String namespace) { + public ObjectNameAttributeMappingStrategy(SimpleType openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) { super(openType); this.tracker = dependencyTracker; this.serviceName = serviceName; @@ -44,10 +44,7 @@ public class ObjectNameAttributeMappingStrategy extends ObjectName on = (ObjectName) value; - String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY); - - String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional. absent()) - : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName)); + String refName = ObjectNameUtil.getReferenceName(on); return Optional.of(new MappedDependency(namespace, serviceName, refName)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java index d8f0e2357e..57a44d8af0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java @@ -9,11 +9,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving; import com.google.common.base.Optional; -import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,10 +20,10 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy> { - private final Services serviceTracker; + private final ServiceRegistryWrapper serviceTracker; private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class); - ObjectNameAttributeResolvingStrategy(Services serviceTracker) { + ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) { super(SimpleType.OBJECTNAME); this.serviceTracker = serviceTracker; } @@ -45,9 +42,7 @@ public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResol String namespace = mappedDep.getNamespace(); logger.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName); - ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName); - ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName()); - on = ObjectNameUtil.createON(on.toString() + "," + AttributesConstants.REF_NAME_ON_PROPERTY_KEY + "=" + refName); + ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName); logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType()); return Optional.of(on); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index a3e2813fa0..82c8c1ec6b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -15,7 +15,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; @@ -26,9 +26,9 @@ import java.util.Map.Entry; public class ObjectResolver extends AttributeIfcSwitchStatement>> { - private final Services serviceTracker; + private final ServiceRegistryWrapper serviceTracker; - public ObjectResolver(Services serviceTracker) { + public ObjectResolver(ServiceRegistryWrapper serviceTracker) { this.serviceTracker = serviceTracker; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index 3a5fa1170f..ec73cd6068 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -14,7 +14,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -99,7 +98,7 @@ public class Config { // } public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, - Element dataElement, Services serviceTracker) { + Element dataElement, ServiceRegistryWrapper serviceTracker) { Map>> moduleToInstances = getMappedInstances(instancesToMap, moduleConfigs); @@ -120,81 +119,84 @@ public class Config { ModuleConfig mapping = moduleConfigs.get(moduleNamespace).get(moduleMappingEntry.getKey()); if (moduleMappingEntry.getValue().isEmpty()) { - addEmptyModulesCommented(document, modulesElement, moduleNamespace, moduleMappingEntry); - } else { - for (ObjectName objectName : moduleMappingEntry.getValue()) { - modulesElement - .appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace)); - } + continue; + } + + for (ObjectName objectName : moduleMappingEntry.getValue()) { + modulesElement.appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace)); } } } - root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document)); + root.appendChild(Services.toXml(serviceTracker, document)); return root; } - // TODO remove commented modules from output - private void addEmptyModulesCommented(Document document, Element root, String moduleNamespace, - Entry> moduleMappingEntry) { - Element emptyModule = document.createElement(XmlNetconfConstants.MODULE_KEY); - - Element typeElement = XmlUtil.createTextElement(document, XmlNetconfConstants.TYPE_KEY, - moduleMappingEntry.getKey()); - emptyModule.appendChild(typeElement); - - root.appendChild(document.createComment(XmlUtil.toString(emptyModule, false))); - } - // TODO refactor, replace string representing namespace with namespace class // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved // class - public ConfigElementResolved fromXml(XmlElement xml, - EditStrategyType defaultEditStrategyType, ServiceReferenceReadableRegistry taClient) { - Map> retVal = Maps.newHashMap(); - List recognisedChildren = Lists.newArrayList(); + public Map> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient); - List moduleElements = fromXmlModules(xml, recognisedChildren); - - xml.checkUnrecognisedElements(recognisedChildren); + Map> retVal = Maps.newHashMap(); for (XmlElement moduleElement : moduleElements) { - resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType); - } + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { + return moduleMapping.fromXml(moduleElement, serviceTracker, + instanceName, moduleNamespace, defaultStrategy); + } + }; - return new ConfigElementResolved(retVal, serviceTracker); + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); + } + return retVal; } - public static class ConfigElementResolved { + /** + * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted. + */ + public Map> fromXmlModulesMap(XmlElement xml, + EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - private final Map> resolvedModules; - private final Services services; + Map> retVal = Maps.newHashMap(); - public ConfigElementResolved(Map> retVal, Services serviceTracker) { - this.resolvedModules = retVal; - this.services = serviceTracker; - } + for (XmlElement moduleElement : moduleElements) { + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, + ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, + EditStrategyType defaultStrategy) { + // TODO: add check for conflicts between global and local + // edit strategy + String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY, + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy); + } + }; - public Map> getResolvedModules() { - return resolvedModules; + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); } + return retVal; + } - public Services getServices() { - return services; - } + private static Optional getModulesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); } - private List fromXmlModules(XmlElement xml, List recognisedChildren) { - Optional modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + private List getModulesElementList(Optional modulesElement) { List moduleElements; + if (modulesElement.isPresent()) { moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY); - recognisedChildren.add(modulesElement.get()); modulesElement.get().checkUnrecognisedElements(moduleElements); } else { moduleElements = Lists.newArrayList(); @@ -202,8 +204,8 @@ public class Config { return moduleElements; } - private void resolveModule(Map> retVal, Services serviceTracker, - XmlElement moduleElement, EditStrategyType defaultStrategy) { + private void resolveModule(Map> retVal, ServiceRegistryWrapper serviceTracker, + XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) { XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Entry prefixToNamespace = typeElement.findNamespaceOfTextContent(); String moduleNamespace = prefixToNamespace.getValue(); @@ -215,35 +217,49 @@ public class Config { ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName); - Multimap innerMap = retVal.get(moduleNamespace); + Multimap innerMap = retVal.get(moduleNamespace); if (innerMap == null) { innerMap = HashMultimap.create(); retVal.put(moduleNamespace, innerMap); } - ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker, + T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker, instanceName, moduleNamespace, defaultStrategy); - innerMap.put(factoryName, moduleElementResolved); + innerMap.put(factoryName, resolvedElement); } - private Services fromXmlServices(XmlElement xml, List recognisedChildren, - ServiceReferenceReadableRegistry taClient) { - Optional servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + public Services fromXmlServices(XmlElement xml) { + Optional servicesElement = getServicesElement(xml); - Map>> mappedServices; + Services services; if (servicesElement.isPresent()) { - mappedServices = Services.fromXml(servicesElement.get()); - recognisedChildren.add(servicesElement.get()); + services = Services.fromXml(servicesElement.get()); } else { - mappedServices = new HashMap<>(); + services = new Services(); } - Services services = Services.resolveServices(mappedServices, taClient); return services; } + private static Optional getServicesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + } + + public static void checkUnrecognisedChildren(XmlElement parent) { + Optional servicesOpt = getServicesElement(parent); + Optional modulesOpt = getModulesElement(parent); + + List recognised = Lists.newArrayList(); + if(servicesOpt.isPresent()) + recognised.add(servicesOpt.get()); + if(modulesOpt.isPresent()) + recognised.add(modulesOpt.get()); + + parent.checkUnrecognisedElements(recognised); + } + private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) { checkState( factoryNameWithPrefix.startsWith(prefixOrEmptyString), @@ -271,4 +287,8 @@ public class Config { return moduleMapping; } + private interface ResolvingStrategy { + public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, + String instanceName, String moduleNamespace, EditStrategyType defaultStrategy); + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index aae1636165..b8870e51ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -52,7 +52,7 @@ public final class InstanceConfig { this.configRegistryClient = configRegistryClient; } - private Map getMappedConfiguration(ObjectName on, Services depTracker) { + private Map getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) { // TODO make field, mappingStrategies can be instantiated only once Map>> mappingStrategies = new ObjectMapper(depTracker) @@ -84,7 +84,7 @@ public final class InstanceConfig { return toXml; } - public Element toXml(ObjectName on, Services depTracker, String namespace, Document document, Element rootElement) { + public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) { Element cfgElement = rootElement; @@ -104,7 +104,7 @@ public final class InstanceConfig { return cfgElement; } - private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, Services depTracker) { + private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) { // TODO make field, resolvingStrategies can be instantiated only once Map>> resolvingStrategies = new ObjectResolver( @@ -128,7 +128,7 @@ public final class InstanceConfig { } } - public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace, + public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace, EditStrategyType defaultStrategy, Multimap providedServices) { Map retVal = Maps.newHashMap(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java index 55cb60bed5..0bb4191bf2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java @@ -28,7 +28,7 @@ public class InstanceConfigElementResolved { private final Multimap providedServices; public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) { - EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy); + EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy); this.editStrategy = valueOf; this.configuration = configuration; this.providedServices = providedServices; @@ -41,19 +41,19 @@ public class InstanceConfigElementResolved { } - EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) { - EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy); + static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) { + EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy); if (defaultStrategy.isEnforcing()) { Preconditions .checkArgument( - valueOf == defaultStrategy, + parsedStrategy == defaultStrategy, "With " + defaultStrategy + " as " + EditConfigXmlParser.DEFAULT_OPERATION_KEY + " operations on module elements are not permitted since the default option is restrictive"); } - return valueOf; + return parsedStrategy; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index 2ac6fe0a9b..48ff835a45 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -53,7 +53,7 @@ public class ModuleConfig { return providedServices; } - public Element toXml(ObjectName instanceON, Services depTracker, Document document, String namespace) { + public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) { Element root = document.createElement(XmlNetconfConstants.MODULE_KEY); // Xml.addNamespaceAttr(document, root, namespace); @@ -84,7 +84,7 @@ public class ModuleConfig { } - public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName, + public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java new file mode 100644 index 0000000000..9111701ba0 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013 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.confignetconfconnector.mapping.config; + +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy; + +public class ModuleElementDefinition { + + public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy(); + public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy(); + + private final String instanceName; + private final EditStrategyType editStrategy; + + public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) { + this.instanceName = instanceName; + if (currentStrategy == null || currentStrategy.isEmpty()) + this.editStrategy = defaultStrategy; + else + this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy); + } + + public String getInstanceName() { + return instanceName; + } + + public EditStrategyType getEditStrategyType() { + return editStrategy; + } + + public EditConfigStrategy getEditStrategy() { + switch (editStrategy) { + case delete : + case remove : + case none : return NONE_EDIT_CONFIG_STRATEGY; + default : return MISSING_INSTANCE_HANDLING_STRATEGY; + } + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java new file mode 100644 index 0000000000..7df671297c --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013 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.confignetconfconnector.mapping.config; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; + +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ServiceRegistryWrapper { + + private ServiceReferenceReadableRegistry configServiceRefRegistry; + + private long suffix = 1; + + public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) { + this.configServiceRefRegistry = configServiceRefRegistry; + } + + + public boolean hasRefName(String namespace, String serviceName, ObjectName on) { + String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); + Map forQName = configServiceRefRegistry.getServiceMapping().get(qname); + if(forQName==null) return false; + return forQName.values().contains(on); + } + + public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) { + Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); + + Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); + + Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " + + serviceNameToRefNameToInstance.keySet()); + + String instanceId = refNameToInstance.get(refName); + Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":" + + refName + ", " + serviceNameToRefNameToInstance.keySet()); + + Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId); + Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName + + " under service name " + serviceName + " , " + refNameToInstance.keySet()); + + String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); + try { + return configServiceRefRegistry.getServiceReference(qNameOfService, refName); + } catch (InstanceNotFoundException e) { + throw new IllegalArgumentException("No serviceInstance mapped to " + refName + + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e); + + } + } + + public Map>> getMappedServices() { + Map>> retVal = Maps.newHashMap(); + + Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); + for (String serviceQName : serviceMapping.keySet()) + for (String refName : serviceMapping.get(serviceQName).keySet()) { + + ObjectName on = serviceMapping.get(serviceQName).get(refName); + Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on); + + // FIXME use QName's new String constructor, after it is fixed +// QName qname; +// try { +// qname = new QName(serviceQName); +// } catch (ParseException e) { +// throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e); +// } + Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); + Matcher matcher = p.matcher(serviceQName); + Preconditions.checkArgument(matcher.matches()); + String namespace = matcher.group(1); + String localName = matcher.group(2); + +// String namespace = qname.getNamespace().toString(); + Map> serviceToRefs = retVal.get(namespace); + if(serviceToRefs==null) { + serviceToRefs = Maps.newHashMap(); + retVal.put(namespace, serviceToRefs); + } + +// String localName = qname.getLocalName(); + Map refsToSis = serviceToRefs.get(localName); + if(refsToSis==null) { + refsToSis = Maps.newHashMap(); + serviceToRefs.put(localName, refsToSis); + } + + Preconditions.checkState(refsToSis.containsKey(refName) == false, + "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, + localName, on); + refsToSis.put(refName, si.toString()); + } + + return retVal; + } + + @VisibleForTesting + public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) { + String refName; + refName = "ref_" + instanceName; + + Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); + + Map refNameToInstance; + if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { + refNameToInstance = Collections.emptyMap(); + } else + refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + + final Set refNamesAsSet = toSet(refNameToInstance.keySet()); + if (refNamesAsSet.contains(refName)) { + refName = findAvailableRefName(refName, refNamesAsSet); + } + + return refName; + } + + + private Set toSet(Collection values) { + Set refNamesAsSet = Sets.newHashSet(); + + for (String refName : values) { + boolean resultAdd = refNamesAsSet.add(refName); + Preconditions.checkState(resultAdd, + "Error occurred building services element, reference name {} was present twice", refName); + } + + return refNamesAsSet; + } + + private String findAvailableRefName(String refName, Set refNamesAsSet) { + String intitialRefName = refName; + + while (true) { + refName = intitialRefName + "_" + suffix++; + if (refNamesAsSet.contains(refName) == false) + return refName; + } + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index 77f3cf283f..7de7ea8c71 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,14 +8,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -27,12 +21,9 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.management.ObjectName; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,124 +36,8 @@ public final class Services { public static final String TYPE_KEY = "type"; public static final String SERVICE_KEY = "service"; - private long suffix = 1; - private final Map>> namespaceToServiceNameToRefNameToInstance = Maps .newHashMap(); - private ServiceReferenceReadableRegistry configServiceRefRegistry; - - public Services(ServiceReferenceReadableRegistry configServiceRefRegistry) { - this.configServiceRefRegistry = configServiceRefRegistry; - } - - @VisibleForTesting - public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) { - String refName; - refName = "ref_" + instanceName; - - Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Map refNameToInstance; - if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { - refNameToInstance = Collections.emptyMap(); - } else - refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - - final Set refNamesAsSet = toSet(refNameToInstance.keySet()); - if (refNamesAsSet.contains(refName)) { - refName = findAvailableRefName(refName, refNamesAsSet); - } - - return refName; - } - - private Set toSet(Collection values) { - Set refNamesAsSet = Sets.newHashSet(); - - for (String refName : values) { - boolean resultAdd = refNamesAsSet.add(refName); - Preconditions.checkState(resultAdd, - "Error occurred building services element, reference name {} was present twice", refName); - } - - return refNamesAsSet; - } - - public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) { - Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); - - Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " - + serviceNameToRefNameToInstance.keySet()); - - String instanceId = refNameToInstance.get(refName); - Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":" - + refName + ", " + serviceNameToRefNameToInstance.keySet()); - - ServiceInstance serviceInstance = ServiceInstance.fromString(instanceId); - Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName - + " under service name " + serviceName + " , " + refNameToInstance.keySet()); - return serviceInstance; - } - - // TODO hide getMappedServices, call it explicitly in toXml - - public Map>> getMappedServices() { - Map>> retVal = Maps.newHashMap(); - - for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) { - - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance - .get(namespace); - Map> innerRetVal = Maps.newHashMap(); - - for (String serviceName : serviceNameToRefNameToInstance.keySet()) { - - Map innerInnerRetVal = Maps.newHashMap(); - for (Entry refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) { - innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString()); - } - innerRetVal.put(serviceName, innerInnerRetVal); - } - retVal.put(namespace, innerRetVal); - } - - Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); - for (String serviceQName : serviceMapping.keySet()) - for (String refName : serviceMapping.get(serviceQName).keySet()) { - - ObjectName on = serviceMapping.get(serviceQName).get(refName); - ServiceInstance si = ServiceInstance.fromObjectName(on); - - // FIXME use QName's new String constructor, after its implemented - Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); - Matcher matcher = p.matcher(serviceQName); - Preconditions.checkArgument(matcher.matches()); - String namespace = matcher.group(1); - String localName = matcher.group(2); - - Map> serviceToRefs = retVal.get(namespace); - if(serviceToRefs==null) { - serviceToRefs = Maps.newHashMap(); - retVal.put(namespace, serviceToRefs); - } - - Map refsToSis = serviceToRefs.get(localName); - if(refsToSis==null) { - refsToSis = Maps.newHashMap(); - serviceToRefs.put(localName, refsToSis); - } - - Preconditions.checkState(refsToSis.containsKey(refName) == false, - "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, - localName, on); - refsToSis.put(refName, si.toString()); - } - - return retVal; - } /** * @@ -171,10 +46,8 @@ public final class Services { return namespaceToServiceNameToRefNameToInstance; } - // TODO hide resolveServices, call it explicitly in fromXml - - public static Services resolveServices(Map>> mappedServices, ServiceReferenceReadableRegistry taClient) { - Services tracker = new Services(taClient); + private static Services resolveServices(Map>> mappedServices) { + Services tracker = new Services(); for (Entry>> namespaceEntry : mappedServices.entrySet()) { String namespace = namespaceEntry.getKey(); @@ -210,7 +83,7 @@ public final class Services { // TODO support edit strategies on services - public static Map>> fromXml(XmlElement xml) { + public static Services fromXml(XmlElement xml) { Map>> retVal = Maps.newHashMap(); List services = xml.getChildElements(SERVICE_KEY); @@ -250,23 +123,14 @@ public final class Services { } } - return retVal; - } - - private String findAvailableRefName(String refName, Set refNamesAsSet) { - String intitialRefName = refName; - - while (true) { - refName = intitialRefName + "_" + suffix++; - if (refNamesAsSet.contains(refName) == false) - return refName; - } + return resolveServices(retVal); } - public Element toXml(Map>> mappedServices, Document document) { + public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) { Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY); XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + Map>> mappedServices = serviceRegistryWrapper.getMappedServices(); for (String namespace : mappedServices.keySet()) { for (Entry> serviceEntry : mappedServices.get(namespace).entrySet()) { @@ -294,51 +158,6 @@ public final class Services { return root; } - public String getRefName(String namespace, String serviceName, ObjectName on, Optional expectedRefName) { - Optional refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName); - Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace, - serviceName, on); - return refNameOptional.get(); - } - - public Optional getRefNameOptional(String namespace, String serviceName, ObjectName on, - Optional expectedRefName) { - Map> services = getMappedServices().get(namespace); - - if(services == null) return Optional.absent(); - Map refs = services.get(serviceName); - - if(refs == null) return Optional.absent(); - Multimap reverted = revertMap(refs); - - ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on); - Collection references = reverted.get(serviceInstance); - - if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) { - logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on); - return expectedRefName; - } else if (references.size() > 0) { - String next = references.iterator().next(); - logger.debug("Returning random ref name {} for {}", next, on); - return Optional.of(next); - } else - return Optional.absent(); - } - - private Multimap revertMap(Map refs) { - Multimap multimap = HashMultimap.create(); - - for (Entry e : refs.entrySet()) { - multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey()); - } - - return multimap; - } - - public boolean hasRefName(String key, String value, ObjectName on) { - return getRefNameOptional(key, value, on, Optional.absent()).isPresent(); - } - public static final class ServiceInstance { public ServiceInstance(String moduleName, String instanceName) { this.moduleName = moduleName; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java index 70b10d0019..6a0d7508c8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java @@ -88,7 +88,6 @@ public class InstanceRuntime { public Element toXml(ObjectName rootOn, Set childRbeOns, Document document, String instanceIndex, Element parentElement, String namespace) { - // TODO namespace Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement); if (instanceIndex != null) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java index 11e97ebdbb..4936d1dbcd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti import com.google.common.collect.Sets; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -41,7 +41,7 @@ public class ModuleRuntime { } public Element toXml(String namespace, Collection runtimeBeanOns, - Document document, ModuleConfig moduleConfig, ObjectName configBeanON, Services serviceTracker) { + Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) { Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java index 89c782c51c..129143835f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java @@ -11,11 +11,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; @@ -61,9 +60,7 @@ public class Runtime { return retVal; } - public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) { - Services serviceTracker = new Services(serviceRegistry); - + public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceRegistryWrapper serviceRegistry) { Element root = document.createElement(XmlNetconfConstants.DATA_KEY); Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY); @@ -88,11 +85,11 @@ public class Runtime { Element runtimeXml; ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName); if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) { - runtimeXml = moduleConfig.toXml(instanceON, serviceTracker, document, localNamespace); + runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace); } else { ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName); runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document, - moduleConfig, instanceON, serviceTracker); + moduleConfig, instanceON, serviceRegistry); } modulesElement.appendChild(runtimeXml); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java index 65df965afd..1d37fcd493 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,7 +24,7 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { try { ObjectName on = ta.lookupConfigBean(module, instance); @@ -36,10 +36,13 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { } + // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR + // edit configs should not handle missing + abstract void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services); + String module, String instance, ServiceRegistryWrapper services); abstract void executeStrategy(Map configuration, ConfigTransactionClient ta, - ObjectName objectName, Services services); + ObjectName objectName, ServiceRegistryWrapper services); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java index 12beaf8f8e..13e8c30211 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java @@ -12,7 +12,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,12 +36,12 @@ public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { + String module, String instance, ServiceRegistryWrapper services) { throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found"); } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { try { ta.destroyModule(on); logger.debug("ServiceInstance {} deleted successfully", on); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index 1bb1d9bfba..709573c241 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; @@ -105,8 +106,8 @@ public class EditConfig extends AbstractConfigNetconfOperation { logger.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG); } - private void test(ConfigRegistryClient configRegistryClient, - EditConfigExecution execution, EditStrategyType editStrategyType) { + private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution, + EditStrategyType editStrategyType) { ObjectName taON = transactionProvider.getTestTransaction(); try { @@ -115,8 +116,11 @@ public class EditConfig extends AbstractConfigNetconfOperation { transactionProvider.wipeTestTransaction(taON); } - setOnTransaction(configRegistryClient, execution.getResolvedXmlElements(), execution.getServices(), taON); - // TODO add service reference persistance testing here + ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + + handleMisssingInstancesOnTransaction(ta, execution); + setServicesOnTransaction(ta, execution); + setOnTransaction(ta, execution); transactionProvider.validateTestTransaction(taON); } finally { transactionProvider.abortTestTransaction(taON); @@ -132,14 +136,16 @@ public class EditConfig extends AbstractConfigNetconfOperation { transactionProvider.wipeTransaction(); } - setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(), - editConfigExecution.getServices(), taON); - setServicesOnTransaction(configRegistryClient, editConfigExecution.getServices(), taON); + ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + + handleMisssingInstancesOnTransaction(ta, editConfigExecution); + setServicesOnTransaction(ta, editConfigExecution); + setOnTransaction(ta, editConfigExecution); } - private void setServicesOnTransaction(ConfigRegistryClient configRegistryClient, Services services, - ObjectName taON) { - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + + Services services = execution.getServices(); Map>> namespaceToServiceNameToRefNameToInstance = services .getNamespaceToServiceNameToRefNameToInstance(); @@ -153,9 +159,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { for (String refName : refNameToInstance.keySet()) { ObjectName on = refNameToInstance.get(refName).getObjectName(ta.getTransactionName()); - // TODO check for duplicates try { - ta.saveServiceReference(qnameOfService, refName, on); + ObjectName saved = ta.saveServiceReference(qnameOfService, refName, on); + logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService, + on, refName, saved); } catch (InstanceNotFoundException e) { throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e); } @@ -168,11 +175,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { return ta.getServiceInterfaceName(namespace, serviceName); } - private void setOnTransaction(ConfigRegistryClient configRegistryClient, - Map> resolvedXmlElements, Services services, ObjectName taON) { - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + + for (Multimap modulesToResolved : execution.getResolvedXmlElements(ta).values()) { - for (Multimap modulesToResolved : resolvedXmlElements.values()) { for (Entry moduleToResolved : modulesToResolved.entries()) { String moduleName = moduleToResolved.getKey(); @@ -181,7 +187,22 @@ public class EditConfig extends AbstractConfigNetconfOperation { InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved(); EditConfigStrategy strategy = ice.getEditStrategy(); - strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, services); + strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta)); + } + } + } + + private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta, + EditConfigExecution execution) { + + for (Multimap modulesToResolved : execution.getModulesDefinition(ta).values()) { + for (Entry moduleToResolved : modulesToResolved.entries()) { + String moduleName = moduleToResolved.getKey(); + + ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue(); + + EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy(); + strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta)); } } } @@ -189,32 +210,38 @@ public class EditConfig extends AbstractConfigNetconfOperation { public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, Map> mBeanEntries) { - Map> factories = transform(configRegistryClient, mBeanEntries); + Map> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries); return new Config(factories); } - // TODO refactor - private static Map> transform - (final ConfigRegistryClient configRegistryClient, Map> transformMbeToModuleConfigs + (final ConfigRegistryClient configRegistryClient, Map> mBeanEntries) { - return Maps.transformEntries(mBeanEntries, - new Maps.EntryTransformer, Map>() { - - @Override - public Map transformEntry(String arg0, Map arg1) { - return Maps.transformEntries(arg1, - new Maps.EntryTransformer() { - - @Override - public ModuleConfig transformEntry(String key, ModuleMXBeanEntry moduleMXBeanEntry) { - return new ModuleConfig(key, new InstanceConfig(configRegistryClient, moduleMXBeanEntry - .getAttributes()), moduleMXBeanEntry.getProvidedServices().values()); - } - }); - } - }); + + Map> namespaceToModuleNameToModuleConfig = Maps.newHashMap(); + + for (String namespace : mBeanEntries.keySet()) { + for (Entry moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) { + String moduleName = moduleNameToMbe.getKey(); + ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue(); + + ModuleConfig moduleConfig = new ModuleConfig(moduleName, new InstanceConfig(configRegistryClient, + moduleMXBeanEntry.getAttributes()), moduleMXBeanEntry + .getProvidedServices().values()); + + Map moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace); + if(moduleNameToModuleConfig == null) { + moduleNameToModuleConfig = Maps.newHashMap(); + namespaceToModuleNameToModuleConfig.put(namespace, moduleNameToModuleConfig); + } + + moduleNameToModuleConfig.put(moduleName, moduleConfig); + } + } + + return namespaceToModuleNameToModuleConfig; } @Override diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java index 23166e8cca..cebcb0239b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java @@ -10,13 +10,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import java.util.Map; public interface EditConfigStrategy { void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services); + ConfigTransactionClient ta, ServiceRegistryWrapper services); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index 81327133b8..e481bbe57f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -14,10 +14,11 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.util.ConfigRegistryClient; -import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; @@ -26,7 +27,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.ObjectName; import java.util.Arrays; import java.util.Map; @@ -98,11 +98,7 @@ public class EditConfigXmlParser { XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY); - ObjectName taON = transactionProvider.getOrCreateTransaction(); - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); - - return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, - ta, editStrategyType); + return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType); } @VisibleForTesting @@ -132,15 +128,17 @@ public class EditConfigXmlParser { @VisibleForTesting static class EditConfigExecution { - private final Map> resolvedXmlElements; private final TestOption testOption; private final EditStrategyType defaultEditStrategyType; private final Services services; - - EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, ServiceReferenceReadableRegistry ta, EditStrategyType defaultStrategy) { - Config.ConfigElementResolved configElementResolved = configResolver.fromXml(configElement, defaultStrategy, ta); - this.resolvedXmlElements = configElementResolved.getResolvedModules(); - this.services = configElementResolved.getServices(); + private final Config configResolver; + private final XmlElement configElement; + + EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) { + Config.checkUnrecognisedChildren(configElement); + this.configResolver = configResolver; + this.configElement = configElement; + this.services = configResolver.fromXmlServices(configElement); this.testOption = testOption; this.defaultEditStrategyType = defaultStrategy; } @@ -153,8 +151,17 @@ public class EditConfigXmlParser { return testOption == TestOption.set || testOption == TestOption.testThenSet; } - Map> getResolvedXmlElements() { - return resolvedXmlElements; + Map> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); + } + + ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) { + // TODO cache service registry + return new ServiceRegistryWrapper(serviceRegistry); + } + + Map> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); } EditStrategyType getDefaultStrategy() { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java index 676467553b..06560b2d27 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java @@ -13,7 +13,6 @@ import com.google.common.collect.Multimap; import java.util.EnumSet; import java.util.Set; -//FIXME: make thread safe public enum EditStrategyType { // can be default merge, replace, none, diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java index 06befb0565..f2e2b193a8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.Attribute; -import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import java.util.Map; @@ -38,22 +38,13 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { - ObjectName on = null; - try { - on = ta.createModule(module, instance); - logger.info("New instance for {} {} created under name {}", module, instance, on); - addRefNames(services, providedServices, module, instance, ta, on); - executeStrategy(configuration, ta, on, services); - } catch (InstanceAlreadyExistsException e1) { - throw new IllegalStateException("Unable to create instance for " + module + " : " + instance); - } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); - } + String module, String instance, ServiceRegistryWrapper services) { + throw new IllegalStateException( + "Unable to handle missing instance, no missing instances should appear at this point, missing: " + + module + ":" + instance); } - private void addRefNames(Services services, Multimap providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -61,14 +52,20 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { continue; String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - module, instance); + ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); ta.saveServiceReference( ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on); } } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + try { + addRefNames(services, providedServices, ta, on); + } catch (InstanceNotFoundException e) { + throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + } + for (Entry configAttributeEntry : configuration.entrySet()) { try { AttributeConfigElement ace = configAttributeEntry.getValue(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java new file mode 100644 index 0000000000..8ed9eb8731 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013 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.confignetconfconnector.operations.editconfig; + +import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; +import java.util.Map; + +public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy { + + private static final Logger logger = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class); + + @Override + void handleMissingInstance(Map configuration, ConfigTransactionClient ta, + String module, String instance, ServiceRegistryWrapper services) { + ObjectName on = null; + try { + on = ta.createModule(module, instance); + logger.info("New instance for {} {} created under name {}", module, instance, on); + } catch (InstanceAlreadyExistsException e1) { + throw new IllegalStateException("Unable to create instance for " + module + " : " + instance); + } + } + + @Override + void executeStrategy(Map configuration, ConfigTransactionClient ta, + ObjectName objectName, ServiceRegistryWrapper services) { + return; + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java index 8347c6b88e..bd182a4267 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java @@ -8,21 +8,21 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import java.util.Map; - import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; + public class NoneEditConfigStrategy implements EditConfigStrategy { private static final Logger logger = LoggerFactory.getLogger(NoneEditConfigStrategy.class); @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { logger.debug("Skipping configuration element for {}:{}", module, instance); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java index 64f082da40..df1f65372a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,7 +22,7 @@ public class RemoveEditConfigStrategy extends DeleteEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { + String module, String instance, ServiceRegistryWrapper services) { logger.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java index 43d852e76a..4976244eae 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.Attribute; -import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import java.util.Map; @@ -39,23 +39,13 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { - ObjectName on = null; - try { - on = ta.createModule(module, instance); - logger.debug("New instance for {} {} created under name {}", module, instance, on); - addRefNames(services, providedServices, module, instance, ta, on); - executeStrategy(configuration, ta, on, services); - } catch (InstanceAlreadyExistsException e) { - logger.warn("Error creating instance {}:{}, replace failed", module, instance, e); - throw new IllegalStateException("Unable to create new instance for " + module + " : " + instance, e); - } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); - } + String module, String instance, ServiceRegistryWrapper services) { + throw new IllegalStateException( + "Unable to handle missing instance, no missing instances should appear at this point, missing: " + + module + ":" + instance); } - private void addRefNames(Services services, Multimap providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -63,13 +53,20 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { continue; String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - module, instance); + ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); ta.saveServiceReference( ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on); } } + @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + try { + addRefNames(services, providedServices, ta, on); + } catch (InstanceNotFoundException e) { + throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + } + for (Entry configAttributeEntry : configuration.entrySet()) { try { AttributeConfigElement ace = configAttributeEntry.getValue(); 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 efe4f7dde9..ea602091a0 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 @@ -20,12 +20,13 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorT import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; -import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -143,14 +144,14 @@ public class Get extends AbstractConfigNetconfOperation { final Map> moduleRuntimes = createModuleRuntimes(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); - final Map> moduleConfigs = GetConfig.transform(configRegistryClient, - yangStoreSnapshot.getModuleMXBeanEntryMap()); + final Map> moduleConfigs = EditConfig.transformMbeToModuleConfigs( + configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs); ObjectName txOn = transactionProvider.getOrCreateTransaction(); ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn); - final Element element = runtime.toXml(runtimeBeans, configBeans, document, ta); + final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta)); logger.info("{} operation successful", XmlNetconfConstants.GET); 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 d75cfd5d6f..16dd5ad80a 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,21 +9,18 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig; import com.google.common.base.Optional; -import com.google.common.collect.Maps; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -83,14 +80,14 @@ public class GetConfig extends AbstractConfigNetconfOperation { final Set instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider) .queryInstances(configRegistryClient); - final Config configMapping = new Config(transform(configRegistryClient, + final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap())); ObjectName on = transactionProvider.getOrCreateTransaction(); ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on); - Services serviceTracker = new Services(ta); + ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta); dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker); logger.info("{} operation successful", GET_CONFIG); @@ -98,27 +95,6 @@ public class GetConfig extends AbstractConfigNetconfOperation { return dataElement; } - // TODO refactor ... duplicate code - public static Map> transform(final ConfigRegistryClient configRegistryClient, - Map> mBeanEntries) { - return Maps.transformEntries(mBeanEntries, - new Maps.EntryTransformer, Map>() { - - @Override - public Map transformEntry(String arg0, Map arg1) { - return Maps.transformEntries(arg1, - new Maps.EntryTransformer() { - - @Override - public ModuleConfig transformEntry(String key, ModuleMXBeanEntry value) { - return new ModuleConfig(key, new InstanceConfig(configRegistryClient, value - .getAttributes()), value.getProvidedServices().values()); - } - }); - } - }); - } - @Override protected String getOperationName() { return GET_CONFIG; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index 7463bdd429..f838c6f9f5 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -127,7 +127,6 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { if (contextInstanceElement.isPresent() == false) return HandlingPriority.CANNOT_HANDLE; - // FIXME update xpath to instance to conform to config-api yang final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get() .getTextContent(), netconfOperationName, netconfOperationNamespace); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java index 1c806742e9..fc8ddc01bd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java @@ -9,13 +9,6 @@ package org.opendaylight.controller.netconf.confignetconfconnector.util; import com.google.common.base.Preconditions; -import org.opendaylight.controller.config.yang.store.api.YangStoreException; -import org.opendaylight.controller.config.yang.store.api.YangStoreService; -import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -41,15 +34,4 @@ public final class Util { + " should be " + clazz + " of " + value); } - // TODO: add message and proper error types - public static YangStoreSnapshot getYangStore(final YangStoreService yangStoreService) - throws NetconfDocumentedException { - try { - return yangStoreService.getYangStoreSnapshot(); - } catch (final YangStoreException e) { - throw new NetconfDocumentedException("TODO", e, ErrorType.application, ErrorTag.bad_attribute, - ErrorSeverity.error); - } - } - } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 11cf1aae6a..9511673ea4 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -143,12 +143,19 @@ public class NetconfMappingTest extends AbstractConfigTest { "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1"); + edit("netconfMessages/editConfig_addServiceName.xml"); config = getConfigCandidate(); assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"); + edit("netconfMessages/editConfig_addServiceNameOnTest.xml"); + config = getConfigCandidate(); + assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user", + "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", + "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"); + commit(); config = getConfigRunning(); assertCorrectRefNamesForDependencies(config); @@ -229,6 +236,7 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); Element configCandidate = getConfigCandidate(); + System.err.println(XmlUtil.toString(configCandidate)); checkBinaryLeafEdited(configCandidate); diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java index 6e7a225f38..505a91c6ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java @@ -23,7 +23,9 @@ import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution; @@ -35,7 +37,7 @@ import java.util.Collections; import java.util.Map; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyMapOf; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -82,8 +84,8 @@ public class EditConfigTest { ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING); EditConfigStrategy editStrat = mock(EditConfigStrategy.class); - doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMap(), - any(ConfigTransactionClient.class), any(Services.class)); + doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class), + any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class)); EditConfigExecution editConfigExecution = mockExecution(editStrat); @@ -96,20 +98,44 @@ public class EditConfigTest { verify(provider).getOrCreateTransaction(); // For every instance execute strat - verify(editStrat, times(2/* Test */+ 2/* Set */)).executeConfiguration(anyString(), anyString(), anyMap(), - any(ConfigTransactionClient.class), any(Services.class)); + verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(), + anyString(), anyMapOf(String.class, AttributeConfigElement.class), + any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class)); } private EditConfigExecution mockExecution(EditConfigStrategy editStrat) { EditConfigExecution mock = mock(EditConfigExecution.class); - doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(); + doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class)); + doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class)); doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy(); doReturn(true).when(mock).shouldSet(); doReturn(true).when(mock).shouldTest(); - doReturn(mockServices()).when(mock).getServices(); + doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class)); + doReturn(new Services()).when(mock).getServices(); return mock; } + private Object getMappingDefinition(EditConfigStrategy editStrat) { + Map> result = Maps.newHashMap(); + + Multimap innerMultimap = HashMultimap.create(); + Map attributes = getSimpleAttributes(); + + ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class); + doReturn(editStrat).when(mockedDefinition).getEditStrategy(); + doReturn("i1").when(mockedDefinition).getInstanceName(); + innerMultimap.put("m1", mockedDefinition); + + ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class); + doReturn(editStrat).when(mockedDefinition2).getEditStrategy(); + doReturn("i2").when(mockedDefinition2).getInstanceName(); + innerMultimap.put("m1", mockedDefinition2); + + result.put("n1", innerMultimap); + + return result; + } + private static ServiceReferenceReadableRegistry mockServiceRegistry() { ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class); doReturn( @@ -120,8 +146,8 @@ public class EditConfigTest { return mock; } - static Services mockServices() { - return new Services(mockServiceRegistry()); + static ServiceRegistryWrapper mockServices() { + return new ServiceRegistryWrapper(mockServiceRegistry()); } private Map> getMapping(EditConfigStrategy editStrat) { diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java index 1c3ac7a455..b66a1a57c2 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.persist.impl; +import org.opendaylight.controller.config.persist.api.Persister; import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification; import org.opendaylight.controller.netconf.api.jmx.DefaultCommitOperationMXBean; import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification; @@ -36,11 +37,11 @@ public class ConfigPersisterNotificationHandler implements NotificationListener, private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class); private final MBeanServerConnection mBeanServerConnection; private final NetconfClient netconfClient; - private final PersisterAggregator persisterAggregator; + private final Persister persisterAggregator; private final Pattern ignoredMissingCapabilityRegex; public ConfigPersisterNotificationHandler(MBeanServerConnection mBeanServerConnection, NetconfClient netconfClient, - PersisterAggregator persisterAggregator, Pattern ignoredMissingCapabilityRegex) { + Persister persisterAggregator, Pattern ignoredMissingCapabilityRegex) { this.mBeanServerConnection = mBeanServerConnection; this.netconfClient = netconfClient; this.persisterAggregator = persisterAggregator; @@ -72,8 +73,9 @@ public class ConfigPersisterNotificationHandler implements NotificationListener, if (notification instanceof CommitJMXNotification) { try { handleAfterCommitNotification((CommitJMXNotification) notification); - } catch (Exception e) { - // TODO: notificationBroadcast support logs only DEBUG + } catch (Throwable e) { + // log exceptions from notification Handler here since + // notificationBroadcastSupport logs only DEBUG level logger.warn("Exception occured during notification handling: ", e); throw e; } diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java index 811ba38c10..86a024a240 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java @@ -40,8 +40,6 @@ public final class Util { return true; } - - // TODO: check if closing in correct order public static void closeClientAndDispatcher(NetconfClient client) { NetconfClientDispatcher dispatcher = client.getNetconfClientDispatcher(); Exception fromClient = null; diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java index 15ed5c48fa..2a95cca937 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java @@ -1,10 +1,9 @@ -/** - * @author Tomas Olvecky +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * - * 11 2013 - * - * Copyright (c) 2013 by Cisco Systems, Inc. - * 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.persist.impl.osgi; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java index 1d2e039b29..8dbdb26bff 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java @@ -15,6 +15,8 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; import org.opendaylight.controller.netconf.mapping.api.Capability; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.Map; @@ -24,6 +26,8 @@ public class CapabilityProviderImpl implements CapabilityProvider { private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot; private final Set capabilityURIs; + private static final Logger logger = LoggerFactory.getLogger(DefaultCommitNotificationProducer.class); + public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) { this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot; Map urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot); @@ -38,7 +42,11 @@ public class CapabilityProviderImpl implements CapabilityProvider { final Set caps = netconfOperationService.getCapabilities(); for (Capability cap : caps) { - // TODO check for duplicates ? + + if(capabilityMap.containsKey(cap.getCapabilityUri())) { + logger.debug("Duplicate capability {} from service {}", cap.getCapabilityUri(), netconfOperationService); + } + capabilityMap.put(cap.getCapabilityUri(), cap); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java index 4f60788975..7c5bd0cb21 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java @@ -12,12 +12,13 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.util.concurrent.Promise; -import java.net.InetSocketAddress; import org.opendaylight.controller.netconf.api.NetconfSession; import org.opendaylight.controller.netconf.impl.util.DeserializerExceptionHandler; import org.opendaylight.controller.netconf.util.AbstractChannelInitializer; import org.opendaylight.protocol.framework.AbstractDispatcher; +import java.net.InetSocketAddress; + public class NetconfServerDispatcher extends AbstractDispatcher { private final ServerChannelInitializer initializer; @@ -28,7 +29,6 @@ public class NetconfServerDispatcher extends AbstractDispatcher() { diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java index e74723032d..91734beacb 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.impl; +import com.google.common.base.Preconditions; import io.netty.channel.Channel; import io.netty.util.Timer; import io.netty.util.concurrent.Promise; @@ -28,9 +29,12 @@ import org.w3c.dom.Node; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; +import java.io.InputStream; public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory { + public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml"; + private final Timer timer; private static final Document helloMessageTemplate = loadHelloMessageTemplate(); @@ -45,8 +49,11 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF } private static Document loadHelloMessageTemplate() { - return NetconfUtil.createMessage( - NetconfServerSessionNegotiatorFactory.class.getResourceAsStream("/server_hello.xml")).getDocument(); + InputStream resourceAsStream = NetconfServerSessionNegotiatorFactory.class + .getResourceAsStream(SERVER_HELLO_XML_LOCATION); + Preconditions.checkNotNull(resourceAsStream, "Unable to load server hello message blueprint from %s", + SERVER_HELLO_XML_LOCATION); + return NetconfUtil.createMessage(resourceAsStream).getDocument(); } @Override diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java index 1b3542595f..505c74714a 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java @@ -68,6 +68,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S @Override public Schemas getSchemas() { // FIXME, session ID + // capabilities should be split from operations (it will allow to move getSchema operation to monitoring module) return transformSchemas(factoriesListener.getSnapshot(0)); } @@ -78,6 +79,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S for (NetconfOperationService netconfOperationService : snapshot.getServices()) { // TODO check for duplicates ? move capability merging to snapshot + // Split capabilities from operations first and delete this duplicate code caps.addAll(netconfOperationService.getCapabilities()); } @@ -115,8 +117,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.NETCONF)); for (String location : locations) { - // TODO how to create enumerration from string location ? - // monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.valueOf(location))); + monitoringLocations.add(new Schema.Location(new Uri(location))); } return monitoringLocations; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index ee474dbba0..d70a15c18b 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -185,7 +185,6 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { private NetconfOperationExecution getNetconfOperationWithHighestPriority( Document message, NetconfSession session) { - // TODO test TreeMap> sortedPriority = getSortedNetconfOperationsWithCanHandle( message, session); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java index f2c70d6101..b70a31a84b 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java @@ -1,11 +1,6 @@ package org.opendaylight.controller.netconf.impl.util; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - +import com.google.common.base.Preconditions; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; @@ -13,12 +8,18 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.xml.sax.SAXException; -// TODO purge nulls +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + public class NetconfUtil { private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class); public static NetconfMessage createMessage(final File f) { + Preconditions.checkNotNull(f, "File parameter was null"); try { return createMessage(new FileInputStream(f)); } catch (final FileNotFoundException e) { @@ -28,6 +29,7 @@ public class NetconfUtil { } public static NetconfMessage createMessage(final InputStream is) { + Preconditions.checkNotNull(is, "InputStream parameter was null"); Document doc = null; try { doc = XmlUtil.readXmlToDocument(is); diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java index 0140b65c14..0ecc1cb383 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java @@ -24,21 +24,14 @@ import java.net.InetSocketAddress; public class NetconfDispatcherImplTest { private EventLoopGroup nettyGroup; + private NetconfServerDispatcher dispatch; + private DefaultCommitNotificationProducer commitNot; @Before public void setUp() throws Exception { nettyGroup = new NioEventLoopGroup(); - } - - @After - public void tearDown() throws Exception { - nettyGroup.shutdownGracefully(); - } - @Test - public void test() throws Exception { - - DefaultCommitNotificationProducer commitNot = new DefaultCommitNotificationProducer( + commitNot = new DefaultCommitNotificationProducer( ManagementFactory.getPlatformMBeanServer()); NetconfOperationServiceFactoryListener factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); @@ -50,13 +43,20 @@ public class NetconfDispatcherImplTest { factoriesListener, commitNot, idProvider, null); NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory, listenerFactory); - - NetconfServerDispatcher dispatch = new NetconfServerDispatcher( + dispatch = new NetconfServerDispatcher( serverChannelInitializer, nettyGroup, nettyGroup); + } + @After + public void tearDown() throws Exception { + commitNot.close(); + nettyGroup.shutdownGracefully(); + } + + @Test + public void test() throws Exception { InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8333); ChannelFuture s = dispatch.createServer(addr); - - commitNot.close(); + s.get(); } } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java new file mode 100644 index 0000000000..14f70d398c --- /dev/null +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2013 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.it; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import io.netty.channel.ChannelFuture; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.util.HashedWheelTimer; +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.matchers.JUnitMatchers; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.opendaylight.controller.config.manager.impl.AbstractConfigTest; +import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; +import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; +import org.opendaylight.controller.config.persist.api.Persister; +import org.opendaylight.controller.config.spi.ModuleFactory; +import org.opendaylight.controller.config.yang.store.api.YangStoreException; +import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService; +import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification; +import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession; +import org.opendaylight.controller.netconf.client.NetconfClient; +import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; +import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; +import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; +import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory; +import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory; +import org.opendaylight.controller.netconf.impl.SessionIdProvider; +import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; +import org.opendaylight.controller.netconf.mapping.api.Capability; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator; +import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService; +import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler; +import org.opendaylight.controller.netconf.util.test.XmlFileLoader; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; + +import javax.management.InstanceNotFoundException; +import javax.management.Notification; +import javax.management.NotificationListener; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +public class NetconfConfigPersisterITTest extends AbstractConfigTest { + + private static final Logger logger = LoggerFactory.getLogger(NetconfConfigPersisterITTest.class); + + private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023); + + private EventLoopGroup nettyThreadgroup; + + private NetconfClientDispatcher clientDispatcher; + + @Before + public void setUp() throws Exception { + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray( + new ModuleFactory[0]))); + + NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener()); + + NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); + factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore())); + factoriesListener + .onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory( + new NetconfMonitoringOperationService(monitoringService))); + + nettyThreadgroup = new NioEventLoopGroup(); + + NetconfServerDispatcher dispatch = createDispatcher(factoriesListener); + ChannelFuture s = dispatch.createServer(tcpAddress); + s.await(); + + clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup); + } + + private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException { + final Collection yangDependencies = NetconfITTest.getBasicYangs(); + return new HardcodedYangStoreService(yangDependencies); + } + + private NetconfServerDispatcher createDispatcher( + NetconfOperationServiceFactoryListenerImpl factoriesListener) { + SessionIdProvider idProvider = new SessionIdProvider(); + NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( + new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider); + + NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory( + factoriesListener, new DefaultCommitNotificationProducer(platformMBeanServer), idProvider, mockSessionMonitoringService()); + + NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer( + serverNegotiatorFactory, listenerFactory); + return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup); + } + + private SessionMonitoringService mockSessionMonitoringService() { + SessionMonitoringService mockedSessionMonitor = mock(SessionMonitoringService.class); + doNothing().when(mockedSessionMonitor).onSessionUp(any(NetconfManagementSession.class)); + doNothing().when(mockedSessionMonitor).onSessionDown(any(NetconfManagementSession.class)); + return mockedSessionMonitor; + } + + @Test + public void testNetconfCommitNotifications() throws Exception { + + VerifyingNotificationListener notificationVerifier = createCommitNotificationListener(); + VerifyingPersister mockedAggregator = mockAggregator(); + + try (NetconfClient persisterClient = new NetconfClient("persister", tcpAddress, 4000, clientDispatcher)) { + ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler( + platformMBeanServer, persisterClient, mockedAggregator, + Pattern.compile("")); + configPersisterNotificationHandler.init(); + + try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) { + NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage()); + assertResponse(response, " caps = Sets.newHashSet(); + doReturn(caps).when(service).getCapabilities(); + Set services = Sets.newHashSet(service); + doReturn(services).when(snap).getServices(); + doReturn(snap).when(factoriesListener).getSnapshot(anyLong()); + + return factoriesListener; + } + + private static class VerifyingNotificationListener implements NotificationListener { + public List notifications = Lists.newArrayList(); + + @Override + public void handleNotification(Notification notification, Object handback) { + this.notifications.add(notification); + } + + void assertNotificationCount(Object size) { + assertEquals(size, notifications.size()); + } + + void assertNotificationContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) { + Notification notification = notifications.get(notificationIndex); + assertEquals(CommitJMXNotification.class, notification.getClass()); + int capsSize = ((CommitJMXNotification) notification).getCapabilities().size(); + assertEquals("Expected capabilities count", expectedCapsSize, capsSize); + Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot(); + int modulesSize = configSnapshot.getElementsByTagName("module").getLength(); + assertEquals("Expected modules count", expectedModulesSize, modulesSize); + int servicesSize = configSnapshot.getElementsByTagName("instance").getLength(); + assertEquals("Expected services count", expectedServicesSize, servicesSize); + } + } + + private static class VerifyingPersister implements Persister { + + public List snapshots = Lists.newArrayList(); + private Persister mockedPersister; + + public VerifyingPersister() throws IOException { + Persister mockedAggregator = mock(Persister.class); + + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0]; + snapshots.add(configSnapshot); + return null; + } + }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class)); + + this.mockedPersister = mockedAggregator; + } + + void assertSnapshotCount(Object size) { + assertEquals(size, snapshots.size()); + } + + void assertSnapshotContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) { + ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex); + int capsSize = snapshot.getCapabilities().size(); + assertEquals("Expected capabilities count", expectedCapsSize, capsSize); + String configSnapshot = snapshot.getConfigSnapshot(); + int modulesSize = StringUtils.countMatches(configSnapshot, ""); + assertEquals("Expected modules count", expectedModulesSize, modulesSize); + int servicesSize = StringUtils.countMatches(configSnapshot, ""); + assertEquals("Expected services count", expectedServicesSize, servicesSize); + } + + @Override + public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException { + mockedPersister.persistConfig(configSnapshotHolder); + } + + @Override + public List loadLastConfigs() throws IOException { + return mockedPersister.loadLastConfigs(); + } + + @Override + public void close() { + mockedPersister.close(); + } + } +} diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index bc2961c317..36f30dd328 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -16,19 +16,6 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; -import java.io.IOException; -import java.io.InputStream; -import java.lang.management.ManagementFactory; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import javax.management.ObjectName; -import javax.xml.parsers.ParserConfigurationException; import junit.framework.Assert; import org.junit.After; import org.junit.Before; @@ -74,6 +61,21 @@ import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; + +import javax.management.ObjectName; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.management.ManagementFactory; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + import static java.util.Collections.emptyList; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; @@ -215,20 +217,6 @@ public class NetconfITTest extends AbstractConfigTest { } } - - //TODO: test persister actually - @Ignore - @Test(timeout = 10000) - public void testPersister() throws Exception { -// Persister persister = mock(Persister.class); -// doReturn("mockPersister").when(persister).toString(); -// doReturn(Collections.emptyList()).when(persister).loadLastConfigs(); -// ConfigPersisterNotificationHandler h = -// new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer(), -// Pattern.compile(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX)); -// h.init(); - } - @Ignore @Test public void waitingTest() throws Exception { diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java index 3a7b7de7a0..fdea831b47 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java @@ -7,27 +7,14 @@ */ package org.opendaylight.controller.netconf.it; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; +import com.google.common.base.Charsets; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; - import junit.framework.Assert; - import org.junit.Before; import org.junit.Test; import org.junit.matchers.JUnitMatchers; @@ -61,9 +48,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import com.google.common.base.Charsets; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; public class NetconfMonitoringITTest extends AbstractConfigTest { @@ -197,7 +195,7 @@ public class NetconfMonitoringITTest extends AbstractConfigTest { return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml"); } - public NetconfOperationServiceFactoryListener getFactoriesListener() { + public static NetconfOperationServiceFactoryListener getFactoriesListener() { NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class); NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class); NetconfOperationService service = mock(NetconfOperationService.class); diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java index 5a0688c8d1..176cf2d28c 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java @@ -36,8 +36,6 @@ public class HandlingPriority implements Comparable { return Optional.of(priority).or(Optional. absent()); } - // TODO test - @Override public int compareTo(HandlingPriority o) { if (this == o) diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java index 4fee930eff..26ea7ceb79 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java @@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; public abstract class AbstractNetconfSessionNegotiator

extends AbstractSessionNegotiator { - // TODO what time ? + // TODO Adjust wait time for negotiation, now is 1 minute ? private static final long INITIAL_HOLDTIMER = 1; private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class); diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml new file mode 100644 index 0000000000..6e68326382 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml @@ -0,0 +1,38 @@ + + + + + + + test-only + + merge + + + + + instance-from-code_dep + + test-impl:impl-dep + + + + + + + prefix:testing + + ref_dep_user_another_test1 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + ref_dep_user_another_test2 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + + + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml index 7f884dc43c..36f79a50bc 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml @@ -1,19 +1,6 @@ - - - - - + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml index a7f1c86391..ade40f6a49 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml @@ -21,12 +21,11 @@ - test-impl:impl-netconf - test1 + instance-from-code 44 8ad1 @@ -72,7 +71,7 @@ test-impl:impl-netconf - test2 + test3 diff --git a/opendaylight/netconf/pom.xml b/opendaylight/netconf/pom.xml index c4b1467220..21a1ffe81d 100644 --- a/opendaylight/netconf/pom.xml +++ b/opendaylight/netconf/pom.xml @@ -48,7 +48,7 @@ 5.0.0 - 2.3.7 + 2.4.0 1.7.2 4.0.10.Final 0.9.2