Report HTTP status 409 on DATA_MISSING error
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / utils / parser / ParserIdentifierTest.java
index dd2330800eb12101f35e14459442b7d1e47308a3..0383d53d593ab232da393b663359d830b542f8d2 100644 (file)
@@ -5,28 +5,28 @@
  * 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;
 
 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.fail;
 import static org.mockito.Mockito.when;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.collect.Maps;
+import java.util.Map.Entry;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
-import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoint;
+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.restconf.common.context.InstanceIdentifierContext;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
@@ -36,10 +36,10 @@ import org.opendaylight.restconf.common.schema.SchemaExportContext;
 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
 import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+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.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
 /**
@@ -78,15 +78,16 @@ public class ParserIdentifierTest {
             "parser-identifier:cont2/listTest/list-in-grouping=name/leaf-A.B";
 
     // schema context with test modules
-    private SchemaContext schemaContext;
+    private EffectiveModelContext schemaContext;
     // contains the same modules but it is different object (it can be compared with equals)
-    private SchemaContext schemaContextOnMountPoint;
+    private EffectiveModelContext schemaContextOnMountPoint;
 
     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";
 
     // mount point and mount point service
     private DOMMountPoint mountPoint;
@@ -97,6 +98,10 @@ public class ParserIdentifierTest {
     private DOMMountPoint mockMountPoint;
     @Mock
     private DOMMountPointService mockMountPointService;
+    @Mock
+    private DOMSchemaService domSchemaService;
+    @Mock
+    private DOMYangTextSourceProvider sourceProvider;
 
     @Rule
     public final ExpectedException thrown = ExpectedException.none();
@@ -104,26 +109,26 @@ public class ParserIdentifierTest {
     @Before
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
-        this.schemaContext = YangParserTestUtils.parseYangSources(TestRestconfUtils.loadFiles("/parser-identifier"));
+        this.schemaContext = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/parser-identifier"));
         this.schemaContextOnMountPoint =
-                YangParserTestUtils.parseYangSources(TestRestconfUtils.loadFiles("/parser-identifier"));
+                YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/parser-identifier"));
+
+        this.mountPointService = new DOMMountPointServiceImpl();
 
         // create and register mount point
-        this.mountPoint = SimpleDOMMountPoint.create(
-                YangInstanceIdentifier.builder()
-                        .node(QName.create("mount:point", "2016-06-02", "mount-container"))
-                        .node(QName.create("mount:point", "2016-06-02", "point-number"))
-                        .build(),
-                ImmutableClassToInstanceMap.copyOf(Maps.newHashMap()),
-                this.schemaContextOnMountPoint
-        );
+        final YangInstanceIdentifier mountPointId = YangInstanceIdentifier.builder()
+                .node(QName.create("mount:point", "2016-06-02", "mount-container"))
+                .node(QName.create("mount:point", "2016-06-02", "point-number"))
+                .build();
 
-        this.mountPointService = new DOMMountPointServiceImpl();
-        ((DOMMountPointServiceImpl) this.mountPointService).registerMountPoint(this.mountPoint);
+        mountPoint = mountPointService.createMountPoint(mountPointId)
+                .addInitialSchemaContext(this.schemaContextOnMountPoint)
+                .register()
+                .getInstance();
 
         // register mount point with null schema context
-        when(this.mockMountPoint.getSchemaContext()).thenReturn(null);
-        when(this.mockMountPointService.getMountPoint(YangInstanceIdentifier.EMPTY))
+        when(this.mockMountPoint.getEffectiveModelContext()).thenReturn(null);
+        when(this.mockMountPointService.getMountPoint(YangInstanceIdentifier.empty()))
                 .thenReturn(Optional.of(this.mockMountPoint));
     }
 
@@ -138,7 +143,7 @@ public class ParserIdentifierTest {
     @Test
     public void toInstanceIdentifierTest() {
         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
-                TEST_IDENT, this.schemaContext, Optional.absent());
+                TEST_IDENT, this.schemaContext, Optional.empty());
 
         assertEquals("Returned not expected identifier",
                 TEST_IDENT_RESULT, context .getInstanceIdentifier().toString());
@@ -151,7 +156,7 @@ public class ParserIdentifierTest {
     @Test
     public void toInstanceIdentifierOtherModulesTest() {
         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
-                TEST_IDENT_OTHERS, this.schemaContext, Optional.absent());
+                TEST_IDENT_OTHERS, this.schemaContext, Optional.empty());
 
         assertEquals("Returned not expected identifier",
                 TEST_IDENT_OTHERS_RESULT, context.getInstanceIdentifier().toString());
@@ -183,9 +188,9 @@ public class ParserIdentifierTest {
     @Test
     public void toInstanceIdentifierNullIdentifierTest() {
         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
-                null, this.schemaContext, Optional.absent());
+                null, this.schemaContext, Optional.empty());
         assertEquals("Returned not expected identifier",
-                YangInstanceIdentifier.EMPTY, context.getInstanceIdentifier());
+                YangInstanceIdentifier.empty(), context.getInstanceIdentifier());
     }
 
     /**
@@ -195,7 +200,7 @@ public class ParserIdentifierTest {
     @Test
     public void toInstanceIdentifierNullSchemaContextNegativeTest() {
         this.thrown.expect(NullPointerException.class);
-        ParserIdentifier.toInstanceIdentifier(TEST_IDENT, null, Optional.absent());
+        ParserIdentifier.toInstanceIdentifier(TEST_IDENT, null, Optional.empty());
     }
 
     /**
@@ -204,27 +209,27 @@ public class ParserIdentifierTest {
     @Test
     public void toInstanceIdentifierEmptyIdentifierTest() {
         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
-                "", this.schemaContext, Optional.absent());
+                "", this.schemaContext, Optional.empty());
         assertEquals("Returned not expected identifier",
-                YangInstanceIdentifier.EMPTY, context.getInstanceIdentifier());
+                YangInstanceIdentifier.empty(), context.getInstanceIdentifier());
     }
 
     /**
-     * Negative test with invalid test identifier. Test should fail with <code>IllegalArgumentException</code>.
+     * Negative test with invalid test identifier. Test should fail with <code>RestconfDocumentedException</code>.
      */
     @Test
     public void toInstanceIdentifierInvalidIdentifierNegativeTest() {
-        this.thrown.expect(IllegalArgumentException.class);
-        ParserIdentifier.toInstanceIdentifier(INVALID_TEST_IDENT, this.schemaContext, Optional.absent());
+        this.thrown.expect(RestconfDocumentedException.class);
+        ParserIdentifier.toInstanceIdentifier(INVALID_TEST_IDENT, this.schemaContext, Optional.empty());
     }
 
     /**
      * Negative test when identifier contains {@link RestconfConstants#MOUNT} but identifier part is not valid. Test
-     * should fail with <code>IllegalArgumentException</code>.
+     * should fail with <code>RestconfDocumentedException</code>.
      */
     @Test
     public void toInstanceIdentifierMountPointInvalidIdentifierNegativeTest() {
-        this.thrown.expect(IllegalArgumentException.class);
+        this.thrown.expect(RestconfDocumentedException.class);
         ParserIdentifier.toInstanceIdentifier(
                 INVALID_MOUNT_POINT_IDENT, this.schemaContext, Optional.of(this.mountPointService));
     }
@@ -245,8 +250,6 @@ public class ParserIdentifierTest {
                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
             assertEquals("Not expected error tag",
                     ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
-            assertEquals("Not expected error status code",
-                    404, e.getErrors().get(0).getErrorTag().getStatusCode());
         }
     }
 
@@ -258,7 +261,7 @@ public class ParserIdentifierTest {
     @Test
     public void toInstanceIdentifierMissingMountPointServiceNegativeTest() {
         try {
-            ParserIdentifier.toInstanceIdentifier(RestconfConstants.MOUNT, this.schemaContext, Optional.absent());
+            ParserIdentifier.toInstanceIdentifier(RestconfConstants.MOUNT, this.schemaContext, Optional.empty());
             fail("Test should fail due to absent mount point service");
         } catch (final RestconfDocumentedException e) {
             assertEquals("Not expected error type",
@@ -280,13 +283,12 @@ public class ParserIdentifierTest {
      */
     @Test
     public void makeQNameFromIdentifierTest() {
-        final QName qName = ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION);
+        final Entry<String, Revision> qName = ParserIdentifier.makeQNameFromIdentifier(
+            TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION);
 
         assertNotNull("QName should be created", qName);
-        assertEquals("Returned not expected module name",
-                TEST_MODULE_NAME, qName.getLocalName());
-        assertEquals("Returned not expected module revision",
-                TEST_MODULE_REVISION, qName.getFormattedRevision());
+        assertEquals("Returned not expected module name", TEST_MODULE_NAME, qName.getKey());
+        assertEquals("Returned not expected module revision", Revision.of(TEST_MODULE_REVISION), qName.getValue());
     }
 
     /**
@@ -335,7 +337,7 @@ public class ParserIdentifierTest {
      */
     @Test
     public void makeQNameFromIdentifierMountTest() {
-        final QName qName = ParserIdentifier.makeQNameFromIdentifier(
+        final Entry<String, Revision> qName = ParserIdentifier.makeQNameFromIdentifier(
                 MOUNT_POINT_IDENT
                 + "/"
                 + TEST_MODULE_NAME
@@ -343,10 +345,8 @@ public class ParserIdentifierTest {
                 + TEST_MODULE_REVISION);
 
         assertNotNull("QName should be created", qName);
-        assertEquals("Returned not expected module name",
-                TEST_MODULE_NAME, qName.getLocalName());
-        assertEquals("Returned not expected module revision",
-                TEST_MODULE_REVISION, qName.getFormattedRevision());
+        assertEquals("Returned not expected module name", TEST_MODULE_NAME, qName.getKey());
+        assertEquals("Returned not expected module revision", Revision.of(TEST_MODULE_REVISION), qName.getValue());
     }
 
     /**
@@ -461,7 +461,7 @@ public class ParserIdentifierTest {
     @Test
     public void toSchemaExportContextFromIdentifierTest() {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
-                this.schemaContext, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null);
+                this.schemaContext, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider);
 
         assertNotNull("Export context should be parsed", exportContext);
 
@@ -471,7 +471,7 @@ public class ParserIdentifierTest {
         assertEquals("Returned not expected module name",
                 TEST_MODULE_NAME, module.getName());
         assertEquals("Returned not expected module revision",
-                TEST_MODULE_REVISION, SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision()));
+                Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
         assertEquals("Returned not expected module namespace",
                 TEST_MODULE_NAMESPACE, module.getNamespace().toString());
     }
@@ -485,7 +485,7 @@ public class ParserIdentifierTest {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
                 this.schemaContext,
                 "not-existing-module" + "/" + "2016-01-01",
-                null);
+                null, sourceProvider);
 
         assertNotNull("Export context should be parsed", exportContext);
         assertNull("Not-existing module should be null", exportContext.getModule());
@@ -500,7 +500,7 @@ public class ParserIdentifierTest {
     public void toSchemaExportContextFromIdentifierInvalidIdentifierNegativeTest() {
         try {
             ParserIdentifier.toSchemaExportContextFromIdentifier(
-                    this.schemaContext, TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null);
+                    this.schemaContext, TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null, sourceProvider);
             fail("Test should fail due to invalid identifier supplied");
         } catch (final RestconfDocumentedException e) {
             assertEquals("Not expected error type",
@@ -521,7 +521,7 @@ public class ParserIdentifierTest {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
                 this.schemaContext,
                 MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
-                this.mountPointService);
+                this.mountPointService, sourceProvider);
 
         final Module module = exportContext.getModule();
         assertNotNull("Export context should contains test module", module);
@@ -529,7 +529,7 @@ public class ParserIdentifierTest {
         assertEquals("Returned not expected module name",
                 TEST_MODULE_NAME, module.getName());
         assertEquals("Returned not expected module revision",
-                TEST_MODULE_REVISION, SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision()));
+                Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
         assertEquals("Returned not expected module namespace",
                 TEST_MODULE_NAMESPACE, module.getNamespace().toString());
     }
@@ -543,7 +543,7 @@ public class ParserIdentifierTest {
         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
                 this.schemaContext,
                 MOUNT_POINT_IDENT + "/" + "not-existing-module" + "/" + "2016-01-01",
-                this.mountPointService);
+                this.mountPointService, sourceProvider);
 
         assertNotNull("Export context should be parsed", exportContext);
         assertNull("Not-existing module should be null", exportContext.getModule());
@@ -560,7 +560,7 @@ public class ParserIdentifierTest {
             ParserIdentifier.toSchemaExportContextFromIdentifier(
                     this.schemaContext,
                     MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME,
-                    this.mountPointService);
+                    this.mountPointService, sourceProvider);
 
             fail("Test should fail due to invalid identifier supplied");
         } catch (final RestconfDocumentedException e) {
@@ -580,7 +580,7 @@ public class ParserIdentifierTest {
     @Test
     public void toSchemaExportContextFromIdentifierNullIdentifierNegativeTest() {
         this.thrown.expect(NullPointerException.class);
-        ParserIdentifier.toSchemaExportContextFromIdentifier(this.schemaContext, null, null);
+        ParserIdentifier.toSchemaExportContextFromIdentifier(this.schemaContext, null, null, sourceProvider);
     }
 
     /**
@@ -590,7 +590,8 @@ public class ParserIdentifierTest {
     @Test
     public void toSchemaExportContextFromIdentifierNullSchemaContextNegativeTest() {
         this.thrown.expect(NullPointerException.class);
-        ParserIdentifier.toSchemaExportContextFromIdentifier(null, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null);
+        ParserIdentifier.toSchemaExportContextFromIdentifier(null, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null,
+                sourceProvider);
     }
 
     /**
@@ -608,7 +609,8 @@ public class ParserIdentifierTest {
                 + TEST_MODULE_NAME
                 + "/"
                 + TEST_MODULE_REVISION,
-                this.mountPointService);
+                this.mountPointService,
+                sourceProvider);
     }
 
     /**
@@ -626,7 +628,8 @@ public class ParserIdentifierTest {
                 + TEST_MODULE_NAME
                 + "/"
                 + TEST_MODULE_REVISION,
-                null);
+                null,
+                sourceProvider);
     }
 
     /**
@@ -644,7 +647,8 @@ public class ParserIdentifierTest {
                 + TEST_MODULE_NAME
                 + "/"
                 + TEST_MODULE_REVISION,
-                this.mockMountPointService);
+                this.mockMountPointService,
+                sourceProvider);
     }
 
     /**
@@ -656,7 +660,7 @@ public class ParserIdentifierTest {
     @Test
     public void invokeRpcTest() {
         final InstanceIdentifierContext<?> result = ParserIdentifier.toInstanceIdentifier(
-                INVOKE_RPC, this.schemaContext, Optional.absent());
+                INVOKE_RPC, this.schemaContext, Optional.empty());
 
         // RPC schema node
         final QName rpcQName = result.getSchemaNode().getQName();
@@ -690,4 +694,45 @@ public class ParserIdentifierTest {
         assertEquals(this.mountPoint, result.getMountPoint());
         assertEquals(this.schemaContextOnMountPoint, result.getSchemaContext());
     }
+
+    /**
+     * Test Action.
+     * Verify if Action schema node was found.
+     */
+    @Test
+    public void invokeActionTest() {
+        final InstanceIdentifierContext<?> result = ParserIdentifier
+            .toInstanceIdentifier(INVOKE_ACTION, this.schemaContext, Optional.empty());
+
+        // Action schema node
+        final QName actionQName = result.getSchemaNode().getQName();
+        assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
+        assertEquals("reset", actionQName.getLocalName());
+
+        // other fields
+        assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, schemaContext), result.getInstanceIdentifier());
+        assertNull(result.getMountPoint());
+        assertSame(this.schemaContext, result.getSchemaContext());
+    }
+
+    /**
+     * Test invoke Action on mount point.
+     * Verify if Action schema node was found.
+     */
+    @Test
+    public void invokeActionOnMountPointTest() {
+        final InstanceIdentifierContext<?> result = ParserIdentifier
+            .toInstanceIdentifier(MOUNT_POINT_IDENT + "/" + INVOKE_ACTION, this.schemaContext,
+                Optional.of(this.mountPointService));
+
+        // Action schema node
+        final QName actionQName = result.getSchemaNode().getQName();
+        assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
+        assertEquals("reset", actionQName.getLocalName());
+
+        // other fields
+        assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, schemaContext), result.getInstanceIdentifier());
+        assertEquals(this.mountPoint, result.getMountPoint());
+        assertEquals(this.schemaContextOnMountPoint, result.getSchemaContext());
+    }
 }