Use DatabindContext in deserialization path 80/109080/2
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 27 Nov 2023 23:04:16 +0000 (00:04 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 27 Nov 2023 23:50:28 +0000 (00:50 +0100)
Rather than passing a naked EffectiveModelContext, from which we create
a DataSchemaContextTree, pass down the readily-available
DatabindContext -- which provides the tree very cheaply.

JIRA: NETCONF-1157
Change-Id: I68c8478845392c9a1e2fc9fbeb92ed4803d93a5b
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/Insert.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/legacy/InstanceIdentifierContext.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/IdentifierCodec.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/StringModuleInstanceIdentifierCodec.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/YangInstanceIdentifierDeserializer.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/server/mdsal/MdsalRestconfServer.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/databind/jaxrs/QueryParamsTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/IdentifierCodecTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifierTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/YangInstanceIdentifierDeserializerTest.java

index d611cd9c474495f2d29edd21fd180e1424dafb19..404014db173cf7f0a5779d72d0242769ccf67c22 100644 (file)
@@ -18,10 +18,10 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.restconf.api.query.InsertParam;
 import org.opendaylight.restconf.api.query.PointParam;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.restconf.nb.rfc8040.utils.parser.YangInstanceIdentifierDeserializer;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 /**
  * Parser and holder of query parameters from uriInfo for data and datastore modification operations.
@@ -56,7 +56,7 @@ public final class Insert implements Immutable {
      * @throws NullPointerException if any argument is {@code null}
      * @throws IllegalArgumentException if the parameters are invalid
      */
-    public static @Nullable Insert ofQueryParameters(final EffectiveModelContext modelContext,
+    public static @Nullable Insert ofQueryParameters(final DatabindContext databind,
             final Map<String, String> queryParameters) {
         InsertParam insert = null;
         PointParam point = null;
@@ -78,11 +78,7 @@ public final class Insert implements Immutable {
         }
 
         return Insert.forParams(insert, point,
-            // TODO: instead of a EffectiveModelContext, we should have received
-            //       YangInstanceIdentifierDeserializer.Result, from which we can use to seed the parser. This
-            //       call-site should not support 'yang-ext:mount' and should just reuse DataSchemaContextTree,
-            //       saving a lookup
-            value -> YangInstanceIdentifierDeserializer.create(modelContext, value).path.getLastPathArgument());
+            value -> YangInstanceIdentifierDeserializer.create(databind, value).path.getLastPathArgument());
     }
 
     public static @Nullable Insert forParams(final @Nullable InsertParam insert, final @Nullable PointParam point,
index 4ae6973d2c0874d499ce9a51c4c870d9ebbfbc9d..24977a2a8599195338015a66fabf875d0c364dc2 100644 (file)
@@ -128,7 +128,7 @@ public abstract class InstanceIdentifierContext {
                     ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED);
             }
 
-            final var mountPath = IdentifierCodec.deserialize(path.subPath(prefix, mount), databind.modelContext());
+            final var mountPath = IdentifierCodec.deserialize(path.subPath(prefix, mount), databind);
             final var userPath = path.subPath(0, mount);
             final var nextMountPoint = mountService.getMountPoint(mountPath)
                 .orElseThrow(() -> new RestconfDocumentedException("Mount point '" + userPath + "' does not exist",
@@ -148,8 +148,7 @@ public abstract class InstanceIdentifierContext {
             currentMountPoint = nextMountPoint;
         }
 
-        final var result = YangInstanceIdentifierDeserializer.create(currentDatabind.modelContext(),
-            path.subPath(prefix));
+        final var result = YangInstanceIdentifierDeserializer.create(currentDatabind, path.subPath(prefix));
         return InstanceIdentifierContext.ofPath(currentDatabind, result.stack, result.node, result.path,
             currentMountPoint);
     }
index 8c0e15e2976f8c30afd4da20c3b9401d4c490bfa..6b537700daac8f6061fb4d1cfbe2ef8d7526811c 100644 (file)
@@ -8,14 +8,13 @@
 package org.opendaylight.restconf.nb.rfc8040.utils.parser;
 
 import org.opendaylight.restconf.api.ApiPath;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 /**
- * Codec for identifier to serialize {@link YangInstanceIdentifier} to
- * {@link String} and deserialize {@link String} to
+ * Codec for identifier to serialize {@link YangInstanceIdentifier} to {@link String} and deserialize {@link String} to
  * {@link YangInstanceIdentifier}.
- *
  */
 public final class IdentifierCodec {
     private IdentifierCodec() {
@@ -26,8 +25,8 @@ public final class IdentifierCodec {
         return YangInstanceIdentifierSerializer.create(schemaContext, data);
     }
 
-    public static YangInstanceIdentifier deserialize(final ApiPath data, final EffectiveModelContext schemaContext) {
+    public static YangInstanceIdentifier deserialize(final ApiPath data, final DatabindContext databind) {
         return data == null ? YangInstanceIdentifier.of()
-            : YangInstanceIdentifierDeserializer.create(schemaContext, data).path;
+            : YangInstanceIdentifierDeserializer.create(databind, data).path;
     }
 }
index ad46d6671914d2c001c1222d3cb05c8fa082657b..74e5ac783b46d25c3ee20a9eb144427497994c43 100644 (file)
@@ -10,37 +10,31 @@ package org.opendaylight.restconf.nb.rfc8040.utils.parser;
 import static java.util.Objects.requireNonNull;
 
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.yangtools.yang.common.XMLNamespace;
 import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
 final class StringModuleInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec {
-    private final @NonNull EffectiveModelContext context;
+    private final @NonNull DatabindContext databind;
 
-    private volatile DataSchemaContextTree dataContextTree;
-
-    StringModuleInstanceIdentifierCodec(final @NonNull EffectiveModelContext context) {
-        this.context = requireNonNull(context);
+    StringModuleInstanceIdentifierCodec(final DatabindContext databind) {
+        this.databind = requireNonNull(databind);
     }
 
     @Override
-    protected Module moduleForPrefix(final String prefix) {
-        return context.findModules(prefix).stream().findFirst().orElse(null);
+    protected DataSchemaContextTree getDataContextTree() {
+        return databind.schemaTree();
     }
 
     @Override
-    protected DataSchemaContextTree getDataContextTree() {
-        DataSchemaContextTree local = dataContextTree;
-        if (local == null) {
-            dataContextTree = local = DataSchemaContextTree.from(context);
-        }
-        return local;
+    protected Module moduleForPrefix(final String prefix) {
+        return databind.modelContext().findModules(prefix).stream().findFirst().orElse(null);
     }
 
     @Override
     protected String prefixForNamespace(final XMLNamespace namespace) {
-        return context.findModules(namespace).stream().findFirst().map(Module::getName).orElse(null);
+        return databind.modelContext().findModule(namespace).stream().findFirst().map(Module::getName).orElse(null);
     }
 }
index 257d456c28d1fe4e4fe1cdab2e99cc369a960d59..caba62cf2b262e1e9594ebbcf6fbdf068e3486ca 100644 (file)
@@ -19,6 +19,7 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.restconf.api.ApiPath;
 import org.opendaylight.restconf.api.ApiPath.ListInstance;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -31,7 +32,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContext;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContext.PathMixin;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
 import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
@@ -58,16 +58,16 @@ public final class YangInstanceIdentifierDeserializer {
         public final @NonNull SchemaInferenceStack stack;
         public final @NonNull SchemaNode node;
 
-        Result(final EffectiveModelContext context) {
+        Result(final EffectiveModelContext modelContext) {
             path = YangInstanceIdentifier.of();
-            node = requireNonNull(context);
-            stack = SchemaInferenceStack.of(context);
+            stack = SchemaInferenceStack.of(modelContext);
+            node = requireNonNull(modelContext);
         }
 
-        Result(final EffectiveModelContext context, final QName qname) {
+        Result(final EffectiveModelContext modelContext, final QName qname) {
             // Legacy behavior: RPCs do not really have a YangInstanceIdentifier, but the rest of the code expects it
             path = YangInstanceIdentifier.of(qname);
-            stack = SchemaInferenceStack.of(context);
+            stack = SchemaInferenceStack.of(modelContext);
 
             final var stmt = stack.enterSchemaTree(qname);
             verify(stmt instanceof RpcDefinition, "Unexpected statement %s", stmt);
@@ -81,23 +81,25 @@ public final class YangInstanceIdentifierDeserializer {
         }
     }
 
-    private final @NonNull EffectiveModelContext schemaContext;
+    private final @NonNull DatabindContext databind;
+    private final @NonNull EffectiveModelContext modelContext;
     private final @NonNull ApiPath apiPath;
 
-    private YangInstanceIdentifierDeserializer(final EffectiveModelContext schemaContext, final ApiPath apiPath) {
-        this.schemaContext = requireNonNull(schemaContext);
+    private YangInstanceIdentifierDeserializer(final DatabindContext databind, final ApiPath apiPath) {
+        this.databind = requireNonNull(databind);
         this.apiPath = requireNonNull(apiPath);
+        modelContext = databind.modelContext();
     }
 
     /**
      * Method to create {@link List} from {@link PathArgument} which are parsing from data by {@link SchemaContext}.
      *
-     * @param schemaContext for validate of parsing path arguments
+     * @param databind for validate of parsing path arguments
      * @param data path to data, in URL string form
      * @return {@link Iterable} of {@link PathArgument}
      * @throws RestconfDocumentedException the path is not valid
      */
-    public static Result create(final EffectiveModelContext schemaContext, final String data) {
+    public static Result create(final DatabindContext databind, final String data) {
         final ApiPath path;
         try {
             path = ApiPath.parse(requireNonNull(data));
@@ -105,11 +107,11 @@ public final class YangInstanceIdentifierDeserializer {
             throw new RestconfDocumentedException("Invalid path '" + data + "' at offset " + e.getErrorOffset(),
                 ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, e);
         }
-        return create(schemaContext, path);
+        return create(databind, path);
     }
 
-    public static Result create(final EffectiveModelContext schemaContext, final ApiPath path) {
-        return new YangInstanceIdentifierDeserializer(schemaContext, path).parse();
+    public static Result create(final DatabindContext databind, final ApiPath path) {
+        return new YangInstanceIdentifierDeserializer(databind, path).parse();
     }
 
     // FIXME: NETCONF-818: this method really needs to report an Inference and optionally a YangInstanceIdentifier
@@ -123,7 +125,7 @@ public final class YangInstanceIdentifierDeserializer {
     private Result parse() {
         final var it = apiPath.steps().iterator();
         if (!it.hasNext()) {
-            return new Result(schemaContext);
+            return new Result(modelContext);
         }
 
         // First step is somewhat special:
@@ -143,7 +145,7 @@ public final class YangInstanceIdentifierDeserializer {
         var qname = step.identifier().bindTo(namespace);
 
         // We go through more modern APIs here to get this special out of the way quickly
-        final var optRpc = schemaContext.findModuleStatement(namespace).orElseThrow()
+        final var optRpc = modelContext.findModuleStatement(namespace).orElseThrow()
             .findSchemaTreeNode(RpcEffectiveStatement.class, qname);
         if (optRpc.isPresent()) {
             // We have found an RPC match,
@@ -156,14 +158,14 @@ public final class YangInstanceIdentifierDeserializer {
                     + "therefore it must not contain key values", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
             }
 
-            return new Result(schemaContext, optRpc.orElseThrow().argument());
+            return new Result(modelContext, optRpc.orElseThrow().argument());
         }
 
-        final var stack = SchemaInferenceStack.of(schemaContext);
+        final var stack = SchemaInferenceStack.of(modelContext);
         final var path = new ArrayList<PathArgument>();
         final SchemaNode node;
 
-        DataSchemaContext parentNode = DataSchemaContextTree.from(schemaContext).getRoot();
+        DataSchemaContext parentNode = databind.schemaTree().getRoot();
         while (true) {
             final var parentSchema = parentNode.dataSchemaNode();
             if (parentSchema instanceof ActionNodeContainer actionParent) {
@@ -267,13 +269,13 @@ public final class YangInstanceIdentifierDeserializer {
             final @NonNull String value) {
 
         TypeDefinition<? extends TypeDefinition<?>> typedef;
-        if (schemaNode instanceof LeafListSchemaNode) {
-            typedef = ((LeafListSchemaNode) schemaNode).getType();
+        if (schemaNode instanceof LeafListSchemaNode leafList) {
+            typedef = leafList.getType();
         } else {
             typedef = ((LeafSchemaNode) schemaNode).getType();
         }
-        if (typedef instanceof LeafrefTypeDefinition) {
-            typedef = stack.resolveLeafref((LeafrefTypeDefinition) typedef);
+        if (typedef instanceof LeafrefTypeDefinition leafref) {
+            typedef = stack.resolveLeafref(leafref);
         }
 
         if (typedef instanceof IdentityrefTypeDefinition) {
@@ -282,7 +284,7 @@ public final class YangInstanceIdentifierDeserializer {
 
         try {
             if (typedef instanceof InstanceIdentifierTypeDefinition) {
-                return new StringModuleInstanceIdentifierCodec(schemaContext).deserialize(value);
+                return new StringModuleInstanceIdentifierCodec(databind).deserialize(value);
             }
 
             return verifyNotNull(TypeDefinitionAwareCodec.from(typedef),
@@ -313,7 +315,7 @@ public final class YangInstanceIdentifierDeserializer {
             localName = value;
         }
 
-        return schemaContext.getModuleStatement(namespace)
+        return modelContext.getModuleStatement(namespace)
             .streamEffectiveSubstatements(IdentityEffectiveStatement.class)
             .map(IdentityEffectiveStatement::argument)
             .filter(qname -> localName.equals(qname.getLocalName()))
@@ -324,7 +326,7 @@ public final class YangInstanceIdentifierDeserializer {
     }
 
     private @NonNull QNameModule resolveNamespace(final String moduleName) {
-        final var it = schemaContext.findModuleStatements(moduleName).iterator();
+        final var it = modelContext.findModuleStatements(moduleName).iterator();
         if (it.hasNext()) {
             return it.next().localQNameModule();
         }
index a20911e0a7b258adc9a56b21650fc9f19379c9bc..bf9543b677759308973837074a891a66d5b66f99 100644 (file)
@@ -331,18 +331,16 @@ public final class MdsalRestconfServer
 
     private @NonNull RestconfFuture<CreateResource> dataCreatePOST(final InstanceIdentifierContext reqPath,
             final ChildBody body, final Map<String, String> queryParameters) {
-        final var inference = reqPath.inference();
-
         final Insert insert;
         try {
-            insert = Insert.ofQueryParameters(inference.getEffectiveModelContext(), queryParameters);
+            insert = Insert.ofQueryParameters(reqPath.databind(), queryParameters);
         } catch (IllegalArgumentException e) {
             return RestconfFuture.failed(new RestconfDocumentedException(e.getMessage(),
                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e));
         }
 
         final var parentPath = reqPath.getInstanceIdentifier();
-        final var payload = body.toPayload(parentPath, inference);
+        final var payload = body.toPayload(parentPath, reqPath.inference());
         return getRestconfStrategy(reqPath.databind(), reqPath.getMountPoint())
             .postData(concat(parentPath, payload.prefix()), payload.body(), insert);
     }
@@ -455,7 +453,7 @@ public final class MdsalRestconfServer
             final ResourceBody body, final Map<String, String> queryParameters) {
         final Insert insert;
         try {
-            insert = Insert.ofQueryParameters(reqPath.databind().modelContext(), queryParameters);
+            insert = Insert.ofQueryParameters(reqPath.databind(), queryParameters);
         } catch (IllegalArgumentException e) {
             return RestconfFuture.failed(new RestconfDocumentedException(e.getMessage(),
                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e));
index 71e09f999a95224adb981938c450be474cefa781..d9119f4b86c6b1499bb0476048a0554ca77f5fe7 100644 (file)
@@ -79,14 +79,14 @@ public class QueryParamsTest {
      */
     @Test
     public void checkParametersTypesNegativeTest() {
+        final var mockDatabind = DatabindContext.ofModel(mock(EffectiveModelContext.class));
         assertInvalidIAE(ReceiveEventsParams::ofQueryParameters);
         assertUnknownParam(QueryParams::newReadDataParams);
-        assertInvalidIAE(queryParams -> Insert.ofQueryParameters(mock(EffectiveModelContext.class), queryParams));
+        assertInvalidIAE(queryParams -> Insert.ofQueryParameters(mockDatabind, queryParams));
 
         assertInvalidIAE(ReceiveEventsParams::ofQueryParameters, ContentParam.ALL);
         assertInvalidParam(QueryParams::newReadDataParams, InsertParam.LAST);
-        assertInvalidIAE(queryParams -> Insert.ofQueryParameters(mock(EffectiveModelContext.class), queryParams),
-            ContentParam.ALL);
+        assertInvalidIAE(queryParams -> Insert.ofQueryParameters(mockDatabind, queryParams), ContentParam.ALL);
     }
 
     /**
index 22e87bc914ab6486117e3cbb6837fdc4874fb0e2..cd6b7e800e4992fc16691e93a32df6d53d0633fc 100644 (file)
@@ -11,16 +11,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import org.junit.jupiter.api.Test;
 import org.opendaylight.restconf.api.ApiPath;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
 /**
  * Unit tests for {@link IdentifierCodec} mostly according to examples from draft-ietf-netconf-restconf-13.
  */
 class IdentifierCodecTest {
-    private static final EffectiveModelContext SCHEMA_CONTEXT =
-        YangParserTestUtils.parseYangResourceDirectory("/restconf/parser");
+    private static final DatabindContext DATABIND = DatabindContext.ofModel(
+        YangParserTestUtils.parseYangResourceDirectory("/restconf/parser"));
 
     /**
      * Positive test of deserialization URI <code>String</code> to <code>YangInstanceIdentifier</code> and
@@ -30,9 +30,9 @@ class IdentifierCodecTest {
     @Test
     void codecListAndLeafTest() throws Exception {
         final var dataYangII = IdentifierCodec.deserialize(ApiPath.parse(
-            "list-test:top/list1=%2C%27\"%3A\"%20%2F,,foo/list2=a,b/result"), SCHEMA_CONTEXT);
+            "list-test:top/list1=%2C%27\"%3A\"%20%2F,,foo/list2=a,b/result"), DATABIND);
         assertEquals("list-test:top/list1=%2C%27\"%3A\" %2F,,foo/list2=a,b/result",
-            IdentifierCodec.serialize(dataYangII, SCHEMA_CONTEXT));
+            IdentifierCodec.serialize(dataYangII, DATABIND.modelContext()));
     }
 
     /**
@@ -43,8 +43,8 @@ class IdentifierCodecTest {
     @Test
     void codecLeafListTest() throws Exception {
         final var str = "list-test:top/Y=4";
-        final var dataYangII = IdentifierCodec.deserialize(ApiPath.parse(str), SCHEMA_CONTEXT);
-        assertEquals(str, IdentifierCodec.serialize(dataYangII, SCHEMA_CONTEXT));
+        final var dataYangII = IdentifierCodec.deserialize(ApiPath.parse(str), DATABIND);
+        assertEquals(str, IdentifierCodec.serialize(dataYangII, DATABIND.modelContext()));
     }
 
     /**
@@ -54,7 +54,7 @@ class IdentifierCodecTest {
      */
     @Test
     void codecDeserializeNullTest() {
-        final var dataYangII = IdentifierCodec.deserialize(null, SCHEMA_CONTEXT);
+        final var dataYangII = IdentifierCodec.deserialize(null, DATABIND);
         assertEquals(YangInstanceIdentifier.of(), dataYangII);
     }
 
@@ -64,7 +64,7 @@ class IdentifierCodecTest {
      */
     @Test
     void codecSerializeEmptyTest() {
-        assertEquals("", IdentifierCodec.serialize(YangInstanceIdentifier.of(), SCHEMA_CONTEXT));
+        assertEquals("", IdentifierCodec.serialize(YangInstanceIdentifier.of(), DATABIND.modelContext()));
     }
 
     /**
@@ -73,8 +73,8 @@ class IdentifierCodecTest {
      */
     @Test
     void codecDeserializeAndSerializeEmptyTest() throws Exception {
-        final var serialized = IdentifierCodec.serialize(YangInstanceIdentifier.of(), SCHEMA_CONTEXT);
+        final var serialized = IdentifierCodec.serialize(YangInstanceIdentifier.of(), DATABIND.modelContext());
         assertEquals(YangInstanceIdentifier.of(), IdentifierCodec.deserialize(ApiPath.parse(serialized),
-            SCHEMA_CONTEXT));
+            DATABIND));
     }
 }
index 02901cbee84517150fe5075b321566888f5eb78f..58225ad1a76966b69f3187a528a2c9c091bbb6cc 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
 import org.opendaylight.restconf.api.ApiPath;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.restconf.nb.rfc8040.legacy.ErrorTags;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
@@ -219,7 +220,7 @@ public class ParserIdentifierTest {
         assertEquals("rpc-test", rpcQName.getLocalName());
 
         // other fields
-        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_RPC), MODEL_CONTEXT),
+        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_RPC), DatabindContext.ofModel(MODEL_CONTEXT)),
             result.getInstanceIdentifier());
         assertEquals(null, result.getMountPoint());
         assertSame(MODEL_CONTEXT, result.databind().modelContext());
@@ -239,7 +240,7 @@ public class ParserIdentifierTest {
         assertEquals("rpc-test", rpcQName.getLocalName());
 
         // other fields
-        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_RPC), MODEL_CONTEXT),
+        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_RPC), DatabindContext.ofModel(MODEL_CONTEXT)),
             result.getInstanceIdentifier());
         assertEquals(mountPoint, result.getMountPoint());
         assertSame(MODEL_CONTEXT_ON_MOUNT_POINT, result.databind().modelContext());
@@ -258,7 +259,7 @@ public class ParserIdentifierTest {
         assertEquals("reset", actionQName.getLocalName());
 
         // other fields
-        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_ACTION), MODEL_CONTEXT),
+        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_ACTION), DatabindContext.ofModel(MODEL_CONTEXT)),
             result.getInstanceIdentifier());
         assertNull(result.getMountPoint());
         assertSame(MODEL_CONTEXT, result.databind().modelContext());
@@ -278,7 +279,7 @@ public class ParserIdentifierTest {
         assertEquals("reset", actionQName.getLocalName());
 
         // other fields
-        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_ACTION), MODEL_CONTEXT),
+        assertEquals(IdentifierCodec.deserialize(ApiPath.parse(INVOKE_ACTION), DatabindContext.ofModel(MODEL_CONTEXT)),
             result.getInstanceIdentifier());
         assertEquals(mountPoint, result.getMountPoint());
         assertSame(MODEL_CONTEXT_ON_MOUNT_POINT, result.databind().modelContext());
index 0736598a4a3233fb97d27b6299b4a96cafac1268..ca2c280d3da2fa9d016d910bddb67604632ca3bf 100644 (file)
@@ -14,15 +14,11 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThrows;
 
 import com.google.common.collect.ImmutableMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -34,7 +30,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
 /**
@@ -44,18 +39,8 @@ public class YangInstanceIdentifierDeserializerTest {
     private static final QName ACTIONS_INTERFACES =
         QName.create("https://example.com/ns/example-actions", "2016-07-07", "interfaces");
 
-    // schema context
-    private static EffectiveModelContext SCHEMA_CONTEXT;
-
-    @BeforeClass
-    public static void beforeClass() {
-        SCHEMA_CONTEXT = YangParserTestUtils.parseYangResourceDirectory("/restconf/parser/deserializer");
-    }
-
-    @AfterClass
-    public static void afterClass() {
-        SCHEMA_CONTEXT = null;
-    }
+    private static final DatabindContext DATABIND = DatabindContext.ofModel(
+        YangParserTestUtils.parseYangResourceDirectory("/restconf/parser/deserializer"));
 
     /**
      * Test of deserialization <code>String</code> URI with container to
@@ -63,8 +48,8 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeContainerTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA")
-            .path.getPathArguments();
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:contA").path
+            .getPathArguments();
         assertEquals(1, result.size());
         assertEquals(NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")), result.get(0));
     }
@@ -75,8 +60,8 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeContainerWithLeafTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA/leaf-A")
-            .path.getPathArguments();
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:contA/leaf-A").path
+            .getPathArguments();
         assertEquals(2, result.size());
         assertEquals(NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")), result.get(0));
         assertEquals(NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "leaf-A")), result.get(1));
@@ -88,7 +73,7 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeContainerWithListWithLeafListTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test:contA/list-A=100/leaf-list-AA=instance").path.getPathArguments();
         assertEquals(5, result.size());
 
@@ -111,7 +96,7 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeContainerWithListWithActionTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "example-actions:interfaces/interface=eth0/reset").path.getPathArguments();
         assertEquals(4, result.size());
         // container
@@ -130,7 +115,7 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeContainerWithChoiceSchemaNodeWithActionTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "example-actions:interfaces/typeA-gigabyte/interface=eth0/reboot").path.getPathArguments();
         assertEquals(6, result.size());
 
@@ -156,8 +141,8 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeContainerWithChoiceCaseSchemaNodeWithActionTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
-            "example-actions:interfaces/udp/reboot").path.getPathArguments();
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND, "example-actions:interfaces/udp/reboot")
+            .path.getPathArguments();
         assertEquals(4, result.size());
         // container
         assertEquals(NodeIdentifier.create(ACTIONS_INTERFACES), result.get(0));
@@ -175,10 +160,10 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeListWithNoKeysTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:list-no-key")
-            .path.getPathArguments();
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:list-no-key").path
+            .getPathArguments();
         assertEquals(2, result.size());
-        final QName list = QName.create("deserializer:test", "2016-06-06", "list-no-key");
+        final var list = QName.create("deserializer:test", "2016-06-06", "list-no-key");
         assertEquals(NodeIdentifier.create(list), result.get(0));
         assertEquals(NodeIdentifier.create(list), result.get(1));
     }
@@ -189,8 +174,8 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeListWithOneKeyTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
-            "deserializer-test:list-one-key=value").path.getPathArguments();
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:list-one-key=value")
+            .path.getPathArguments();
         assertEquals(2, result.size());
         final QName list = QName.create("deserializer:test", "2016-06-06", "list-one-key");
         assertEquals(NodeIdentifier.create(list), result.get(0));
@@ -203,13 +188,13 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeListWithMultipleKeysTest() {
-        final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
-        final Map<QName, Object> values = ImmutableMap.of(
+        final var list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
+        final var values = ImmutableMap.<QName, Object>of(
             QName.create(list, "name"), "value",
             QName.create(list, "number"), Uint8.valueOf(100),
             QName.create(list, "enabled"), false);
 
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test:list-multiple-keys=value,100,false").path.getPathArguments();
         assertEquals(2, result.size());
         assertEquals(NodeIdentifier.create(list), result.get(0));
@@ -222,8 +207,8 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeLeafListTest() {
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
-            "deserializer-test:leaf-list-0=true").path.getPathArguments();
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:leaf-list-0=true")
+            .path.getPathArguments();
         assertEquals(2, result.size());
 
         final QName leafList = QName.create("deserializer:test", "2016-06-06", "leaf-list-0");
@@ -236,7 +221,7 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializeEmptyDataTest() {
-        assertEquals(List.of(), YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "").path.getPathArguments());
+        assertEquals(List.of(), YangInstanceIdentifierDeserializer.create(DATABIND, "").path.getPathArguments());
     }
 
     /**
@@ -256,7 +241,7 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void nullDataNegativeNegativeTest() {
         assertThrows(NullPointerException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, (String) null));
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, (String) null));
     }
 
     /**
@@ -266,10 +251,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void deserializeBadCharMissingSlashOrEqualNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:cont*leaf-A"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test:cont*leaf-A' at offset 22, "
-            + "error-info: Expecting [a-zA-Z_.-], not '*']]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:cont*leaf-A"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test:cont*leaf-A' at offset 22, \
+            error-info: Expecting [a-zA-Z_.-], not '*']]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -284,10 +270,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void validArgIdentifierContainerEndsWithSlashNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA/"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test:contA/' at offset 24, "
-            + "error-info: Identifier may not be empty]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:contA/"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test:contA/' at offset 24, \
+            error-info: Identifier may not be empty]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -302,10 +289,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void validArgIdentifierContainerEndsWithMultipleSlashesNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA///"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test:contA///' at offset 24, "
-            + "error-info: Identifier may not be empty]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:contA///"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test:contA///' at offset 24, \
+            error-info: Identifier may not be empty]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -320,10 +308,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void validArgIdentifierListEndsWithSlashLNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:list-one-key=value/"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test:list-one-key=value/' at offset 37, "
-            + "error-info: Identifier may not be empty]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:list-one-key=value/"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test:list-one-key=value/' at offset 37, \
+            error-info: Identifier may not be empty]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -338,10 +327,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void validArgIdentifierListEndsWithSlashesNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:list-one-key=value//"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test:list-one-key=value//' at offset 37, "
-            + "error-info: Identifier may not be empty]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:list-one-key=value//"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test:list-one-key=value//' at offset 37, \
+            error-info: Identifier may not be empty]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -356,10 +346,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareQnameEmptyIdentifierNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "/"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path '/' at offset 0, "
-            + "error-info: Identifier may not be empty]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "/"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path '/' at offset 0, \
+            error-info: Identifier may not be empty]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -374,10 +365,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareQnameBuildPathNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test*contA"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test*contA' at offset 17, "
-            + "error-info: Expecting [a-zA-Z_.-], not '*']]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test*contA"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test*contA' at offset 17, \
+            error-info: Expecting [a-zA-Z_.-], not '*']]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -392,9 +384,10 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareQnameNotExistingPrefixNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "not-existing:contA"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: unknown-element, "
-            + "error-message: Failed to lookup for module with name 'not-existing'.]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "not-existing:contA"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: unknown-element, \
+            error-message: Failed to lookup for module with name 'not-existing'.]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -408,10 +401,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareQnameNotValidPrefixAndLocalNameNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class, () ->
-            YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:*not-parsable-identifier"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test:*not-parsable-identifier' at offset 18, "
-            + "error-info: Expecting [a-zA-Z_], not '*']]", ex.getMessage());
+            YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:*not-parsable-identifier"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test:*not-parsable-identifier' at offset 18, \
+            error-info: Expecting [a-zA-Z_], not '*']]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -426,10 +420,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareQnameErrorParsingNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: malformed-message, "
-            + "error-message: Invalid path 'deserializer-test:' at offset 18, "
-            + "error-info: Identifier may not be empty]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: malformed-message, \
+            error-message: Invalid path 'deserializer-test:' at offset 18, \
+            error-info: Identifier may not be empty]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -445,9 +440,10 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareQnameNotValidContainerNameNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA/leafB"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: data-missing, "
-            + "error-message: Schema for '(deserializer:test?revision=2016-06-06)leafB' not found]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:contA/leafB"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: data-missing, \
+            error-message: Schema for '(deserializer:test?revision=2016-06-06)leafB' not found]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -462,8 +458,7 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareQnameNotValidListNameNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
-                "deserializer-test:list-no-key/disabled=false"));
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:list-no-key/disabled=false"));
         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
         assertEquals(ErrorTag.DATA_MISSING, ex.getErrors().get(0).getErrorTag());
     }
@@ -475,10 +470,11 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void prepareIdentifierNotKeyedEntryNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:list-one-key"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: missing-attribute, "
-            + "error-message: Entry '(deserializer:test?revision=2016-06-06)list-one-key' requires key or value "
-            + "predicate to be present.]]", ex.getMessage());
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:list-one-key"));
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: missing-attribute, \
+            error-message: Entry '(deserializer:test?revision=2016-06-06)list-one-key' requires key or value \
+            predicate to be present.]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -492,11 +488,12 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void deserializeKeysEndsWithCommaTooManyNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test:list-multiple-keys=value,100,false,"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: unknown-attribute, "
-            + "error-message: Schema for (deserializer:test?revision=2016-06-06)list-multiple-keys "
-            + "requires 3 key values, 4 supplied]]", ex.getMessage());
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: unknown-attribute, \
+            error-message: Schema for (deserializer:test?revision=2016-06-06)list-multiple-keys requires 3 key values, \
+            4 supplied]]""", ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         assertEquals(ErrorType.PROTOCOL, errors.get(0).getErrorType());
@@ -510,11 +507,12 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void deserializeKeysEndsWithCommaIllegalNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test:list-multiple-keys=value,100,"));
-        assertEquals("errors: [RestconfError [error-type: protocol, error-tag: invalid-value, "
-            + "error-message: Invalid value '' for (deserializer:test?revision=2016-06-06)enabled, "
-            + "error-info: Invalid value '' for boolean type. Allowed values are 'true' and 'false']]",
+        assertEquals("""
+            errors: [RestconfError [error-type: protocol, error-tag: invalid-value, \
+            error-message: Invalid value '' for (deserializer:test?revision=2016-06-06)enabled, \
+            error-info: Invalid value '' for boolean type. Allowed values are 'true' and 'false']]""",
             ex.getMessage());
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
@@ -531,12 +529,12 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void notAllListKeysEncodedPositiveTest() {
         final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
-        final Map<QName, Object> values = ImmutableMap.of(
+        final var values = ImmutableMap.<QName, Object>of(
             QName.create(list, "name"), ":foo",
             QName.create(list, "number"), Uint8.ONE,
             QName.create(list, "enabled"), false);
 
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test:list-multiple-keys=%3Afoo,1,false/string-value").path.getPathArguments();
         assertEquals(3, result.size());
         // list
@@ -555,7 +553,7 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void notAllListKeysEncodedNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND,
                     "deserializer-test:list-multiple-keys=%3Afoo/string-value"));
         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
         assertEquals(ErrorTag.MISSING_ATTRIBUTE, ex.getErrors().get(0).getErrorTag());
@@ -568,9 +566,9 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void percentEncodedKeyEndsWithNoPercentEncodedChars() {
         final String URI = "deserializer-test:list-multiple-keys=%3Afoo,1,true";
-        final YangInstanceIdentifier result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, URI).path;
+        final YangInstanceIdentifier result = YangInstanceIdentifierDeserializer.create(DATABIND, URI).path;
 
-        final Iterator<Entry<QName, Object>> resultListKeys =
+        final var resultListKeys =
                 ((NodeIdentifierWithPredicates)result.getLastPathArgument()).entrySet().iterator();
 
         assertEquals(":foo", resultListKeys.next().getValue());
@@ -584,12 +582,12 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void deserializeAllKeysEmptyTest() {
         final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
-        final Map<QName, Object> values = ImmutableMap.of(
+        final var values = ImmutableMap.<QName, Object>of(
             QName.create(list, "name"), "",
             QName.create(list, "number"), Uint8.ZERO,
             QName.create(list, "enabled"), true);
 
-        final var result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test:list-multiple-keys=,0,true").path.getPathArguments();
         assertEquals(2, result.size());
         assertEquals(NodeIdentifier.create(list), result.get(0));
@@ -604,7 +602,7 @@ public class YangInstanceIdentifierDeserializerTest {
     @Test
     public void leafListMissingKeyNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:leaf-list-0="));
+            () -> YangInstanceIdentifierDeserializer.create(DATABIND, "deserializer-test:leaf-list-0="));
         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
     }
@@ -614,7 +612,7 @@ public class YangInstanceIdentifierDeserializerTest {
      */
     @Test
     public void deserializePartInOtherModuleTest() {
-        final List<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test-included:augmented-list=100/deserializer-test:augmented-leaf")
             .path.getPathArguments();
         assertEquals(3, result.size());
@@ -632,7 +630,7 @@ public class YangInstanceIdentifierDeserializerTest {
 
     @Test
     public void deserializeListInOtherModuleTest() {
-        final List<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
+        final var result = YangInstanceIdentifierDeserializer.create(DATABIND,
             "deserializer-test-included:augmented-list=100/deserializer-test:augmenting-list=0")
             .path.getPathArguments();
         assertEquals(4, result.size());
@@ -668,7 +666,7 @@ public class YangInstanceIdentifierDeserializerTest {
     }
 
     private static void assertIdentityrefKeyValue(final String path) {
-        final var pathArgs = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, path).path.getPathArguments();
+        final var pathArgs = YangInstanceIdentifierDeserializer.create(DATABIND, path).path.getPathArguments();
         assertEquals(4, pathArgs.size());
 
         assertEquals("refs", pathArgs.get(0).getNodeType().getLocalName());