Enable editing of storage plugin via http

Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/e46f1beb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/e46f1beb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/e46f1beb

Branch: refs/heads/master
Commit: e46f1beb3234cdf66b507db9932fd0dc569557c0
Parents: 6de54c4
Author: Jacques Nadeau <[email protected]>
Authored: Tue Jun 3 09:00:21 2014 -0700
Committer: Jacques Nadeau <[email protected]>
Committed: Sun Jun 8 19:13:05 2014 -0700

----------------------------------------------------------------------
 distribution/src/resources/drill-override.conf  |   4 +-
 exec/java-exec/pom.xml                          |   9 +-
 .../org/apache/drill/exec/server/Drillbit.java  |  11 +-
 .../drill/exec/server/rest/DrillRestServer.java |  35 ++++-
 .../drill/exec/server/rest/DrillRoot.java       |   7 +
 .../exec/server/rest/StorageResources.java      | 137 +++++++++++++++++++
 .../drill/exec/store/StoragePluginRegistry.java |  75 ++++++++--
 .../src/main/resources/rest/storage/list.ftl    |  22 +++
 .../src/main/resources/rest/storage/update.ftl  |  33 +++++
 .../src/main/protobuf/ExecutionProtos.proto     |   6 -
 10 files changed, 311 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/distribution/src/resources/drill-override.conf
----------------------------------------------------------------------
diff --git a/distribution/src/resources/drill-override.conf 
b/distribution/src/resources/drill-override.conf
index da3d094..472296b 100644
--- a/distribution/src/resources/drill-override.conf
+++ b/distribution/src/resources/drill-override.conf
@@ -99,8 +99,8 @@ drill.exec: {
     filesystem: "drill-local:///"
   },
   buffer:{
-    impl: "org.apache.drill.exec.work.batch.SpoolingRawBatchBuffer",
-    size: "20000",
+    impl: "org.apache.drill.exec.work.batch.UnlimitedRawBatchBuffer",
+    size: "100",
     spooling: {
       delete: false,
       size: 100000000

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/pom.xml
----------------------------------------------------------------------
diff --git a/exec/java-exec/pom.xml b/exec/java-exec/pom.xml
index ff6f552..da0c96a 100644
--- a/exec/java-exec/pom.xml
+++ b/exec/java-exec/pom.xml
@@ -88,9 +88,14 @@
     </dependency>
     <dependency>
       <groupId>org.glassfish.jersey.media</groupId>
-      <artifactId>jersey-media-json-jackson</artifactId>
+      <artifactId>jersey-media-multipart</artifactId>
       <version>2.8</version>
-    </dependency>
+    </dependency>    
+    <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-json-provider</artifactId>
+        <version>2.2.0</version>
+    </dependency>    
     <dependency>
       <groupId>org.glassfish.jersey.ext</groupId>
       <artifactId>jersey-mvc-freemarker</artifactId>

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java
index 60dd50f..38f2179 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java
@@ -30,12 +30,12 @@ import 
org.apache.drill.exec.exception.DrillbitStartupException;
 import org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint;
 import org.apache.drill.exec.server.rest.DrillRestServer;
 import org.apache.drill.exec.service.ServiceEngine;
-import org.apache.drill.exec.store.sys.PStoreRegistry;
 import org.apache.drill.exec.store.sys.PStoreProvider;
+import org.apache.drill.exec.store.sys.PStoreRegistry;
 import org.apache.drill.exec.store.sys.local.LocalPStoreProvider;
-import org.apache.drill.exec.store.sys.zk.ZkPStoreProvider;
 import org.apache.drill.exec.work.WorkManager;
 import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.ErrorHandler;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.glassfish.jersey.servlet.ServletContainer;
@@ -113,6 +113,11 @@ public class Drillbit implements Closeable{
     if(embeddedJetty == null) return;
 
     ServletContextHandler context = new 
ServletContextHandler(ServletContextHandler.NO_SESSIONS);
+
+    ErrorHandler errorHandler = new ErrorHandler();
+    errorHandler.setShowStacks(true);
+    errorHandler.setShowMessageInTitle(true);
+    context.setErrorHandler(errorHandler);
     context.setContextPath("/");
     embeddedJetty.setHandler(context);
     ServletHolder h = new ServletHolder(new ServletContainer(new 
DrillRestServer(manager)));
@@ -120,6 +125,8 @@ public class Drillbit implements Closeable{
     h.setInitOrder(1);
     context.addServlet(h, "/*");
     embeddedJetty.start();
+
+    System.out.println("");
   }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
index c0e0f19..38354ca 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java
@@ -18,28 +18,57 @@
 package org.apache.drill.exec.server.rest;
 
 import org.apache.drill.exec.client.DrillClient;
+import org.apache.drill.exec.store.StoragePluginRegistry;
+import org.apache.drill.exec.store.sys.PStoreProvider;
 import org.apache.drill.exec.work.WorkManager;
 import org.glassfish.hk2.utilities.binding.AbstractBinder;
-import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.server.ServerProperties;
 import org.glassfish.jersey.server.mvc.freemarker.FreemarkerMvcFeature;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.jaxrs.base.JsonMappingExceptionMapper;
+import com.fasterxml.jackson.jaxrs.base.JsonParseExceptionMapper;
+import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+
 public class DrillRestServer extends ResourceConfig {
   static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(DrillRestServer.class);
 
   public DrillRestServer(final WorkManager workManager) {
-//    registerClasses(HelloResource.class);
-    register(JacksonFeature.class);
     register(DrillRoot.class);
+    register(StorageResources.class);
     register(FreemarkerMvcFeature.class);
     property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);
+    register(MultiPartFeature.class);
+
+    register_jackson : {
+
+      //disable moxy so it doesn't conflict with jackson.
+      final String disableMoxy = 
PropertiesHelper.getPropertyNameForRuntime(CommonProperties.MOXY_JSON_FEATURE_DISABLE,
 getConfiguration().getRuntimeType());
+      property(disableMoxy, true);
+
+      register(JsonParseExceptionMapper.class);
+      register(JsonMappingExceptionMapper.class);
+
+      JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
+      provider.setMapper(workManager.getContext().getConfig().getMapper());
+      register(provider);
+    }
+
+
     register(new AbstractBinder() {
       @Override
       protected void configure() {
         bind(workManager).to(WorkManager.class);
+        
bind(workManager.getContext().getConfig().getMapper()).to(ObjectMapper.class);
+        
bind(workManager.getContext().getPersistentStoreProvider()).to(PStoreProvider.class);
+        
bind(workManager.getContext().getStorage()).to(StoragePluginRegistry.class);
         bind(new DrillClient()).to(DrillClient.class);
       }
     });
   }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java
index f073e11..1da5d79 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java
@@ -27,8 +27,12 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
+import org.apache.drill.common.exceptions.ExecutionSetupException;
+import org.apache.drill.common.logical.StoragePluginConfig;
 import org.apache.drill.exec.cache.DistributedMap;
 import org.apache.drill.exec.proto.UserBitShared.QueryProfile;
+import org.apache.drill.exec.store.StoragePlugin;
+import org.apache.drill.exec.store.StoragePluginRegistry;
 import org.apache.drill.exec.work.WorkManager;
 import org.apache.drill.exec.work.foreman.QueryStatus;
 import org.glassfish.jersey.server.mvc.Viewable;
@@ -38,6 +42,8 @@ import com.google.common.collect.Lists;
 @Path("/")
 public class DrillRoot {
 
+  static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(DrillRoot.class);
+
   @Inject WorkManager work;
 
   @GET
@@ -61,6 +67,7 @@ public class DrillRoot {
     return new Viewable("/rest/status/list.ftl", ids);
   }
 
+
   @GET
   @Path("/query/{queryid}")
   @Produces(MediaType.TEXT_HTML)

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java
new file mode 100644
index 0000000..244d8a8
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java
@@ -0,0 +1,137 @@
+/**
+ * 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.server.rest;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.drill.common.exceptions.ExecutionSetupException;
+import org.apache.drill.common.logical.StoragePluginConfig;
+import org.apache.drill.exec.store.StoragePlugin;
+import org.apache.drill.exec.store.StoragePluginRegistry;
+import org.apache.drill.exec.store.sys.PStoreProvider;
+import org.glassfish.jersey.server.mvc.Viewable;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+
+import freemarker.template.SimpleHash;
+
+@Path("/storage")
+public class StorageResources {
+  static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(StorageResources.class);
+
+  @Inject StoragePluginRegistry storage;
+  @Inject PStoreProvider storeProvider;
+  @Inject ObjectMapper mapper;
+
+  @GET
+  @Produces(MediaType.TEXT_HTML)
+  public Viewable getQueries() {
+
+    List<String> names = Lists.newArrayList();
+    for (Map.Entry<String, StoragePluginConfig> config : storage.getStore()) {
+      names.add(config.getKey());
+    }
+
+    return new Viewable("/rest/storage/list.ftl", names);
+  }
+
+  @GET
+  @Path("/{name}/config/update")
+  @Produces(MediaType.TEXT_HTML)
+  public Viewable update(@PathParam("name") String name) throws 
JsonProcessingException {
+    StoragePluginConfig config = findConfig(name);
+    String conf = config == null ? "" : mapper.writeValueAsString(config);
+
+    SimpleHash map = new SimpleHash();
+    map.put("config", conf);
+    map.put("name", name);
+    map.put("exists", config != null);
+    return new Viewable("/rest/storage/update.ftl", map);
+  }
+
+  @GET
+  @Produces(MediaType.APPLICATION_JSON)
+  @Path("/{name}/config")
+  public StoragePluginConfig getConfig(@PathParam("name") String name) {
+    return findConfig(name);
+  }
+
+  private StoragePluginConfig findConfig(String name) {
+    try {
+      StoragePlugin plugin = storage.getPlugin(name);
+      if (plugin != null) {
+        return plugin.getConfig();
+      }
+    } catch (Exception e) {
+      logger.info("Failure while trying to access storage config: {}", name, 
e);
+      ;
+    }
+    return null;
+  }
+
+  @POST
+  @Path("/config/update")
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes("application/x-www-form-urlencoded")
+  public JsonResult createTrackInJSON(@FormParam("name") String name, 
@FormParam("config") String storagePluginConfig)
+      throws ExecutionSetupException, JsonParseException, 
JsonMappingException, IOException {
+    StoragePluginConfig config = mapper.readValue(new 
StringReader(storagePluginConfig), StoragePluginConfig.class);
+    storage.createOrUpdate(name, config, true);
+    return r("success");
+  }
+
+  @POST
+  @Path("/config/delete")
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes("application/x-www-form-urlencoded")
+  public JsonResult deleteConfig(@FormParam("name") String name) {
+    storage.deletePlugin(name);
+    return r("success");
+  }
+
+  private JsonResult r(String message) {
+    return new JsonResult(message);
+  }
+
+  public static class JsonResult {
+    public String result = "data updated";
+
+    public JsonResult(String result) {
+      super();
+      this.result = result;
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
index 33a9942..a4f94e3 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
@@ -34,6 +34,7 @@ import net.hydromatic.optiq.SchemaPlus;
 import net.hydromatic.optiq.tools.RuleSet;
 
 import org.apache.drill.common.config.DrillConfig;
+import org.apache.drill.common.exceptions.DrillRuntimeException;
 import org.apache.drill.common.exceptions.ExecutionSetupException;
 import org.apache.drill.common.logical.FormatPluginConfig;
 import org.apache.drill.common.logical.StoragePluginConfig;
@@ -55,7 +56,6 @@ import 
org.apache.drill.exec.store.sys.SystemTablePluginConfig;
 import org.eigenbase.relopt.RelOptRule;
 
 import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
 import com.google.common.collect.Lists;
@@ -72,8 +72,10 @@ public class StoragePluginRegistry implements 
Iterable<Map.Entry<String, Storage
   private DrillbitContext context;
   private final DrillSchemaFactory schemaFactory = new DrillSchemaFactory();
   private final PStore<StoragePluginConfig> pluginSystemTable;
-
+  private final Object updateLock = new Object();
+  private volatile long lastUpdate = 0;
   private RuleSet storagePluginsRuleSet;
+  private static final long UPDATE_FREQUENCY = 2 * 60 * 1000;
 
   public StoragePluginRegistry(DrillbitContext context) {
     try{
@@ -90,6 +92,10 @@ public class StoragePluginRegistry implements 
Iterable<Map.Entry<String, Storage
     }
   }
 
+  public PStore<StoragePluginConfig> getStore(){
+    return pluginSystemTable;
+  }
+
   @SuppressWarnings("unchecked")
   public void init() throws DrillbitStartupException {
     DrillConfig config = context.getConfig();
@@ -174,23 +180,53 @@ public class StoragePluginRegistry implements 
Iterable<Map.Entry<String, Storage
     return activePlugins;
   }
 
-  public StoragePlugin getPlugin(String registeredStoragePluginName) throws 
ExecutionSetupException {
-    StoragePlugin plugin = plugins.get(registeredStoragePluginName);
+  public void deletePlugin(String name){
+    plugins.remove(name);
+    pluginSystemTable.delete(name);
+  }
+
+  public StoragePlugin createOrUpdate(String name, StoragePluginConfig config, 
boolean persist) throws ExecutionSetupException{
+    StoragePlugin oldPlugin = plugins.get(name);
+
+    StoragePlugin newPlugin = create(name, config);
+    boolean ok;
+    if(oldPlugin != null){
+      ok = plugins.replace(name, oldPlugin, newPlugin);
+    }else{
+      ok = (null == plugins.putIfAbsent(name, newPlugin));
+    }
+
+    if(!ok) throw new ExecutionSetupException("Two processes tried to change a 
plugin at the same time.");
+
+    if(persist) pluginSystemTable.put(name, config);
+
+    return newPlugin;
+  }
+
+
+  public StoragePlugin getPlugin(String name) throws ExecutionSetupException {
+    StoragePlugin plugin = plugins.get(name);
+    if(name.equals("sys") || name.equals("INFORMATION_SCHEMA")) return plugin;
+
+    StoragePluginConfig config = this.pluginSystemTable.get(name);
 
-    if(plugin == null){
-      StoragePluginConfig config = 
this.pluginSystemTable.get(registeredStoragePluginName);
-      if(config != null){
-        this.plugins.put(registeredStoragePluginName, 
create(registeredStoragePluginName, config));
-        plugin = plugins.get(registeredStoragePluginName);
+    // since we lazily manage the list of plugins per server, we need to 
update this once we know that it is time.
+
+    if(config == null){
+      if(plugin != null) plugins.remove(name);
+      return null;
+    }else{
+      if(plugin == null || !plugin.getConfig().equals(config)){
+        plugin = createOrUpdate(name, config, false);
       }
+      return plugin;
     }
 
-    return plugin;
   }
 
   public StoragePlugin getPlugin(StoragePluginConfig config) throws 
ExecutionSetupException {
     if(config instanceof NamedStoragePluginConfig){
-      return plugins.get(((NamedStoragePluginConfig) config).name);
+      return getPlugin(((NamedStoragePluginConfig) config).name);
     }else{
       // TODO: for now, we'll throw away transient configs.  we really ought 
to clean these up.
       return create(null, config);
@@ -222,6 +258,7 @@ public class StoragePluginRegistry implements 
Iterable<Map.Entry<String, Storage
     }
   }
 
+
   @Override
   public Iterator<Entry<String, StoragePlugin>> iterator() {
     return plugins.entrySet().iterator();
@@ -239,10 +276,22 @@ public class StoragePluginRegistry implements 
Iterable<Map.Entry<String, Storage
 
     @Override
     public void registerSchemas(UserSession session, SchemaPlus parent) {
-      for(Map.Entry<String, StoragePlugin> e : plugins.entrySet()){
-        e.getValue().registerSchemas(session, parent);
+      try{
+      for(Map.Entry<String, StoragePluginConfig> e : pluginSystemTable){
+        StoragePlugin p = getPlugin(e.getKey());
+        if(p != null){
+          p.registerSchemas(session, parent);
+        }
+      }
+
+      getPlugin("sys").registerSchemas(session, parent);
+      getPlugin("INFORMATION_SCHEMA").registerSchemas(session, parent);
+
+      }catch(ExecutionSetupException e){
+        throw new DrillRuntimeException("Failure while updating storage 
plugins", e);
       }
 
+
       // Add second level schema as top level schema with name qualified with 
parent schema name
       // Ex: "dfs" schema has "default" and "tmp" as sub schemas. Add 
following extra schemas "dfs.default" and
       // "dfs.tmp" under root schema.

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/src/main/resources/rest/storage/list.ftl
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/resources/rest/storage/list.ftl 
b/exec/java-exec/src/main/resources/rest/storage/list.ftl
new file mode 100644
index 0000000..380c3fc
--- /dev/null
+++ b/exec/java-exec/src/main/resources/rest/storage/list.ftl
@@ -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. -->
+
+<html>
+Registered Storage Plugins 
+<br />
+<#list model as plugin>
+
+${plugin} <a href="/storage/${plugin}/config">view</a> <a 
href="/storage/${plugin}/config/update">update</a><br />
+
+</#list>
+
+
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/exec/java-exec/src/main/resources/rest/storage/update.ftl
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/resources/rest/storage/update.ftl 
b/exec/java-exec/src/main/resources/rest/storage/update.ftl
new file mode 100644
index 0000000..8c7588a
--- /dev/null
+++ b/exec/java-exec/src/main/resources/rest/storage/update.ftl
@@ -0,0 +1,33 @@
+<#-- 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. -->
+
+<html>
+Create/Update  
+<br />
+
+<form action="/storage/config/update" method="post">
+<input type="hidden" name="name" value="${model.name}" />
+<textarea rows="20" cols="50" name="config">
+${model.config}
+</textarea>
+<br />
+<input type="submit" value="<#if model.exists >update<#else>create</#if>"/>
+</form>
+
+<#if model.exists >
+<form action="/storage/config/delete" method="post"><input type="hidden" 
name="name" value="${model.name}" />
+<input type="submit" value="delete" onclick="return confirm('Are you sure?')" 
/>
+</form>
+</#if>
+
+
+
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/e46f1beb/protocol/src/main/protobuf/ExecutionProtos.proto
----------------------------------------------------------------------
diff --git a/protocol/src/main/protobuf/ExecutionProtos.proto 
b/protocol/src/main/protobuf/ExecutionProtos.proto
index f7062c2..8ad8c47 100644
--- a/protocol/src/main/protobuf/ExecutionProtos.proto
+++ b/protocol/src/main/protobuf/ExecutionProtos.proto
@@ -13,9 +13,3 @@ message FragmentHandle {
        optional int32 minor_fragment_id = 3;
 }
 
-message ViewPointer {
-  optional string name = 1;
-  optional string path = 2;
-}
-
-

Reply via email to