paul-rogers commented on a change in pull request #2251:
URL: https://github.com/apache/drill/pull/2251#discussion_r662667413



##########
File path: 
exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
##########
@@ -21,19 +21,18 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.calcite.schema.SchemaPlus;

Review comment:
       The plugin registry is a complex beast. Before this change, it supported 
built-in plugins and those provided in the plugins folder. The registry handles 
both the "connector" (code) and "instances" (code + a config.)
   
   This change adds per-user plugins. The overall bug description does not seem 
to provide answers to several questions. For example:
   
   * Are we controlling access to the "connectors" (code) or to the "instances" 
(configs?)
   * If we control the connectors, do we load new copies of the connector 
metadata per user?
   * Can a user see the common set of system-wide configs? Or, only their own 
private configs?
   * If system wide, how do we handle name conflicts? I add a "foo" plugin, 
later the admin adds a system-wide "foo" or visa-versa.
   * Can a private plugin be promoted to system level? Is that a copy/paste 
operation? With the user logged in as different windows? Or, is there a button 
to do the operation?
   * When is the per-user information created? As you know, on the web, the 
user session comes into existence for every single REST call. Plugin setup is 
pretty heavy-weight. Is the user config cached between requests? If so, when do 
we expire the user information if the user then becomes idle?
   * The registry handles updates. The current code is rather awful since there 
is no coordination among Drillbits: multiple drillbits could come up at the 
same time and they can all decide to do the upgrade. Adding users complicates 
the effort. Will a user session trigger a plugin upgrade? How do we handle 
races?
   * This registry handles a subtle, obscure case. Suppose (before this 
change), I run a query that users the "foo" plugin. Before the query starts 
running (but after planning), I rush in and delete the "foo" config. What 
happens? As it turns out, Drill saves the old config so that queries continue 
to work. This works because there is only one registry. If we add per-user 
registries, we'd need to pass the user info with the exec plan so that the 
readers grab the user's version of the config, including any cached, 
recently-deleted configs. (Distributed systems are complex!)
   * There are probably a few more issues that also deserve consideration. The 
comments in this part of the code try to explain the various issues.

##########
File path: 
exec/java-exec/src/main/java/org/apache/drill/exec/work/prepare/PreparedStatementProvider.java
##########
@@ -138,7 +139,9 @@ public void run() {
         final QueryId limit0QueryId = userWorker.submitWork(wrapper, 
limit0Query);
 
         final long timeoutMillis =
-            
userWorker.getSystemOptions().getOption(CREATE_PREPARE_STATEMENT_TIMEOUT_MILLIS).num_val;
+            
userWorker.getDrillbitContext().getConfig().getBoolean(ExecConstants.SEPARATE_WORKSPACE)

Review comment:
       As noted above, this kind of code will lead to countless subtle errors. 
Suggestion: introduce yet another option manager whose job is to decide which 
of the two "system" option managers is needed. Option managers are designed to 
nest, so this should be not too hard.
   
   And, there is still the question: why do we need two *system* option 
managers? Do users get their own system options now? See questions above...

##########
File path: 
exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StatusResources.java
##########
@@ -183,9 +188,9 @@ public Viewable getSystemInternalOptions(@Context UriInfo 
uriInfo) {
   public Viewable updateSystemOption(@FormParam("name") String name,
                                    @FormParam("value") String value,
                                    @FormParam("kind") String kind) {
-    SystemOptionManager optionManager = work.getContext()
-      .getOptionManager();
-
+    SystemOptionManager optionManager = authEnabled.separateWorkspace()

Review comment:
       This seems to say that updating a *system* option works differently 
depending on whether the user has their own workspace. Shouldn't *system* 
options always update the (global) system options? Otherwise, do we need a 
"real system option" attribute to really update the global options?

##########
File path: 
exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StatusResources.java
##########
@@ -112,7 +115,9 @@ public String getMetrics(@PathParam("hostname") String 
hostname) throws Exceptio
   private List<OptionWrapper> getSystemOptionsJSONHelper(boolean internal)
   {
     List<OptionWrapper> options = new LinkedList<>();
-    OptionManager optionManager = work.getContext().getOptionManager();
+    OptionManager optionManager = authEnabled.separateWorkspace()

Review comment:
       This is a complex bit of code which is repeated several times. Can it be 
factored out somewhere?

##########
File path: 
exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java
##########
@@ -138,7 +141,9 @@ public Viewable getPlugins() {
   @Produces(MediaType.APPLICATION_JSON)
   public PluginConfigWrapper getPluginConfig(@PathParam("name") String name) {
     try {
-      return new PluginConfigWrapper(name, storage.getStoredConfig(name));
+      return authEnabled.separateWorkspace()

Review comment:
       On this, and similar lines, it would be better to factor out the logic 
into a method on `WebUserConnection` such as `getStorage()` or some such. Too 
much copy/paste and room for error otherwise.

##########
File path: 
exec/java-exec/src/test/java/org/apache/drill/exec/store/TestUserPluginRegistry.java
##########
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+package org.apache.drill.exec.store;
+
+import org.apache.drill.common.config.DrillProperties;
+import org.apache.drill.common.logical.StoragePluginConfig;
+import org.apache.drill.exec.ExecConstants;
+import org.apache.drill.exec.rpc.user.UserServer;
+import org.apache.drill.exec.rpc.user.UserSession;
+import 
org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl;
+import org.apache.drill.exec.store.dfs.FileSystemConfig;
+import org.apache.drill.exec.store.dfs.FileSystemPlugin;
+import org.apache.drill.test.ClientFixture;
+import org.apache.drill.test.ClusterFixture;
+import org.apache.drill.test.ClusterFixtureBuilder;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static 
org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_1;
+import static 
org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_1_PASSWORD;
+import static 
org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_2;
+import static 
org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl.TEST_USER_2_PASSWORD;
+import static org.apache.drill.exec.util.StoragePluginTestUtils.CP_PLUGIN_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class TestUserPluginRegistry extends BasePluginRegistry {

Review comment:
       Thanks for providing these tests. Thanks for building on the tests added 
back when I refactored the plugin registry: there were many gaps in test 
coverage before that time.
   
   Do the test also test interaction of the per-user registry with the shared 
system registry? See the above comment for the kinds of things to test: 
duplicate names, etc.
   
   This area is highly complex (unfortunately) so we have to be very careful so 
we don't break stuff.
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to