Relocate ParserIdentifier methods 44/109044/4
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 22 Nov 2023 03:18:34 +0000 (04:18 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 22 Nov 2023 15:12:23 +0000 (16:12 +0100)
Vast majority of methods here are implementation details of
RestconfSchemaServiceImpl. Move them there.

JIRA: NETCONF-773
Change-Id: I95836e3f6ee99f91c755f19ced3b3205ab2f7b56
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfSchemaServiceImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifier.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfModulesGetTest.java [new file with mode: 0644]
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfValidationTest.java [moved from restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/RestconfValidationTest.java with 81% similarity]
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifierTest.java

index 5379b0f626fdbc6c9868da2df6fdb0aa14c32d5a..b437a089d1ce0f11e37166686d7fee517f8e7239 100644 (file)
@@ -8,24 +8,48 @@
 package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import java.time.format.DateTimeParseException;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Locale;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import org.opendaylight.mdsal.dom.api.DOMMountPoint;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.nb.rfc8040.legacy.SchemaExportContext;
 import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.common.ErrorType;
+import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.YangConstants;
+import org.opendaylight.yangtools.yang.common.YangNames;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 
 /**
  * Retrieval of the YANG modules which server supports.
  */
 @Path("/")
 public class RestconfSchemaServiceImpl {
+    // FIXME: Remove this constant. All logic relying on this constant should instead rely on YangInstanceIdentifier
+    //        equivalent coming out of argument parsing. This may require keeping List<YangInstanceIdentifier> as the
+    //        nested path split on yang-ext:mount. This splitting needs to be based on consulting the
+    //        EffectiveModelContext and allowing it only where yang-ext:mount is actually used in models.
+    private static final String MOUNT = "yang-ext:mount";
+    private static final Splitter SLASH_SPLITTER = Splitter.on('/');
+
     private final DOMSchemaService schemaService;
     private final DOMMountPointService mountPointService;
     private final DOMYangTextSourceProvider sourceProvider;
@@ -54,7 +78,125 @@ public class RestconfSchemaServiceImpl {
     @Produces({ YangConstants.RFC6020_YIN_MEDIA_TYPE, YangConstants.RFC6020_YANG_MEDIA_TYPE })
     @Path("modules/{identifier:.+}")
     public SchemaExportContext getSchema(@PathParam("identifier") final String identifier) {
-        return ParserIdentifier.toSchemaExportContextFromIdentifier(schemaService.getGlobalContext(), identifier,
-            mountPointService, sourceProvider);
+        return toSchemaExportContextFromIdentifier(schemaService.getGlobalContext(), identifier, mountPointService,
+            sourceProvider);
+    }
+
+    /**
+     * Parsing {@link Module} module by {@link String} module name and
+     * {@link Date} revision and from the parsed module create
+     * {@link SchemaExportContext}.
+     *
+     * @param schemaContext
+     *             {@link EffectiveModelContext}
+     * @param identifier
+     *             path parameter
+     * @param domMountPointService
+     *             {@link DOMMountPointService}
+     * @return {@link SchemaExportContext}
+     */
+    @VisibleForTesting
+    static SchemaExportContext toSchemaExportContextFromIdentifier(final EffectiveModelContext schemaContext,
+            final String identifier, final DOMMountPointService domMountPointService,
+            final DOMYangTextSourceProvider sourceProvider) {
+        final var pathComponents = SLASH_SPLITTER.split(identifier);
+        final var componentIter = pathComponents.iterator();
+        if (!Iterables.contains(pathComponents, MOUNT)) {
+            final var module = coerceModule(schemaContext, validateAndGetModulName(componentIter),
+                validateAndGetRevision(componentIter), null);
+            return new SchemaExportContext(schemaContext, module, sourceProvider);
+        }
+
+        final var pathBuilder = new StringBuilder();
+        while (componentIter.hasNext()) {
+            final var current = componentIter.next();
+            if (MOUNT.equals(current)) {
+                pathBuilder.append('/').append(MOUNT);
+                break;
+            }
+
+            if (!pathBuilder.isEmpty()) {
+                pathBuilder.append('/');
+            }
+            pathBuilder.append(current);
+        }
+        final var point = ParserIdentifier.toInstanceIdentifier(pathBuilder.toString(), schemaContext,
+                requireNonNull(domMountPointService));
+        final var context = coerceModelContext(point.getMountPoint());
+        final var module = coerceModule(context, validateAndGetModulName(componentIter),
+            validateAndGetRevision(componentIter), point.getMountPoint());
+        return new SchemaExportContext(context, module, sourceProvider);
+    }
+
+
+    /**
+     * Validation and parsing of revision.
+     *
+     * @param revisionDate iterator
+     * @return A Revision
+     */
+    @VisibleForTesting
+    static Revision validateAndGetRevision(final Iterator<String> revisionDate) {
+        if (!revisionDate.hasNext()) {
+            throw new RestconfDocumentedException("Revision date must be supplied.",
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+        try {
+            return Revision.of(revisionDate.next());
+        } catch (final DateTimeParseException e) {
+            throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e);
+        }
+    }
+
+    /**
+     * Validation of name.
+     *
+     * @param moduleName iterator
+     * @return {@link String}
+     */
+    @VisibleForTesting
+    static String validateAndGetModulName(final Iterator<String> moduleName) {
+        if (!moduleName.hasNext()) {
+            throw new RestconfDocumentedException("Module name must be supplied.",
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+
+        final var name = moduleName.next();
+        if (name.isEmpty() || !YangNames.IDENTIFIER_START.matches(name.charAt(0))) {
+            throw new RestconfDocumentedException("Identifier must start with character from set 'a-zA-Z_",
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+        if (name.toUpperCase(Locale.ROOT).startsWith("XML")) {
+            throw new RestconfDocumentedException("Identifier must NOT start with XML ignore case.",
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+        if (YangNames.NOT_IDENTIFIER_PART.matchesAnyOf(name.substring(1))) {
+            throw new RestconfDocumentedException("Supplied name has not expected identifier format.",
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+        }
+        return name;
+    }
+
+    private static ModuleEffectiveStatement coerceModule(final EffectiveModelContext context, final String moduleName,
+            final Revision revision, final DOMMountPoint mountPoint) {
+        return context.findModule(moduleName, revision)
+            .map(Module::asEffectiveStatement)
+            .orElseThrow(() -> {
+                final var msg = "Module %s %s cannot be found on %s.".formatted(moduleName, revision,
+                    mountPoint == null ? "controller" : mountPoint.getIdentifier());
+                return new RestconfDocumentedException(msg, ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
+            });
+    }
+
+    private static EffectiveModelContext coerceModelContext(final DOMMountPoint mountPoint) {
+        final EffectiveModelContext context = modelContext(mountPoint);
+        checkState(context != null, "Mount point %s does not have a model context", mountPoint);
+        return context;
+    }
+
+    private static EffectiveModelContext modelContext(final DOMMountPoint mountPoint) {
+        return mountPoint.getService(DOMSchemaService.class)
+            .map(DOMSchemaService::getGlobalContext)
+            .orElse(null);
     }
 }
index 16b727e02106e1067840a2494ff07ff2a667166a..b471d863fc68897f4187d2a6e83ec5cc2b5238e4 100644 (file)
@@ -7,46 +7,22 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.utils.parser;
 
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
 import java.text.ParseException;
-import java.time.format.DateTimeParseException;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Locale;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.restconf.api.ApiPath;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.nb.rfc8040.legacy.InstanceIdentifierContext;
-import org.opendaylight.restconf.nb.rfc8040.legacy.SchemaExportContext;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.YangNames;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 
 /**
  * Util class for parsing identifier.
  */
 public final class ParserIdentifier {
-    // FIXME: Remove this constant. All logic relying on this constant should instead rely on YangInstanceIdentifier
-    //        equivalent coming out of argument parsing. This may require keeping List<YangInstanceIdentifier> as the
-    //        nested path split on yang-ext:mount. This splitting needs to be based on consulting the
-    //        EffectiveModelContext and allowing it only where yang-ext:mount is actually used in models.
-    private static final String MOUNT = "yang-ext:mount";
-    private static final Splitter SLASH_SPLITTER = Splitter.on('/');
-
     private ParserIdentifier() {
         // Hidden on purpose
     }
@@ -78,120 +54,4 @@ public final class ParserIdentifier {
 
         return InstanceIdentifierContext.ofApiPath(apiPath, schemaContext, mountPointService);
     }
-
-    /**
-     * Parsing {@link Module} module by {@link String} module name and
-     * {@link Date} revision and from the parsed module create
-     * {@link SchemaExportContext}.
-     *
-     * @param schemaContext
-     *             {@link EffectiveModelContext}
-     * @param identifier
-     *             path parameter
-     * @param domMountPointService
-     *             {@link DOMMountPointService}
-     * @return {@link SchemaExportContext}
-     */
-    public static SchemaExportContext toSchemaExportContextFromIdentifier(final EffectiveModelContext schemaContext,
-            final String identifier, final DOMMountPointService domMountPointService,
-            final DOMYangTextSourceProvider sourceProvider) {
-        final var pathComponents = SLASH_SPLITTER.split(identifier);
-        final var componentIter = pathComponents.iterator();
-        if (!Iterables.contains(pathComponents, MOUNT)) {
-            final var module = coerceModule(schemaContext, validateAndGetModulName(componentIter),
-                validateAndGetRevision(componentIter), null);
-            return new SchemaExportContext(schemaContext, module, sourceProvider);
-        }
-
-        final var pathBuilder = new StringBuilder();
-        while (componentIter.hasNext()) {
-            final var current = componentIter.next();
-            if (MOUNT.equals(current)) {
-                pathBuilder.append('/').append(MOUNT);
-                break;
-            }
-
-            if (!pathBuilder.isEmpty()) {
-                pathBuilder.append('/');
-            }
-            pathBuilder.append(current);
-        }
-        final var point = toInstanceIdentifier(pathBuilder.toString(), schemaContext,
-                requireNonNull(domMountPointService));
-        final var context = coerceModelContext(point.getMountPoint());
-        final var module = coerceModule(context, validateAndGetModulName(componentIter),
-            validateAndGetRevision(componentIter), point.getMountPoint());
-        return new SchemaExportContext(context, module, sourceProvider);
-    }
-
-    /**
-     * Validation and parsing of revision.
-     *
-     * @param revisionDate iterator
-     * @return A Revision
-     */
-    @VisibleForTesting
-    static Revision validateAndGetRevision(final Iterator<String> revisionDate) {
-        if (!revisionDate.hasNext()) {
-            throw new RestconfDocumentedException("Revision date must be supplied.",
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
-        }
-        try {
-            return Revision.of(revisionDate.next());
-        } catch (final DateTimeParseException e) {
-            throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e);
-        }
-    }
-
-    /**
-     * Validation of name.
-     *
-     * @param moduleName iterator
-     * @return {@link String}
-     */
-    @VisibleForTesting
-    static String validateAndGetModulName(final Iterator<String> moduleName) {
-        if (!moduleName.hasNext()) {
-            throw new RestconfDocumentedException("Module name must be supplied.",
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
-        }
-
-        final var name = moduleName.next();
-        if (name.isEmpty() || !YangNames.IDENTIFIER_START.matches(name.charAt(0))) {
-            throw new RestconfDocumentedException("Identifier must start with character from set 'a-zA-Z_",
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
-        }
-        if (name.toUpperCase(Locale.ROOT).startsWith("XML")) {
-            throw new RestconfDocumentedException("Identifier must NOT start with XML ignore case.",
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
-        }
-        if (YangNames.NOT_IDENTIFIER_PART.matchesAnyOf(name.substring(1))) {
-            throw new RestconfDocumentedException("Supplied name has not expected identifier format.",
-                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
-        }
-        return name;
-    }
-
-    private static ModuleEffectiveStatement coerceModule(final EffectiveModelContext context, final String moduleName,
-            final Revision revision, final DOMMountPoint mountPoint) {
-        return context.findModule(moduleName, revision)
-            .map(Module::asEffectiveStatement)
-            .orElseThrow(() -> {
-                final var msg = "Module %s %s cannot be found on %s.".formatted(moduleName, revision,
-                    mountPoint == null ? "controller" : mountPoint.getIdentifier());
-                return new RestconfDocumentedException(msg, ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
-            });
-    }
-
-    private static EffectiveModelContext coerceModelContext(final DOMMountPoint mountPoint) {
-        final EffectiveModelContext context = modelContext(mountPoint);
-        checkState(context != null, "Mount point %s does not have a model context", mountPoint);
-        return context;
-    }
-
-    private static EffectiveModelContext modelContext(final DOMMountPoint mountPoint) {
-        return mountPoint.getService(DOMSchemaService.class)
-            .map(DOMSchemaService::getGlobalContext)
-            .orElse(null);
-    }
 }
diff --git a/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfModulesGetTest.java b/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfModulesGetTest.java
new file mode 100644 (file)
index 0000000..27e8fec
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o.
+ *
+ * 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.restconf.nb.rfc8040.rests.services.impl;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.doReturn;
+
+import java.util.Optional;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.opendaylight.mdsal.dom.api.DOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
+import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.common.ErrorType;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+@ExtendWith(MockitoExtension.class)
+class RestconfModulesGetTest {
+    private static final EffectiveModelContext MODEL_CONTEXT =
+        YangParserTestUtils.parseYangResourceDirectory("/parser-identifier");
+    private static final EffectiveModelContext MODEL_CONTEXT_ON_MOUNT_POINT =
+        YangParserTestUtils.parseYangResourceDirectory("/parser-identifier");
+    private static final String TEST_MODULE_NAME = "test-module";
+    private static final String TEST_MODULE_REVISION = "2016-06-02";
+    private static final String TEST_MODULE_NAMESPACE = "test:module";
+    private static final String MOUNT_POINT_IDENT = "mount-point:mount-container/point-number/yang-ext:mount";
+    private static final YangInstanceIdentifier MOUNT_IID = YangInstanceIdentifier.of(
+        QName.create("mount:point", "2016-06-02", "mount-container"),
+        QName.create("mount:point", "2016-06-02", "point-number"));
+
+    @Mock
+    private DOMYangTextSourceProvider sourceProvider;
+    @Mock
+    private DOMMountPoint mountPoint;
+    @Mock
+    private DOMMountPointService mountPointService;
+
+    /**
+     * Positive test of getting <code>SchemaExportContext</code>. Expected module name, revision and namespace are
+     * verified.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierTest() {
+        final var exportContext = RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(
+                MODEL_CONTEXT, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider);
+        assertNotNull(exportContext);
+
+        final var module = exportContext.module();
+        assertNotNull(module);
+        assertEquals(TEST_MODULE_NAME, module.argument().getLocalName());
+        final var namespace = module.localQNameModule();
+        assertEquals(Revision.ofNullable(TEST_MODULE_REVISION), namespace.getRevision());
+        assertEquals(TEST_MODULE_NAMESPACE, namespace.getNamespace().toString());
+    }
+
+    /**
+     * Test of getting <code>SchemaExportContext</code> when desired module is not found.
+     * <code>SchemaExportContext</code> should not be created and exception is thrown.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierNotFoundTest() {
+        final var ex = assertThrows(RestconfDocumentedException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(
+                MODEL_CONTEXT, "not-existing-module" + "/" + "2016-01-01", null, sourceProvider));
+        final var errors = ex.getErrors();
+        assertEquals(1, errors.size());
+        final var error = errors.get(0);
+        assertEquals("Module not-existing-module 2016-01-01 cannot be found on controller.", error.getErrorMessage());
+        assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
+        assertEquals(ErrorType.APPLICATION, error.getErrorType());
+    }
+
+    /**
+     * Negative test trying to get <code>SchemaExportContext</code> with invalid identifier. Test is expected to fail
+     * with <code>RestconfDocumentedException</code> error type, error tag and error status code are compared to
+     * expected values.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierInvalidIdentifierNegativeTest() {
+        final var ex = assertThrows(RestconfDocumentedException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
+                TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null, sourceProvider));
+        final var errors = ex.getErrors();
+        assertEquals(1, errors.size());
+        final var error = errors.get(0);
+        assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
+        assertEquals(ErrorType.PROTOCOL, error.getErrorType());
+        assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
+    }
+
+    /**
+     * Positive test of getting <code>SchemaExportContext</code> for module behind mount point.
+     * Expected module name, revision and namespace are verified.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierMountPointTest() {
+        mockMountPoint();
+
+        final var exportContext = RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
+            MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
+            mountPointService, sourceProvider);
+
+        final var module = exportContext.module();
+        assertEquals(TEST_MODULE_NAME, module.argument().getLocalName());
+        final var namespace = module.localQNameModule();
+        assertEquals(Revision.ofNullable(TEST_MODULE_REVISION), namespace.getRevision());
+        assertEquals(TEST_MODULE_NAMESPACE, namespace.getNamespace().toString());
+    }
+
+    /**
+     * Negative test of getting <code>SchemaExportContext</code> when desired module is not found behind mount point.
+     * <code>SchemaExportContext</code> should not be created and exception is thrown.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierMountPointNotFoundTest() {
+        mockMountPoint();
+        doReturn(MOUNT_IID).when(mountPoint).getIdentifier();
+
+        final var ex = assertThrows(RestconfDocumentedException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
+                MOUNT_POINT_IDENT + "/" + "not-existing-module" + "/" + "2016-01-01",
+                mountPointService, sourceProvider));
+        final var errors = ex.getErrors();
+        assertEquals(1, errors.size());
+        final var error = errors.get(0);
+        assertEquals("Module not-existing-module 2016-01-01 cannot be found on "
+            + "/(mount:point?revision=2016-06-02)mount-container/point-number.", error.getErrorMessage());
+        assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
+        assertEquals(ErrorType.APPLICATION, error.getErrorType());
+    }
+
+    /**
+     * Negative test trying to get <code>SchemaExportContext</code> behind mount point with invalid identifier. Test is
+     * expected to fail with <code>RestconfDocumentedException</code> error type, error tag and error status code are
+     * compared to expected values.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierMountPointInvalidIdentifierNegativeTest() {
+        mockMountPoint();
+
+        final var ex = assertThrows(RestconfDocumentedException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
+                MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, mountPointService,
+                sourceProvider));
+        final var errors = ex.getErrors();
+        assertEquals(1, errors.size());
+        final var error = errors.get(0);
+        assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
+        assertEquals(ErrorType.PROTOCOL, error.getErrorType());
+        assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
+    }
+
+    /**
+     * Negative test of getting <code>SchemaExportContext</code> when supplied identifier is null.
+     * <code>NullPointerException</code> is expected. <code>DOMMountPointService</code> is not used.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierNullIdentifierNegativeTest() {
+        assertThrows(NullPointerException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(MODEL_CONTEXT, null, null,
+                sourceProvider));
+    }
+
+    /**
+     * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
+     * <code>null</code>. Test is expected to fail with <code>NullPointerException</code>.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierNullSchemaContextNegativeTest() {
+        assertThrows(NullPointerException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(null,
+                TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider));
+    }
+
+    /**
+     * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
+     * <code>null</code> and identifier specifies module behind mount point. Test is expected to fail with
+     * <code>NullPointerException</code>.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierMountPointNullSchemaContextNegativeTest() {
+        assertThrows(NullPointerException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(null,
+                MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, mountPointService,
+                sourceProvider));
+    }
+
+    /**
+     * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>DOMMountPointService</code>
+     * is <code>null</code> and identifier defines module behind mount point. Test is expected to fail with
+     * <code>NullPointerException</code>.
+     */
+    @Test
+    void toSchemaExportContextFromIdentifierNullMountPointServiceNegativeTest() {
+        assertThrows(NullPointerException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(
+                MODEL_CONTEXT, MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null,
+                sourceProvider));
+    }
+
+    @Test
+    void toSchemaExportContextFromIdentifierNullSchemaContextBehindMountPointNegativeTest() {
+        final var ex = assertThrows(RestconfDocumentedException.class,
+            () -> RestconfSchemaServiceImpl.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
+                "/yang-ext:mount/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, mountPointService,
+                sourceProvider));
+        final var errors = ex.getErrors();
+        assertEquals(1, errors.size());
+        final var error = errors.get(0);
+        // FIXME: this should be something different
+        assertEquals("Identifier may not be empty", error.getErrorMessage());
+        assertEquals(ErrorType.PROTOCOL, error.getErrorType());
+        assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
+    }
+
+    private void mockMountPoint() {
+        doReturn(Optional.of(FixedDOMSchemaService.of(MODEL_CONTEXT_ON_MOUNT_POINT))).when(mountPoint)
+            .getService(DOMSchemaService.class);
+        doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(MOUNT_IID);
+    }
+}
@@ -5,7 +5,7 @@
  * 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.restconf.nb.rfc8040.utils.parser;
+package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.function.Executable;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
+import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.Revision;
@@ -33,7 +34,7 @@ class RestconfValidationTest {
      */
     @Test
     void validateAndGetRevisionTest() {
-        assertEquals(Revision.of("2014-01-01"), ParserIdentifier.validateAndGetRevision(REVISIONS.iterator()));
+        assertEquals(Revision.of("2014-01-01"), RestconfSchemaServiceImpl.validateAndGetRevision(REVISIONS.iterator()));
     }
 
     /**
@@ -43,7 +44,7 @@ class RestconfValidationTest {
     @Test
     void validateAndGetRevisionNotSuppliedTest() {
         final var error = assertInvalidValue(
-            () -> ParserIdentifier.validateAndGetRevision(Collections.emptyIterator()));
+            () -> RestconfSchemaServiceImpl.validateAndGetRevision(Collections.emptyIterator()));
         assertEquals("Revision date must be supplied.", error.getErrorMessage());
     }
 
@@ -54,7 +55,8 @@ class RestconfValidationTest {
     @Test
     void validateAndGetRevisionNotParsableTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> ParserIdentifier.validateAndGetRevision(Iterators.singletonIterator("not-parsable-as-date")));
+            () -> RestconfSchemaServiceImpl.validateAndGetRevision(Iterators.singletonIterator(
+                "not-parsable-as-date")));
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         final var error = errors.get(0);
@@ -68,7 +70,7 @@ class RestconfValidationTest {
      */
     @Test
     void validateAndGetModulNameTest() {
-        assertEquals("_module-1", ParserIdentifier.validateAndGetModulName(NAMES.iterator()));
+        assertEquals("_module-1", RestconfSchemaServiceImpl.validateAndGetModulName(NAMES.iterator()));
     }
 
     /**
@@ -78,7 +80,7 @@ class RestconfValidationTest {
     @Test
     void validateAndGetModulNameNotSuppliedTest() {
         final var error = assertInvalidValue(
-            () -> ParserIdentifier.validateAndGetModulName(Collections.emptyIterator()));
+            () -> RestconfSchemaServiceImpl.validateAndGetModulName(Collections.emptyIterator()));
         assertEquals("Module name must be supplied.", error.getErrorMessage());
     }
 
@@ -90,7 +92,7 @@ class RestconfValidationTest {
     @Test
     void validateAndGetModuleNameNotParsableFirstTest() {
         final var error = assertInvalidValue(
-            () -> ParserIdentifier.validateAndGetModulName(Iterators.singletonIterator(
+            () -> RestconfSchemaServiceImpl.validateAndGetModulName(Iterators.singletonIterator(
                 "01-not-parsable-as-name-on-firts-char")));
         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
     }
@@ -102,8 +104,9 @@ class RestconfValidationTest {
      */
     @Test
     public void validateAndGetModuleNameNotParsableNextTest() {
-        final var error = assertInvalidValue(() -> ParserIdentifier.validateAndGetModulName(Iterators.singletonIterator(
-            "not-parsable-as-name-after-first-char*")));
+        final var error = assertInvalidValue(
+            () -> RestconfSchemaServiceImpl.validateAndGetModulName(Iterators.singletonIterator(
+                "not-parsable-as-name-after-first-char*")));
         assertEquals("Supplied name has not expected identifier format.", error.getErrorMessage());
     }
 
@@ -114,7 +117,7 @@ class RestconfValidationTest {
     @Test
     void validateAndGetModuleNameNotParsableXmlTest() {
         final var error = assertInvalidValue(
-            () -> ParserIdentifier.validateAndGetModulName(Iterators.singletonIterator("xMl-module-name")));
+            () -> RestconfSchemaServiceImpl.validateAndGetModulName(Iterators.singletonIterator("xMl-module-name")));
         assertEquals("Identifier must NOT start with XML ignore case.", error.getErrorMessage());
     }
 
@@ -125,7 +128,7 @@ class RestconfValidationTest {
     @Test
     void validateAndGetModuleNameEmptyTest() {
         final var error = assertInvalidValue(
-            () -> ParserIdentifier.validateAndGetModulName(Iterators.singletonIterator("")));
+            () -> RestconfSchemaServiceImpl.validateAndGetModulName(Iterators.singletonIterator("")));
         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
     }
 
index 4319ec754cc2edf52512edf747472f298092f922..d5de088f93dee5f89aa2d615987381daf06565ca 100644 (file)
@@ -7,21 +7,16 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.utils.parser;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThrows;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
 import org.opendaylight.restconf.api.ApiPath;
@@ -30,7 +25,6 @@ import org.opendaylight.restconf.nb.rfc8040.legacy.ErrorTags;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
@@ -38,14 +32,10 @@ import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 /**
  * Unit tests for {@link ParserIdentifier}.
  */
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class ParserIdentifierTest {
     // mount point identifier
     private static final String MOUNT_POINT_IDENT = "mount-point:mount-container/point-number/yang-ext:mount";
 
-    // invalid mount point identifier
-    private static final String INVALID_MOUNT_POINT_IDENT = "mount-point:point-number/yang-ext:mount";
-
     // test identifier + expected result
     private static final String TEST_IDENT =
             "parser-identifier:cont1/cont2/listTest/list-in-grouping=name/leaf-A.B";
@@ -68,10 +58,6 @@ public class ParserIdentifierTest {
     private static final String INVALID_TEST_IDENT =
             "parser-identifier:cont2/listTest/list-in-grouping=name/leaf-A.B";
 
-    private static final String TEST_MODULE_NAME = "test-module";
-    private static final String TEST_MODULE_REVISION = "2016-06-02";
-    private static final String TEST_MODULE_NAMESPACE = "test:module";
-
     private static final String INVOKE_RPC = "invoke-rpc-module:rpc-test";
     private static final String INVOKE_ACTION = "example-actions:interfaces/interface=eth0/reset";
 
@@ -87,28 +73,17 @@ public class ParserIdentifierTest {
     private final DOMMountPointService mountPointService = new DOMMountPointServiceImpl();
     private DOMMountPoint mountPoint;
 
-    // mock mount point and mount point service
-    @Mock
-    private DOMMountPoint mockMountPoint;
-    @Mock
-    private DOMMountPointService mockMountPointService;
-    @Mock
-    private DOMSchemaService domSchemaService;
-    @Mock
-    private DOMYangTextSourceProvider sourceProvider;
-
-    @Before
-    public void setup() throws Exception {
+    @BeforeEach
+    void beforeEach() {
         // create and register mount point
-        final var mountPointId = YangInstanceIdentifier.builder()
-                .node(QName.create("mount:point", "2016-06-02", "mount-container"))
-                .node(QName.create("mount:point", "2016-06-02", "point-number"))
-                .build();
+        final var mountPointId = YangInstanceIdentifier.of(
+            QName.create("mount:point", "2016-06-02", "mount-container"),
+            QName.create("mount:point", "2016-06-02", "point-number"));
 
         mountPoint = mountPointService.createMountPoint(mountPointId)
-                .addService(DOMSchemaService.class, FixedDOMSchemaService.of(MODEL_CONTEXT_ON_MOUNT_POINT))
-                .register()
-                .getInstance();
+            .addService(DOMSchemaService.class, FixedDOMSchemaService.of(MODEL_CONTEXT_ON_MOUNT_POINT))
+            .register()
+            .getInstance();
     }
 
     /**
@@ -120,7 +95,7 @@ public class ParserIdentifierTest {
      * in one module.
      */
     @Test
-    public void toInstanceIdentifierTest() {
+    void toInstanceIdentifierTest() {
         final var context = ParserIdentifier.toInstanceIdentifier(TEST_IDENT, MODEL_CONTEXT, null);
         assertEquals(TEST_IDENT_RESULT, context.getInstanceIdentifier().toString());
     }
@@ -130,7 +105,7 @@ public class ParserIdentifierTest {
      * multiple modules.
      */
     @Test
-    public void toInstanceIdentifierOtherModulesTest() {
+    void toInstanceIdentifierOtherModulesTest() {
         final var context = ParserIdentifier.toInstanceIdentifier(TEST_IDENT_OTHERS, MODEL_CONTEXT, null);
         assertEquals(TEST_IDENT_OTHERS_RESULT, context.getInstanceIdentifier().toString());
     }
@@ -139,7 +114,7 @@ public class ParserIdentifierTest {
      * Positive test of creating {@code InstanceIdentifierContext} from identifier containing {@code yang-ext:mount}.
      */
     @Test
-    public void toInstanceIdentifierMountPointTest() {
+    void toInstanceIdentifierMountPointTest() {
         final var context = ParserIdentifier.toInstanceIdentifier(MOUNT_POINT_IDENT + "/" + TEST_IDENT, MODEL_CONTEXT,
             mountPointService);
         assertEquals(TEST_IDENT_RESULT.toString(), context.getInstanceIdentifier().toString());
@@ -152,7 +127,7 @@ public class ParserIdentifierTest {
      * <code>null</code>. Test fails expecting <code>NullPointerException</code>.
      */
     @Test
-    public void toInstanceIdentifierNullSchemaContextNegativeTest() {
+    void toInstanceIdentifierNullSchemaContextNegativeTest() {
         assertThrows(NullPointerException.class, () -> ParserIdentifier.toInstanceIdentifier(TEST_IDENT, null, null));
     }
 
@@ -160,7 +135,7 @@ public class ParserIdentifierTest {
      * Api path can be empty. <code>YangInstanceIdentifier.EMPTY</code> is expected to be returned.
      */
     @Test
-    public void toInstanceIdentifierEmptyIdentifierTest() {
+    void toInstanceIdentifierEmptyIdentifierTest() {
         final var context = ParserIdentifier.toInstanceIdentifier("", MODEL_CONTEXT, null);
         assertEquals(YangInstanceIdentifier.of(), context.getInstanceIdentifier());
     }
@@ -169,7 +144,7 @@ public class ParserIdentifierTest {
      * Negative test with invalid test identifier. Test should fail with <code>RestconfDocumentedException</code>.
      */
     @Test
-    public void toInstanceIdentifierInvalidIdentifierNegativeTest() {
+    void toInstanceIdentifierInvalidIdentifierNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
             () -> ParserIdentifier.toInstanceIdentifier(INVALID_TEST_IDENT, MODEL_CONTEXT, null));
         final var errors = ex.getErrors();
@@ -185,9 +160,10 @@ public class ParserIdentifierTest {
      * should fail with {@link RestconfDocumentedException}.
      */
     @Test
-    public void toInstanceIdentifierMountPointInvalidIdentifierNegativeTest() {
+    void toInstanceIdentifierMountPointInvalidIdentifierNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> ParserIdentifier.toInstanceIdentifier(INVALID_MOUNT_POINT_IDENT, MODEL_CONTEXT, mountPointService));
+            () -> ParserIdentifier.toInstanceIdentifier("mount-point:point-number/yang-ext:mount", MODEL_CONTEXT,
+                mountPointService));
         final var errors = ex.getErrors();
         assertEquals(1, errors.size());
         final var error = errors.get(0);
@@ -202,7 +178,7 @@ public class ParserIdentifierTest {
      * compared to expected values.
      */
     @Test
-    public void toInstanceIdentifierMissingMountPointNegativeTest() {
+    void toInstanceIdentifierMissingMountPointNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
             () -> ParserIdentifier.toInstanceIdentifier("yang-ext:mount", MODEL_CONTEXT, mountPointService));
         final var errors = ex.getErrors();
@@ -219,7 +195,7 @@ public class ParserIdentifierTest {
      * compared to expected values.
      */
     @Test
-    public void toInstanceIdentifierMissingMountPointServiceNegativeTest() {
+    void toInstanceIdentifierMissingMountPointServiceNegativeTest() {
         final var ex = assertThrows(RestconfDocumentedException.class,
             () -> ParserIdentifier.toInstanceIdentifier("yang-ext:mount", MODEL_CONTEXT, null));
         final var errors = ex.getErrors();
@@ -230,183 +206,11 @@ public class ParserIdentifierTest {
         assertEquals(ErrorTag.OPERATION_FAILED, error.getErrorTag());
     }
 
-    /**
-     * {@link ParserIdentifier#toSchemaExportContextFromIdentifier(SchemaContext, String, DOMMountPointService)} tests.
-     */
-
-    /**
-     * Positive test of getting <code>SchemaExportContext</code>. Expected module name, revision and namespace are
-     * verified.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierTest() {
-        final var exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
-                MODEL_CONTEXT, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider);
-
-        assertNotNull("Export context should be parsed", exportContext);
-
-        final var module = exportContext.module();
-        assertNotNull(module);
-        assertEquals(TEST_MODULE_NAME, module.argument().getLocalName());
-        final var namespace = module.localQNameModule();
-        assertEquals(Revision.ofNullable(TEST_MODULE_REVISION), namespace.getRevision());
-        assertEquals(TEST_MODULE_NAMESPACE, namespace.getNamespace().toString());
-    }
-
-    /**
-     * Test of getting <code>SchemaExportContext</code> when desired module is not found.
-     * <code>SchemaExportContext</code> should not be created and exception is thrown.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierNotFoundTest() {
-        final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
-                MODEL_CONTEXT, "not-existing-module" + "/" + "2016-01-01", null, sourceProvider));
-        final var errors = ex.getErrors();
-        assertEquals(1, errors.size());
-        final var error = errors.get(0);
-        assertEquals("Module not-existing-module 2016-01-01 cannot be found on controller.", error.getErrorMessage());
-        assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
-        assertEquals(ErrorType.APPLICATION, error.getErrorType());
-    }
-
-    /**
-     * Negative test trying to get <code>SchemaExportContext</code> with invalid identifier. Test is expected to fail
-     * with <code>RestconfDocumentedException</code> error type, error tag and error status code are compared to
-     * expected values.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierInvalidIdentifierNegativeTest() {
-        final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> ParserIdentifier.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
-                TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null, sourceProvider));
-        final var errors = ex.getErrors();
-        assertEquals(1, errors.size());
-        final var error = errors.get(0);
-        assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
-        assertEquals(ErrorType.PROTOCOL, error.getErrorType());
-        assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
-    }
-
-    /**
-     * Positive test of getting <code>SchemaExportContext</code> for module behind mount point.
-     * Expected module name, revision and namespace are verified.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierMountPointTest() {
-        final var exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
-            MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
-            mountPointService, sourceProvider);
-
-        final var module = exportContext.module();
-        assertEquals(TEST_MODULE_NAME, module.argument().getLocalName());
-        final var namespace = module.localQNameModule();
-        assertEquals(Revision.ofNullable(TEST_MODULE_REVISION), namespace.getRevision());
-        assertEquals(TEST_MODULE_NAMESPACE, namespace.getNamespace().toString());
-    }
-
-    /**
-     * Negative test of getting <code>SchemaExportContext</code> when desired module is not found behind mount point.
-     * <code>SchemaExportContext</code> should not be created and exception is thrown.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierMountPointNotFoundTest() {
-        final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> ParserIdentifier.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
-                MOUNT_POINT_IDENT + "/" + "not-existing-module" + "/" + "2016-01-01",
-                mountPointService, sourceProvider));
-        final var errors = ex.getErrors();
-        assertEquals(1, errors.size());
-        final var error = errors.get(0);
-        assertEquals("Module not-existing-module 2016-01-01 cannot be found on "
-            + "/(mount:point?revision=2016-06-02)mount-container/point-number.", error.getErrorMessage());
-        assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
-        assertEquals(ErrorType.APPLICATION, error.getErrorType());
-    }
-
-    /**
-     * Negative test trying to get <code>SchemaExportContext</code> behind mount point with invalid identifier. Test is
-     * expected to fail with <code>RestconfDocumentedException</code> error type, error tag and error status code are
-     * compared to expected values.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierMountPointInvalidIdentifierNegativeTest() {
-        final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> ParserIdentifier.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
-                MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, mountPointService,
-                sourceProvider));
-        final var errors = ex.getErrors();
-        assertEquals(1, errors.size());
-        final var error = errors.get(0);
-        assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
-        assertEquals(ErrorType.PROTOCOL, error.getErrorType());
-        assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
-    }
-
-    /**
-     * Negative test of getting <code>SchemaExportContext</code> when supplied identifier is null.
-     * <code>NullPointerException</code> is expected. <code>DOMMountPointService</code> is not used.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierNullIdentifierNegativeTest() {
-        assertThrows(NullPointerException.class,
-            () -> ParserIdentifier.toSchemaExportContextFromIdentifier(MODEL_CONTEXT, null, null, sourceProvider));
-    }
-
-    /**
-     * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
-     * <code>null</code>. Test is expected to fail with <code>NullPointerException</code>.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierNullSchemaContextNegativeTest() {
-        assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(null,
-            TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider));
-    }
-
-    /**
-     * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
-     * <code>null</code> and identifier specifies module behind mount point. Test is expected to fail with
-     * <code>NullPointerException</code>.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierMountPointNullSchemaContextNegativeTest() {
-        assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(null,
-            MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, mountPointService,
-            sourceProvider));
-    }
-
-    /**
-     * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>DOMMountPointService</code>
-     * is <code>null</code> and identifier defines module behind mount point. Test is expected to fail with
-     * <code>NullPointerException</code>.
-     */
-    @Test
-    public void toSchemaExportContextFromIdentifierNullMountPointServiceNegativeTest() {
-        assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
-            MODEL_CONTEXT, MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null,
-            sourceProvider));
-    }
-
-    @Test
-    public void toSchemaExportContextFromIdentifierNullSchemaContextBehindMountPointNegativeTest() {
-        final var ex = assertThrows(RestconfDocumentedException.class,
-            () -> ParserIdentifier.toSchemaExportContextFromIdentifier(MODEL_CONTEXT,
-                "/yang-ext:mount/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, mockMountPointService,
-                sourceProvider));
-        final var errors = ex.getErrors();
-        assertEquals(1, errors.size());
-        final var error = errors.get(0);
-        // FIXME: this should be something different
-        assertEquals("Identifier may not be empty", error.getErrorMessage());
-        assertEquals(ErrorType.PROTOCOL, error.getErrorType());
-        assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
-    }
-
     /**
      * Test invoke RPC. Verify if RPC schema node was found.
      */
     @Test
-    public void invokeRpcTest() throws Exception {
+    void invokeRpcTest() throws Exception {
         final var result = ParserIdentifier.toInstanceIdentifier(INVOKE_RPC, MODEL_CONTEXT, null);
 
         // RPC schema node
@@ -425,7 +229,7 @@ public class ParserIdentifierTest {
      * Test invoke RPC on mount point. Verify if RPC schema node was found.
      */
     @Test
-    public void invokeRpcOnMountPointTest() throws Exception {
+    void invokeRpcOnMountPointTest() throws Exception {
         final var result = ParserIdentifier.toInstanceIdentifier(MOUNT_POINT_IDENT + "/" + INVOKE_RPC, MODEL_CONTEXT,
             mountPointService);
 
@@ -445,7 +249,7 @@ public class ParserIdentifierTest {
      * Test Action. Verify if Action schema node was found.
      */
     @Test
-    public void invokeActionTest() throws Exception {
+    void invokeActionTest() throws Exception {
         final var result = ParserIdentifier.toInstanceIdentifier(INVOKE_ACTION, MODEL_CONTEXT, null);
 
         // Action schema node
@@ -464,7 +268,7 @@ public class ParserIdentifierTest {
      * Test invoke Action on mount point. Verify if Action schema node was found.
      */
     @Test
-    public void invokeActionOnMountPointTest() throws Exception {
+    void invokeActionOnMountPointTest() throws Exception {
         final var result = ParserIdentifier.toInstanceIdentifier(MOUNT_POINT_IDENT + "/" + INVOKE_ACTION,
             MODEL_CONTEXT, mountPointService);