Merge "Implementation for enabling remote rpc calls between 2 instances of md-sal"
authorEd Warnicke <eaw@cisco.com>
Mon, 9 Dec 2013 17:39:39 +0000 (17:39 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 9 Dec 2013 17:39:39 +0000 (17:39 +0000)
43 files changed:
opendaylight/config/logback-config/src/main/yang/config-logging.yang
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java
opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java
opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryTemplatesTest.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/TypeProviderWrapper.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/JavaAttribute.java
opendaylight/config/yang-test/src/main/yang/config-test-impl.yang
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/CodecRegistry.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/IdentitityCodec.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/CodecMapping.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/IntermediateMapping.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java
opendaylight/md-sal/sal-binding-dom-it/pom.xml
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/netconf/config-netconf-connector/pom.xml
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfSession.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml

index 7f4ea39dd4ccb66d5e65979ce994848b884d2dd0..3b28b574696683540391dd53ab041b0b40dd7ebb 100644 (file)
@@ -51,6 +51,7 @@ module config-logging {
                     type string;
                     mandatory true;
                 }
+                key name;
                 config:java-name-prefix FileAppenderTO;
             }
             
@@ -89,6 +90,7 @@ module config-logging {
                     type string;
                     mandatory true;
                 }
+                key name;
 
                 leaf file-name-pattern {
                     type string;
@@ -107,7 +109,7 @@ module config-logging {
                 
                 leaf clean-history-on-start {
                     type boolean;
-                    default 0;
+                    default false;
                 }
                 config:java-name-prefix RollingFileAppenderTO;
             }
@@ -128,6 +130,8 @@ module config-logging {
                     type string;
                     mandatory true;
                 }
+                key name;
+
                 config:java-name-prefix ConsoleAppenderTO;
             }
 
@@ -136,6 +140,7 @@ module config-logging {
                     type string;
                     mandatory true;
                 }
+                key logger-name;
 
                 leaf level {
                     type string;
index 6da68018f2ff92e3795c017b9ddadb2628a7e625..115bb85b618020b61282c83c3c692c9dafca6251 100644 (file)
@@ -129,7 +129,7 @@ public class TemplateFactory {
                 for (JavaAttribute ja : rpc.getParameters()) {
                     Field field = new Field(Collections.<String> emptyList(),
                             ja.getType().getFullyQualifiedName(),
-                            ja.getLowerCaseCammelCase());
+                            ja.getLowerCaseCammelCase(), ja.getNullableDefaultWrappedForCode());
                     fields.add(field);
                 }
                 MethodDeclaration operation = new MethodDeclaration(
@@ -433,15 +433,18 @@ public class TemplateFactory {
                     String varName = BindingGeneratorUtil
                             .parseToValidParamName(attrEntry.getKey());
 
-                    String fullyQualifiedName;
+                    String fullyQualifiedName, nullableDefault = null;
                     if (attrEntry.getValue() instanceof TypedAttribute) {
                         Type type = ((TypedAttribute) attrEntry.getValue()).getType();
                         fullyQualifiedName = serializeType(type);
+                        if(attrEntry.getValue() instanceof JavaAttribute) {
+                            nullableDefault = ((JavaAttribute)attrEntry.getValue()).getNullableDefaultWrappedForCode();
+                        }
                     } else {
                         fullyQualifiedName = FullyQualifiedNameHelper
                                 .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase());
                     }
-                    fields.add(new Field(fullyQualifiedName, varName));
+                    fields.add(new Field(fullyQualifiedName, varName, nullableDefault));
 
                     String getterName = "get" + innerName;
                     MethodDefinition getter = new MethodDefinition(
@@ -531,6 +534,7 @@ public class TemplateFactory {
                 String packageName) {
             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
                 String type;
+                String nullableDefaultWrapped = null;
                 AttributeIfc attributeIfc = attrEntry.getValue();
 
                 if (attributeIfc instanceof TypedAttribute) {
@@ -548,6 +552,7 @@ public class TemplateFactory {
                     if (innerAttr instanceof JavaAttribute) {
                         fullyQualifiedName = ((JavaAttribute) innerAttr)
                                 .getType().getFullyQualifiedName();
+                        nullableDefaultWrapped = ((JavaAttribute) innerAttr).getNullableDefaultWrappedForCode();
                     } else if (innerAttr instanceof TOAttribute) {
                         fullyQualifiedName = FullyQualifiedNameHelper
                                 .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase());
@@ -563,7 +568,7 @@ public class TemplateFactory {
                 }
 
                 fields.add(new Field(type, attributeIfc
-                        .getUpperCaseCammelCase()));
+                        .getUpperCaseCammelCase(), nullableDefaultWrapped));
             }
         }
 
@@ -582,12 +587,16 @@ public class TemplateFactory {
         void processAttributes(Map<String, AttributeIfc> attributes,
                 String packageName) {
             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
-                String type;
+                String type, nullableDefaultWrapped = null;
                 AttributeIfc attributeIfc = attrEntry.getValue();
 
                 if (attributeIfc instanceof TypedAttribute) {
                     TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
                     type = serializeType(typedAttribute.getType());
+                    if (attributeIfc instanceof JavaAttribute) {
+                        nullableDefaultWrapped = ((JavaAttribute) attributeIfc).getNullableDefaultWrappedForCode();
+                    }
+
                 } else if (attributeIfc instanceof TOAttribute) {
                     String fullyQualifiedName = FullyQualifiedNameHelper
                             .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
@@ -600,6 +609,7 @@ public class TemplateFactory {
                     if (innerAttr instanceof JavaAttribute) {
                         fullyQualifiedName = ((JavaAttribute) innerAttr)
                                 .getType().getFullyQualifiedName();
+                        nullableDefaultWrapped = ((JavaAttribute) innerAttr).getNullableDefaultWrappedForCode();
                     } else if (innerAttr instanceof TOAttribute) {
                         fullyQualifiedName = FullyQualifiedNameHelper
                                 .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase());
@@ -631,8 +641,7 @@ public class TemplateFactory {
                 String varName = BindingGeneratorUtil
                         .parseToValidParamName(attrEntry.getKey());
                 moduleFields.add(new ModuleField(type, varName, attributeIfc
-                        .getUpperCaseCammelCase(), attributeIfc
-                        .getNullableDefault(), isDependency, dependency));
+                        .getUpperCaseCammelCase(), nullableDefaultWrapped, isDependency, dependency));
 
                 String getterName = "get"
                         + attributeIfc.getUpperCaseCammelCase();
index fe9e885b6fab8edcc457008b479f534512073386..0857ec6f8da64e16e64119d44d78834fd477cb9c 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model;
 
-import java.util.List;
-
 import com.google.common.collect.Lists;
 
+import java.util.List;
+
 public class Field {
     private final String type;
     private final String name;
@@ -21,6 +21,10 @@ public class Field {
         this(Lists.<String> newArrayList(), type, name, null);
     }
 
+    public Field(String type, String name, String definition) {
+        this(Lists.<String> newArrayList(), type, name, definition);
+    }
+
     public Field(List<String> modifiers, String type, String name) {
         this(modifiers, type, name, null);
     }
index 2f1437404a7d49f7673d0c6ae34637f597be6847..1945cac1c270919d10b59481139581e848c87f0a 100644 (file)
@@ -534,7 +534,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
         assertDeclaredField(fieldDeclarations,
                 "private java.util.concurrent.ThreadFactory threadfactoryDependency");
         assertDeclaredField(fieldDeclarations,
-                "private java.lang.Long keepAlive=10");
+                "private java.lang.Long keepAlive=new java.lang.Long(\"10\")");
         assertDeclaredField(fieldDeclarations,
                 "private java.lang.Long coreSize");
         assertDeclaredField(fieldDeclarations, "private byte[] binary");
index 3c479318968e35cc6a132e9c6b88ae8d6700ff72..48d5b30eb282731bc7adabe46427384352272bf4 100644 (file)
@@ -7,14 +7,7 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.plugin;
 
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.util.Collections;
-import java.util.Map;
-
+import com.google.common.collect.Maps;
 import org.junit.Test;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
@@ -23,7 +16,13 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFa
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
 
-import com.google.common.collect.Maps;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 public class ModuleMXBeanEntryTemplatesTest {
 
@@ -61,6 +60,7 @@ public class ModuleMXBeanEntryTemplatesTest {
         doReturn("package.type").when(typeA).getFullyQualifiedName();
         doReturn(typeA).when(attr).getType();
         doReturn("Type").when(attr).getUpperCaseCammelCase();
+        doReturn("new Default()").when(attr).getNullableDefault();
         return attr;
     }
 
index a2238d1a13da854c07df8278c697e8fddd15bdd2..764ecd38868c7b224c1c8e0065d7989f8126fa37 100644 (file)
@@ -26,6 +26,10 @@ public class TypeProviderWrapper {
         return getType(leaf, type);
     }
 
+    public String getDefault(LeafSchemaNode node) {
+        return typeProvider.getTypeDefaultConstruction(node);
+    }
+
     public Type getType(SchemaNode leaf, TypeDefinition<?> type) {
         Type javaType;
         try {
index 325ca9ee06fd1bd9d29d56a94cedc0871aac77c7..3e20e4a55ad47f58e538a33594d1f5d4f0e70d32 100644 (file)
@@ -22,7 +22,7 @@ import javax.management.openmbean.SimpleType;
 public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
 
     private final Type type;
-    private final String nullableDescription, nullableDefault;
+    private final String nullableDescription, nullableDefault, nullableDefaultWrappedForCode;
     private final TypeProviderWrapper typeProviderWrapper;
     private final TypeDefinition<?> typeDefinition;
 
@@ -33,6 +33,7 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
         this.typeDefinition = leaf.getType();
         this.typeProviderWrapper = typeProviderWrapper;
         this.nullableDefault = leaf.getDefault();
+        this.nullableDefaultWrappedForCode = leaf.getDefault() == null ? null : typeProviderWrapper.getDefault(leaf);
         this.nullableDescription = leaf.getDescription();
     }
 
@@ -42,10 +43,14 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
         this.type = typeProviderWrapper.getType(leaf);
         this.typeDefinition = leaf.getType();
         this.typeProviderWrapper = typeProviderWrapper;
-        this.nullableDefault = null;
+        this.nullableDefault = nullableDefaultWrappedForCode = null;
         this.nullableDescription = leaf.getDescription();
     }
 
+    public TypeDefinition<?> getTypeDefinition() {
+        return typeDefinition;
+    }
+
     /**
      * Returns the most base type
      */
@@ -56,6 +61,10 @@ public class JavaAttribute extends AbstractAttribute implements TypedAttribute {
         return baseType;
     }
 
+    public String getNullableDefaultWrappedForCode() {
+        return nullableDefaultWrappedForCode;
+    }
+
     @Override
     public Type getType() {
         return type;
index bd83a4cc701c358fc85829e1098fb21d73806505..9ad7a44915b15bdfbce7a64cbdaf2eb02f8bba14 100644 (file)
@@ -48,28 +48,40 @@ module config-test-impl {
            container dto-a {
                 leaf simple-arg {
                     type uint32;
+                    default 1;
                 }
 
                 leaf port {
                     type inet:port-number;
+                    default 8080;
                 }
 
+                leaf ip4 {
+                    type inet:ipv4-address;
+                    default 127.0.0.1;
+                }
+
+                leaf ip {
+                    type inet:ip-address;
+                    // TODO defaults for union default 0:0:0:0:0:0:0:1;
+                }
             }
 
             leaf as-number {
-                mandatory true;
                 type inet:as-number;
+                default 44;
             }
 
 
             leaf simpleInt {
                 type uint32;
-                default 99L;
+                default 99;
             }
 
             container dto_b {
                 leaf simple-int1 {
                     type uint32;
+                    default 32;
                 }
 
                 leaf simple-int2 {
@@ -101,28 +113,34 @@ module config-test-impl {
             when "/config:modules/config:module/config:type = 'impl-netconf'";
             leaf binaryLeaf {
                 type binary;
+                default ZGVmYXVsdEJpbg==;
             }
 
             leaf type {
                 type string;
+                default "default-string";
             }
 
             leaf extended {
                 type tt:extend-once;
+                default 1;
             }
 
             leaf extended-twice {
                 type tt:extend-twice;
+                default 2;
             }
 
             leaf extended-enum {
                 type tt:extend-enum;
+                default ONE;
             }
 
             leaf sleep-factor {
                 type decimal64 {
                     fraction-digits 2;
                 }
+                default 2.00;
             }
 
            container dto-c {
@@ -153,23 +171,28 @@ module config-test-impl {
             }
 
             leaf simple-long {
-                type int64  ;
+                type int64;
+                default -45;
             }
 
             leaf simple-long-2 {
                 type uint32;
+                default 445;
             }
 
             leaf simple-BigInteger {
                 type uint64;
+                default 545454;
             }
 
             leaf simple-byte {
                 type int8;
+                default -4;
             }
 
             leaf simple-short {
                 type uint8;
+                default 45;
             }
 
             leaf simple-test {
@@ -209,6 +232,7 @@ module config-test-impl {
                     container deep {
                         leaf simple-int3 {
                             type uint16;
+                            default 0;
                         }
                     }
                 }
@@ -393,6 +417,7 @@ module config-test-impl {
             container retValContainer {
                 leaf v1 {
                     type string;
+                    default "from rpc";
                 }
 
                 leaf v2 {
index e83fdcc5c885eac73f9d9837e0f5758ea2240499..c2f9bc311dc18b8cbde89c2c964c1fde73ad5939 100644 (file)
                <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
                <instance>
                        <name>global-boss-group</name>
-                       <provider>/config/modules/module[name='netty-threadgroup-fixed']/instance[name='global-boss-group']</provider>
+                       <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
                </instance>
                <instance>
                        <name>global-worker-group</name>
-                       <provider>/config/modules/module[name='netty-threadgroup-fixed']/instance[name='global-worker-group']</provider>
+                       <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
                </instance>
        </service>
        <service>
                <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
                <instance>
                        <name>global-event-executor</name>
-                       <provider>/config/modules/module[name='netty-global-event-executor']/instance[name='global-event-executor']</provider>
+                       <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
                </instance>
        </service>
        <service>
                <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
                <instance>
                        <name>global-timer</name>
-                       <provider>/config/modules/module[name='netty-hashed-wheel-timer']/instance[name='global-timer']</provider>
+                       <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
                </instance>
        </service>
 //CAPABILITIES START
index 430a278a6061b332e885df89094b3ac4271b7ac8..fa33215ea6e9454d5c016e5e2f2fb58474099b55 100644 (file)
                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
                <instance>
                        <name>ref_yang-schema-service</name>
-                       <provider>/config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']</provider>
+                       <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
                </instance>
        </service>
        <service>
                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
                <instance>
                        <name>ref_binding-notification-broker</name>
-                       <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
+                       <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
                </instance>
        </service>
        <service>
                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
                <instance>
                        <name>ref_hash-map-data-store</name>
-                       <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</provider>
+                       <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
                </instance>
                <instance>
-            <name>ref_cluster-data-store</name>
-            <provider>/config/modules/module[name='dom-clustered-store-impl']/instance[name='cluster-data-store']</provider>
-        </instance>
+                       <name>ref_cluster-data-store</name>
+                       <provider>/modules/module[type='dom-clustered-store-impl'][name='cluster-data-store']</provider>
+               </instance>
        </service>
        <service>
                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
                <instance>
                        <name>ref_binding-broker-impl</name>
-                       <provider>/config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']</provider>
+                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
                </instance>
        </service>
        <service>
                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
                <instance>
-                       <name>ref_binding-rpc-broker</name>
-                       <provider>/config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']</provider>
+                       <name>binding-rpc-broker</name>
+                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
                </instance>
        </service>
        <service>
                <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
                <instance>
                        <name>ref_runtime-mapping-singleton</name>
-                       <provider>/config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']</provider>
+                       <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
                </instance>
        </service>
        <service>
        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
                <instance>
                        <name>ref_dom-broker</name>
-                       <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']</provider>
+                       <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
                </instance>
        </service>
        <service>
                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
                <instance>
                        <name>ref_binding-data-broker</name>
-                       <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
+                       <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
                </instance>
        </service>
 //CAPABILITIES START
index 24bfc4fdf4c09079230189c43e9d33a428ab0cbf..84b3e53e065cfea03f225cc1c6fe0f8ebaa27582 100644 (file)
@@ -260,13 +260,13 @@ public class FRMUtil {
                 }
             } else if (action instanceof SetDlDstAction) {
                 MacAddress address = ((SetDlDstAction) action).getAddress();
-                if (address != null && !isL2AddressValid(address.toString())) {
+                if (address != null && !isL2AddressValid(address.getValue())) {
                     logger.error("SetDlDstAction: Address not valid");
                     return false;
                 }
             } else if (action instanceof SetDlSrcAction) {
                 MacAddress address = ((SetDlSrcAction) action).getAddress();
-                if (address != null && !isL2AddressValid(address.toString())) {
+                if (address != null && !isL2AddressValid(address.getValue())) {
                     logger.error("SetDlSrcAction: Address not valid");
                     return false;
                 }
index a31d3eedd2ee5ba0e08b203fdbb77647ea39e523..b9a4fe87ac80518d054372b5d1056227ea683efb 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.sal.binding.dom.serializer.api;
 
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.Identifier;
 
@@ -14,6 +15,8 @@ import org.opendaylight.controller.sal.binding.dom.serializer.api.IdentifierCode
 public interface CodecRegistry {
 
     InstanceIdentifierCodec getInstanceIdentifierCodec();
+    
+    IdentitityCodec<?> getIdentityCodec();
 
     <T extends DataContainer> DataContainerCodec<T> getCodecForDataObject(Class<T> object);
 
@@ -22,6 +25,8 @@ public interface CodecRegistry {
     <T extends Identifier<?>> IdentifierCodec<T> getCodecForIdentifier(Class<T> object);
 
     <T extends Augmentation<?>> AugmentationCodec<T> getCodecForAugmentation(Class<T> object);
+    
+    <T extends BaseIdentity> IdentitityCodec<T> getCodecForIdentity(Class<T> codec);
 
     Class<?> getClassForPath(List<QName> names);
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/IdentitityCodec.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/api/IdentitityCodec.java
new file mode 100644 (file)
index 0000000..0c480f5
--- /dev/null
@@ -0,0 +1,14 @@
+package org.opendaylight.controller.sal.binding.dom.serializer.api;
+
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yangtools.yang.binding.BindingCodec;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public interface IdentitityCodec<T extends BaseIdentity> extends BindingCodec<QName, Class<T>>{
+
+    @Override
+    public QName serialize(Class<T> input);
+    
+    @Override
+    public Class<T> deserialize(QName input);
+}
index 172fb05292043e49612a8bee700750c6ca68810f..fa2d32a1387d95aa6a65c251279465ca3aaf27f6 100644 (file)
@@ -3,6 +3,7 @@ package org.opendaylight.controller.sal.binding.dom.serializer.impl;
 import java.lang.reflect.Field;
 import java.util.Map;
 
+import org.opendaylight.controller.sal.binding.dom.serializer.api.IdentitityCodec;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.InstanceIdentifierCodec;
 import org.opendaylight.yangtools.yang.binding.BindingCodec;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -15,6 +16,8 @@ public class CodecMapping {
     private static final Logger LOG = LoggerFactory.getLogger(CodecMapping.class);
     
     public static final String INSTANCE_IDENTIFIER_CODEC = "INSTANCE_IDENTIFIER_CODEC";
+    public static final String IDENTITYREF_CODEC = "IDENTITYREF_CODEC";
+    
     public static final String CLASS_TO_CASE_MAP = "CLASS_TO_CASE";
     public static final String COMPOSITE_TO_CASE = "COMPOSITE_TO_CASE";
     public static final String AUGMENTATION_CODEC = "AUGMENTATION_CODEC";
@@ -27,7 +30,22 @@ public class CodecMapping {
                 instanceIdField.set(null, codec);
             }
         } catch (NoSuchFieldException e) {
-           LOG.debug("Instance identifier codec is not needed for {}",obj.getName(),e);
+           LOG.trace("Instance identifier codec is not needed for {}",obj.getName(),e);
+        } catch (SecurityException | IllegalAccessException e) {
+            LOG.error("Instance identifier could not be set for {}",obj.getName(),e);
+        }
+    }
+
+
+    public static void setIdentityRefCodec(Class<?> obj,IdentitityCodec<?> codec) {
+        Field instanceIdField;
+        try {
+            instanceIdField = obj.getField(IDENTITYREF_CODEC);
+            if(obj != null) {
+                instanceIdField.set(null, codec);
+            }
+        } catch (NoSuchFieldException e) {
+           LOG.trace("Instance identifier codec is not needed for {}",obj.getName(),e);
         } catch (SecurityException | IllegalAccessException e) {
             LOG.error("Instance identifier could not be set for {}",obj.getName(),e);
         }
@@ -71,4 +89,18 @@ public class CodecMapping {
                 LOG.error("Augmentation codec could not be set for {}",dataCodec.getName(),e);
             }
     }
+    
+    
+    public static BindingCodec<?,?> getAugmentationCodec(Class<? extends BindingCodec<?,?>> dataCodec) {
+            Field instanceIdField;
+            try {
+                instanceIdField = dataCodec.getField(AUGMENTATION_CODEC);
+                return (BindingCodec<?,?>) instanceIdField.get(null);
+            } catch (NoSuchFieldException e) {
+                LOG.debug("BUG: Augmentation codec is not needed for {}",dataCodec.getName(),e);
+            } catch (SecurityException | IllegalAccessException e) {
+                LOG.error("Augmentation codec could not be set for {}",dataCodec.getName(),e);
+            }
+            return null;
+    }
 }
index d0b114e3c37930727146fa6c3cb7a1e191a2ef61..04b8674727ced600871d3e9c44b05657c95d6658 100644 (file)
@@ -13,7 +13,10 @@ class IntermediateMapping {
     
     
     
-    static def Node<?> toNode(Map map) {
+    static def Node<?> toNode(Map<?,?> map) {
+        if(map instanceof Node<?>) {
+            return map as Node<?>;
+        }
         val nodeMap = map as Map<QName,Object>;
         Preconditions.checkArgument(map.size == 1);
         val elem = nodeMap.entrySet.iterator.next;
@@ -22,10 +25,15 @@ class IntermediateMapping {
         toNodeImpl(qname, value);
     }
 
+
     static def dispatch Node<?> toNodeImpl(QName name, List<?> objects) {
         val values = new ArrayList<Node<?>>(objects.size);
         for (obj : objects) {
-            values.add(toNode(obj as Map));
+            if(obj instanceof Node<?>) {
+                values.add(obj as Node<?>);
+            } else if(obj instanceof Map<?,?>) {
+                values.add(toNode(obj as Map<?,?>));
+            }
         }
         return new CompositeNodeTOImpl(name, null, values);
     }
index d33272d6413bfa90628f49a459671eab756ef2d0..39bd0816f50fb63e68bbbdb85ca7cbdce74812b6 100644 (file)
@@ -1,7 +1,9 @@
 package org.opendaylight.controller.sal.binding.dom.serializer.impl;
 
+import java.awt.CompositeContext;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -12,11 +14,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.Set;
 import java.util.WeakHashMap;
 
+import org.apache.commons.lang3.text.translate.AggregateTranslator;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.AugmentationCodec;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.ChoiceCaseCodec;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.ChoiceCodec;
@@ -24,6 +28,7 @@ import org.opendaylight.controller.sal.binding.dom.serializer.api.CodecRegistry;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.DataContainerCodec;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.DomCodec;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.IdentifierCodec;
+import org.opendaylight.controller.sal.binding.dom.serializer.api.IdentitityCodec;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.InstanceIdentifierCodec;
 import org.opendaylight.controller.sal.binding.dom.serializer.api.ValueWithQName;
 import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils;
@@ -34,6 +39,7 @@ import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.binding.BindingCodec;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -41,6 +47,7 @@ import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
@@ -61,10 +68,12 @@ import static org.opendaylight.controller.sal.binding.dom.serializer.impl.Interm
 import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext;
 import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 
+import com.google.common.collect.FluentIterable;
 import com.google.common.util.concurrent.CycleDetectingLockFactory.WithExplicitOrdering;
 
 public class LazyGeneratedCodecRegistry implements //
@@ -76,27 +85,31 @@ public class LazyGeneratedCodecRegistry implements //
     private final static LateMixinCodec NOT_READY_CODEC = new LateMixinCodec();
 
     private final InstanceIdentifierCodec instanceIdentifierCodec = new InstanceIdentifierCodecImpl(this);
+    private final IdentityCompositeCodec identityRefCodec = new IdentityCompositeCodec();
 
     private TransformerGenerator generator;
 
     // Concrete class to codecs
-    private Map<Class<?>, DataContainerCodec<?>> containerCodecs = new WeakHashMap<>();
-    private Map<Class<?>, IdentifierCodec<?>> identifierCodecs = new WeakHashMap<>();
-    private Map<Class<?>, ChoiceCodecImpl<?>> choiceCodecs = new WeakHashMap<>();
-    private Map<Class<?>, ChoiceCaseCodecImpl<?>> caseCodecs = new WeakHashMap<>();
-    private Map<Class<?>, AugmentableCompositeCodec> augmentableCodecs = new WeakHashMap<>();
-
+    private static final Map<Class<?>, DataContainerCodec<?>> containerCodecs = new WeakHashMap<>();
+    private static final Map<Class<?>, IdentifierCodec<?>> identifierCodecs = new WeakHashMap<>();
+    private static final Map<Class<?>, ChoiceCodecImpl<?>> choiceCodecs = new WeakHashMap<>();
+    private static final Map<Class<?>, ChoiceCaseCodecImpl<?>> caseCodecs = new WeakHashMap<>();
+    private static final Map<Class<?>, AugmentableCompositeCodec> augmentableCodecs = new WeakHashMap<>();
+    private static final Map<Class<?>, AugmentationCodec<?>> augmentationCodecs = new WeakHashMap<>();
+    private static final Map<Class<?>, QName> identityQNames = new WeakHashMap<>();
+    private static final Map<QName, Type> qnamesToIdentityMap = new ConcurrentHashMap<>();
     /** Binding type to encountered classes mapping **/
     @SuppressWarnings("rawtypes")
-    Map<Type, WeakReference<Class>> typeToClass = new ConcurrentHashMap<>();
+    private static final Map<Type, WeakReference<Class>> typeToClass = new ConcurrentHashMap<>();
 
     @SuppressWarnings("rawtypes")
-    private ConcurrentMap<Type, ChoiceCaseCodecImpl> typeToCaseCodecs = new ConcurrentHashMap<>();
+    private static final ConcurrentMap<Type, ChoiceCaseCodecImpl> typeToCaseCodecs = new ConcurrentHashMap<>();
 
     private CaseClassMapFacade classToCaseRawCodec = new CaseClassMapFacade();
 
-    Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap<>();
-    Map<List<QName>, Type> pathToInstantiatedType = new ConcurrentHashMap<>();
+    private static final Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap<>();
+    private static final Map<List<QName>, Type> pathToInstantiatedType = new ConcurrentHashMap<>();
+    private static final Map<Type, QName> typeToQname = new ConcurrentHashMap<>();
 
     private SchemaContext currentSchema;
 
@@ -115,8 +128,56 @@ public class LazyGeneratedCodecRegistry implements //
 
     @Override
     public <T extends Augmentation<?>> AugmentationCodec<T> getCodecForAugmentation(Class<T> object) {
-        // TODO Auto-generated method stub
-        return null;
+        AugmentationCodec<T> codec = null;
+        @SuppressWarnings("rawtypes")
+        AugmentationCodec potentialCodec = augmentationCodecs.get(object);
+        if (potentialCodec != null) {
+            codec = potentialCodec;
+        } else
+            try {
+                Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentRawCodec = generator
+                        .augmentationTransformerFor(object);
+                BindingCodec<Map<QName, Object>, Object> rawCodec = augmentRawCodec.newInstance();
+                codec = new AugmentationCodecWrapper<T>(rawCodec);
+                augmentationCodecs.put(augmentRawCodec, codec);
+            } catch (InstantiationException e) {
+                LOG.error("Can not instantiate raw augmentation codec {}", object.getSimpleName(), e);
+            } catch (IllegalAccessException e) {
+                LOG.debug("BUG: Constructor for {} is not accessible.", object.getSimpleName(), e);
+            }
+        Class<? extends Augmentable<?>> objectSupertype = getAugmentableArgumentFrom(object);
+        if (objectSupertype != null) {
+            getAugmentableCodec(objectSupertype).addAugmentationCodec(object, codec);
+        } else {
+            LOG.warn("Could not find augmentation target for augmentation {}", object);
+        }
+        return codec;
+    }
+
+    private static Class<? extends Augmentable<?>> getAugmentableArgumentFrom(
+            final Class<? extends Augmentation<?>> augmentation) {
+        try {
+            Class<? extends Augmentable<?>> ret = ClassLoaderUtils.withClassLoader(augmentation.getClassLoader(),
+                    new Callable<Class<? extends Augmentable<?>>>() {
+                        @Override
+                        @SuppressWarnings("unchecked")
+                        public Class<? extends Augmentable<?>> call() throws Exception {
+                            for (java.lang.reflect.Type supertype : augmentation.getGenericInterfaces()) {
+                                if (supertype instanceof ParameterizedType
+                                        && Augmentation.class.equals(((ParameterizedType) supertype).getRawType())) {
+                                    ParameterizedType augmentationGeneric = (ParameterizedType) supertype;
+                                    return (Class<? extends Augmentable<?>>) augmentationGeneric
+                                            .getActualTypeArguments()[0];
+                                }
+                            }
+                            return null;
+                        }
+                    });
+            return ret;
+        } catch (Exception e) {
+            LOG.error("Could not find augmentable for {}", augmentation, e);
+            return null;
+        }
     }
 
     @Override
@@ -165,7 +226,6 @@ public class LazyGeneratedCodecRegistry implements //
         return newWrapper;
     }
 
-    @Override
     @SuppressWarnings("rawtypes")
     public void bindingClassEncountered(Class cls) {
 
@@ -268,9 +328,21 @@ public class LazyGeneratedCodecRegistry implements //
         return newWrapper;
     }
 
+    @Override
+    public IdentitityCodec<?> getIdentityCodec() {
+        return identityRefCodec;
+    }
+
+    @Override
+    public <T extends BaseIdentity> IdentitityCodec<T> getCodecForIdentity(Class<T> codec) {
+        bindingClassEncountered(codec);
+        return identityRefCodec;
+    }
+
     @Override
     public void onCodecCreated(Class<?> cls) {
         CodecMapping.setIdentifierCodec(cls, instanceIdentifierCodec);
+        CodecMapping.setIdentityRefCodec(cls, identityRefCodec);
     }
 
     @Override
@@ -316,6 +388,10 @@ public class LazyGeneratedCodecRegistry implements //
 
     public void onModuleContextAdded(SchemaContext schemaContext, Module module, ModuleContext context) {
         pathToType.putAll(context.getChildNodes());
+        qnamesToIdentityMap.putAll(context.getIdentities());
+        for(Entry<QName, GeneratedTOBuilder> identity : context.getIdentities().entrySet()) {
+            typeToQname.put(new ReferencedTypeImpl(identity.getValue().getPackageName(), identity.getValue().getName()),identity.getKey());
+        }
         captureCases(context.getCases(), schemaContext);
     }
 
@@ -324,7 +400,6 @@ public class LazyGeneratedCodecRegistry implements //
             ReferencedTypeImpl typeref = new ReferencedTypeImpl(caseNode.getValue().getPackageName(), caseNode
                     .getValue().getName());
 
-            LOG.info("Case path: {} Type : {}", caseNode.getKey(), caseNode.getValue().getFullyQualifiedName());
             pathToType.put(caseNode.getKey(), caseNode.getValue());
 
             ChoiceCaseNode node = (ChoiceCaseNode) SchemaContextUtil.findDataSchemaNode(module, caseNode.getKey());
@@ -371,10 +446,10 @@ public class LazyGeneratedCodecRegistry implements //
             if (path != null && (type = pathToType.get(path)) != null) {
                 ReferencedTypeImpl typeref = new ReferencedTypeImpl(type.getPackageName(), type.getName());
                 ChoiceCaseCodecImpl partialCodec = typeToCaseCodecs.get(typeref);
-                if(partialCodec.getSchema() == null ) {
+                if (partialCodec.getSchema() == null) {
                     partialCodec.setSchema(caseNode);
                 }
-                
+
                 Class<?> caseClass = ClassLoaderUtils.tryToLoadClassWithTCCL(type.getFullyQualifiedName());
                 if (caseClass != null) {
                     getCaseCodecFor(caseClass);
@@ -402,7 +477,7 @@ public class LazyGeneratedCodecRegistry implements //
 
     }
 
-    private AugmentableCompositeCodec getAugmentableCodec(Class<?> dataClass) {
+    public AugmentableCompositeCodec getAugmentableCodec(Class<?> dataClass) {
         AugmentableCompositeCodec ret = augmentableCodecs.get(dataClass);
         if (ret != null) {
             return ret;
@@ -739,7 +814,7 @@ public class LazyGeneratedCodecRegistry implements //
 
         private final Class augmentableType;
 
-        Map<Class, BindingCodec> rawAugmentationCodecs = new WeakHashMap<>();
+        Map<Class, AugmentationCodec<?>> localAugmentationCodecs = new WeakHashMap<>();
 
         public AugmentableCompositeCodec(Class type) {
             checkArgument(Augmentable.class.isAssignableFrom(type));
@@ -772,53 +847,33 @@ public class LazyGeneratedCodecRegistry implements //
         private List serializeImpl(Map<Class, Augmentation> input) {
             List ret = new ArrayList<>();
             for (Entry<Class, Augmentation> entry : input.entrySet()) {
-                BindingCodec codec = getRawCodecForAugmentation(entry.getKey());
-                List output = (List) codec.serialize(new ValueWithQName(null, entry.getValue()));
-                ret.addAll(output);
+                AugmentationCodec codec = getCodecForAugmentation(entry.getKey());
+                CompositeNode node = codec.serialize(new ValueWithQName(null, entry.getValue()));
+                ret.addAll(node.getChildren());
             }
             return ret;
         }
 
-        private BindingCodec getRawCodecForAugmentation(Class key) {
-            BindingCodec ret = rawAugmentationCodecs.get(key);
-            if (ret != null) {
-                return ret;
-            }
-            try {
-                Class<? extends BindingCodec> retClass = generator.augmentationTransformerFor(key);
-                ret = retClass.newInstance();
-                rawAugmentationCodecs.put(key, ret);
-                return ret;
-            } catch (InstantiationException e) {
-                LOG.error("Can not instantiate raw augmentation codec {}", key.getSimpleName(), e);
-            } catch (IllegalAccessException e) {
-                LOG.debug("BUG: Constructor for {} is not accessible.", key.getSimpleName(), e);
-            }
-            return null;
+        public synchronized <T extends Augmentation<?>> void addAugmentationCodec(Class<T> augmentationClass,
+                AugmentationCodec<T> value) {
+            localAugmentationCodecs.put(augmentationClass, value);
         }
 
         @Override
         public Map<Class, Augmentation> deserialize(Object input) {
             Map<Class, Augmentation> ret = new HashMap<>();
             if (input instanceof CompositeNode) {
-                for (Entry<Class, BindingCodec> codec : rawAugmentationCodecs.entrySet()) {
-                    Augmentation value = (Augmentation) codec.getValue().deserialize(input);
-                    if (value != null) {
-                        ret.put(codec.getKey(), value);
+                List<Entry<Class, AugmentationCodec<?>>> codecs = new ArrayList<>(localAugmentationCodecs.entrySet());
+                for (Entry<Class, AugmentationCodec<?>> codec : codecs) {
+                    ValueWithQName<?> value = codec.getValue().deserialize((CompositeNode) input);
+                    if (value != null && value.getValue() != null) {
+                        ret.put(codec.getKey(), (Augmentation) value.getValue());
                     }
                 }
             }
             return ret;
         }
 
-        public Map<Class, BindingCodec> getRawAugmentationCodecs() {
-            return rawAugmentationCodecs;
-        }
-
-        public void setRawAugmentationCodecs(Map<Class, BindingCodec> rawAugmentationCodecs) {
-            this.rawAugmentationCodecs = rawAugmentationCodecs;
-        }
-
         public Class getAugmentableType() {
             return augmentableType;
         }
@@ -847,4 +902,82 @@ public class LazyGeneratedCodecRegistry implements //
             return getDelegate().serialize(input);
         }
     }
+
+    private static class AugmentationCodecWrapper<T extends Augmentation<?>> implements AugmentationCodec<T>,
+            Delegator<BindingCodec> {
+
+        private BindingCodec delegate;
+
+        public AugmentationCodecWrapper(BindingCodec<Map<QName, Object>, Object> rawCodec) {
+            this.delegate = rawCodec;
+        }
+
+        @Override
+        public BindingCodec getDelegate() {
+            return delegate;
+        }
+
+        @Override
+        public CompositeNode serialize(ValueWithQName<T> input) {
+            @SuppressWarnings("unchecked")
+            List<Map<QName, Object>> rawValues = (List<Map<QName, Object>>) getDelegate().serialize(input);
+            List<Node<?>> serialized = new ArrayList<>(rawValues.size());
+            for (Map<QName, Object> val : rawValues) {
+                serialized.add(toNode(val));
+            }
+            return new CompositeNodeTOImpl(input.getQname(), null, serialized);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public ValueWithQName<T> deserialize(Node<?> input) {
+            Object rawCodecValue = getDelegate().deserialize((Map<QName, Object>) input);
+            return new ValueWithQName<T>(input.getNodeType(), (T) rawCodecValue);
+        }
+    }
+
+    private class IdentityCompositeCodec implements IdentitityCodec {
+
+        @Override
+        public Object deserialize(Object input) {
+            checkArgument(input instanceof QName);
+            return deserialize((QName) input);
+        }
+
+        @Override
+        public Class<?> deserialize(QName input) {
+            Type type = qnamesToIdentityMap.get(input);
+            if(type == null) {
+                return null;
+            }
+            ReferencedTypeImpl typeref = new ReferencedTypeImpl(type.getPackageName(), type.getName());
+            WeakReference<Class> softref = typeToClass.get(typeref);
+            if(softref == null) {
+                return null;
+            }
+            return softref.get();
+        }
+
+        @Override
+        public QName serialize(Class input) {
+            checkArgument(BaseIdentity.class.isAssignableFrom(input));
+            bindingClassEncountered(input);
+            QName qname = identityQNames.get(input);
+            if(qname != null) {
+                return qname;
+            }
+            ConcreteType typeref = Types.typeForClass(input);
+            qname = typeToQname.get(typeref);
+            if(qname != null) {
+                identityQNames.put(input, qname);
+            }
+            return qname;
+        }
+
+        @Override
+        public Object serialize(Object input) {
+            checkArgument(input instanceof Class);
+            return serialize((Class) input);
+        }
+    }
 }
\ No newline at end of file
index cb25f4da8bb9247845c251ed95b67ee6ffeca4d5..13975cad4c807abc636870f99fbea2a921e4a312 100644 (file)
@@ -37,6 +37,12 @@ import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationE
 import java.util.concurrent.Callable
 import org.opendaylight.yangtools.yang.binding.Augmentation
 import org.opendaylight.controller.sal.binding.impl.util.YangSchemaUtils
+import org.opendaylight.controller.sal.binding.dom.serializer.api.AugmentationCodec
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
 
 class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable {
 
@@ -112,9 +118,21 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
 
     override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
         Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+        
+        try {
         val key = toDataDom(entry.key)
-        val data = toCompositeNodeImpl(entry.value);
+        var CompositeNode data;
+        if(Augmentation.isAssignableFrom(entry.key.targetType)) {
+            data = toCompositeNodeImpl(key,entry.value);
+        } else {
+          data = toCompositeNodeImpl(entry.value);
+        }
         return new SimpleEntry(key, data);
+        
+        } catch (Exception e) {
+            LOG.error("Error during serialization for {}.", entry.key,e);
+            throw e;
+        }
     }
 
     private def CompositeNode toCompositeNodeImpl(DataObject object) {
@@ -124,6 +142,26 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         val ret = codec.serialize(new ValueWithQName(null, object));
         return ret as CompositeNode;
     }
+    
+    
+    private def CompositeNode toCompositeNodeImpl(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier,DataObject object) {
+       
+        //val cls = object.implementedInterface;
+        //waitForSchema(cls);
+        val last = identifier.path.last;
+        val codec = registry.getCodecForAugmentation(object.implementedInterface as Class) as AugmentationCodec;
+        val ret = codec.serialize(new ValueWithQName(last.nodeType, object));
+        if(last instanceof NodeIdentifierWithPredicates) {
+            val predicates = last as NodeIdentifierWithPredicates;
+            val newNodes = new ArrayList<Node<?>>(predicates.keyValues.size);
+            for(predicate : predicates.keyValues.entrySet) {
+                newNodes.add(new SimpleNodeTOImpl(predicate.key,null,predicate.value));
+            }
+            newNodes.addAll(ret.children);
+            return new CompositeNodeTOImpl(last.nodeType,null,newNodes);
+        }
+        return ret as CompositeNode;
+    }
 
     private def void waitForSchema(Class<? extends DataContainer> class1) {
         if(Augmentation.isAssignableFrom(class1)) {
index 0316614aa1269a93eb8d6aa3f7d2e3fd2a4438a7..b2d25af8850bd5b40a369e136baf710d9e669735 100644 (file)
@@ -91,6 +91,8 @@ class TransformerGenerator {
 
     @Property
     var GeneratorListener listener;
+    
+    public static val CLASS_TYPE = Types.typeForClass(Class);
 
     public new(ClassPool pool) {
         classPool = pool;
@@ -269,6 +271,7 @@ class TransformerGenerator {
             val ctCls = createClass(inputType.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
                 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+                staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 staticQNameField(node.QName);
                 implementsType(BINDING_CODEC)
                 method(Object, "toDomStatic", QName, Object) [
@@ -351,6 +354,7 @@ class TransformerGenerator {
                 staticQNameField(node.QName);
                 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
                 staticField(it, AUGMENTATION_CODEC, BindingCodec)
+                staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 method(Object, "toDomStatic", QName, Object) [
                     modifiers = PUBLIC + FINAL + STATIC
                     body = '''
@@ -409,6 +413,7 @@ class TransformerGenerator {
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
                 staticQNameField(node.QName);
                 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+                staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 staticField(it, AUGMENTATION_CODEC, BindingCodec)
                 implementsType(BINDING_CODEC)
                 method(Object, "toDomStatic", QName, Object) [
@@ -459,6 +464,7 @@ class TransformerGenerator {
                 staticQNameField(node.augmentationQName);
                 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
                 staticField(it, AUGMENTATION_CODEC, BindingCodec)
+                staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 implementsType(BINDING_CODEC)
                 method(Object, "toDomStatic", QName, Object) [
                     modifiers = PUBLIC + FINAL + STATIC
@@ -466,7 +472,7 @@ class TransformerGenerator {
                         {
                             //System.out.println("Qname " + $1);
                             //System.out.println("Value " + $2);
-                            Â«QName.name» _resultName = Â«QName.name».create($1,QNAME.getLocalName());
+                            Â«QName.name» _resultName = Â«QName.name».create(QNAME,QNAME.getLocalName());
                             java.util.List _childNodes = new java.util.ArrayList();
                             Â«type.resolvedName» value = («type.resolvedName») $2;
                             Â«FOR child : node.childNodes»
@@ -540,6 +546,7 @@ class TransformerGenerator {
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
                 //staticQNameField(inputType);
                 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+                staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 staticField(it, CLASS_TO_CASE_MAP, Map)
                 staticField(it, COMPOSITE_TO_CASE, Map)
                 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
@@ -828,6 +835,7 @@ class TransformerGenerator {
                 if (hasYangBinding) {
                     implementsType(BINDING_CODEC)
                     staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+                    staticField(it, IDENTITYREF_CODEC, BindingCodec)
                     implementsType(BindingDeserializer.asCtClass)
                 }
                 method(Object, "toDomValue", Object) [
@@ -1020,10 +1028,10 @@ class TransformerGenerator {
 
     private def dispatch String deserializeValue(Type type, String domParameter) {
         if (INSTANCE_IDENTIFIER.equals(type)) {
-
             return '''(«InstanceIdentifier.name») Â«INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
+        } else if (CLASS_TYPE.equals(type)) {
+            return '''(«Class.name») Â«IDENTITYREF_CODEC».deserialize(«domParameter»)'''
         }
-
         return '''(«type.resolvedName») Â«domParameter»'''
 
     }
@@ -1192,6 +1200,8 @@ class TransformerGenerator {
     private def dispatch serializeValue(Type signature, String property) {
         if (INSTANCE_IDENTIFIER == signature) {
             return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
+        }else if (CLASS_TYPE.equals(signature)) {
+            return '''(«QName.resolvedName») Â«IDENTITYREF_CODEC».serialize(«property»)'''
         }
         return '''«property»''';
     }
index 5f3189f7d2a196593ec2c903c1a2eb717c488ac5..9eff29f8cc4e256f6d9c3163cb551650e226b02f 100644 (file)
@@ -22,6 +22,8 @@ import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
 import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.Augmentable;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcError;
@@ -61,8 +63,22 @@ public class BindingIndependentDataServiceConnector implements //
     public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
         try {
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+            
+            
             CompositeNode result = biDataService.readOperationalData(biPath);
+            Class<? extends DataObject> targetType = path.getTargetType();
+            
+            if(Augmentation.class.isAssignableFrom(targetType)) {
+                path = mappingService.fromDataDom(biPath);
+                Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
+                DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
+                if(parentTo instanceof Augmentable<?>) {
+                    return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
+                }
+                
+            }
             return mappingService.dataObjectFromDataDom(path, result);
+            
         } catch (DeserializationException e) {
             throw new IllegalStateException(e);
         }
@@ -116,7 +132,7 @@ public class BindingIndependentDataServiceConnector implements //
                 DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
                 target.putConfigurationData(baKey, baData);
             } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}. Reason {}.", entry.getKey(), e);
+                LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
             }
         }
         for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
@@ -127,7 +143,7 @@ public class BindingIndependentDataServiceConnector implements //
                 DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
                 target.putOperationalData(baKey, baData);
             } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}. Reason {}.", entry.getKey(), e);
+                LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
             }
         }
         for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
@@ -136,7 +152,7 @@ public class BindingIndependentDataServiceConnector implements //
                 InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
                 target.removeConfigurationData(baEntry);
             } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}. Reason {}.", entry, e);
+                LOG.error("Ommiting from BA transaction: {}.", entry, e);
             }
         }
         for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
@@ -145,7 +161,7 @@ public class BindingIndependentDataServiceConnector implements //
                 InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
                 target.removeOperationalData(baEntry);
             } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry, e);
+                LOG.error("Ommiting from BA transaction: {}.", entry, e);
             }
         }
         return target;
index 9a143d3f008f5843ce36676f16afc5a293bf6143..6525fa078ed991ed26bed4e9491b79b4dd4ebe95 100644 (file)
@@ -49,7 +49,7 @@
     </build>
 
     <dependencies>
-    <dependency>
+        <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-broker-impl</artifactId>
             <version>1.0-SNAPSHOT</version>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+            <version>1.7.2</version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java
new file mode 100644 (file)
index 0000000..96d0361
--- /dev/null
@@ -0,0 +1,176 @@
+package org.opendaylight.controller.sal.binding.test.bugfix;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.supported.actions.ActionType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.supported.actions.ActionTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.SupportType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import static org.junit.Assert.*;
+
+public class PutAugmentationTest extends AbstractDataServiceTest implements DataChangeListener {
+
+    private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+    private static final String NODE_ID = "openflow:1";
+
+    private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
+
+    private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+            NODE_ID);
+
+    private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
+            .toInstance();
+
+
+    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier//
+            .builder(NODES_INSTANCE_ID_BA) //
+            .child(Node.class, NODE_KEY).toInstance();
+    
+    
+    private static final InstanceIdentifier<SupportedActions> SUPPORTED_ACTIONS_INSTANCE_ID_BA = InstanceIdentifier//
+            .builder(NODES_INSTANCE_ID_BA) //
+            .child(Node.class, NODE_KEY) //
+            .augmentation(FlowCapableNode.class) //
+            .child(SupportedActions.class)
+            .toInstance();
+    
+
+    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
+    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+            .node(Nodes.QNAME) //
+            .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+            .toInstance();
+    private static final QName SUPPORTED_ACTIONS_QNAME = QName.create(FlowCapableNode.QNAME, SupportedActions.QNAME.getLocalName());
+
+    
+    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier SUPPORTED_ACTIONS_INSTANCE_ID_BI = //
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+                    .node(Nodes.QNAME) //
+                    .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+                    .node(SUPPORTED_ACTIONS_QNAME) //
+                    .toInstance();
+    
+    private DataChangeEvent<InstanceIdentifier<?>, DataObject> receivedChangeEvent;
+
+    
+    
+    /**
+     * Test for Bug 148
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void putNodeAndAugmentation() throws Exception {
+
+        baDataService.registerDataChangeListener(NODES_INSTANCE_ID_BA, this);
+        
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setId(new NodeId(NODE_ID));
+        nodeBuilder.setKey(NODE_KEY);
+        DataModificationTransaction baseTransaction = baDataService.beginTransaction();
+        baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build());
+        RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        assertNotNull(receivedChangeEvent);
+        Node node = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
+        assertNotNull(node);
+        assertEquals(NODE_KEY, node.getKey());
+        
+        FlowCapableNodeBuilder fnub = new FlowCapableNodeBuilder();
+        fnub.setHardware("Hardware Foo");
+        fnub.setManufacturer("Manufacturer Foo");
+        fnub.setSerialNumber("Serial Foo");
+        fnub.setDescription("Description Foo");
+        fnub.setSoftware("JUnit emulated");
+        FlowCapableNode fnu = fnub.build();
+        InstanceIdentifier<FlowCapableNode> augmentIdentifier = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance();
+        DataModificationTransaction augmentedTransaction = baDataService.beginTransaction();
+        augmentedTransaction.putOperationalData(augmentIdentifier, fnu);
+        
+        result = augmentedTransaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        
+        Node augmentedNode = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
+        assertNotNull(node);
+        assertEquals(NODE_KEY, augmentedNode.getKey());
+        System.out.println("Before assertion");
+        assertNotNull(augmentedNode.getAugmentation(FlowCapableNode.class));
+        FlowCapableNode readedAugmentation = augmentedNode.getAugmentation(FlowCapableNode.class);
+        assertEquals(fnu.getDescription(), readedAugmentation.getDescription());
+        assertBindingIndependentVersion(NODE_INSTANCE_ID_BI);
+        testNodeRemove();
+    }
+
+    
+    private void testNodeRemove() throws Exception {
+        DataModificationTransaction transaction = baDataService.beginTransaction();
+        transaction.removeOperationalData(NODE_INSTANCE_ID_BA);
+        RpcResult<TransactionStatus> result = transaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        Node node = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
+        assertNull(node);
+    }
+
+    private void verifyNodes(Nodes nodes,Node original) {
+        assertNotNull(nodes);
+        assertNotNull(nodes.getNode());
+        assertEquals(1, nodes.getNode().size());
+        Node readedNode = nodes.getNode().get(0);
+        assertEquals(original.getId(), readedNode.getId());
+        assertEquals(original.getKey(), readedNode.getKey());
+        
+        FlowCapableNode fnu = original.getAugmentation(FlowCapableNode.class);
+        FlowCapableNode readedAugment = readedNode.getAugmentation(FlowCapableNode.class);
+        assertNotNull(fnu);
+        assertEquals(fnu.getDescription(), readedAugment.getDescription());
+        assertEquals(fnu.getSerialNumber(), readedAugment.getSerialNumber());
+        
+    }
+
+    private void assertBindingIndependentVersion(
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
+        CompositeNode node = biDataService.readOperationalData(nodeId);
+        assertNotNull(node);
+    }
+
+    private Nodes checkForNodes() {
+        return (Nodes) baDataService.readOperationalData(NODES_INSTANCE_ID_BA);
+    }
+    
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        receivedChangeEvent = change;
+    }
+
+}
index 7fe5f0c5bea91336c103ce3f6224ed6986d9c545..7111501b5392e174d25b16d456da6493cdfe3d77 100644 (file)
@@ -116,6 +116,7 @@ public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
     
     @Test
     public void simpleModifyOperation() throws Exception {
+        assertNull(biDataService.readConfigurationData(FLOW_INSTANCE_ID_BI));
         
         registerCommitHandler();
         
@@ -123,7 +124,7 @@ public class ChangeOriginatedInDomBrokerTest extends AbstractDataServiceTest {
         DataModificationTransaction biTransaction = biDataService.beginTransaction();
         biTransaction.putConfigurationData(FLOW_INSTANCE_ID_BI, domflow);
         RpcResult<TransactionStatus> biResult = biTransaction.commit().get();
-        
+        assertEquals(TransactionStatus.COMMITED, biResult.getResult());
         assertNotNull(modificationCapture);
         Flow flow = (Flow) modificationCapture.getCreatedConfigurationData().get(FLOW_INSTANCE_ID_BA);
         assertNotNull(flow);
index 1b0fda41ca723d67f640de2418ebd6e33e153751..df6b58c8971331b74c89418a6e1ee039e1fcdf10 100644 (file)
@@ -9,9 +9,12 @@ 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.InstanceIdentifier
+import org.slf4j.LoggerFactory
 
 class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
 
+
+    val static LOG = LoggerFactory.getLogger(BrokerFacade)
     val static BrokerFacade INSTANCE = new BrokerFacade
 
     @Property
@@ -38,11 +41,13 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
 
     override readConfigurationData(InstanceIdentifier path) {
         checkPreconditions
+        LOG.info("Read Configuration via Restconf: {}",path)
         return dataService.readConfigurationData(path);
     }
 
     override readOperationalData(InstanceIdentifier path) {
         checkPreconditions
+        LOG.info("Read Operational via Restconf: {}",path)
         return dataService.readOperationalData(path);
     }
 
index 602e8b92425ea9d1ab26bd784893f7ff3a3a9ba1..fed56fe297a8ed9cc929437329701799ce06ccfb 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
 
 import static com.google.common.base.Preconditions.*
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 
 class ControllerContext implements SchemaServiceListener {
 
@@ -291,7 +292,16 @@ class ControllerContext implements SchemaServiceListener {
         checkArgument(node instanceof LeafSchemaNode);
         val urlDecoded = URLDecoder.decode(uriValue);
         val typedef = (node as LeafSchemaNode).type;
-        val decoded = TypeDefinitionAwareCodec.from(typedef)?.deserialize(urlDecoded)
+        var decoded = TypeDefinitionAwareCodec.from(typedef)?.deserialize(urlDecoded)
+        if(decoded == null) {
+            var baseType = typedef
+            while (baseType.baseType != null) {
+                baseType = baseType.baseType;
+            }
+            if(baseType instanceof IdentityrefTypeDefinition) {
+                decoded = toQName(urlDecoded)
+            }
+        }
         map.put(node.QName, decoded);
     }
 
index d855f1554125764c16170b84c26457bd0976fa04..888f13c8fee1750bdd402b5e104a5798ea5730b1 100644 (file)
                             org.osgi.framework,
                             org.osgi.util.tracker,
                             org.slf4j,
-                            org.w3c.dom
+                            org.w3c.dom,
+                            com.google.common.io,
+                            org.opendaylight.yangtools.yang.model.api.type
                         </Import-Package>
                         <Export-Package>
                         </Export-Package>
index 2b6f862bd7dc17ed8cb3960a81fe951721b7888e..697b811d51c90c9b7cab4f05f266292d25d2a260 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribu
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeType;
@@ -30,7 +31,10 @@ public abstract class AttributeIfcSwitchStatement<T> {
 
         if (attributeIfc instanceof JavaAttribute) {
             try {
-                return caseJavaAttribute(attributeIfc.getOpenType());
+                if(((JavaAttribute)attributeIfc).getTypeDefinition() instanceof BinaryTypeDefinition) {
+                    return caseJavaBinaryAttribute(attributeIfc.getOpenType());
+                } else
+                    return caseJavaAttribute(attributeIfc.getOpenType());
             } catch (UnknownOpenTypeException e) {
                 throw getIllegalArgumentException(attributeIfc);
             }
@@ -48,6 +52,9 @@ public abstract class AttributeIfcSwitchStatement<T> {
         throw getIllegalArgumentException(attributeIfc);
     }
 
+    protected T caseJavaBinaryAttribute(OpenType<?> openType) {
+        return caseJavaAttribute(openType);
+    }
 
     private IllegalArgumentException getIllegalArgumentException(AttributeIfc attributeIfc) {
         return new IllegalArgumentException("Unknown attribute type " + attributeIfc.getClass() + ", " + attributeIfc
index 867d94e0b70f628a1454cde825f44d6c27233528..793911262810f826f332f84c75bb642bb1d7fe6e 100644 (file)
@@ -27,11 +27,14 @@ public abstract class AbstractAttributeReadingStrategy implements AttributeReadi
     @Override
     public AttributeConfigElement readElement(List<XmlElement> configNodes) {
         if (configNodes.size() == 0)
-            return AttributeConfigElement.createNullValue(nullableDefault);
+            return AttributeConfigElement.createNullValue(postprocessNullableDefault(nullableDefault));
 
         return readElementHook(configNodes);
     }
 
     abstract AttributeConfigElement readElementHook(List<XmlElement> configNodes);
 
+    protected Object postprocessNullableDefault(String nullableDefault) {
+        return nullableDefault;
+    }
 }
index 598935a0bc4f15ddcc61039723e313d55c0d9860..a1f46dde54ff078596b709e12e0eeeb8914e7056 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
 
 import javax.management.openmbean.OpenType;
@@ -47,24 +46,14 @@ public class AttributeConfigElement {
 
     }
 
-    public static AttributeConfigElement create(AttributeIfc attributeIfc, Object value) {
-        String nullableDefault = attributeIfc.getNullableDefault();
-        return create(nullableDefault, value);
-    }
-
-    public static AttributeConfigElement create(String nullableDefault, Object value) {
+    public static AttributeConfigElement create(Object nullableDefault, Object value) {
         return new AttributeConfigElement(nullableDefault, value);
     }
 
-    public static AttributeConfigElement createNullValue(AttributeIfc attributeIfc) {
-        return new AttributeConfigElement(attributeIfc.getNullableDefault(), null);
-    }
-
-    public static AttributeConfigElement createNullValue(String nullableDefault) {
+    public static AttributeConfigElement createNullValue(Object nullableDefault) {
         return new AttributeConfigElement(nullableDefault, null);
     }
 
-
     public Object getValue() {
         return value;
     }
index e2ea404e2158f40c0d56ada00994e8fcd371da82..a2691f241cfa9a6c273c95c653c2fa9720d03cb9 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attrib
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
 import javax.management.openmbean.SimpleType;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -41,6 +42,11 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement<AttributeReadin
         return switchAttribute(attributeIfc);
     }
 
+    @Override
+    protected AttributeReadingStrategy caseJavaBinaryAttribute(OpenType<?> openType) {
+        return new SimpleBinaryAttributeReadingStrategy(lastAttribute.getNullableDefault());
+    }
+
     @Override
     public AttributeReadingStrategy caseJavaSimpleAttribute(SimpleType<?> openType) {
         return new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault());
index be86a2ab6f58181894700e95e1f5bee413bc8a21..a8605243af3f77f587563d453ea69d51401f2aa4 100644 (file)
@@ -28,7 +28,13 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra
         String textContent = xmlElement.getTextContent();
 
         Preconditions.checkNotNull(textContent, "This element should contain text %s", xmlElement);
-        return AttributeConfigElement.create(getNullableDefault(), postprocessParsedValue(textContent));
+        return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()),
+                postprocessParsedValue(textContent));
+    }
+
+    @Override
+    protected Object postprocessNullableDefault(String nullableDefault) {
+        return nullableDefault;
     }
 
     protected Object postprocessParsedValue(String textContent) {
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java
new file mode 100644 (file)
index 0000000..2cac902
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.fromxml;
+
+import com.google.common.collect.Lists;
+import com.google.common.io.BaseEncoding;
+
+import java.util.List;
+
+public class SimpleBinaryAttributeReadingStrategy extends SimpleAttributeReadingStrategy {
+
+    public SimpleBinaryAttributeReadingStrategy(String nullableDefault) {
+        super(nullableDefault);
+    }
+
+    protected Object postprocessParsedValue(String textContent) {
+        BaseEncoding en = BaseEncoding.base64();
+        byte[] decode = en.decode(textContent);
+        List<String> parsed = Lists.newArrayListWithCapacity(decode.length);
+        for (byte b : decode) {
+            parsed.add(Byte.toString(b));
+        }
+        return parsed;
+    }
+
+    @Override
+    protected Object postprocessNullableDefault(String nullableDefault) {
+        return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
+    }
+}
index 9249ac9fa82b4a8cd03cfb8ce394c58b207f0dc2..22c9e015a94d4bb2a72e800927f7af1da2ca2363 100644 (file)
@@ -14,7 +14,6 @@ import java.util.HashMap;
 
 public class SimpleCompositeAttributeReadingStrategy extends SimpleAttributeReadingStrategy {
 
-
     private final String key;
 
     public SimpleCompositeAttributeReadingStrategy(String nullableDefault, String key) {
@@ -28,4 +27,8 @@ public class SimpleCompositeAttributeReadingStrategy extends SimpleAttributeRead
         return map;
     }
 
+    @Override
+    protected Object postprocessNullableDefault(String nullableDefault) {
+        return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
+    }
 }
index a85f3064cf742b3ec0782f213a5bf3cd8e173468..c477821051b08d03288d129fc29c1aaddd32eef6 100644 (file)
@@ -70,7 +70,7 @@ final class CompositeAttributeResolvingStrategy extends
                     parsedInnerValue.isPresent() ? parsedInnerValue.get() : null);
         }
 
-        CompositeDataSupport parsedValue = null;
+        CompositeDataSupport parsedValue;
         try {
             parsedValue = new CompositeDataSupport(getOpenType(), items);
         } catch (OpenDataException e) {
index ad587ea9879b41ca06f59020f41b0be0ba5fb536..a174e9a25160e8aa3d52ab66891c9d1314e58185 100644 (file)
@@ -19,6 +19,7 @@ import org.w3c.dom.Document;
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
 import javax.management.openmbean.SimpleType;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -51,6 +52,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement<AttributeWritin
         return switchAttribute(expectedAttr);
     }
 
+    @Override
+    protected AttributeWritingStrategy caseJavaBinaryAttribute(OpenType<?> openType) {
+        return new SimpleBinaryAttributeWritingStrategy(document, key);
+    }
+
     @Override
     protected AttributeWritingStrategy caseJavaSimpleAttribute(SimpleType<?> openType) {
         return new SimpleAttributeWritingStrategy(document, key);
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java
new file mode 100644 (file)
index 0000000..c159e46
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.toxml;
+
+import com.google.common.base.Preconditions;
+import com.google.common.io.BaseEncoding;
+import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
+import org.w3c.dom.Document;
+
+import java.util.List;
+
+public class SimpleBinaryAttributeWritingStrategy extends SimpleAttributeWritingStrategy {
+
+    /**
+     * @param document
+     * @param key
+     */
+    public SimpleBinaryAttributeWritingStrategy(Document document, String key) {
+        super(document, key);
+    }
+
+    protected Object preprocess(Object value) {
+        Util.checkType(value, List.class);
+        BaseEncoding en = BaseEncoding.base64();
+
+        List<?> list = (List<?>) value;
+        byte[] decoded = new byte[list.size()];
+        int i = 0;
+        for (Object bAsStr : list) {
+            Preconditions.checkArgument(bAsStr instanceof String, "Unexpected inner value for %s, expected string", value);
+            byte b = Byte.parseByte((String) bAsStr);
+            decoded[i++] = b;
+        }
+
+        return en.encode(decoded);
+    }
+
+}
index 35fa0428ec1cd60ed4a9e39415ce219c2a06ae9c..f8916ecac2244943b55abe0dd036e0e52204f3f3 100644 (file)
@@ -55,7 +55,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
 import javax.management.InstanceAlreadyExistsException;
@@ -125,6 +124,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         edit("netconfMessages/editConfig.xml");
         checkBinaryLeafEdited(getConfigCandidate());
 
+
         // default-operation:none, should not affect binary leaf
         edit("netconfMessages/editConfig_none.xml");
         checkBinaryLeafEdited(getConfigCandidate());
@@ -132,7 +132,6 @@ public class NetconfMappingTest extends AbstractConfigTest {
         // check after edit
         commit();
         Element response = getConfigRunning();
-        System.err.println(XmlUtil.toString(response));
 
         checkBinaryLeafEdited(response);
         checkTypeConfigAttribute(response);
@@ -165,6 +164,15 @@ public class NetconfMappingTest extends AbstractConfigTest {
         verifyNoMoreInteractions(netconfOperationRouter);
     }
 
+    private void checkBigDecimal(Element response) {
+        String responseTrimmed = XmlUtil.toString(response).replaceAll("\\s", "");
+
+        assertContainsString(responseTrimmed, "<sleep-factorxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">2.58</sleep-factor>");
+        // Default
+        assertContainsString(responseTrimmed, "<sleep-factorxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">2.00</sleep-factor>");
+
+    }
+
     private void closeSession() throws NetconfDocumentedException, ParserConfigurationException, SAXException,
             IOException {
         DefaultCloseSession closeOp = new DefaultCloseSession(NETCONF_SESSION_ID);
@@ -232,14 +240,9 @@ public class NetconfMappingTest extends AbstractConfigTest {
             edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml");
         } catch (NetconfDocumentedException e) {
             String message = e.getMessage();
-            assertThat(message,
-                    JUnitMatchers
-                            .containsString("Element simple-long-2 present multiple times with different namespaces"));
-            assertThat(message,
-                    JUnitMatchers.containsString("urn:opendaylight:params:xml:ns:yang:controller:test:impl"));
-            assertThat(message,
-                    JUnitMatchers
-                            .containsString(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG));
+            assertContainsString(message, "Element simple-long-2 present multiple times with different namespaces");
+            assertContainsString(message, "urn:opendaylight:params:xml:ns:yang:controller:test:impl");
+            assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
             throw e;
         }
     }
@@ -250,9 +253,9 @@ public class NetconfMappingTest extends AbstractConfigTest {
             edit("netconfMessages/namespaces/editConfig_differentNamespaceTO.xml");
         } catch (NetconfDocumentedException e) {
             String message = e.getMessage();
-            assertThat(message, JUnitMatchers.containsString("Unrecognised elements"));
-            assertThat(message, JUnitMatchers.containsString("simple-int2"));
-            assertThat(message, JUnitMatchers.containsString("dto_d"));
+            assertContainsString(message, "Unrecognised elements");
+            assertContainsString(message, "simple-int2");
+            assertContainsString(message, "dto_d");
             throw e;
         }
     }
@@ -263,13 +266,9 @@ public class NetconfMappingTest extends AbstractConfigTest {
             edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml");
         } catch (NetconfDocumentedException e) {
             String message = e.getMessage();
-            assertThat(message,
-                    JUnitMatchers.containsString("Element binaryLeaf present multiple times with different namespaces"));
-            assertThat(message,
-                    JUnitMatchers.containsString("urn:opendaylight:params:xml:ns:yang:controller:test:impl"));
-            assertThat(message,
-                    JUnitMatchers
-                            .containsString(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG));
+            assertContainsString(message, "Element binaryLeaf present multiple times with different namespaces");
+            assertContainsString(message, "urn:opendaylight:params:xml:ns:yang:controller:test:impl");
+            assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
             throw e;
         }
     }
@@ -306,8 +305,8 @@ public class NetconfMappingTest extends AbstractConfigTest {
             try {
                 edit(file);
             } catch (NetconfDocumentedException e) {
-                assertThat(e.getMessage(), JUnitMatchers.containsString("Unrecognised elements"));
-                assertThat(e.getMessage(), JUnitMatchers.containsString("unknownAttribute"));
+                assertContainsString(e.getMessage(), "Unrecognised elements");
+                assertContainsString(e.getMessage(), "unknownAttribute");
                 continue;
             }
             fail("Unrecognised test should throw exception " + file);
@@ -353,22 +352,37 @@ public class NetconfMappingTest extends AbstractConfigTest {
     }
 
     private void checkBinaryLeafEdited(final Element response) {
-        final NodeList children = response.getElementsByTagName("binaryLeaf");
-        assertEquals(3, children.getLength());
-        final StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < 3; i++) {
-            final Element e = (Element) children.item(i);
-            buf.append(XmlElement.fromDomElement(e).getTextContent());
-        }
-        assertEquals("810", buf.toString());
+        String responseTrimmed = XmlUtil.toString(response).replaceAll("\\s", "");
+        String substring = "<binaryLeafxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">YmluYXJ5</binaryLeaf>";
+        assertContainsString(responseTrimmed, substring);
+        substring = "<binaryLeafxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">ZGVmYXVsdEJpbg==</binaryLeaf>";
+        assertContainsString(responseTrimmed, substring);
     }
 
     private void checkTypedefs(final Element response) {
-        NodeList children = response.getElementsByTagName("extended");
-        assertEquals(1, children.getLength());
+        String responseTrimmed = XmlUtil.toString(response).replaceAll("\\s", "");
+
+        String substring = "<extendedxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">10</extended>";
+        assertContainsString(responseTrimmed, substring);
+        // Default
+        assertContainsString(responseTrimmed,
+                "<extendedxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">1</extended>");
 
-        children = response.getElementsByTagName("extended-twice");
-        assertEquals(1, children.getLength());
+        assertContainsString(responseTrimmed,
+                "<extended-twicexmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">20</extended-twice>");
+        // Default
+        assertContainsString(responseTrimmed,
+                "<extended-twicexmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">2</extended-twice>");
+
+        assertContainsString(responseTrimmed,
+                "<extended-enumxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">TWO</extended-enum>");
+        // Default
+        assertContainsString(responseTrimmed,
+                "<extended-enumxmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">ONE</extended-enum>");
+    }
+
+    private void assertContainsString(String string, String substring) {
+        assertThat(string, JUnitMatchers.containsString(substring));
     }
 
     private void checkEnum(final Element response) {
@@ -396,12 +410,6 @@ public class NetconfMappingTest extends AbstractConfigTest {
         assertEquals(2, testingDepsSize);
     }
 
-    private void checkBigDecimal(Element response) {
-        int size = response.getElementsByTagName("sleep-factor").getLength();
-        assertEquals(1, size);
-    }
-
-
     private void checkTypeConfigAttribute(Element response) {
 
         XmlElement modulesElement = XmlElement.fromDomElement(response).getOnlyChildElement("data")
@@ -458,17 +466,17 @@ public class NetconfMappingTest extends AbstractConfigTest {
         RuntimeRpc netconf = new RuntimeRpc(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID);
 
         response = executeOp(netconf, "netconfMessages/rpc.xml");
-        assertThat(XmlUtil.toString(response), JUnitMatchers.containsString("testarg1".toUpperCase()));
+        assertContainsString(XmlUtil.toString(response), "testarg1".toUpperCase());
 
         response = executeOp(netconf, "netconfMessages/rpcInner.xml");
-        assertThat(XmlUtil.toString(response), JUnitMatchers.containsString("ok"));
+        assertContainsString(XmlUtil.toString(response), "ok");
 
         response = executeOp(netconf, "netconfMessages/rpcInnerInner.xml");
-        assertThat(XmlUtil.toString(response), JUnitMatchers.containsString("true"));
+        assertContainsString(XmlUtil.toString(response), "true");
 
         response = executeOp(netconf, "netconfMessages/rpcInnerInner_complex_output.xml");
-        assertThat(XmlUtil.toString(response), JUnitMatchers.containsString("1"));
-        assertThat(XmlUtil.toString(response), JUnitMatchers.containsString("2"));
+        assertContainsString(XmlUtil.toString(response), "1");
+        assertContainsString(XmlUtil.toString(response), "2");
     }
 
     private Element get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
index 1e14bfdba285ec0e8f68f3b0b363abe2e370c66b..eb7235f04490eaaef675e7f993da23455223222f 100644 (file)
@@ -58,7 +58,7 @@ public abstract class NetconfSession extends AbstractProtocolSession<NetconfMess
 
     @Override
     protected void handleMessage(NetconfMessage netconfMessage) {
-        logger.debug("handlign incomming message");
+        logger.debug("handling incoming message");
         sessionListener.onMessage(this, netconfMessage);
     }
 
index dc522d2e64a5601f019e0ce9be476bb2d7e7df71..94b73f4b100754e17918b9d5d75bed8542130f46 100644 (file)
                     <name>test1</name>
 
                     <sleep-factor>
-                        2.00
+                        2.58
                     </sleep-factor>
 
                     <extended>
-                            1
+                            10
                     </extended>
 
                     <extended-twice>
-                            1
+                            20
                     </extended-twice>
 
                     <extended-enum>
@@ -48,9 +48,8 @@
                     </extended-enum>
 
                     <simple-long-2>44</simple-long-2>
-                    <binaryLeaf>8</binaryLeaf>
-                    <binaryLeaf>1</binaryLeaf>
-                    <binaryLeaf>0</binaryLeaf>
+                    <binaryLeaf>YmluYXJ5</binaryLeaf>
+
                     <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">configAttributeType</type>
                     <dto_d xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         <simple-int1>444</simple-int1>
index 388aa4f2ab6b528d8e701be6e9689d5513395ad2..b48730d3f71e74a86fde37131c38602d3f1169c1 100644 (file)
@@ -27,9 +27,7 @@
                     </type>
                     <name>test1</name>
                     <simple-long-2>44</simple-long-2>
-                    <binaryLeaf>8</binaryLeaf>
-                    <binaryLeaf>7</binaryLeaf>
-                    <binaryLeaf>9</binaryLeaf>
+                    <binaryLeaf>8ad1</binaryLeaf>
                     <dto_d>
                         <simple-int1>444</simple-int1>
                         <simple-int2>4444</simple-int2>
index 4d94d9e94962a529fc666eafc5c3ffac077cef5e..df2a5e845257c6b8308ad03eac43a91feb687772 100644 (file)
@@ -32,9 +32,7 @@
                     <name>test1</name>
 
                     <simple-long-2>44</simple-long-2>
-                    <binaryLeaf>8</binaryLeaf>
-                    <binaryLeaf>1</binaryLeaf>
-                    <binaryLeaf>0</binaryLeaf>
+                    <binaryLeaf>8545649856</binaryLeaf>
                     <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">configAttributeType</type>
                     <dto_d>
                         <simple-int1>444</simple-int1>
index 0e70e13a34417b885193310f12b803d6c007e2d2..02aca8d787863a2683db402b0c3a9a82ed6ff699 100644 (file)
@@ -32,9 +32,7 @@
                     <name>test1</name>
 
                     <simple-long-2>44</simple-long-2>
-                    <binaryLeaf>8</binaryLeaf>
-                    <binaryLeaf>1</binaryLeaf>
-                    <binaryLeaf>0</binaryLeaf>
+                    <binaryLeaf>8545649856</binaryLeaf>
                     <dto_d xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         <simple-int1>444</simple-int1>
                         <simple-int2>4444</simple-int2>
index d03bb084b824370f00bd84986dcd5ae6b6746dff..825be6d19fff18b2d8ccb0c078e6266e4e89c3f1 100644 (file)
@@ -32,9 +32,7 @@
                     <name>test1</name>
 
                     <simple-long-2>44</simple-long-2>
-                    <binaryLeaf>8</binaryLeaf>
-                    <binaryLeaf>1</binaryLeaf>
-                    <binaryLeaf>0</binaryLeaf>
+                    <binaryLeaf>8545649856</binaryLeaf>
                     <dto_d>
                         <unknownAttribute>error</unknownAttribute>
                         <simple-int1>444</simple-int1>
index 3722973912192f79c7b70700e4172cdcb888d2cb..9ef2bed7d70dfb7654df642480cacc3df354baae 100644 (file)
@@ -32,9 +32,7 @@
                     <name>test1</name>
 
                     <simple-long-2>44</simple-long-2>
-                    <binaryLeaf>8</binaryLeaf>
-                    <binaryLeaf>1</binaryLeaf>
-                    <binaryLeaf>0</binaryLeaf>
+                    <binaryLeaf>8545649856</binaryLeaf>
                     <dto_d>
                         <simple-int1>444</simple-int1>
                         <simple-int2>4444</simple-int2>