You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by tb...@apache.org on 2015/04/01 23:24:17 UTC

ambari git commit: AMBARI-10306 - Views: Ability for a view instance to be associated to a cluster for configuration (tbeerbower)

Repository: ambari
Updated Branches:
  refs/heads/trunk e508a5fbf -> acdaae986


AMBARI-10306 - Views: Ability for a view instance to be associated to a cluster for configuration (tbeerbower)


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

Branch: refs/heads/trunk
Commit: acdaae986b428b09310c06f08ec42fc98b93d3b4
Parents: e508a5f
Author: tbeerbower <tb...@hortonworks.com>
Authored: Wed Apr 1 17:23:37 2015 -0400
Committer: tbeerbower <tb...@hortonworks.com>
Committed: Wed Apr 1 17:23:57 2015 -0400

----------------------------------------------------------------------
 .../internal/ViewInstanceResourceProvider.java  |  31 +++--
 .../internal/ViewVersionResourceProvider.java   |   3 +
 .../ambari/server/orm/entities/ViewEntity.java  |  32 ++++-
 .../server/orm/entities/ViewInstanceEntity.java |  24 ++++
 .../orm/entities/ViewParameterEntity.java       |  26 ++++
 .../server/upgrade/UpgradeCatalog210.java       |   6 +
 .../apache/ambari/server/view/ClusterImpl.java  |  61 +++++++++
 .../ambari/server/view/ViewContextImpl.java     | 127 ++++++++++++-------
 .../apache/ambari/server/view/ViewRegistry.java |  41 +++++-
 .../view/configuration/ParameterConfig.java     |  15 +++
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   2 +
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   2 +
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   2 +
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |   2 +
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |   4 +-
 .../ViewInstanceResourceProviderTest.java       |  12 +-
 .../server/orm/entities/ViewEntityTest.java     |  15 +++
 .../server/upgrade/UpgradeCatalog210Test.java   |  20 +++
 .../ambari/server/view/ClusterImplTest.java     |  76 +++++++++++
 .../ambari/server/view/ViewContextImplTest.java |  32 ++++-
 .../ambari/server/view/ViewRegistryTest.java    |   2 +-
 .../view/configuration/ParameterConfigTest.java |   9 ++
 .../view/configuration/ViewConfigTest.java      |   1 +
 .../org/apache/ambari/view/ViewContext.java     |  15 +++
 .../ambari/view/ViewInstanceDefinition.java     |   8 ++
 .../org/apache/ambari/view/cluster/Cluster.java |  42 ++++++
 ambari-views/src/main/resources/view.xsd        |   5 +
 27 files changed, 546 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
index 28e5e12..7cecedc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
@@ -55,18 +55,19 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
   /**
    * View instance property id constants.
    */
-  public static final String VIEW_NAME_PROPERTY_ID     = "ViewInstanceInfo/view_name";
-  public static final String VIEW_VERSION_PROPERTY_ID  = "ViewInstanceInfo/version";
-  public static final String INSTANCE_NAME_PROPERTY_ID = "ViewInstanceInfo/instance_name";
-  public static final String LABEL_PROPERTY_ID         = "ViewInstanceInfo/label";
-  public static final String DESCRIPTION_PROPERTY_ID   = "ViewInstanceInfo/description";
-  public static final String VISIBLE_PROPERTY_ID       = "ViewInstanceInfo/visible";
-  public static final String ICON_PATH_ID              = "ViewInstanceInfo/icon_path";
-  public static final String ICON64_PATH_ID            = "ViewInstanceInfo/icon64_path";
-  public static final String PROPERTIES_PROPERTY_ID    = "ViewInstanceInfo/properties";
-  public static final String DATA_PROPERTY_ID          = "ViewInstanceInfo/instance_data";
-  public static final String CONTEXT_PATH_PROPERTY_ID  = "ViewInstanceInfo/context_path";
-  public static final String STATIC_PROPERTY_ID        = "ViewInstanceInfo/static";
+  public static final String VIEW_NAME_PROPERTY_ID      = "ViewInstanceInfo/view_name";
+  public static final String VIEW_VERSION_PROPERTY_ID   = "ViewInstanceInfo/version";
+  public static final String INSTANCE_NAME_PROPERTY_ID  = "ViewInstanceInfo/instance_name";
+  public static final String LABEL_PROPERTY_ID          = "ViewInstanceInfo/label";
+  public static final String DESCRIPTION_PROPERTY_ID    = "ViewInstanceInfo/description";
+  public static final String VISIBLE_PROPERTY_ID        = "ViewInstanceInfo/visible";
+  public static final String ICON_PATH_ID               = "ViewInstanceInfo/icon_path";
+  public static final String ICON64_PATH_ID             = "ViewInstanceInfo/icon64_path";
+  public static final String PROPERTIES_PROPERTY_ID     = "ViewInstanceInfo/properties";
+  public static final String DATA_PROPERTY_ID           = "ViewInstanceInfo/instance_data";
+  public static final String CONTEXT_PATH_PROPERTY_ID   = "ViewInstanceInfo/context_path";
+  public static final String STATIC_PROPERTY_ID         = "ViewInstanceInfo/static";
+  public static final String CLUSTER_HANDLE_PROPERTY_ID = "ViewInstanceInfo/cluster_handle";
 
   // validation properties
   public static final String VALIDATION_RESULT_PROPERTY_ID           = "ViewInstanceInfo/validation_result";
@@ -105,6 +106,7 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
     propertyIds.add(DATA_PROPERTY_ID);
     propertyIds.add(CONTEXT_PATH_PROPERTY_ID);
     propertyIds.add(STATIC_PROPERTY_ID);
+    propertyIds.add(CLUSTER_HANDLE_PROPERTY_ID);
     propertyIds.add(VALIDATION_RESULT_PROPERTY_ID);
     propertyIds.add(PROPERTY_VALIDATION_RESULTS_PROPERTY_ID);
   }
@@ -229,6 +231,7 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
     setResourceProperty(resource, DESCRIPTION_PROPERTY_ID, viewInstanceEntity.getDescription(), requestedIds);
     setResourceProperty(resource, VISIBLE_PROPERTY_ID, viewInstanceEntity.isVisible(), requestedIds);
     setResourceProperty(resource, STATIC_PROPERTY_ID, viewInstanceEntity.isXmlDriven(), requestedIds);
+    setResourceProperty(resource, CLUSTER_HANDLE_PROPERTY_ID, viewInstanceEntity.getClusterHandle(), requestedIds);
 
     // only allow an admin to access the view properties
     if (ViewRegistry.getInstance().checkAdmin()) {
@@ -326,6 +329,10 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
       viewInstanceEntity.setIcon64((String) properties.get(ICON64_PATH_ID));
     }
 
+    if (properties.containsKey(CLUSTER_HANDLE_PROPERTY_ID)) {
+      viewInstanceEntity.setClusterHandle((String) properties.get(CLUSTER_HANDLE_PROPERTY_ID));
+    }
+
     Map<String, String> instanceProperties = new HashMap<String, String>();
 
     boolean isUserAdmin = viewRegistry.checkAdmin();

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewVersionResourceProvider.java
index 95703fd..6352817 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewVersionResourceProvider.java
@@ -56,6 +56,7 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider {
   public static final String MASKER_CLASS_PROPERTY_ID       = "ViewVersionInfo/masker_class";
   public static final String VIEW_STATUS_PROPERTY_ID        = "ViewVersionInfo/status";
   public static final String VIEW_STATUS_DETAIL_PROPERTY_ID = "ViewVersionInfo/status_detail";
+  public static final String CLUSTER_CONFIG_PROPERTY_ID     = "ViewVersionInfo/cluster_configurable";
   public static final String SYSTEM_PROPERTY_ID             = "ViewVersionInfo/system";
 
   /**
@@ -84,6 +85,7 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider {
     propertyIds.add(MASKER_CLASS_PROPERTY_ID);
     propertyIds.add(VIEW_STATUS_PROPERTY_ID);
     propertyIds.add(VIEW_STATUS_DETAIL_PROPERTY_ID);
+    propertyIds.add(CLUSTER_CONFIG_PROPERTY_ID);
     propertyIds.add(SYSTEM_PROPERTY_ID);
   }
 
@@ -145,6 +147,7 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider {
             setResourceProperty(resource, MASKER_CLASS_PROPERTY_ID, viewDefinition.getMask(), requestedIds);
             setResourceProperty(resource, VIEW_STATUS_PROPERTY_ID, viewDefinition.getStatus().toString(), requestedIds);
             setResourceProperty(resource, VIEW_STATUS_DETAIL_PROPERTY_ID, viewDefinition.getStatusDetail(), requestedIds);
+            setResourceProperty(resource, CLUSTER_CONFIG_PROPERTY_ID, viewDefinition.isClusterConfigurable(), requestedIds);
             setResourceProperty(resource, SYSTEM_PROPERTY_ID, viewDefinition.isSystem(), requestedIds);
 
             resources.add(resource);

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
index f77c97e..6039fb6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewEntity.java
@@ -22,6 +22,7 @@ import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.view.ViewSubResourceDefinition;
+import org.apache.ambari.server.view.configuration.ParameterConfig;
 import org.apache.ambari.server.view.configuration.ResourceConfig;
 import org.apache.ambari.server.view.configuration.ViewConfig;
 import org.apache.ambari.view.validation.Validator;
@@ -229,6 +230,12 @@ public class ViewEntity implements ViewDefinition {
   @Transient
   private String statusDetail;
 
+  /**
+   * Indicates whether or not this view is configurable through cluster association.
+   */
+  @Transient
+  private boolean clusterConfigurable;
+
 
   // ----- Constructors ------------------------------------------------------
 
@@ -241,6 +248,7 @@ public class ViewEntity implements ViewDefinition {
     this.archive              = null;
     this.externalResourceType = null;
     this.system               = 0;
+    this.clusterConfigurable  = false;
   }
 
   /**
@@ -252,7 +260,8 @@ public class ViewEntity implements ViewDefinition {
    */
   public ViewEntity(ViewConfig configuration, Configuration ambariConfiguration,
                     String archivePath) {
-    this.configuration       = configuration;
+    setConfiguration(configuration);
+
     this.ambariConfiguration = ambariConfiguration;
     this.archive             = archivePath;
 
@@ -690,7 +699,17 @@ public class ViewEntity implements ViewDefinition {
    * @param configuration  the view configuration
    */
   public void setConfiguration(ViewConfig configuration) {
-    this.configuration = configuration;
+    this.configuration       = configuration;
+    this.clusterConfigurable = false;
+
+    // if any of the parameters contain a cluster config element then the view is cluster configurable
+    for (ParameterConfig parameterConfig : configuration.getParameters()) {
+      String clusterConfig = parameterConfig.getClusterConfig();
+      if (clusterConfig != null && !clusterConfig.isEmpty()) {
+        this.clusterConfigurable = true;
+        return;
+      }
+    }
   }
 
   /**
@@ -820,6 +839,15 @@ public class ViewEntity implements ViewDefinition {
   }
 
   /**
+   * Determine whether or not this view is configurable through a cluster association.
+   *
+   * @return true if this view is cluster configurable
+   */
+  public boolean isClusterConfigurable() {
+    return clusterConfigurable;
+  }
+
+  /**
    * Determine whether or not the entity is deployed.
    *
    * @return true if the entity is deployed

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
index d55f949..a66f1bd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
@@ -112,6 +112,12 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
   private String description;
 
   /**
+   * The associated cluster handle.
+   */
+  @Column(name = "cluster_handle", nullable = true)
+  private String clusterHandle;
+
+  /**
    * Visible flag.
    */
   @Column
@@ -217,6 +223,7 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
     this.view = view;
     this.viewName = view.getName();
     this.description = instanceConfig.getDescription();
+    this.clusterHandle = null;
     this.visible = instanceConfig.isVisible() ? 'Y' : 'N';
 
     String label = instanceConfig.getLabel();
@@ -252,6 +259,7 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
     this.view = view;
     this.viewName = view.getName();
     this.description = null;
+    this.clusterHandle = null;
     this.visible = 'Y';
     this.label = label;
   }
@@ -315,6 +323,11 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
   }
 
   @Override
+  public String getClusterHandle() {
+    return clusterHandle;
+  }
+
+  @Override
   public boolean isVisible() {
     return visible == 'y' || visible == 'Y';
   }
@@ -386,6 +399,17 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
   }
 
   /**
+   * Set a cluster association for this view instance with the Ambari cluster
+   * identified by the given cluster handle.  For a local cluster reference,
+   * the cluster handle is simply the unique cluster name.
+   *
+   * @param clusterHandle  the cluster identifier
+   */
+  public void setClusterHandle(String clusterHandle) {
+    this.clusterHandle = clusterHandle;
+  }
+
+  /**
    * Set the visible flag.
    *
    * @param visible visible flag

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewParameterEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewParameterEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewParameterEntity.java
index a8ddcdb..5419d58 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewParameterEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewParameterEntity.java
@@ -69,6 +69,12 @@ public class ViewParameterEntity {
   private String defaultValue;
 
   /**
+   * The cluster configuration id used to populate the property through cluster association.
+   */
+  @Column(name = "cluster_config")
+  private String clusterConfig;
+
+  /**
    * Indicates whether or not the parameter is required.
    */
   @Column
@@ -249,4 +255,24 @@ public class ViewParameterEntity {
   public void setDefaultValue(String defaultValue) {
     this.defaultValue = defaultValue;
   }
+
+  /**
+   * Get the cluster configuration id used to populate the property for this parameter through
+   * cluster association.
+   *
+   * @return the cluster configuration id
+   */
+  public String getClusterConfig() {
+    return clusterConfig;
+  }
+
+  /**
+   * Set the cluster configuration id used to populate the property for this parameter through
+   * cluster association.
+   *
+   * @param clusterConfig  the cluster configuration id
+   */
+  public void setClusterConfig(String clusterConfig) {
+    this.clusterConfig = clusterConfig;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
index 064f536..7bdfb4f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
@@ -57,6 +57,8 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
   private static final String USER_WIDGET_TABLE = "user_widget";
   private static final String WIDGET_LAYOUT_TABLE = "widget_layout";
   private static final String WIDGET_LAYOUT_USER_WIDGET_TABLE = "widget_layout_user_widget";
+  private static final String VIEW_INSTANCE_TABLE = "viewinstance";
+  private static final String VIEW_PARAMETER_TABLE = "viewparameter";
 
   /**
    * {@inheritDoc}
@@ -230,6 +232,10 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
         "host_id", HOSTS_TABLE, "id", false);
 
     dbAccessor.dropColumn(CLUSTER_HOST_MAPPING_TABLE, "host_name");
+
+    // view columns for cluster association
+    dbAccessor.addColumn(VIEW_INSTANCE_TABLE, new DBColumnInfo("cluster_handle", String.class, 255, null, true));
+    dbAccessor.addColumn(VIEW_PARAMETER_TABLE, new DBColumnInfo("cluster_config", String.class, 255, null, true));
   }
 
   private void executeWidgetDDLUpdates() throws AmbariException, SQLException {

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/view/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ClusterImpl.java
new file mode 100644
index 0000000..529e09a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ClusterImpl.java
@@ -0,0 +1,61 @@
+/**
+ * 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.ambari.server.view;
+
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.view.cluster.Cluster;
+
+/**
+ * View associated cluster implementation.
+ */
+public class ClusterImpl implements Cluster {
+
+  /**
+   * The associated Ambari cluster.
+   */
+  private final org.apache.ambari.server.state.Cluster cluster;
+
+
+  // ----- Constructors ------------------------------------------------------
+
+  /**
+   * Create a view associated cluster from an Ambari cluster.
+   *
+   * @param cluster  the Ambari cluster
+   */
+  public ClusterImpl(org.apache.ambari.server.state.Cluster cluster) {
+    this.cluster = cluster;
+  }
+
+
+  // ----- Cluster -----------------------------------------------------------
+
+  @Override
+  public String getName() {
+    return cluster.getClusterName();
+  }
+
+  @Override
+  public String getConfigurationValue(String type, String key) {
+
+    Config config = cluster.getDesiredConfigByType(type);
+
+    return config == null ? null : config.getProperties().get(key);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/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 b7a48a8..9a4aae2 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
@@ -42,9 +42,9 @@ import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.ViewController;
 import org.apache.ambari.view.ViewDefinition;
 import org.apache.ambari.view.ViewInstanceDefinition;
+import org.apache.ambari.view.cluster.Cluster;
 import org.apache.ambari.view.events.Event;
 import org.apache.ambari.view.events.Listener;
-import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.velocity.VelocityContext;
@@ -55,6 +55,7 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -104,8 +105,12 @@ public class ViewContextImpl implements ViewContext, ViewController {
    */
   private Masker masker;
 
+  /**
+   * The velocity context used to evaluate property templates.
+   */
   private final VelocityContext velocityContext;
 
+
   // ---- Constructors -------------------------------------------------------
 
   /**
@@ -163,40 +168,7 @@ public class ViewContextImpl implements ViewContext, ViewController {
     if (viewInstanceEntity == null) {
       return null;
     } else {
-      Map<String, String> properties = viewInstanceEntity.getPropertyMap();
-
-      // unmasking
-      for (Entry<String, String> entry: properties.entrySet()) {
-        ParameterConfig parameterConfig = null;
-        for (ParameterConfig paramConfig : viewEntity.getConfiguration().getParameters()) {
-          if (StringUtils.equals(paramConfig.getName(), entry.getKey())) {
-            parameterConfig = paramConfig;
-            break;
-          }
-        }
-        if (parameterConfig == null || !parameterConfig.isMasked()) {
-          properties.put(entry.getKey(), entry.getValue());
-        } else {
-          try {
-            properties.put(entry.getKey(), masker.unmask(entry.getValue()));
-          } catch (MaskException e) {
-            LOG.error("Failed to unmask view property", e);
-          }
-        }
-      }
-
-      // parametrizing
-
-      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);
+      return Collections.unmodifiableMap(getPropertyValues());
     }
   }
 
@@ -339,6 +311,11 @@ public class ViewContextImpl implements ViewContext, ViewController {
     return new ImpersonatorSettingImpl(this);
   }
 
+  @Override
+  public Cluster getCluster() {
+    return viewRegistry.getCluster(viewInstanceEntity);
+  }
+
 
   // ----- ViewController ----------------------------------------------------
 
@@ -396,24 +373,86 @@ public class ViewContextImpl implements ViewContext, ViewController {
   }
 
   /**
-   * Parameterize string using VelocityContext instance
+   * Get the property values for the associated view instance.
    *
-   * @param raw original string with parameters in formal or shorthand notation
+   * @return the property values for the instance
+   */
+  private Map<String, String> getPropertyValues() {
+    Map<String, String> properties = viewInstanceEntity.getPropertyMap();
+
+    Map<String, ParameterConfig> parameters = new HashMap<String, ParameterConfig>();
+
+    for (ParameterConfig paramConfig : viewEntity.getConfiguration().getParameters()) {
+      parameters.put(paramConfig.getName(), paramConfig);
+    }
+
+    Cluster cluster = getCluster();
+
+    for (Entry<String, String> entry: properties.entrySet()) {
+      String propertyName  = entry.getKey();
+      String propertyValue = entry.getValue();
+
+      ParameterConfig parameterConfig = parameters.get(propertyName);
+
+      if (parameterConfig != null) {
+
+        String clusterConfig = parameterConfig.getClusterConfig();
+        if (clusterConfig != null && cluster != null) {
+          propertyValue = getClusterConfigurationValue(cluster, clusterConfig);
+        } else {
+          if (parameterConfig.isMasked()) {
+            try {
+              propertyValue = masker.unmask(propertyValue);
+            } catch (MaskException e) {
+              LOG.error("Failed to unmask view property", e);
+            }
+          }
+        }
+      }
+      properties.put(propertyName, evaluatePropertyTemplates(propertyValue));
+    }
+    return properties;
+  }
+
+  /**
+   * Get a specified configuration value from the given cluster.
    *
-   * @return parameterized string
+   * @param cluster        the cluster
+   * @param clusterConfig  the cluster configuration identifier
    *
-   * @throws ParseErrorException if original string cannot be parsed by Velocity
+   * @return the configuration value or <code>null</code> if the desired configuration can not be found
    */
-  private String parameterize(String raw) throws ParseErrorException {
-    if (raw != null) {
-      Writer templateWriter = new StringWriter();
-      Velocity.evaluate(velocityContext, templateWriter, raw, raw);
-      return templateWriter.toString();
+  private static String getClusterConfigurationValue(Cluster cluster, String clusterConfig) {
+    if (clusterConfig != null) {
+      String[] parts = clusterConfig.split("/");
+      if (parts.length == 2) {
+        return cluster.getConfigurationValue(parts[0], parts[1]);
+      }
     }
     return null;
   }
 
   /**
+   * Evaluate any templates in the given property value.
+   *
+   * @param rawValue original string with parameters in formal or shorthand notation
+   *
+   * @return the evaluated property value
+   */
+  private String evaluatePropertyTemplates(String rawValue) {
+    if (rawValue != null) {
+      try {
+        Writer templateWriter = new StringWriter();
+        Velocity.evaluate(velocityContext, templateWriter, rawValue, rawValue);
+        return templateWriter.toString();
+      } catch (ParseErrorException e) {
+        LOG.warn(String.format("Error during parsing '%s' parameter. Leaving original value.", rawValue));
+      }
+    }
+    return rawValue;
+  }
+
+  /**
    * Instantiate and initialize context for parameters processing using Velocity.
    *
    * @return initialized context instance

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
index 419ba02..1ae1dfd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
@@ -24,6 +24,7 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.Transactional;
 
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
 import org.apache.ambari.server.api.resources.SubResourceDefinition;
 import org.apache.ambari.server.api.resources.ViewExternalSubResourceDefinition;
@@ -60,6 +61,7 @@ import org.apache.ambari.server.orm.entities.ViewParameterEntity;
 import org.apache.ambari.server.orm.entities.ViewResourceEntity;
 import org.apache.ambari.server.security.SecurityHelper;
 import org.apache.ambari.server.security.authorization.AmbariGrantedAuthority;
+import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.utils.VersionUtils;
 import org.apache.ambari.server.view.configuration.EntityConfig;
 import org.apache.ambari.server.view.configuration.InstanceConfig;
@@ -70,6 +72,8 @@ import org.apache.ambari.server.view.configuration.PropertyConfig;
 import org.apache.ambari.server.view.configuration.ResourceConfig;
 import org.apache.ambari.server.view.configuration.ViewConfig;
 import org.apache.ambari.server.view.validation.ValidationException;
+import org.apache.ambari.view.ViewInstanceDefinition;
+import org.apache.ambari.view.cluster.Cluster;
 import org.apache.ambari.view.validation.Validator;
 import org.apache.ambari.view.Masker;
 import org.apache.ambari.view.SystemException;
@@ -211,10 +215,16 @@ public class ViewRegistry {
   ResourceTypeDAO resourceTypeDAO;
 
   /**
+   * The Ambari managed clusters.
+   */
+  @Inject
+  Provider<Clusters> clustersProvider;
+
+  /**
    * Ambari meta info.
    */
   @Inject
-  Provider<AmbariMetaInfo> ambariMetaInfo;
+  Provider<AmbariMetaInfo> ambariMetaInfoProvider;
 
   /**
    * Ambari configuration.
@@ -811,6 +821,27 @@ public class ViewRegistry {
     }
   }
 
+  /**
+   * Get the cluster associated with the given view instance.
+   *
+   * @param viewInstance  the view instance
+   *
+   * @return the cluster
+   */
+  public Cluster getCluster(ViewInstanceDefinition viewInstance) {
+    if (viewInstance != null) {
+      String clusterId = viewInstance.getClusterHandle();
+
+      if (clusterId != null) {
+        try {
+          return new ClusterImpl(clustersProvider.get().getCluster(clusterId));
+        } catch (AmbariException e) {
+          LOG.warn("Could not find the cluster identified by " + clusterId + ".");
+        }
+      }
+    }
+    return null;
+  }
 
   // ----- helper methods ----------------------------------------------------
 
@@ -861,6 +892,7 @@ public class ViewRegistry {
       viewParameterEntity.setLabel(parameterConfiguration.getLabel());
       viewParameterEntity.setPlaceholder(parameterConfiguration.getPlaceholder());
       viewParameterEntity.setDefaultValue(parameterConfiguration.getDefaultValue());
+      viewParameterEntity.setClusterConfig(parameterConfiguration.getClusterConfig());
       viewParameterEntity.setRequired(parameterConfiguration.isRequired());
       viewParameterEntity.setMasked(parameterConfiguration.isMasked());
       viewParameterEntity.setViewEntity(viewDefinition);
@@ -1016,8 +1048,8 @@ public class ViewRegistry {
 
   // Set the entities defined in the view persistence element for the given view instance
   private static void setPersistenceEntities(ViewInstanceEntity viewInstanceDefinition) {
-    ViewEntity        viewDefinition    = viewInstanceDefinition.getViewEntity();
-    ViewConfig        viewConfig        = viewDefinition.getConfiguration();
+    ViewEntity viewDefinition = viewInstanceDefinition.getViewEntity();
+    ViewConfig viewConfig     = viewDefinition.getConfiguration();
 
     Collection<ViewEntityEntity> entities = new HashSet<ViewEntityEntity>();
 
@@ -1205,6 +1237,7 @@ public class ViewRegistry {
     instance1.setVisible(instance2.isVisible());
     instance1.setResource(instance2.getResource());
     instance1.setViewInstanceId(instance2.getViewInstanceId());
+    instance1.setClusterHandle(instance2.getClusterHandle());
     instance1.setData(instance2.getData());
     instance1.setEntities(instance2.getEntities());
     instance1.setProperties(instance2.getProperties());
@@ -1292,7 +1325,7 @@ public class ViewRegistry {
 
           Set<Runnable> extractionRunnables = new HashSet<Runnable>();
 
-          final String serverVersion = ambariMetaInfo.get().getServerVersion();
+          final String serverVersion = ambariMetaInfoProvider.get().getServerVersion();
 
           for (final File archiveFile : files) {
             if (!archiveFile.isDirectory()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ParameterConfig.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ParameterConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ParameterConfig.java
index e983609..8e686eb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ParameterConfig.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ParameterConfig.java
@@ -54,6 +54,12 @@ public class ParameterConfig {
   private String defaultValue;
 
   /**
+   * The parameter cluster configuration id value.
+   */
+  @XmlElement(name="cluster-config")
+  private String clusterConfig;
+
+  /**
    * Indicates whether or not the parameter is required.
    */
   private boolean required;
@@ -109,6 +115,15 @@ public class ParameterConfig {
   }
 
   /**
+   * Get the cluster configuration id used to pull configuration from an associated Ambari cluster.
+   *
+   * @return the cluster configuration id
+   */
+  public String getClusterConfig() {
+    return clusterConfig;
+  }
+
+  /**
    * Indicates whether or not the parameter is required.
    *
    * @return true if the parameter is required; false otherwise

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index 26ff9bb..e28edfd 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -456,6 +456,7 @@ CREATE TABLE viewinstance (
   icon VARCHAR(255),
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
+  cluster_handle VARCHAR(255),
   PRIMARY KEY(view_instance_id));
 
 CREATE TABLE viewinstanceproperty (
@@ -472,6 +473,7 @@ CREATE TABLE viewparameter (
   label VARCHAR(255),
   placeholder VARCHAR(255),
   default_value VARCHAR(2000),
+  cluster_config VARCHAR(255),
   required CHAR(1),
   masked CHAR(1),
   PRIMARY KEY(view_name, name));

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index 13e8939..513d951 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -445,6 +445,7 @@ CREATE TABLE viewinstance (
   icon VARCHAR(255),
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
+  cluster_handle VARCHAR(255),
   PRIMARY KEY(view_instance_id));
 
 CREATE TABLE viewinstanceproperty (
@@ -461,6 +462,7 @@ CREATE TABLE viewparameter (
   label VARCHAR(255),
   placeholder VARCHAR(255),
   default_value VARCHAR(2000),
+  cluster_config VARCHAR(255),
   required CHAR(1),
   masked CHAR(1),
   PRIMARY KEY(view_name, name));

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 622fca3..6361edb 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -448,6 +448,7 @@ CREATE TABLE viewinstance (
   icon VARCHAR(255),
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
+  cluster_handle VARCHAR(255),
   PRIMARY KEY(view_instance_id));
 
 CREATE TABLE viewinstanceproperty (
@@ -464,6 +465,7 @@ CREATE TABLE viewparameter (
   label VARCHAR(255),
   placeholder VARCHAR(255),
   default_value VARCHAR(2000),
+  cluster_config VARCHAR(255),
   required CHAR(1),
   masked CHAR(1),
   PRIMARY KEY(view_name, name));

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index 9fe9cd7..2121805 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -501,6 +501,7 @@ CREATE TABLE ambari.viewinstance (
   icon VARCHAR(255),
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
+  cluster_handle VARCHAR(255),
   PRIMARY KEY(view_instance_id));
 
 CREATE TABLE ambari.viewinstanceproperty (
@@ -517,6 +518,7 @@ CREATE TABLE ambari.viewparameter (
   label VARCHAR(255),
   placeholder VARCHAR(255),
   default_value VARCHAR(2000),
+  cluster_config VARCHAR(255),
   required CHAR(1),
   masked CHAR(1),
   PRIMARY KEY(view_name, name));

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index a722d2a..40b00d9 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -97,9 +97,9 @@ CREATE TABLE blueprint_configuration (blueprint_name varchar(255) NOT NULL, type
 CREATE TABLE hostgroup_configuration (blueprint_name VARCHAR(255) NOT NULL, hostgroup_name VARCHAR(255) NOT NULL, type_name VARCHAR(255) NOT NULL, config_data TEXT NOT NULL, config_attributes TEXT, PRIMARY KEY(blueprint_name, hostgroup_name, type_name));
 CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), description VARCHAR(2048), version VARCHAR(255), resource_type_id INTEGER NOT NULL, icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), mask VARCHAR(255), system_view BIT NOT NULL DEFAULT 0, PRIMARY KEY(view_name));
 CREATE TABLE viewinstancedata (view_instance_id BIGINT, view_name VARCHAR(255) NOT NULL, view_instance_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, user_name VARCHAR(255) NOT NULL, value VARCHAR(2000) NOT NULL, PRIMARY KEY(view_instance_id, name, user_name));
-CREATE TABLE viewinstance (view_instance_id BIGINT, resource_id BIGINT NOT NULL, view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, label VARCHAR(255), description VARCHAR(2048), visible CHAR(1), icon VARCHAR(255), icon64 VARCHAR(255), xml_driven CHAR(1), PRIMARY KEY(view_instance_id));
+CREATE TABLE viewinstance (view_instance_id BIGINT, resource_id BIGINT NOT NULL, view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, label VARCHAR(255), description VARCHAR(2048), visible CHAR(1), icon VARCHAR(255), icon64 VARCHAR(255), xml_driven CHAR(1), cluster_handle VARCHAR(255), PRIMARY KEY(view_instance_id));
 CREATE TABLE viewinstanceproperty (view_name VARCHAR(255) NOT NULL, view_instance_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, value VARCHAR(2000) NOT NULL, PRIMARY KEY(view_name, view_instance_name, name));
-CREATE TABLE viewparameter (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(2048), label VARCHAR(255), placeholder VARCHAR(255), default_value VARCHAR(2000), required CHAR(1), masked CHAR(1), PRIMARY KEY(view_name, name));
+CREATE TABLE viewparameter (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(2048), label VARCHAR(255), placeholder VARCHAR(255), default_value VARCHAR(2000), cluster_config VARCHAR(255), required CHAR(1), masked CHAR(1), PRIMARY KEY(view_name, name));
 CREATE TABLE viewresource (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, plural_name VARCHAR(255), id_property VARCHAR(255), subResource_names VARCHAR(255), provider VARCHAR(255), service VARCHAR(255), resource VARCHAR(255), PRIMARY KEY(view_name, name));
 CREATE TABLE viewentity (id BIGINT NOT NULL, view_name VARCHAR(255) NOT NULL, view_instance_name VARCHAR(255) NOT NULL, class_name VARCHAR(255) NOT NULL, id_property VARCHAR(255), PRIMARY KEY(id));
 CREATE TABLE adminresourcetype (resource_type_id INTEGER NOT NULL, resource_type_name VARCHAR(255) NOT NULL, PRIMARY KEY(resource_type_id));

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java
index 31c65c3..1af7264 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java
@@ -62,6 +62,7 @@ public class ViewInstanceResourceProviderTest {
     ViewInstanceResourceProvider provider = new ViewInstanceResourceProvider();
     Set<String> propertyIds = new HashSet<String>();
     propertyIds.add(ViewInstanceResourceProvider.PROPERTIES_PROPERTY_ID);
+    propertyIds.add(ViewInstanceResourceProvider.CLUSTER_HANDLE_PROPERTY_ID);
     ViewInstanceEntity viewInstanceEntity = createNiceMock(ViewInstanceEntity.class);
     ViewEntity viewEntity = createNiceMock(ViewEntity.class);
     expect(viewInstanceEntity.getViewEntity()).andReturn(viewEntity).anyTimes();
@@ -78,13 +79,20 @@ public class ViewInstanceResourceProviderTest {
     expect(singleton.checkAdmin()).andReturn(true);
     expect(singleton.checkAdmin()).andReturn(false);
 
+    expect(viewInstanceEntity.getClusterHandle()).andReturn("c1");
+
     replay(singleton, viewEntity, viewInstanceEntity);
 
     // as admin
     Resource resource = provider.toResource(viewInstanceEntity, propertyIds);
     Map<String, Map<String, Object>> properties = resource.getPropertiesMap();
-    assertEquals(1, properties.size());
-    Map<String, Object> props = properties.get("ViewInstanceInfo/properties");
+    assertEquals(2, properties.size());
+    Map<String, Object> props = properties.get("ViewInstanceInfo");
+    assertNotNull(props);
+    assertEquals(1, props.size());
+    assertEquals("c1", props.get("cluster_handle"));
+
+    props = properties.get("ViewInstanceInfo/properties");
     assertNotNull(props);
     assertEquals(2, props.size());
     assertEquals("val1", props.get("par1"));

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java
index a9ceb93..ac2715c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java
@@ -140,6 +140,21 @@ public class ViewEntityTest {
   }
 
   @Test
+  public void testIsClusterConfigurable() throws Exception {
+    ViewConfig viewConfig = ViewConfigTest.getConfig();
+    ViewEntity viewDefinition = getViewEntity(viewConfig);
+    Assert.assertEquals(viewConfig, viewDefinition.getConfiguration());
+
+    ViewConfig newViewConfig = ViewConfigTest.getConfig();
+    viewDefinition.setConfiguration(newViewConfig);
+    Assert.assertTrue(viewDefinition.isClusterConfigurable());
+
+    newViewConfig = ViewConfigTest.getConfig(with_ambari_versions);
+    viewDefinition.setConfiguration(newViewConfig);
+    Assert.assertFalse(viewDefinition.isClusterConfigurable());
+  }
+
+  @Test
   public void testGetAmbariProperty() throws Exception {
     ViewConfig viewConfig = ViewConfigTest.getConfig();
     ViewEntity viewDefinition = getViewEntity(viewConfig);

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
index 07b8410..47cadf3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
@@ -98,10 +98,15 @@ public class UpgradeCatalog210Test {
 
     // Column Capture section
     Capture<DBAccessor.DBColumnInfo> hostsColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+    Capture<DBAccessor.DBColumnInfo> viewInstanceColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+    Capture<DBAccessor.DBColumnInfo> viewParamColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
 
     // Add columns and alter table section
     dbAccessor.addColumn(eq("hosts"), capture(hostsColumnCapture));
 
+    dbAccessor.addColumn(eq("viewinstance"), capture(viewInstanceColumnCapture));
+    dbAccessor.addColumn(eq("viewparameter"), capture(viewParamColumnCapture));
+
     Capture<List<DBColumnInfo>> userWidgetColumnsCapture = new Capture<List<DBColumnInfo>>();
     Capture<List<DBColumnInfo>> widgetLayoutColumnsCapture = new Capture<List<DBColumnInfo>>();
     Capture<List<DBColumnInfo>> widgetLayoutUserWidgetColumnsCapture = new Capture<List<DBColumnInfo>>();
@@ -133,6 +138,8 @@ public class UpgradeCatalog210Test {
 
     // Verification section
     verifyHosts(hostsColumnCapture);
+    verifyViewInstance(viewInstanceColumnCapture);
+    verifyViewParameter(viewParamColumnCapture);
 
 
     // Verify widget tables
@@ -147,6 +154,19 @@ public class UpgradeCatalog210Test {
     Assert.assertEquals("id", hostsIdColumn.getName());
   }
 
+  private void verifyViewInstance(Capture<DBAccessor.DBColumnInfo> viewInstanceColumnCapture) {
+    DBColumnInfo clusterIdColumn = viewInstanceColumnCapture.getValue();
+    Assert.assertEquals(String.class, clusterIdColumn.getType());
+    Assert.assertEquals("cluster_handle", clusterIdColumn.getName());
+  }
+
+
+  private void verifyViewParameter(Capture<DBAccessor.DBColumnInfo> viewParamColumnCapture) {
+    DBColumnInfo clusterConfigColumn = viewParamColumnCapture.getValue();
+    Assert.assertEquals(String.class, clusterConfigColumn.getType());
+    Assert.assertEquals("cluster_config", clusterConfigColumn.getName());
+  }
+
   /**
    * @param dbAccessor
    * @return

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/test/java/org/apache/ambari/server/view/ClusterImplTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ClusterImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ClusterImplTest.java
new file mode 100644
index 0000000..daf87ec
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ClusterImplTest.java
@@ -0,0 +1,76 @@
+/**
+ * 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.ambari.server.view;
+
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.view.configuration.InstanceConfig;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.*;
+
+/**
+ * ClusterImpl tests.
+ */
+public class ClusterImplTest {
+
+  @Test
+  public void testGetName() throws Exception {
+    Cluster cluster = createNiceMock(Cluster.class);
+
+    expect(cluster.getClusterName()).andReturn("c1").anyTimes();
+
+    replay(cluster);
+
+    ClusterImpl clusterImpl = new ClusterImpl(cluster);
+
+    Assert.assertEquals("c1", clusterImpl.getName());
+
+    verify(cluster);
+  }
+
+  @Test
+  public void testGetConfigurationValue() throws Exception {
+    Cluster cluster = createNiceMock(Cluster.class);
+    Config config = createNiceMock(Config.class);
+
+    Map<String, String> properties = new HashMap<String, String>();
+
+    properties.put("foo", "bar");
+
+    expect(cluster.getDesiredConfigByType("core-site")).andReturn(config).anyTimes();
+    expect(config.getProperties()).andReturn(properties).anyTimes();
+
+    replay(cluster, config);
+
+    ClusterImpl clusterImpl = new ClusterImpl(cluster);
+
+    Assert.assertEquals("bar", clusterImpl.getConfigurationValue("core-site", "foo"));
+
+    verify(cluster, config);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/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 84794e8..b470da2 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
@@ -27,6 +27,7 @@ import org.apache.ambari.server.view.configuration.InstanceConfig;
 import org.apache.ambari.server.view.configuration.InstanceConfigTest;
 import org.apache.ambari.server.view.configuration.ViewConfigTest;
 import org.apache.ambari.view.ResourceProvider;
+import org.apache.ambari.view.cluster.Cluster;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -73,6 +74,9 @@ public class ViewContextImplTest {
     ViewEntity viewDefinition = ViewEntityTest.getViewEntity();
     ViewInstanceEntity viewInstanceDefinition = new ViewInstanceEntity(viewDefinition, instanceConfig);
     ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
+
+    expect(viewRegistry.getCluster(viewInstanceDefinition)).andReturn(null).anyTimes();
+
     viewInstanceDefinition.putProperty("p1", "v1");
     viewInstanceDefinition.putProperty("p2", new DefaultMasker().mask("v2"));
     viewInstanceDefinition.putProperty("p3", "v3");
@@ -90,8 +94,10 @@ public class ViewContextImplTest {
   @Test
   public void testGetPropertiesWithParameters() throws Exception {
     InstanceConfig instanceConfig = createNiceMock(InstanceConfig.class);
+    expect(instanceConfig.getName()).andReturn("Instance").anyTimes();
     replay(instanceConfig);
     ViewEntity viewDefinition = createNiceMock(ViewEntity.class);
+    expect(viewDefinition.getName()).andReturn("View").anyTimes();
     expect(viewDefinition.getCommonName()).andReturn("View").times(2);
     expect(viewDefinition.getClassLoader()).andReturn(ViewContextImplTest.class.getClassLoader()).anyTimes();
     expect(viewDefinition.getConfiguration()).andReturn(ViewConfigTest.getConfig()).anyTimes();
@@ -110,10 +116,12 @@ public class ViewContextImplTest {
         .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);
-    expect(viewInstanceDefinition.getViewEntity()).andReturn(viewDefinition).times(1);
+    expect(viewInstanceDefinition.getName()).andReturn("Instance").anyTimes();
+    expect(viewInstanceDefinition.getViewEntity()).andReturn(viewDefinition).anyTimes();
     replay(viewInstanceDefinition);
     ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
+    expect(viewRegistry.getCluster(viewInstanceDefinition)).andReturn(null).anyTimes();
+    replay(viewRegistry);
     viewInstanceDefinition.putProperty("p1", "/tmp/some/path/${username}");
     viewInstanceDefinition.putProperty("p2", new DefaultMasker().mask("/tmp/path/$viewName"));
     viewInstanceDefinition.putProperty("p3", "/path/$instanceName");
@@ -212,4 +220,24 @@ public class ViewContextImplTest {
 
     verify(viewRegistry);
   }
+
+  @Test
+  public void testGetCluster() throws Exception {
+    InstanceConfig instanceConfig = InstanceConfigTest.getInstanceConfigs().get(0);
+    ViewEntity viewDefinition = ViewEntityTest.getViewEntity();
+    ViewInstanceEntity viewInstanceDefinition = new ViewInstanceEntity(viewDefinition, instanceConfig);
+    ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
+
+    Cluster cluster = createNiceMock(Cluster.class);
+
+    expect(viewRegistry.getCluster(viewInstanceDefinition)).andReturn(cluster);
+
+    replay(viewRegistry);
+
+    ViewContextImpl viewContext = new ViewContextImpl(viewInstanceDefinition, viewRegistry);
+
+    Assert.assertEquals(cluster, viewContext.getCluster());
+
+    verify(viewRegistry);
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
index f5118e2..3a57b1b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
@@ -1617,7 +1617,7 @@ public class ViewRegistryTest {
     instance.extractor.archiveUtility = instance.archiveUtility;
 
     final AmbariMetaInfo finalMetaInfo = ambariMetaInfo;
-    instance.ambariMetaInfo = new Provider<AmbariMetaInfo>() {
+    instance.ambariMetaInfoProvider = new Provider<AmbariMetaInfo>() {
       @Override
       public AmbariMetaInfo get() {
         return finalMetaInfo;

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ParameterConfigTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ParameterConfigTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ParameterConfigTest.java
index 278e441..ce599b6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ParameterConfigTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ParameterConfigTest.java
@@ -74,6 +74,15 @@ public class ParameterConfigTest {
   }
 
   @Test
+  public void testGetClusterConfig() throws Exception {
+    List<ParameterConfig> parameters = getParameterConfigs();
+
+    Assert.assertEquals(2, parameters.size());
+    Assert.assertNull(parameters.get(0).getClusterConfig());
+    Assert.assertEquals("hdfs-site/dfs.namenode.http-address", parameters.get(1).getClusterConfig());
+  }
+
+  @Test
   public void testIsRequired() throws Exception {
     List<ParameterConfig> parameters = getParameterConfigs();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
index 75ab10a..1875238 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
@@ -66,6 +66,7 @@ public class ViewConfigTest {
       "        <name>p2</name>\n" +
       "        <description>Parameter 2.</description>\n" +
       "        <default-value>Default value 1.</default-value>\n" +
+      "        <cluster-config>hdfs-site/dfs.namenode.http-address</cluster-config>\n" +
       "        <required>false</required>\n" +
       "        <masked>true</masked>" +
       "    </parameter>\n" +

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java b/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
index 432babb..2522486 100644
--- a/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
+++ b/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
@@ -18,6 +18,8 @@
 
 package org.apache.ambari.view;
 
+import org.apache.ambari.view.cluster.Cluster;
+
 import java.util.Collection;
 import java.util.Map;
 
@@ -187,13 +189,26 @@ public interface ViewContext {
    * Get the HTTP Impersonator.
    *
    * @return the HTTP Impersonator, which internally uses the App Cookie Manager
+   *
+   * @deprecated  As of release 2.0
    */
+  @Deprecated
   public HttpImpersonator getHttpImpersonator();
 
   /**
    * Get the default settings for the Impersonator.
    *
    * @return the Impersonator settings.
+   *
+   * @deprecated  As of release 2.0
    */
+  @Deprecated
   public ImpersonatorSetting getImpersonatorSetting();
+
+  /**
+   * Get the cluster associated with this view instance.
+   *
+   * @return the associated cluster; <code>null</code> if no cluster is associated
+   */
+  public Cluster getCluster();
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java b/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java
index ff9090b..d694459 100644
--- a/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java
+++ b/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java
@@ -54,6 +54,14 @@ public interface ViewInstanceDefinition {
   public String getDescription();
 
   /**
+   * Get the cluster handle associated with this view instance.  For a local cluster reference,
+   * the cluster handle is simply the unique cluster name.
+   *
+   * @return the associated cluster handle; <code>null</code> if no cluster is associated
+   */
+  public String getClusterHandle();
+
+  /**
    * Indicates whether or not the view instance should be visible.
    *
    * @return true if the view instance should be visible; false otherwise

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-views/src/main/java/org/apache/ambari/view/cluster/Cluster.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/cluster/Cluster.java b/ambari-views/src/main/java/org/apache/ambari/view/cluster/Cluster.java
new file mode 100644
index 0000000..f1b8177
--- /dev/null
+++ b/ambari-views/src/main/java/org/apache/ambari/view/cluster/Cluster.java
@@ -0,0 +1,42 @@
+/**
+ * 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.ambari.view.cluster;
+
+/**
+ * View associated cluster.  A cluster may be associated with a view instance so that the view instance may pull
+ * configuration values from the cluster.
+ */
+public interface Cluster {
+  /**
+   * Get the cluster name.
+   *
+   * @return the cluster name
+   */
+  public String getName();
+
+  /**
+   * Get a value for the given configuration type and key.
+   *
+   * @param type  the configuration id  (i.e. hdfs-site)
+   * @param key   the configuration key (i.e. dfs.namenode.http-address)
+   *
+   * @return the configuration value
+   */
+  public String getConfigurationValue(String type, String key);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/acdaae98/ambari-views/src/main/resources/view.xsd
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/resources/view.xsd b/ambari-views/src/main/resources/view.xsd
index e994faf..b5ed669 100644
--- a/ambari-views/src/main/resources/view.xsd
+++ b/ambari-views/src/main/resources/view.xsd
@@ -48,6 +48,11 @@
           <xs:documentation>The default value of the configuration parameter.</xs:documentation>
         </xs:annotation>
       </xs:element>
+      <xs:element type="xs:string" name="cluster-config" minOccurs="0" maxOccurs="1">
+        <xs:annotation>
+          <xs:documentation>The cluster configuration id.  The presence of this element indicates that the property value may be obtained through a cluster association.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
       <xs:element type="xs:boolean" name="required" minOccurs="0" maxOccurs="1" default="false">
         <xs:annotation>
           <xs:documentation>If true, the configuration parameter is required in order to create a view instance.  The default is false (not required).</xs:documentation>