BUG-4322: return default valued-object 51/28251/11
authorIgor Foltin <ifoltin@cisco.com>
Tue, 3 Nov 2015 07:17:56 +0000 (08:17 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 17 Nov 2015 18:00:45 +0000 (18:00 +0000)
This patch modifies DataObjectCodecContext to return a default value
generated from the 'default' statement when a request is made for a
field which is not present in NormalizedNodes.

That has the effect of leaves with default value being seen as set to
the default value.

Added unit tests.

Change-Id: I99c97d796a9b32557955c4b0bd95d0051ab56f5c
Signed-off-by: Robert Varga <robert.varga@pantheon.sk>
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/LeafDefaultValueTest.java [new file with mode: 0644]
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/DataObjectCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/LeafNodeCodecContext.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/NormalizedNodeSerializeDeserializeTest.java
binding/mdsal-binding-test-model/src/main/yang/opendaylight-default-value-test.yang [new file with mode: 0644]

diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/LeafDefaultValueTest.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/LeafDefaultValueTest.java
new file mode 100644 (file)
index 0000000..72c3469
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2015 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.mdsal.binding.dom.adapter.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Optional;
+import java.util.Arrays;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.api.WriteTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BigIntContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BigIntContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BigUintContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BigUintContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BinaryContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BinaryContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BitsContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BitsContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BooleanContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.BooleanContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.DecimalContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.DecimalContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.EnumContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.EnumContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.IdentityrefContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.IdentityrefContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.NormalIntContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.NormalIntContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.NormalUintContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.NormalUintContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.SmallIntContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.SmallIntContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.SmallUintContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.SmallUintContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.StringContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.StringContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.TinyIntContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.TinyIntContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.TinyUintContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns._default.value.test.rev700101.TinyUintContainerBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class LeafDefaultValueTest extends AbstractDataBrokerTest {
+
+    private static final InstanceIdentifier<TinyIntContainer> TINY_INT_NODE_PATH = InstanceIdentifier.create
+            (TinyIntContainer.class);
+    private static final InstanceIdentifier<SmallIntContainer> SMALL_INT_NODE_PATH = InstanceIdentifier.create
+            (SmallIntContainer.class);
+    private static final InstanceIdentifier<NormalIntContainer> NORMAL_INT_NODE_PATH = InstanceIdentifier.create
+            (NormalIntContainer.class);
+    private static final InstanceIdentifier<BigIntContainer> BIG_INT_NODE_PATH = InstanceIdentifier.create
+            (BigIntContainer.class);
+
+    private static final InstanceIdentifier<TinyUintContainer> TINY_UINT_NODE_PATH = InstanceIdentifier.create
+            (TinyUintContainer.class);
+    private static final InstanceIdentifier<SmallUintContainer> SMALL_UINT_NODE_PATH = InstanceIdentifier.create
+            (SmallUintContainer.class);
+    private static final InstanceIdentifier<NormalUintContainer> NORMAL_UINT_NODE_PATH = InstanceIdentifier.create
+            (NormalUintContainer.class);
+    private static final InstanceIdentifier<BigUintContainer> BIG_UINT_NODE_PATH = InstanceIdentifier.create
+            (BigUintContainer.class);
+
+    private static final InstanceIdentifier<DecimalContainer> DECIMAL_NODE_PATH = InstanceIdentifier.create
+            (DecimalContainer.class);
+
+    private static final InstanceIdentifier<StringContainer> STRING_NODE_PATH = InstanceIdentifier.create
+            (StringContainer.class);
+
+    private static final InstanceIdentifier<BooleanContainer> BOOLEAN_NODE_PATH = InstanceIdentifier.create
+            (BooleanContainer.class);
+
+    private static final InstanceIdentifier<EnumContainer> ENUM_NODE_PATH = InstanceIdentifier.create(EnumContainer
+            .class);
+
+    private static final InstanceIdentifier<BitsContainer> BITS_NODE_PATH = InstanceIdentifier.create(BitsContainer
+            .class);
+
+    private static final InstanceIdentifier<BinaryContainer> BINARY_NODE_PATH = InstanceIdentifier.create
+            (BinaryContainer.class);
+
+    private static final InstanceIdentifier<IdentityrefContainer> IDENTITYREF_NODE_PATH = InstanceIdentifier.create
+            (IdentityrefContainer.class);
+
+    @Test
+    public void testTinyIntDefaultValue() throws ExecutionException, InterruptedException, TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, TINY_INT_NODE_PATH, new TinyIntContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<TinyIntContainer> tinyIntContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                TINY_INT_NODE_PATH).get();
+
+        assertTrue(tinyIntContainerNode.isPresent());
+
+        TinyIntContainer tIntCont = tinyIntContainerNode.get();
+        assertEquals(-18, tIntCont.getTinyIntLeaf().getValue().byteValue());
+        assertEquals(-18, tIntCont.getTinyIntLeaf2().getValue().byteValue());
+        assertEquals(-15, tIntCont.getTinyIntLeaf3().getValue().byteValue());
+        assertEquals(-18, tIntCont.getTinyIntLeaf4().getValue().byteValue());
+        assertEquals(-120, tIntCont.getTinyIntLeaf5().byteValue());
+        assertEquals(null, tIntCont.getTinyIntLeaf6());
+    }
+
+    @Test
+    public void testSmallIntDefaultValue() throws ExecutionException, InterruptedException, TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, SMALL_INT_NODE_PATH, new SmallIntContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<SmallIntContainer> smallIntContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                SMALL_INT_NODE_PATH).get();
+
+        assertTrue(smallIntContainerNode.isPresent());
+
+        SmallIntContainer sIntCont = smallIntContainerNode.get();
+        assertEquals(-20000, sIntCont.getSmallIntLeaf().getValue().shortValue());
+        assertEquals(-20000, sIntCont.getSmallIntLeaf2().getValue().shortValue());
+        assertEquals(-15000, sIntCont.getSmallIntLeaf3().getValue().shortValue());
+        assertEquals(-20000, sIntCont.getSmallIntLeaf4().getValue().shortValue());
+        assertEquals(-5000, sIntCont.getSmallIntLeaf5().shortValue());
+        assertEquals(null, sIntCont.getSmallIntLeaf6());
+    }
+
+    @Test
+    public void testNormalIntDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, NORMAL_INT_NODE_PATH, new NormalIntContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<NormalIntContainer> normalIntContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                NORMAL_INT_NODE_PATH).get();
+
+        assertTrue(normalIntContainerNode.isPresent());
+
+        NormalIntContainer nIntCont = normalIntContainerNode.get();
+        assertEquals(-200000, nIntCont.getNormalIntLeaf().getValue().intValue());
+        assertEquals(-200000, nIntCont.getNormalIntLeaf2().getValue().intValue());
+        assertEquals(-130000, nIntCont.getNormalIntLeaf3().getValue().intValue());
+        assertEquals(-200000, nIntCont.getNormalIntLeaf4().getValue().intValue());
+        assertEquals(-95000, nIntCont.getNormalIntLeaf5().intValue());
+        assertEquals(null, nIntCont.getNormalIntLeaf6());
+    }
+
+    @Test
+    public void testBigIntDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, BIG_INT_NODE_PATH, new BigIntContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<BigIntContainer> bigIntContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                BIG_INT_NODE_PATH).get();
+
+        assertTrue(bigIntContainerNode.isPresent());
+
+        BigIntContainer bIntCont = bigIntContainerNode.get();
+        assertEquals(-3300000000L, bIntCont.getBigIntLeaf().getValue().longValue());
+        assertEquals(-3300000000L, bIntCont.getBigIntLeaf2().getValue().longValue());
+        assertEquals(-2800000000L, bIntCont.getBigIntLeaf3().getValue().longValue());
+        assertEquals(-3300000000L, bIntCont.getBigIntLeaf4().getValue().longValue());
+        assertEquals(-2500000000L, bIntCont.getBigIntLeaf5().longValue());
+        assertEquals(null, bIntCont.getBigIntLeaf6());
+    }
+
+    @Test
+    public void testTinyUintDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, TINY_UINT_NODE_PATH, new TinyUintContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<TinyUintContainer> tinyUintContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                TINY_UINT_NODE_PATH).get();
+
+        assertTrue(tinyUintContainerNode.isPresent());
+
+        TinyUintContainer tUintCont = tinyUintContainerNode.get();
+        assertEquals(150, tUintCont.getTinyUintLeaf().getValue().shortValue());
+        assertEquals(150, tUintCont.getTinyUintLeaf2().getValue().shortValue());
+        assertEquals(170, tUintCont.getTinyUintLeaf3().getValue().shortValue());
+        assertEquals(150, tUintCont.getTinyUintLeaf4().getValue().shortValue());
+        assertEquals(155, tUintCont.getTinyUintLeaf5().shortValue());
+        assertEquals(null, tUintCont.getTinyUintLeaf6());
+    }
+
+    @Test
+    public void testSmallUintDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, SMALL_UINT_NODE_PATH, new SmallUintContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<SmallUintContainer> smallUintContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                SMALL_UINT_NODE_PATH).get();
+
+        assertTrue(smallUintContainerNode.isPresent());
+
+        SmallUintContainer sUintCont = smallUintContainerNode.get();
+        assertEquals(35000, sUintCont.getSmallUintLeaf().getValue().intValue());
+        assertEquals(35000, sUintCont.getSmallUintLeaf2().getValue().intValue());
+        assertEquals(45000, sUintCont.getSmallUintLeaf3().getValue().intValue());
+        assertEquals(35000, sUintCont.getSmallUintLeaf4().getValue().intValue());
+        assertEquals(62000, sUintCont.getSmallUintLeaf5().intValue());
+        assertEquals(null, sUintCont.getSmallUintLeaf6());
+    }
+
+    @Test
+    public void testNormalUintDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, NORMAL_UINT_NODE_PATH, new NormalUintContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<NormalUintContainer> normalUintContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                NORMAL_UINT_NODE_PATH).get();
+
+        assertTrue(normalUintContainerNode.isPresent());
+
+        NormalUintContainer nUintCont = normalUintContainerNode.get();
+        assertEquals(100000, nUintCont.getNormalUintLeaf().getValue().longValue());
+        assertEquals(100000, nUintCont.getNormalUintLeaf2().getValue().longValue());
+        assertEquals(250000, nUintCont.getNormalUintLeaf3().getValue().longValue());
+        assertEquals(100000, nUintCont.getNormalUintLeaf4().getValue().longValue());
+        assertEquals(150000, nUintCont.getNormalUintLeaf5().longValue());
+        assertEquals(null, nUintCont.getNormalUintLeaf6());
+    }
+
+    @Test
+    public void testBigUintDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, BIG_UINT_NODE_PATH, new BigUintContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<BigUintContainer> bigUintContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                BIG_UINT_NODE_PATH).get();
+
+        assertTrue(bigUintContainerNode.isPresent());
+
+        BigUintContainer bUintCont = bigUintContainerNode.get();
+        assertEquals(5000000000L, bUintCont.getBigUintLeaf().getValue().longValue());
+        assertEquals(5000000000L, bUintCont.getBigUintLeaf2().getValue().longValue());
+        assertEquals(5800000000L, bUintCont.getBigUintLeaf3().getValue().longValue());
+        assertEquals(5000000000L, bUintCont.getBigUintLeaf4().getValue().longValue());
+        assertEquals(6500000000L, bUintCont.getBigUintLeaf5().longValue());
+        assertEquals(null, bUintCont.getBigUintLeaf6());
+    }
+
+    @Test
+    public void testDecimalDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, DECIMAL_NODE_PATH, new DecimalContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<DecimalContainer> decimalContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                DECIMAL_NODE_PATH).get();
+
+        assertTrue(decimalContainerNode.isPresent());
+
+        DecimalContainer decimalCont = decimalContainerNode.get();
+        assertEquals(66.66, decimalCont.getDecimalLeaf().getValue().doubleValue(), 0.001);
+        assertEquals(66.66, decimalCont.getDecimalLeaf2().getValue().doubleValue(), 0.001);
+        assertEquals(99.9, decimalCont.getDecimalLeaf3().getValue().doubleValue(), 0.01);
+        assertEquals(66.66, decimalCont.getDecimalLeaf4().getValue().doubleValue(), 0.001);
+        assertEquals(120.55, decimalCont.getDecimalLeaf5().doubleValue(), 0.001);
+        assertEquals(null, decimalCont.getDecimalLeaf6());
+    }
+
+    @Test
+    public void testStringDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, STRING_NODE_PATH, new StringContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<StringContainer> stringContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                STRING_NODE_PATH).get();
+
+        assertTrue(stringContainerNode.isPresent());
+
+        StringContainer stringCont = stringContainerNode.get();
+        assertEquals("unspecified string", stringCont.getStringLeaf().getValue());
+        assertEquals("unspecified string", stringCont.getStringLeaf2().getValue());
+        assertEquals("unknown", stringCont.getStringLeaf3().getValue());
+        assertEquals("unspecified string", stringCont.getStringLeaf4().getValue());
+        assertEquals("whatever", stringCont.getStringLeaf5());
+        assertEquals("", stringCont.getStringLeaf6());
+    }
+
+    @Test
+    public void testBooleanDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, BOOLEAN_NODE_PATH, new BooleanContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<BooleanContainer> booleanContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                BOOLEAN_NODE_PATH).get();
+
+        assertTrue(booleanContainerNode.isPresent());
+
+        BooleanContainer boolCont = booleanContainerNode.get();
+        assertTrue(boolCont.isBooleanLeaf());
+        assertFalse(boolCont.isBooleanLeaf2());
+    }
+
+    @Test
+    public void testEnumerationDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, ENUM_NODE_PATH, new EnumContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<EnumContainer> enumContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                ENUM_NODE_PATH).get();
+
+        assertTrue(enumContainerNode.isPresent());
+
+        EnumContainer enumCont = enumContainerNode.get();
+        assertEquals("Second", enumCont.getEnumLeaf().name());
+        assertEquals(2, enumCont.getEnumLeaf().getIntValue());
+    }
+
+    @Test
+    public void testBitsDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, BITS_NODE_PATH, new BitsContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<BitsContainer> bitsContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                BITS_NODE_PATH).get();
+
+        assertTrue(bitsContainerNode.isPresent());
+
+        BitsContainer bitsCont = bitsContainerNode.get();
+        assertFalse(bitsCont.getBitsLeaf().isBitZero());
+        assertTrue(bitsCont.getBitsLeaf().isBitOne());
+        assertFalse(bitsCont.getBitsLeaf().isBitTwo());
+    }
+
+    @Test
+    public void testBinaryDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, BINARY_NODE_PATH, new BinaryContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<BinaryContainer> binaryContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                BINARY_NODE_PATH).get();
+
+        assertTrue(binaryContainerNode.isPresent());
+
+        BinaryContainer binCont = binaryContainerNode.get();
+        byte [] expectedBytes = {104, 101, 108, 108, 111};
+        byte [] actualBytes = binCont.getBinaryLeaf();
+
+        assertTrue(Arrays.equals(expectedBytes, actualBytes));
+    }
+
+    @Test
+    public void testIdentityrefDefaultValue() throws ExecutionException, InterruptedException,
+            TransactionCommitFailedException {
+        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, IDENTITYREF_NODE_PATH, new IdentityrefContainerBuilder().build());
+        writeTx.submit().checkedGet();
+
+        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
+        final Optional<IdentityrefContainer> identityrefContainerNode = readTx.read(LogicalDatastoreType.OPERATIONAL,
+                IDENTITYREF_NODE_PATH).get();
+
+        assertTrue(identityrefContainerNode.isPresent());
+
+        IdentityrefContainer idrefCont = identityrefContainerNode.get();
+        assertEquals("MyIdentity", idrefCont.getIdentityrefLeaf().getSimpleName());
+    }
+}
index 5ceb2756643837a3cd32d4507450746473bf859d..c06fc5ce9b33e3541a32c5c59f27ebeeeb752b63 100644 (file)
@@ -327,8 +327,11 @@ abstract class DataObjectCodecContext<D extends DataObject,T extends DataNodeCon
         final Optional<NormalizedNode<?, ?>> domChild = domData.getChild(childContext.getDomPathArgument());
         if (domChild.isPresent()) {
             return childContext.deserializeObject(domChild.get());
+        } else if (childContext instanceof LeafNodeCodecContext) {
+            return ((LeafNodeCodecContext)childContext).defaultObject();
+        } else {
+            return null;
         }
-        return null;
     }
 
     protected final D createBindingProxy(final NormalizedNodeContainer<?, ?, ?> node) {
index bb3e48201b65da0b8f63808b1161405d6c0b67a9..77748a5b7bb1b3be1ebb39389d0e61c6b7e89fc1 100644 (file)
@@ -14,6 +14,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import javax.annotation.Nullable;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCachingCodec;
 import org.opendaylight.yangtools.concepts.Codec;
@@ -26,7 +27,13 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.IdentityEffectiveStatementImpl;
 
 final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<D> implements NodeContextSupplier {
 
@@ -34,17 +41,60 @@ final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<
     private final Codec<Object, Object> valueCodec;
     private final Method getter;
     private final DataSchemaNode schema;
+    private final Object defaultObject;
 
     public LeafNodeCodecContext(final DataSchemaNode schema, final Codec<Object, Object> codec, final Method getter) {
         this.yangIdentifier = new YangInstanceIdentifier.NodeIdentifier(schema.getQName());
-        this.valueCodec = codec;
+        this.valueCodec = Preconditions.checkNotNull(codec);
         this.getter = getter;
-        this.schema = schema;
+        this.schema = Preconditions.checkNotNull(schema);
+
+        this.defaultObject = createDefaultObject(schema, valueCodec);
+    }
+
+    private static Object createDefaultObject(final DataSchemaNode schema, final Codec<Object, Object> codec) {
+        if (schema instanceof LeafSchemaNode) {
+            Object defaultValue = ((LeafSchemaNode) schema).getDefault();
+            TypeDefinition<?> type = ((LeafSchemaNode) schema).getType();
+            if (defaultValue != null) {
+                return domValueFromString(codec, type, defaultValue);
+            }
+            else {
+                while (type.getBaseType() != null && type.getDefaultValue() == null) {
+                    type = type.getBaseType();
+                }
+
+                defaultValue = type.getDefaultValue();
+                if (defaultValue != null) {
+                    if (defaultValue instanceof Boolean) {
+                        return codec.deserialize(defaultValue);
+                    }
+
+                    if (defaultValue instanceof IdentitySchemaNode) {
+                        defaultValue = ((IdentityEffectiveStatementImpl) defaultValue).argument();
+                        return codec.deserialize(defaultValue);
+                    }
+
+                    if (defaultValue instanceof List) {
+                        return codec.deserialize(defaultValue);
+                    }
+                    return domValueFromString(codec, type, defaultValue);
+                }
+            }
+        }
+        return null;
+    }
+
+    private static Object domValueFromString(final Codec<Object, Object> codec, final TypeDefinition<?> type,
+    Object defaultValue) {
+        TypeDefinitionAwareCodec typeDefAwareCodec = TypeDefinitionAwareCodec.from(type);
+        Object castedDefaultValue = typeDefAwareCodec.deserialize((String) defaultValue);
+        return codec.deserialize(castedDefaultValue);
     }
 
     @Override
     protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
-        return (yangIdentifier);
+        return yangIdentifier;
     }
 
     protected Codec<Object, Object> getValueCodec() {
@@ -112,7 +162,8 @@ final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<
     protected Object deserializeObject(final NormalizedNode<?, ?> normalizedNode) {
         if (normalizedNode instanceof LeafNode<?>) {
             return valueCodec.deserialize(normalizedNode.getValue());
-        } else if(normalizedNode instanceof LeafSetNode<?>) {
+        }
+        if (normalizedNode instanceof LeafSetNode<?>) {
             @SuppressWarnings("unchecked")
             final Collection<LeafSetEntryNode<Object>> domValues = ((LeafSetNode<Object>) normalizedNode).getValue();
             final List<Object> result = new ArrayList<>(domValues.size());
@@ -140,4 +191,12 @@ final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<
         return schema;
     }
 
+    /**
+     * Return the default value object.
+     *
+     * @return The default value object, or null if the default value is not defined.
+     */
+    @Nullable Object defaultObject() {
+        return defaultObject;
+    }
 }
\ No newline at end of file
index f595dc5b8b5f801ef9283b7464262759658c7382..42ecc68502aaf74254521a4d6f4d1730b6001b44 100644 (file)
@@ -279,8 +279,8 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingRunti
 
         final Map.Entry<InstanceIdentifier<?>, DataObject> entry = registry.fromNormalizedNode(BI_TOP_LEVEL_LIST_FOO_PATH, foo);
         final List<NestedList> nestedLists = new ArrayList<>();
-        nestedLists.add(new NestedListBuilder().setKey(new NestedListKey("foo")).build());
-        nestedLists.add(new NestedListBuilder().setKey(new NestedListKey("bar")).build());
+        nestedLists.add(new NestedListBuilder().setKey(new NestedListKey("foo")).setType("").build());
+        nestedLists.add(new NestedListBuilder().setKey(new NestedListKey("bar")).setType("").build());
         final TopLevelList topLevelList = new TopLevelListBuilder().setKey(TOP_LEVEL_LIST_FOO_KEY).setNestedList(nestedLists).build();
         assertEquals(topLevelList, entry.getValue());
     }
diff --git a/binding/mdsal-binding-test-model/src/main/yang/opendaylight-default-value-test.yang b/binding/mdsal-binding-test-model/src/main/yang/opendaylight-default-value-test.yang
new file mode 100644 (file)
index 0000000..47fc56d
--- /dev/null
@@ -0,0 +1,612 @@
+module opendaylight-default-value-test {
+    namespace "urn:opendaylight:params:xml:ns:default:value:test";
+    prefix "def-val-test";
+
+    typedef tiny-signed-integer {
+        type int8 {
+            range "-20..-1";
+        }
+        default "-18";
+    }
+
+    typedef derived-tiny-signed-integer {
+        type tiny-signed-integer;
+    }
+
+    typedef derived-tiny-signed-integer2 {
+        type tiny-signed-integer {
+            range "-16..-11";
+        }
+        default "-15";
+    }
+
+    typedef derived-tiny-signed-integer3 {
+        type derived-tiny-signed-integer;
+    }
+
+    typedef small-signed-integer {
+        type int16 {
+            range "-25000..-9000";
+        }
+        default "-20000";
+    }
+
+    typedef derived-small-signed-integer {
+        type small-signed-integer;
+    }
+
+    typedef derived-small-signed-integer2 {
+        type small-signed-integer {
+            range "-19000..-11000";
+        }
+        default "-15000";
+    }
+
+    typedef derived-small-signed-integer3 {
+        type derived-small-signed-integer;
+    }
+
+    typedef normal-signed-integer {
+        type int32 {
+            range "-250000..-50000";
+        }
+        default "-200000";
+    }
+
+    typedef derived-normal-signed-integer {
+        type normal-signed-integer;
+    }
+
+    typedef derived-normal-signed-integer2 {
+        type normal-signed-integer {
+            range "-140000..-120000";
+        }
+        default "-130000";
+    }
+
+    typedef derived-normal-signed-integer3 {
+        type derived-normal-signed-integer;
+    }
+
+    typedef big-signed-integer {
+        type int64 {
+            range "-3500000000..-2500000000";
+        }
+        default "-3300000000";
+    }
+
+    typedef derived-big-signed-integer {
+        type big-signed-integer;
+    }
+
+    typedef derived-big-signed-integer2 {
+        type big-signed-integer {
+            range "-3100000000..-2600000000";
+        }
+        default "-2800000000";
+    }
+
+    typedef derived-big-signed-integer3 {
+        type derived-big-signed-integer;
+    }
+
+    typedef tiny-unsigned-integer {
+        type uint8 {
+            range "15..220";
+        }
+        default "150";
+    }
+
+    typedef derived-tiny-unsigned-integer {
+        type tiny-unsigned-integer;
+    }
+
+    typedef derived-tiny-unsigned-integer2 {
+        type tiny-unsigned-integer {
+            range "160..190";
+        }
+        default "170";
+    }
+
+    typedef derived-tiny-unsigned-integer3 {
+        type derived-tiny-unsigned-integer;
+    }
+
+    typedef small-unsigned-integer {
+        type uint16 {
+            range "9000..60000";
+        }
+        default "35000";
+    }
+
+    typedef derived-small-unsigned-integer {
+        type small-unsigned-integer;
+    }
+
+    typedef derived-small-unsigned-integer2 {
+        type small-unsigned-integer {
+            range "40000..55000";
+        }
+        default "45000";
+    }
+
+    typedef derived-small-unsigned-integer3 {
+        type derived-small-unsigned-integer;
+    }
+
+    typedef normal-unsigned-integer {
+        type uint32 {
+            range "70000..4200000000";
+        }
+        default "100000";
+    }
+
+    typedef derived-normal-unsigned-integer {
+        type normal-unsigned-integer;
+    }
+
+    typedef derived-normal-unsigned-integer2 {
+        type normal-unsigned-integer {
+            range "150000..3500000000";
+        }
+        default "250000";
+    }
+
+    typedef derived-normal-unsigned-integer3 {
+        type derived-normal-unsigned-integer;
+    }
+
+    typedef big-unsigned-integer {
+        type uint64 {
+            range "4500000000..6500000000";
+        }
+        default "5000000000";
+    }
+
+    typedef derived-big-unsigned-integer {
+        type big-unsigned-integer;
+    }
+
+    typedef derived-big-unsigned-integer2 {
+        type big-unsigned-integer {
+            range "5500000000..6200000000";
+        }
+        default "5800000000";
+    }
+
+    typedef derived-big-unsigned-integer3 {
+        type derived-big-unsigned-integer;
+    }
+
+    typedef my-decimal {
+        type decimal64 {
+            fraction-digits 2;
+            range "5.55 .. 150.55";
+        }
+        default "66.66";
+    }
+
+    typedef my-derived-decimal {
+        type my-decimal;
+    }
+
+    typedef my-derived-decimal2 {
+        type my-decimal {
+            fraction-digits 1;
+            range "77.7 .. 111.1";
+        }
+        default "99.9";
+    }
+
+    typedef my-derived-decimal3 {
+        type my-derived-decimal;
+    }
+
+    typedef my-string {
+        type string {
+            length "1..30";
+            pattern "[a-zA-Z ]+";
+        }
+        default "unspecified string";
+    }
+
+    typedef my-derived-string {
+        type my-string;
+    }
+
+    typedef my-derived-string2 {
+        type my-string {
+            length "5..15";
+            pattern "[a-z]+";
+        }
+        default "unknown";
+    }
+
+    typedef my-derived-string3 {
+        type my-derived-string;
+    }
+
+    typedef my-enumeration {
+        type enumeration {
+            enum first {
+                value 1;
+            }
+            enum second {
+                value 2;
+            }
+            enum third {
+                value 3;
+            }
+        }
+        default "second";
+    }
+
+    typedef my-bits {
+        type bits {
+            bit bit-zero {
+                position 0;
+            }
+            bit bit-one {
+                position 1;
+            }
+            bit bit-two {
+                position 2;
+            }
+        }
+        default "bit-one";
+    }
+
+    identity my-identity {
+        description "identity for testing purposes";
+    }
+
+    typedef my-identityref {
+        type identityref {
+            base my-identity;
+        }
+    }
+
+    container tiny-int-container {
+        presence "presence container";
+
+        leaf tiny-int-leaf {
+            type tiny-signed-integer;
+        }
+
+        leaf tiny-int-leaf2 {
+            type derived-tiny-signed-integer;
+        }
+
+        leaf tiny-int-leaf3 {
+            type derived-tiny-signed-integer2;
+        }
+
+        leaf tiny-int-leaf4 {
+            type derived-tiny-signed-integer3;
+        }
+
+        leaf tiny-int-leaf5 {
+            type int8;
+            default "-120";
+        }
+
+        leaf tiny-int-leaf6 {
+            type int8;
+        }
+    }
+
+    container small-int-container {
+        presence "presence container";
+
+        leaf small-int-leaf {
+            type small-signed-integer;
+        }
+
+        leaf small-int-leaf2 {
+            type derived-small-signed-integer;
+        }
+
+        leaf small-int-leaf3 {
+            type derived-small-signed-integer2;
+        }
+
+        leaf small-int-leaf4 {
+            type derived-small-signed-integer3;
+        }
+
+        leaf small-int-leaf5 {
+            type int16;
+            default "-5000";
+        }
+
+        leaf small-int-leaf6 {
+            type int16;
+        }
+    }
+
+    container normal-int-container {
+        presence "presence container";
+
+        leaf normal-int-leaf {
+            type normal-signed-integer;
+        }
+
+        leaf normal-int-leaf2 {
+            type derived-normal-signed-integer;
+        }
+
+        leaf normal-int-leaf3 {
+            type derived-normal-signed-integer2;
+        }
+
+        leaf normal-int-leaf4 {
+            type derived-normal-signed-integer3;
+        }
+
+        leaf normal-int-leaf5 {
+            type int32;
+            default "-95000";
+        }
+
+        leaf normal-int-leaf6 {
+            type int32;
+        }
+    }
+
+    container big-int-container {
+        presence "presence container";
+
+        leaf big-int-leaf {
+            type big-signed-integer;
+        }
+
+        leaf big-int-leaf2 {
+            type derived-big-signed-integer;
+        }
+
+        leaf big-int-leaf3 {
+            type derived-big-signed-integer2;
+        }
+
+        leaf big-int-leaf4 {
+            type derived-big-signed-integer3;
+        }
+
+        leaf big-int-leaf5 {
+            type int64;
+            default "-2500000000";
+        }
+
+        leaf big-int-leaf6 {
+            type int64;
+        }
+    }
+
+    container tiny-uint-container {
+        presence "presence container";
+
+        leaf tiny-uint-leaf {
+            type tiny-unsigned-integer;
+        }
+
+        leaf tiny-uint-leaf2 {
+            type derived-tiny-unsigned-integer;
+        }
+
+        leaf tiny-uint-leaf3 {
+            type derived-tiny-unsigned-integer2;
+        }
+
+        leaf tiny-uint-leaf4 {
+            type derived-tiny-unsigned-integer3;
+        }
+
+        leaf tiny-uint-leaf5 {
+            type uint8;
+            default "155";
+        }
+
+        leaf tiny-uint-leaf6 {
+            type uint8;
+        }
+    }
+
+    container small-uint-container {
+        presence "presence container";
+
+        leaf small-uint-leaf {
+            type small-unsigned-integer;
+        }
+
+        leaf small-uint-leaf2 {
+            type derived-small-unsigned-integer;
+        }
+
+        leaf small-uint-leaf3 {
+            type derived-small-unsigned-integer2;
+        }
+
+        leaf small-uint-leaf4 {
+            type derived-small-unsigned-integer3;
+        }
+
+        leaf small-uint-leaf5 {
+            type uint16;
+            default "62000";
+        }
+
+        leaf small-uint-leaf6 {
+            type uint16;
+        }
+    }
+
+    container normal-uint-container {
+        presence "presence container";
+
+        leaf normal-uint-leaf {
+            type normal-unsigned-integer;
+        }
+
+        leaf normal-uint-leaf2 {
+            type derived-normal-unsigned-integer;
+        }
+
+        leaf normal-uint-leaf3 {
+            type derived-normal-unsigned-integer2;
+        }
+
+        leaf normal-uint-leaf4 {
+            type derived-normal-unsigned-integer3;
+        }
+
+        leaf normal-uint-leaf5 {
+            type uint32;
+            default "150000";
+        }
+
+        leaf normal-uint-leaf6 {
+            type uint32;
+        }
+    }
+
+    container big-uint-container {
+        presence "presence container";
+
+        leaf big-uint-leaf {
+            type big-unsigned-integer;
+        }
+
+        leaf big-uint-leaf2 {
+            type derived-big-unsigned-integer;
+        }
+
+        leaf big-uint-leaf3 {
+            type derived-big-unsigned-integer2;
+        }
+
+        leaf big-uint-leaf4 {
+            type derived-big-unsigned-integer3;
+        }
+
+        leaf big-uint-leaf5 {
+            type uint64;
+            default "6500000000";
+        }
+
+        leaf big-uint-leaf6 {
+            type uint64;
+        }
+    }
+
+    container decimal-container {
+        presence "presence container";
+
+        leaf decimal-leaf {
+            type my-decimal;
+        }
+
+        leaf decimal-leaf2 {
+            type my-derived-decimal;
+        }
+
+        leaf decimal-leaf3 {
+            type my-derived-decimal2;
+        }
+
+        leaf decimal-leaf4 {
+            type my-derived-decimal3;
+        }
+
+        leaf decimal-leaf5 {
+            type decimal64 {
+                fraction-digits 2;
+            }
+            default "120.55";
+        }
+
+        leaf decimal-leaf6 {
+            type decimal64 {
+                fraction-digits 3;
+            }
+        }
+    }
+
+    container string-container {
+        presence "presence container";
+
+        leaf string-leaf {
+            type my-string;
+        }
+
+        leaf string-leaf2 {
+            type my-derived-string;
+        }
+
+        leaf string-leaf3 {
+            type my-derived-string2;
+        }
+
+        leaf string-leaf4 {
+            type my-derived-string3;
+        }
+
+        leaf string-leaf5 {
+            type string;
+            default "whatever";
+        }
+
+        leaf string-leaf6 {
+            type string;
+        }
+    }
+
+    container boolean-container {
+        presence "presence container";
+
+        leaf boolean-leaf {
+            type boolean;
+            default "true";
+        }
+
+        leaf boolean-leaf2 {
+            type boolean;
+        }
+    }
+
+    container enum-container {
+        presence "presence container";
+
+        leaf enum-leaf {
+            type my-enumeration;
+        }
+    }
+
+    container bits-container {
+        presence "presence container";
+
+        leaf bits-leaf {
+            type my-bits;
+        }
+    }
+
+    container binary-container {
+        presence "presence container";
+
+        leaf binary-leaf {
+            type binary;
+            default "aGVsbG8=";
+        }
+
+        leaf binary-leaf2 {
+            type binary;
+        }
+    }
+
+    container identityref-container {
+        presence "presence container";
+
+        leaf identityref-leaf {
+            type my-identityref;
+        }
+    }
+}
\ No newline at end of file