Repository: ambari
Updated Branches:
  refs/heads/trunk 0d5cc744a -> b4079b950


AMBARI-6231. Views: parameterization of view parameters.


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

Branch: refs/heads/trunk
Commit: b4079b9503bb4c15889134070c6914c5fac4d33d
Parents: 0d5cc74
Author: Siddharth Wagle <swa...@hortonworks.com>
Authored: Fri Jun 20 14:40:11 2014 -0700
Committer: Siddharth Wagle <swa...@hortonworks.com>
Committed: Fri Jun 20 14:40:11 2014 -0700

----------------------------------------------------------------------
 .gitignore                                      |   1 +
 ambari-server/pom.xml                           |   8 ++
 .../ambari/server/view/ViewContextImpl.java     | 109 +++++++++++++++++--
 .../ambari/server/view/ViewContextImplTest.java |  48 ++++++++
 pom.xml                                         |   3 +
 5 files changed, 161 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b4079b95/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 246e53e..0430303 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ target
 derby.log
 pass.txt
 ambari-agent/src/test/python/ambari_agent/dummy_files/current-stack
+velocity.log*

http://git-wip-us.apache.org/repos/asf/ambari/blob/b4079b95/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index b9fe10a..a0dc0a7 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -151,6 +151,9 @@
             <exclude>src/test/resources/TestAmbaryServer.samples/**</exclude>
             <exclude>src/test/resources/*.txt</exclude>
             <exclude>src/test/resources/users_for_dn_with_space.ldif</exclude>
+
+            <!--Velocity log -->
+            <exclude>**/velocity.log*</exclude>
           </excludes>
         </configuration>
         <executions>
@@ -1288,6 +1291,11 @@
       <artifactId>quartz-jobs</artifactId>
       <version>2.2.1</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.velocity</groupId>
+      <artifactId>velocity</artifactId>
+      <version>1.7</version>
+    </dependency>
   </dependencies>
   <!--<reporting> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId>
     <artifactId>findbugs-maven-plugin</artifactId> <version>2.5.2</version> 
</plugin>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b4079b95/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
index 042e5c4..e914c75 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
@@ -35,9 +35,16 @@ import org.apache.ambari.view.ViewDefinition;
 import org.apache.ambari.view.ViewInstanceDefinition;
 import org.apache.ambari.view.events.Event;
 import org.apache.ambari.view.events.Listener;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.exception.ParseErrorException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.Writer;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -75,6 +82,14 @@ public class ViewContextImpl implements ViewContext, 
ViewController {
    */
   private DataStore dataStore = null;
 
+  private final VelocityContext velocityContext;
+
+
+  // ----- Constants ---------------------------------------------------------
+
+  protected final static Logger LOG =
+      LoggerFactory.getLogger(ViewContext.class);
+
 
   // ---- Constructors -------------------------------------------------------
 
@@ -85,10 +100,7 @@ public class ViewContextImpl implements ViewContext, 
ViewController {
    * @param viewRegistry        the view registry
    */
   public ViewContextImpl(ViewInstanceEntity viewInstanceEntity, ViewRegistry 
viewRegistry) {
-    this.viewEntity         = viewInstanceEntity.getViewEntity();
-    this.viewInstanceEntity = viewInstanceEntity;
-    this.viewRegistry       = viewRegistry;
-    this.streamProvider     = ViewURLStreamProvider.getProvider();
+    this(viewInstanceEntity.getViewEntity(), viewInstanceEntity, viewRegistry);
   }
 
   /**
@@ -98,10 +110,15 @@ public class ViewContextImpl implements ViewContext, 
ViewController {
    * @param viewRegistry  the view registry
    */
   public ViewContextImpl(ViewEntity viewEntity, ViewRegistry viewRegistry) {
+    this(viewEntity, null, viewRegistry);
+  }
+
+  private ViewContextImpl(ViewEntity viewEntity, ViewInstanceEntity 
viewInstanceEntity, ViewRegistry viewRegistry) {
     this.viewEntity         = viewEntity;
-    this.viewInstanceEntity = null;
+    this.viewInstanceEntity = viewInstanceEntity;
     this.viewRegistry       = viewRegistry;
     this.streamProvider     = ViewURLStreamProvider.getProvider();
+    this.velocityContext    = initVelocityContext();
   }
 
   // ----- ViewContext -------------------------------------------------------
@@ -128,8 +145,20 @@ public class ViewContextImpl implements ViewContext, 
ViewController {
 
   @Override
   public Map<String, String> getProperties() {
-    return viewInstanceEntity == null ? null :
-        Collections.unmodifiableMap(viewInstanceEntity.getPropertyMap());
+    if (viewInstanceEntity == null) {
+      return null;
+    }
+    Map<String, String> properties = viewInstanceEntity.getPropertyMap();
+    String rawValue;
+    for (String key : properties.keySet()) {
+      rawValue = properties.get(key);
+      try {
+        properties.put(key, parameterize(rawValue));
+      } catch (ParseErrorException ex) {
+        LOG.warn(String.format("Error during parsing '%s' parameter. Leaving 
original value.", key));
+      }
+    }
+    return Collections.unmodifiableMap(properties);
   }
 
   @Override
@@ -171,7 +200,7 @@ public class ViewContextImpl implements ViewContext, 
ViewController {
 
   @Override
   public String getUsername() {
-    return viewInstanceEntity.getUsername();
+    return viewInstanceEntity != null ? viewInstanceEntity.getUsername() : 
null;
   }
 
   @Override
@@ -241,6 +270,52 @@ public class ViewContextImpl implements ViewContext, 
ViewController {
     }
   }
 
+  /**
+   * Parameterize string using VelocityContext instance
+   *
+   * @param raw original string with parameters in formal or shorthand notation
+   *
+   * @return parameterized string
+   *
+   * @throws ParseErrorException if original string cannot be parsed by 
Velocity
+   */
+  private String parameterize(String raw) throws ParseErrorException {
+    Writer templateWriter = new StringWriter();
+    Velocity.evaluate(velocityContext, templateWriter, raw, raw);
+    return templateWriter.toString();
+  }
+
+  /**
+   * Instantiate and initialize context for parameters processing using 
Velocity.
+   *
+   * @return initialized context instance
+   */
+  private VelocityContext initVelocityContext() {
+    VelocityContext context = new VelocityContext();
+    context.put("username",
+        new ParameterResolver() {
+          @Override
+          protected String getValue() {
+            return viewContext.getUsername();
+          }
+        });
+    context.put("viewName",
+        new ParameterResolver() {
+          @Override
+          protected String getValue() {
+            return viewContext.getViewName();
+          }
+        });
+    context.put("instanceName",
+        new ParameterResolver() {
+          @Override
+          protected String getValue() {
+            return viewContext.getInstanceName();
+          }
+        });
+    return context;
+  }
+
 
   // ----- Inner class : ViewURLStreamProvider -------------------------------
 
@@ -296,4 +371,22 @@ public class ViewContextImpl implements ViewContext, 
ViewController {
       return new ViewURLStreamProvider(streamProvider);
     }
   }
+
+  // ----- Inner class : ParameterResolver -------------------------------
+
+  /**
+   * Represents basic parameter resolver to obtain fields of ViewContext at 
runtime.
+   */
+  private abstract class ParameterResolver {
+
+    protected final ViewContext viewContext = ViewContextImpl.this;
+
+    protected abstract String getValue();
+
+    @Override
+    public String toString() {
+      String value = getValue();
+      return value == null ? "" : value;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b4079b95/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
index 92608c6..5358162 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
@@ -36,6 +36,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import static org.easymock.EasyMock.createMockBuilder;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
@@ -90,6 +91,53 @@ public class ViewContextImplTest {
   }
 
   @Test
+  public void testGetPropertiesWithParameters() throws Exception {
+    InstanceConfig instanceConfig = createNiceMock(InstanceConfig.class);
+    replay(instanceConfig);
+    ViewEntity viewDefinition = createNiceMock(ViewEntity.class);
+    expect(viewDefinition.getCommonName()).andReturn("View").times(2);
+    replay(viewDefinition);
+    ViewInstanceEntity viewInstanceDefinition = 
createMockBuilder(ViewInstanceEntity.class)
+        .addMockedMethod("getUsername")
+        .addMockedMethod("getName")
+        .withConstructor(viewDefinition, instanceConfig).createMock();
+    expect(viewInstanceDefinition.getUsername()).andReturn("User").times(1);
+    expect(viewInstanceDefinition.getUsername()).andReturn("User2").times(1);
+    expect(viewInstanceDefinition.getName()).andReturn("Instance").times(3);
+    replay(viewInstanceDefinition);
+    ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
+    viewInstanceDefinition.putProperty("p1", "/tmp/some/path/${username}");
+    viewInstanceDefinition.putProperty("p2", "/tmp/path/$viewName");
+    viewInstanceDefinition.putProperty("p3", "/path/$instanceName");
+    viewInstanceDefinition.putProperty("p4", 
"/path/to/${unspecified_parameter}");
+    viewInstanceDefinition.putProperty("p5", "/path/to/${incorrect_parameter");
+    viewInstanceDefinition.putProperty("p6", "/path/to/\\${username}");
+    viewInstanceDefinition.putProperty("p7", "/path/to/\\$viewName");
+
+    ViewContextImpl viewContext = new ViewContextImpl(viewInstanceDefinition, 
viewRegistry);
+
+    Map<String, String> properties = viewContext.getProperties();
+    Assert.assertEquals(7, properties.size());
+    Assert.assertEquals("/tmp/some/path/User", properties.get("p1"));
+    Assert.assertEquals("/tmp/path/View", properties.get("p2"));
+    Assert.assertEquals("/path/Instance", properties.get("p3"));
+    Assert.assertEquals("/path/to/${unspecified_parameter}", 
properties.get("p4"));
+    Assert.assertEquals("/path/to/${incorrect_parameter", 
properties.get("p5"));
+    Assert.assertEquals("/path/to/${username}", properties.get("p6"));
+    Assert.assertEquals("/path/to/$viewName", properties.get("p7"));
+
+    properties = viewContext.getProperties();
+    Assert.assertEquals(7, properties.size());
+    Assert.assertEquals("/tmp/some/path/User2", properties.get("p1"));
+    Assert.assertEquals("/tmp/path/View", properties.get("p2"));
+    Assert.assertEquals("/path/Instance", properties.get("p3"));
+    Assert.assertEquals("/path/to/${unspecified_parameter}", 
properties.get("p4"));
+    Assert.assertEquals("/path/to/${incorrect_parameter", 
properties.get("p5"));
+    Assert.assertEquals("/path/to/${username}", properties.get("p6"));
+    Assert.assertEquals("/path/to/$viewName", properties.get("p7"));
+  }
+
+  @Test
   public void testGetResourceProvider() throws Exception {
     InstanceConfig instanceConfig = 
InstanceConfigTest.getInstanceConfigs().get(0);
     ViewEntity viewDefinition = ViewEntityTest.getViewEntity();

http://git-wip-us.apache.org/repos/asf/ambari/blob/b4079b95/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ae01194..67415b1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -222,6 +222,9 @@
             <exclude>contrib/views/*/.classpath</exclude>
             <exclude>contrib/views/*/.project</exclude>
             <exclude>contrib/views/*/.settings/**</exclude>
+                       
+            <!--Velocity log -->
+            <exclude>**/velocity.log*</exclude>
           </excludes>
         </configuration>
         <executions>

Reply via email to