[NO ISSUE][COMP] Prohibit statements in Metadata dataverse

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- The following statements should not be allowed to
  operate on objects in the Metadata dataverse:
- CREATE DATASET, TYPE, SYNONYM, FUNCTION,
  LIBRARY, ADAPTER, FEED, INGESTION POLICY
- DROP DATASET, INDEX, TYPE
- LOAD, UPSERT

Change-Id: Iabb047db64b8f505c72d303036fd61df8ea37e97
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/10145
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
Reviewed-by: Ian Maxon <imaxon@uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
index 8777f66..58bdaca 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
@@ -34,14 +34,26 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionConstants;
+import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
 import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
+import org.apache.asterix.lang.common.statement.CreateFeedStatement;
+import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
+import org.apache.asterix.lang.common.statement.CreateLibraryStatement;
+import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
 import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.DataverseDropStatement;
 import org.apache.asterix.lang.common.statement.DeleteStatement;
 import org.apache.asterix.lang.common.statement.DropDatasetStatement;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.statement.IndexDropStatement;
 import org.apache.asterix.lang.common.statement.InsertStatement;
+import org.apache.asterix.lang.common.statement.LoadStatement;
+import org.apache.asterix.lang.common.statement.TypeDecl;
+import org.apache.asterix.lang.common.statement.TypeDropStatement;
+import org.apache.asterix.lang.common.statement.UpsertStatement;
 import org.apache.asterix.metadata.dataset.hints.DatasetHints;
 import org.apache.asterix.metadata.entities.Dataverse;
 import org.apache.asterix.metadata.utils.MetadataConstants;
@@ -59,6 +71,14 @@
 
     private static final Logger LOGGER = LogManager.getLogger();
 
+    protected static final String INVALID_OPERATION_MESSAGE = "Invalid operation - %s";
+
+    protected static final String BAD_DATAVERSE_DML_MESSAGE = "%s operation is not permitted in dataverse %s";
+
+    protected static final String BAD_DATAVERSE_DDL_MESSAGE = "Cannot %s dataverse: %s";
+
+    protected static final String BAD_DATAVERSE_OBJECT_DDL_MESSAGE = "Cannot %s a %s belonging to the dataverse: %s";
+
     public void validateOperation(ICcApplicationContext appCtx, Dataverse defaultDataverse, Statement stmt)
             throws AlgebricksException {
 
@@ -120,15 +140,36 @@
         String message = null;
         DataverseName dataverseName = defaultDataverse != null ? defaultDataverse.getDataverseName() : null;
         switch (stmt.getKind()) {
+            case LOAD:
+                LoadStatement loadStmt = (LoadStatement) stmt;
+                if (loadStmt.getDataverseName() != null) {
+                    dataverseName = loadStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Load", dataverseName);
+                }
+                break;
+
             case INSERT:
                 InsertStatement insertStmt = (InsertStatement) stmt;
                 if (insertStmt.getDataverseName() != null) {
                     dataverseName = insertStmt.getDataverseName();
                 }
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+                invalidOperation = isMetadataDataverse(dataverseName);
                 if (invalidOperation) {
-                    message = "Insert operation is not permitted in dataverse "
-                            + MetadataConstants.METADATA_DATAVERSE_NAME;
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Insert", dataverseName);
+                }
+                break;
+
+            case UPSERT:
+                UpsertStatement upsertStmt = (UpsertStatement) stmt;
+                if (upsertStmt.getDataverseName() != null) {
+                    dataverseName = upsertStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Upsert", dataverseName);
                 }
                 break;
 
@@ -137,10 +178,9 @@
                 if (deleteStmt.getDataverseName() != null) {
                     dataverseName = deleteStmt.getDataverseName();
                 }
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+                invalidOperation = isMetadataDataverse(dataverseName);
                 if (invalidOperation) {
-                    message = "Delete operation is not permitted in dataverse "
-                            + MetadataConstants.METADATA_DATAVERSE_NAME;
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Delete", dataverseName);
                 }
                 break;
 
@@ -150,57 +190,179 @@
                 invalidOperation = FunctionConstants.ASTERIX_DV.equals(dataverseName)
                         || FunctionConstants.ALGEBRICKS_DV.equals(dataverseName);
                 if (invalidOperation) {
-                    message = "Cannot create dataverse: " + dataverseName;
+                    message = String.format(BAD_DATAVERSE_DDL_MESSAGE, "create", dataverseName);
                 }
                 break;
 
             case DATAVERSE_DROP:
                 DataverseDropStatement dvDropStmt = (DataverseDropStatement) stmt;
                 dataverseName = dvDropStmt.getDataverseName();
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+                invalidOperation = isMetadataDataverse(dataverseName);
                 if (invalidOperation) {
-                    message = "Cannot drop dataverse: " + dataverseName;
-                }
-                break;
-
-            case DATASET_DROP:
-                DropDatasetStatement dropStmt = (DropDatasetStatement) stmt;
-                if (dropStmt.getDataverseName() != null) {
-                    dataverseName = dropStmt.getDataverseName();
-                }
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
-                if (invalidOperation) {
-                    message = "Cannot drop a dataset belonging to the dataverse: "
-                            + MetadataConstants.METADATA_DATAVERSE_NAME;
+                    message = String.format(BAD_DATAVERSE_DDL_MESSAGE, "drop", dataverseName);
                 }
                 break;
 
             case DATASET_DECL:
-                DatasetDecl datasetStmt = (DatasetDecl) stmt;
-                Map<String, String> hints = datasetStmt.getHints();
-                if (hints != null && !hints.isEmpty()) {
-                    StringBuilder errorMsgBuffer = new StringBuilder();
-                    for (Entry<String, String> hint : hints.entrySet()) {
-                        Pair<Boolean, String> validationResult =
-                                DatasetHints.validate(appCtx, hint.getKey(), hint.getValue());
-                        if (!validationResult.first) {
-                            errorMsgBuffer.append("Dataset: ").append(datasetStmt.getName().getValue())
-                                    .append(" error in processing hint: ").append(hint.getKey()).append(" ")
-                                    .append(validationResult.second);
-                            errorMsgBuffer.append(" \n");
+                DatasetDecl dsCreateStmt = (DatasetDecl) stmt;
+                if (dsCreateStmt.getDataverse() != null) {
+                    dataverseName = dsCreateStmt.getDataverse();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "dataset", dataverseName);
+                }
+
+                if (!invalidOperation) {
+                    Map<String, String> hints = dsCreateStmt.getHints();
+                    if (hints != null && !hints.isEmpty()) {
+                        StringBuilder errorMsgBuffer = new StringBuilder();
+                        for (Entry<String, String> hint : hints.entrySet()) {
+                            Pair<Boolean, String> validationResult =
+                                    DatasetHints.validate(appCtx, hint.getKey(), hint.getValue());
+                            if (!validationResult.first) {
+                                errorMsgBuffer.append("Dataset: ").append(dsCreateStmt.getName().getValue())
+                                        .append(" error in processing hint: ").append(hint.getKey()).append(" ")
+                                        .append(validationResult.second);
+                                errorMsgBuffer.append(" \n");
+                            }
+                        }
+                        invalidOperation = errorMsgBuffer.length() > 0;
+                        if (invalidOperation) {
+                            message = errorMsgBuffer.toString();
                         }
                     }
-                    invalidOperation = errorMsgBuffer.length() > 0;
-                    if (invalidOperation) {
-                        message = errorMsgBuffer.toString();
-                    }
+                }
+                break;
+
+            case DATASET_DROP:
+                DropDatasetStatement dsDropStmt = (DropDatasetStatement) stmt;
+                if (dsDropStmt.getDataverseName() != null) {
+                    dataverseName = dsDropStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "drop", "dataset", dataverseName);
+                }
+                break;
+
+            case INDEX_DROP:
+                IndexDropStatement idxDropStmt = (IndexDropStatement) stmt;
+                if (idxDropStmt.getDataverseName() != null) {
+                    dataverseName = idxDropStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "drop", "index", dataverseName);
+                }
+                break;
+
+            case TYPE_DECL:
+                TypeDecl typeCreateStmt = (TypeDecl) stmt;
+                if (typeCreateStmt.getDataverseName() != null) {
+                    dataverseName = typeCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "type", dataverseName);
+                }
+                break;
+
+            case TYPE_DROP:
+                TypeDropStatement typeDropStmt = (TypeDropStatement) stmt;
+                if (typeDropStmt.getDataverseName() != null) {
+                    dataverseName = typeDropStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "drop", "type", dataverseName);
+                }
+                break;
+
+            case CREATE_SYNONYM:
+                CreateSynonymStatement synCreateStmt = (CreateSynonymStatement) stmt;
+                if (synCreateStmt.getDataverseName() != null) {
+                    dataverseName = synCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "synonym", dataverseName);
+                }
+                break;
+
+            case FUNCTION_DECL:
+                FunctionDecl fnDeclStmt = (FunctionDecl) stmt;
+                FunctionSignature fnDeclSignature = fnDeclStmt.getSignature();
+                if (fnDeclSignature.getDataverseName() != null) {
+                    dataverseName = fnDeclSignature.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "declare", "function", dataverseName);
+                }
+                break;
+
+            case CREATE_FUNCTION:
+                CreateFunctionStatement fnCreateStmt = (CreateFunctionStatement) stmt;
+                FunctionSignature fnCreateSignature = fnCreateStmt.getFunctionSignature();
+                if (fnCreateSignature.getDataverseName() != null) {
+                    dataverseName = fnCreateSignature.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "function", dataverseName);
+                }
+                break;
+
+            case CREATE_LIBRARY:
+                CreateLibraryStatement libCreateStmt = (CreateLibraryStatement) stmt;
+                if (libCreateStmt.getDataverseName() != null) {
+                    dataverseName = libCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "library", dataverseName);
+                }
+                break;
+
+            case CREATE_ADAPTER:
+                CreateAdapterStatement adCreateStmt = (CreateAdapterStatement) stmt;
+                if (adCreateStmt.getDataverseName() != null) {
+                    dataverseName = adCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "adapter", dataverseName);
+                }
+                break;
+
+            case CREATE_FEED:
+                CreateFeedStatement feedCreateStmt = (CreateFeedStatement) stmt;
+                if (feedCreateStmt.getDataverseName() != null) {
+                    dataverseName = feedCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "feed", dataverseName);
+                }
+                break;
+
+            case CREATE_FEED_POLICY:
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "ingestion policy",
+                            dataverseName);
                 }
                 break;
         }
 
         if (invalidOperation) {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, stmt.getSourceLocation(),
-                    "Invalid operation - " + message);
+                    String.format(INVALID_OPERATION_MESSAGE, message));
         }
     }
+
+    protected static boolean isMetadataDataverse(DataverseName dataverseName) {
+        return MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+    }
 }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
index a952ffb..54e972e 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
@@ -39,6 +39,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Pair;
 import org.apache.hyracks.api.application.INCServiceContext;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
@@ -141,6 +142,9 @@
         if (IFormattedException.matchesAny(e, ErrorCode.UNKNOWN_DATAVERSE, ErrorCode.UNKNOWN_LIBRARY)) {
             return HttpResponseStatus.NOT_FOUND;
         }
+        if (e instanceof AlgebricksException) {
+            return HttpResponseStatus.BAD_REQUEST;
+        }
         return HttpResponseStatus.INTERNAL_SERVER_ERROR;
     }
 }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java
index fc08f49..0645870 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java
@@ -146,7 +146,6 @@
         try {
             ncMb.sendMessageToPrimaryCC(requestMessage);
             responseMsg = (InternalRequestResponse) responseFuture.get(120000, TimeUnit.MILLISECONDS);
-
         } finally {
             ncMb.deregisterMessageFuture(responseFuture.getFutureId());
         }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
index c2b576a..81e35a0 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
@@ -55,41 +55,40 @@
 
     @Override
     public void install(URI path, String libPath, Pair<String, String> credentials) throws Exception {
-        HttpHost h = new HttpHost(path.getHost(), path.getPort(), "http");
+        HttpClientContext hcCtx = createHttpClientContext(path, credentials);
         HttpPost post = new HttpPost(path);
-        CredentialsProvider cp = new BasicCredentialsProvider();
-        cp.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(credentials.first, credentials.second));
-        HttpClientContext hcCtx = HttpClientContext.create();
-        hcCtx.setCredentialsProvider(cp);
-        AuthCache ac = new BasicAuthCache();
-        ac.put(h, new BasicScheme());
-        hcCtx.setAuthCache(ac);
         File lib = new File(libPath);
         HttpEntity file = MultipartEntityBuilder.create().setMode(HttpMultipartMode.STRICT)
                 .addBinaryBody("lib", lib, ContentType.DEFAULT_BINARY, lib.getName()).build();
         post.setEntity(file);
         HttpResponse response = hc.execute(post, hcCtx);
-        response.getEntity().consumeContent();
-        if (response.getStatusLine().getStatusCode() != 200) {
-            throw new AsterixException(response.getStatusLine().toString());
-        }
+        handleResponse(response);
     }
 
     @Override
     public void uninstall(URI path, Pair<String, String> credentials) throws IOException, AsterixException {
+        HttpClientContext hcCtx = createHttpClientContext(path, credentials);
+        HttpDelete del = new HttpDelete(path);
+        HttpResponse response = hc.execute(del, hcCtx);
+        handleResponse(response);
+    }
+
+    private HttpClientContext createHttpClientContext(URI path, Pair<String, String> credentials) {
+        HttpClientContext hcCtx = HttpClientContext.create();
+        HttpHost h = new HttpHost(path.getHost(), path.getPort(), "http");
         CredentialsProvider cp = new BasicCredentialsProvider();
         cp.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(credentials.first, credentials.second));
-        HttpClientContext hcCtx = HttpClientContext.create();
         hcCtx.setCredentialsProvider(cp);
-        HttpHost h = new HttpHost(path.getHost(), path.getPort(), "http");
         AuthCache ac = new BasicAuthCache();
         ac.put(h, new BasicScheme());
         hcCtx.setAuthCache(ac);
-        HttpDelete del = new HttpDelete(path);
-        HttpResponse response = hc.execute(del, hcCtx);
+        return hcCtx;
+    }
+
+    private void handleResponse(HttpResponse response) throws IOException, AsterixException {
         String resp = null;
         int respCode = response.getStatusLine().getStatusCode();
-        if (respCode == 500) {
+        if (respCode == 500 || respCode == 400) {
             resp = IOUtils.toString(response.getEntity().getContent());
         }
         response.getEntity().consumeContent();
@@ -100,5 +99,4 @@
             throw new AsterixException(resp);
         }
     }
-
 }
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_dataset/exception_create_system_dataset.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_dataset/exception_create_system_dataset.1.ddl.sqlpp
new file mode 100644
index 0000000..3b186dd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_dataset/exception_create_system_dataset.1.ddl.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+create dataset Metadata.NewMetaDataset(id uuid not unknown)
+  open type primary key id autogenerated;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed/exception_create_system_feed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed/exception_create_system_feed.1.ddl.sqlpp
new file mode 100644
index 0000000..5b0ffa7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed/exception_create_system_feed.1.ddl.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+create feed Metadata.NewMetaFeed with {
+  "adapter-name" : "http_adapter",
+  "addresses" : "asterix_nc2:10002,asterix_nc1:10001",
+  "address-type" : "NC",
+  "type-name" : "DatasetRecordType",
+  "format" : "adm"
+};
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed_policy/exception_create_system_feed_policy.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed_policy/exception_create_system_feed_policy.1.ddl.sqlpp
new file mode 100644
index 0000000..b9709cb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed_policy/exception_create_system_feed_policy.1.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use Metadata;
+
+create ingestion policy NewMetaPolicy
+  from path 'data/feed-policy/policy.properties'
+  definition 'someString';
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_function/exception_create_system_function.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_function/exception_create_system_function.1.ddl.sqlpp
new file mode 100644
index 0000000..196870c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_function/exception_create_system_function.1.ddl.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+create function Metadata.MyMetaFunction() {
+  1
+};
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_synonym/exception_create_system_synonym.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_synonym/exception_create_system_synonym.1.ddl.sqlpp
new file mode 100644
index 0000000..0e6f7ed
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_synonym/exception_create_system_synonym.1.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+create synonym Metadata.NewMetaSynonym for Metadata.`Dataset`;
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_type/exception_create_system_type.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_type/exception_create_system_type.1.ddl.sqlpp
new file mode 100644
index 0000000..1222af6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_type/exception_create_system_type.1.ddl.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+create type Metadata.NewMetaType as open {
+  id : string
+};
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_declare_system_function/exception_declare_system_function.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_declare_system_function/exception_declare_system_function.1.query.sqlpp
new file mode 100644
index 0000000..fe3f250
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_declare_system_function/exception_declare_system_function.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use Metadata;
+
+declare function MyMetaFunction() {
+  1
+};
+
+MyMetaFunction();
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_index/exception_drop_system_index.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_index/exception_drop_system_index.1.ddl.sqlpp
new file mode 100644
index 0000000..02d32c9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_index/exception_drop_system_index.1.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop index Metadata.`Dataset`.`Dataset`;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_type/exception_drop_system_type.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_type/exception_drop_system_type.1.ddl.sqlpp
new file mode 100644
index 0000000..e109d56
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_type/exception_drop_system_type.1.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop type Metadata.DatasetRecordType;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml b/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml
index 62db526..8af4c67 100644
--- a/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml
+++ b/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml
@@ -327,6 +327,48 @@
   </test-group>
   <test-group name="exception">
     <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_dataset">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a dataset belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_feed">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a feed belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_feed_policy">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a ingestion policy belonging to the dataverse: Metadata (in line 22, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_function">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a function belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_synonym">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a synonym belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_type">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a type belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_declare_system_function">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot declare a function belonging to the dataverse: Metadata (in line 22, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
       <compilation-unit name="exception_drop_dataset">
         <output-dir compare="Text">none</output-dir>
         <expected-error>ASX1050: Cannot find dataset with name UnknownDataset in dataverse Default (in line 19, at column 1)</expected-error>
@@ -351,6 +393,12 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
+      <compilation-unit name="exception_drop_system_index">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot drop a index belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
       <compilation-unit name="exception_drop_nodegroup">
         <output-dir compare="Text">none</output-dir>
         <expected-error>ASX1080: Cannot find node group with name UnknownNodeGroup (in line 19, at column 1)</expected-error>
@@ -363,6 +411,12 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
+      <compilation-unit name="exception_drop_system_type">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot drop a type belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_1">
         <output-dir compare="Text">none</output-dir>
         <expected-error>ASX1079: Compilation error: Invalid operation - Cannot drop a dataset belonging to the dataverse: Metadata (in line 26, at column 1)</expected-error>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/exception_create_system_library/exception_create_system_library.1.lib.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/exception_create_system_library/exception_create_system_library.1.lib.sqlpp
new file mode 100644
index 0000000..ac3d3d0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/exception_create_system_library/exception_create_system_library.1.lib.sqlpp
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+install Metadata testlib admin admin target/data/externallib/asterix-external-data-testlib.zip
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.0.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.0.ddl.sqlpp
new file mode 100644
index 0000000..fd5eb07
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.0.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Description  : Cannot create adapter in Metadata dataverse
+ * Expected Res : Success
+ */
+
+drop dataverse externallibtest if exists;
+create dataverse externallibtest;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.1.lib.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.1.lib.sqlpp
new file mode 100644
index 0000000..45cdfd1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.1.lib.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Description  : Cannot create adapter in Metadata dataverse
+ * Expected Res : Success
+ */
+
+install externallibtest testlib admin admin target/data/externallib/asterix-external-data-testlib.zip
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.2.ddl.sqlpp
new file mode 100644
index 0000000..7fb6235
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.2.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Description  : Cannot create adapter in Metadata dataverse
+ * Expected Res : Success
+ */
+
+create adapter Metadata.NewMetaAdapter
+  as "org.apache.asterix.external.library.adapter.TestTypedAdapterFactory" at externallibtest.testlib;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
index cf5b1a7..954252c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
@@ -35,6 +35,12 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="external-library">
+      <compilation-unit name="exception_create_system_library">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a library belonging to the dataverse: Metadata</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="external-library">
       <compilation-unit name="type_validation">
         <output-dir compare="Text">type_validation</output-dir>
       </compilation-unit>
@@ -104,6 +110,12 @@
   </test-group>
   <test-group name="feeds">
     <test-case FilePath="feeds">
+      <compilation-unit name="exception_create_system_adapter">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a adapter belonging to the dataverse: Metadata (in line 24, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="feeds">
       <compilation-unit name="feed-with-external-function">
         <output-dir compare="Text">feed-with-external-function</output-dir>
       </compilation-unit>