Switch SchemaAwareApplyOperation error reporting 02/90002/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 27 May 2020 12:23:31 +0000 (14:23 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 23 Aug 2020 07:28:39 +0000 (09:28 +0200)
Switch to reporting IllegalStateException when the target schema
node is not as opposed to IllegalArgumentException. This makes it
clear that we have entered internal inconsistency rather than
the user doing something wrong.

Furthermore eliminate the possibility of throwing an unchecked
exception when the user has made a wrong reference -- opting for
a well-controlled checked exception instead.

JIRA: YANGTOOLS-1105
Change-Id: Icd3ddb03a721358d07427e1fddeec8a71e73b933
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ChoiceModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/DataNodeContainerModificationStrategy.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ExcludedDataSchemaNodeException.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/SchemaAwareApplyOperation.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModificationMetadataTreeTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/StoreTreeNodesTest.java

index 8230ecc0b5c655015b300d64a3c89fadf6cc4e61..b79371f48dbc71150cbfe1f21099c92a3805d038 100644 (file)
@@ -57,9 +57,17 @@ final class ChoiceModificationStrategy extends Visible<ChoiceSchemaNode> {
         for (final CaseSchemaNode caze : schema.getCases()) {
             final CaseEnforcer enforcer = CaseEnforcer.forTree(caze, treeConfig);
             if (enforcer != null) {
-                for (final Entry<NodeIdentifier, DataSchemaNode> e : enforcer.getChildEntries()) {
-                    childBuilder.put(e.getKey(), SchemaAwareApplyOperation.from(e.getValue(), treeConfig));
-                    enforcerBuilder.put(e.getKey(), enforcer);
+                for (final Entry<NodeIdentifier, DataSchemaNode> entry : enforcer.getChildEntries()) {
+                    final ModificationApplyOperation childOper;
+                    try {
+                        childOper = SchemaAwareApplyOperation.from(entry.getValue(), treeConfig);
+                    } catch (ExcludedDataSchemaNodeException e) {
+                        // This should never happen as enforcer performs filtering
+                        throw new IllegalStateException("Enforcer references out-of-tree child " + entry, e);
+                    }
+
+                    childBuilder.put(entry.getKey(), childOper);
+                    enforcerBuilder.put(entry.getKey(), enforcer);
                 }
                 for (final Entry<AugmentationIdentifier, AugmentationSchemaNode> e
                         : enforcer.getAugmentationEntries()) {
index 00d752b194a922dce7398da506d6fad3e2407500..4fde21bdd0400a826f6ba1a57dfd3d94f35ab650 100644 (file)
@@ -78,7 +78,7 @@ class DataNodeContainerModificationStrategy<T extends DataNodeContainer & WithSt
 
         try {
             return SchemaAwareApplyOperation.from(child.get(), treeConfig);
-        } catch (IllegalArgumentException e) {
+        } catch (ExcludedDataSchemaNodeException e) {
             LOG.trace("Failed to instantiate child {} in container schema {} children {}", identifier, this,
                 schema.getChildNodes(), e);
             return null;
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ExcludedDataSchemaNodeException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ExcludedDataSchemaNodeException.java
new file mode 100644 (file)
index 0000000..d6176d9
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.yangtools.yang.data.impl.schema.tree;
+
+/**
+ * A mouthful of an exception, reported when the requested schema node does exist in the schema tree, but is filtered
+ * from the current data tree. This can occur when a {@code config=false} node is referenced in the operational data
+ * tree.
+ */
+final class ExcludedDataSchemaNodeException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    ExcludedDataSchemaNodeException(final String message) {
+        super(message);
+    }
+}
index ab101e519875c87feff2ab8cc4ddc2f45a06b58b..683bdc45b02cdda4c9b5d30241fc67c2dcf470c1 100644 (file)
@@ -87,7 +87,11 @@ final class InMemoryDataTree extends AbstractDataTreeTip implements DataTree {
             }
         }
 
-        return SchemaAwareApplyOperation.from(rootSchemaNode, treeConfig);
+        try {
+            return SchemaAwareApplyOperation.from(rootSchemaNode, treeConfig);
+        } catch (ExcludedDataSchemaNodeException e) {
+            throw new IllegalArgumentException("Root node does not belong current data tree", e);
+        }
     }
 
     @Deprecated
index 4fa1ca95da2ce630b4f4c5648a9d1765b2a93f5f..f1f9ed1e5bd1060a0978668ea21ae17547014d6c 100644 (file)
@@ -45,11 +45,10 @@ import org.slf4j.LoggerFactory;
 abstract class SchemaAwareApplyOperation<T extends WithStatus> extends ModificationApplyOperation {
     private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareApplyOperation.class);
 
-    public static ModificationApplyOperation from(final DataSchemaNode schemaNode,
-            final DataTreeConfiguration treeConfig) {
-        if (treeConfig.getTreeType() == TreeType.CONFIGURATION) {
-            checkArgument(schemaNode.isConfiguration(), "Supplied %s does not belongs to configuration tree.",
-                schemaNode);
+    static ModificationApplyOperation from(final DataSchemaNode schemaNode,
+            final DataTreeConfiguration treeConfig) throws ExcludedDataSchemaNodeException {
+        if (!belongsToTree(treeConfig.getTreeType(), schemaNode)) {
+            throw new ExcludedDataSchemaNodeException(schemaNode + " does not belong to configuration tree");
         }
         if (schemaNode instanceof ContainerSchemaNode) {
             return ContainerModificationStrategy.of((ContainerSchemaNode) schemaNode, treeConfig);
@@ -66,11 +65,12 @@ abstract class SchemaAwareApplyOperation<T extends WithStatus> extends Modificat
             return new ValueNodeModificationStrategy<>(AnydataNode.class, (AnydataSchemaNode) schemaNode);
         } else if (schemaNode instanceof AnyxmlSchemaNode) {
             return new ValueNodeModificationStrategy<>(AnyxmlNode.class, (AnyxmlSchemaNode) schemaNode);
+        } else {
+            throw new IllegalStateException("Unsupported schema " + schemaNode);
         }
-        throw new IllegalArgumentException("Not supported schema node type for " + schemaNode.getClass());
     }
 
-    public static AugmentationModificationStrategy from(final DataNodeContainer resolvedTree,
+    static AugmentationModificationStrategy from(final DataNodeContainer resolvedTree,
             final AugmentationTarget augSchemas, final AugmentationIdentifier identifier,
             final DataTreeConfiguration treeConfig) {
         for (final AugmentationSchemaNode potential : augSchemas.getAvailableAugmentations()) {
index 3021952039bb19ae97585aa90f8e7085d1f88707..c2910921a7dc551db92e7eb178355fa4f767c469 100644 (file)
@@ -91,7 +91,7 @@ public class ModificationMetadataTreeTest extends AbstractTestModelTest {
     private RootApplyStrategy rootOper;
 
     @Before
-    public void prepare() {
+    public void prepare() throws ExcludedDataSchemaNodeException {
         rootOper = RootApplyStrategy.from(SchemaAwareApplyOperation.from(SCHEMA_CONTEXT,
             DataTreeConfiguration.DEFAULT_OPERATIONAL));
     }
index 2ee3a2965fa57bef9633fc5a967a0697761d23c3..40408073ee0de10db6c131a1c71c278e022e04bc 100644 (file)
@@ -66,7 +66,7 @@ public class StoreTreeNodesTest extends AbstractTestModelTest {
     private RootApplyStrategy rootOper;
 
     @Before
-    public void prepare() {
+    public void prepare() throws ExcludedDataSchemaNodeException {
         rootOper = RootApplyStrategy.from(SchemaAwareApplyOperation.from(SCHEMA_CONTEXT,
             DataTreeConfiguration.DEFAULT_OPERATIONAL));
     }