You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2014/07/01 22:38:03 UTC
git commit: AMBARI-6344. Views: Add optional attribute to
in view.xml.
Repository: ambari
Updated Branches:
refs/heads/trunk d853a99a8 -> 01e9e7607
AMBARI-6344. Views: Add <mask> optional attribute to <parameter> in view.xml.
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/01e9e760
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/01e9e760
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/01e9e760
Branch: refs/heads/trunk
Commit: 01e9e76079f4fb5aeffa5ce059644f16296f5291
Parents: d853a99
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Tue Jul 1 13:20:37 2014 -0700
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Tue Jul 1 13:39:17 2014 -0700
----------------------------------------------------------------------
.../internal/ViewVersionResourceProvider.java | 15 ++--
.../ambari/server/orm/entities/ViewEntity.java | 27 +++++++
.../orm/entities/ViewParameterEntity.java | 24 ++++++
.../server/upgrade/UpgradeCatalog170.java | 6 ++
.../ambari/server/view/DefaultMasker.java | 48 ++++++++++++
.../ambari/server/view/ViewContextImpl.java | 82 +++++++++++++++-----
.../apache/ambari/server/view/ViewRegistry.java | 48 +++++++++---
.../view/configuration/ParameterConfig.java | 14 ++++
.../server/view/configuration/ViewConfig.java | 45 ++++++++++-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 4 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 4 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 4 +-
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 4 +-
.../server/upgrade/UpgradeCatalog170Test.java | 43 +++++++++-
.../ambari/server/view/DefaultMaskerTest.java | 47 +++++++++++
.../ambari/server/view/ViewContextImplTest.java | 9 ++-
.../view/configuration/ParameterConfigTest.java | 9 +++
.../view/configuration/ViewConfigTest.java | 8 ++
ambari-views/pom.xml | 21 ++---
.../org/apache/ambari/view/MaskException.java | 33 ++++++++
.../java/org/apache/ambari/view/Masker.java | 43 ++++++++++
.../ambari/view/PersistenceException.java | 2 +-
.../org/apache/ambari/view/ViewDefinition.java | 7 ++
23 files changed, 490 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 485eb04..5793a1b 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
@@ -44,12 +44,13 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider {
/**
* View property id constants.
*/
- public static final String VIEW_NAME_PROPERTY_ID = "ViewVersionInfo/view_name";
- public static final String VIEW_VERSION_PROPERTY_ID = "ViewVersionInfo/version";
- public static final String LABEL_PROPERTY_ID = "ViewVersionInfo/label";
- public static final String VERSION_PROPERTY_ID = "ViewVersionInfo/version";
- public static final String PARAMETERS_PROPERTY_ID = "ViewVersionInfo/parameters";
- public static final String ARCHIVE_PROPERTY_ID = "ViewVersionInfo/archive";
+ public static final String VIEW_NAME_PROPERTY_ID = "ViewVersionInfo/view_name";
+ public static final String VIEW_VERSION_PROPERTY_ID = "ViewVersionInfo/version";
+ public static final String LABEL_PROPERTY_ID = "ViewVersionInfo/label";
+ public static final String VERSION_PROPERTY_ID = "ViewVersionInfo/version";
+ public static final String PARAMETERS_PROPERTY_ID = "ViewVersionInfo/parameters";
+ public static final String ARCHIVE_PROPERTY_ID = "ViewVersionInfo/archive";
+ public static final String MASKER_CLASS_PROPERTY_ID = "ViewVersionInfo/masker_class";
/**
* The key property ids for a view resource.
@@ -71,6 +72,7 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider {
propertyIds.add(VERSION_PROPERTY_ID);
propertyIds.add(PARAMETERS_PROPERTY_ID);
propertyIds.add(ARCHIVE_PROPERTY_ID);
+ propertyIds.add(MASKER_CLASS_PROPERTY_ID);
}
@@ -123,6 +125,7 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider {
setResourceProperty(resource, PARAMETERS_PROPERTY_ID,
viewDefinition.getConfiguration().getParameters(), requestedIds);
setResourceProperty(resource, ARCHIVE_PROPERTY_ID, viewDefinition.getArchive(), requestedIds);
+ setResourceProperty(resource, MASKER_CLASS_PROPERTY_ID, viewDefinition.getMask(), requestedIds);
resources.add(resource);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 eaf2589..a26e5e7 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
@@ -94,6 +94,13 @@ public class ViewEntity implements ViewDefinition {
private String archive;
/**
+ * The masker class for parameters.
+ */
+ @Column
+ @Basic
+ private String mask;
+
+ /**
* The list of view parameters.
*/
@OneToMany(cascade = CascadeType.ALL, mappedBy = "view")
@@ -202,6 +209,8 @@ public class ViewEntity implements ViewDefinition {
this.name = getViewName(configuration.getName(), version);
this.label = configuration.getLabel();
this.version = version;
+
+ this.mask = configuration.getMasker();
this.icon = configuration.getIcon();
this.icon64 = configuration.getIcon64();
@@ -580,6 +589,24 @@ public class ViewEntity implements ViewDefinition {
return view;
}
+ /**
+ * Set the mask class name.
+ *
+ * @param mask the mask class name
+ */
+ public void setMask(String mask) {
+ this.mask = mask;
+ }
+
+ /**
+ * Get the mask class name.
+ *
+ * @return the mask class name.
+ */
+ public String getMask() {
+ return mask;
+ }
+
// ----- helper methods ----------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 b3a7320..0c4c70f 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
@@ -58,6 +58,13 @@ public class ViewParameterEntity {
@Basic
private char required;
+ /**
+ * Indicates whether or not the parameter is masked when persisted.
+ */
+ @Column
+ @Basic
+ private char masked;
+
@ManyToOne
@JoinColumn(name = "view_name", referencedColumnName = "view_name", nullable = false)
private ViewEntity view;
@@ -138,6 +145,23 @@ public class ViewParameterEntity {
}
/**
+ * Determine whether or not the parameter is masked.
+ *
+ * @return true if parameter is masked
+ */
+ public boolean isMasked() {
+ return masked == 'y' || masked == 'Y';
+ }
+
+ /**
+ * Set the flag which indicate whether or not the parameter is masked
+ * @param masked the masked flag; true if the parameter is masked
+ */
+ public void setMasked(boolean masked) {
+ this.masked = (masked ? 'Y' : 'N');
+ }
+
+ /**
* Get the associated view entity.
*
* @return the view entity
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
index 029e98c..50087e5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
@@ -65,6 +65,12 @@ public class UpgradeCatalog170 extends AbstractUpgradeCatalog {
DBAccessor.DBColumnInfo clusterConfigAttributesColumn = new DBAccessor.DBColumnInfo(
"config_attributes", String.class, 32000, null, true);
dbAccessor.addColumn("clusterconfig", clusterConfigAttributesColumn);
+
+ // Add columns
+ dbAccessor.addColumn("viewmain", new DBAccessor.DBColumnInfo("mask",
+ String.class, 255, null, true));
+ dbAccessor.addColumn("viewparameter", new DBAccessor.DBColumnInfo("masked",
+ Character.class, 1, null, true));
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-server/src/main/java/org/apache/ambari/server/view/DefaultMasker.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/DefaultMasker.java b/ambari-server/src/main/java/org/apache/ambari/server/view/DefaultMasker.java
new file mode 100644
index 0000000..704ff7d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/DefaultMasker.java
@@ -0,0 +1,48 @@
+/**
+ * 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 java.io.UnsupportedEncodingException;
+
+import org.apache.ambari.view.MaskException;
+import org.apache.ambari.view.Masker;
+import org.apache.commons.codec.binary.Base64;
+
+/**
+ * Provides simple masking of view parameters.
+ */
+public class DefaultMasker implements Masker {
+
+ @Override
+ public String mask(String value) throws MaskException {
+ try {
+ return Base64.encodeBase64String(value.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new MaskException("UTF-8 is not supported", e);
+ }
+ }
+
+ @Override
+ public String unmask(String value) throws MaskException {
+ try {
+ return new String(Base64.decodeBase64(value), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new MaskException("UTF-8 is not supported", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 e914c75..6426575 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
@@ -38,8 +38,6 @@ 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;
@@ -51,6 +49,15 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.ambari.server.view.configuration.ParameterConfig;
+import org.apache.ambari.server.view.configuration.ViewConfig;
+import org.apache.ambari.view.MaskException;
+import org.apache.ambari.view.Masker;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* View context implementation.
@@ -58,6 +65,11 @@ import java.util.Map;
public class ViewContextImpl implements ViewContext, ViewController {
/**
+ * Logger.
+ */
+ private static final Log LOG = LogFactory.getLog(ViewContextImpl.class);
+
+ /**
* The associated view definition.
*/
private final ViewEntity viewEntity;
@@ -82,14 +94,12 @@ public class ViewContextImpl implements ViewContext, ViewController {
*/
private DataStore dataStore = null;
- private final VelocityContext velocityContext;
-
-
- // ----- Constants ---------------------------------------------------------
-
- protected final static Logger LOG =
- LoggerFactory.getLogger(ViewContext.class);
+ /**
+ * Masker for properties.
+ */
+ private Masker masker;
+ private final VelocityContext velocityContext;
// ---- Constructors -------------------------------------------------------
@@ -118,6 +128,7 @@ public class ViewContextImpl implements ViewContext, ViewController {
this.viewInstanceEntity = viewInstanceEntity;
this.viewRegistry = viewRegistry;
this.streamProvider = ViewURLStreamProvider.getProvider();
+ this.masker = getMasker(viewEntity.getClassLoader(), viewEntity.getConfiguration());
this.velocityContext = initVelocityContext();
}
@@ -147,18 +158,42 @@ public class ViewContextImpl implements ViewContext, ViewController {
public Map<String, String> getProperties() {
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));
+ } 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(properties);
}
@Override
@@ -270,6 +305,14 @@ public class ViewContextImpl implements ViewContext, ViewController {
}
}
+ private Masker getMasker(ClassLoader cl, ViewConfig viewConfig) {
+ try {
+ return viewConfig.getMaskerClass(cl).newInstance();
+ } catch (Exception e) {
+ throw new InstantiationError("Could not create masker instance.");
+ }
+ }
+
/**
* Parameterize string using VelocityContext instance
*
@@ -316,7 +359,6 @@ public class ViewContextImpl implements ViewContext, ViewController {
return context;
}
-
// ----- Inner class : ViewURLStreamProvider -------------------------------
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 33485a0..849da64 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
@@ -21,6 +21,7 @@ package org.apache.ambari.server.view;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
+
import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
import org.apache.ambari.server.api.resources.SubResourceDefinition;
import org.apache.ambari.server.api.resources.ViewExternalSubResourceDefinition;
@@ -43,6 +44,8 @@ import org.apache.ambari.server.view.configuration.PersistenceConfig;
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.view.MaskException;
+import org.apache.ambari.view.Masker;
import org.apache.ambari.view.SystemException;
import org.apache.ambari.view.View;
import org.apache.ambari.view.ViewContext;
@@ -50,6 +53,7 @@ import org.apache.ambari.view.ViewDefinition;
import org.apache.ambari.view.ViewResourceHandler;
import org.apache.ambari.view.events.Event;
import org.apache.ambari.view.events.Listener;
+import org.apache.commons.lang.StringUtils;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -57,6 +61,7 @@ import org.slf4j.LoggerFactory;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
+
import java.beans.IntrospectionException;
import java.io.File;
import java.io.FileNotFoundException;
@@ -203,7 +208,7 @@ public class ViewRegistry {
}
/**
- * Get the instance definition for the given view nam,e and instance name.
+ * Get the instance definition for the given view name and instance name.
*
* @param viewName the view name
* @param version the version
@@ -338,7 +343,7 @@ public class ViewRegistry {
for (InstanceConfig instanceConfig : viewConfig.getInstances()) {
try {
- instanceDefinitions.add(createViewInstanceDefinition(viewDefinition, instanceConfig));
+ instanceDefinitions.add(createViewInstanceDefinition(viewConfig, viewDefinition, instanceConfig));
} catch (Exception e) {
LOG.error("Caught exception adding view instance for view " +
viewDefinition.getViewName(), e);
@@ -603,6 +608,7 @@ public class ViewRegistry {
viewParameterEntity.setName(parameterConfiguration.getName());
viewParameterEntity.setDescription(parameterConfiguration.getDescription());
viewParameterEntity.setRequired(parameterConfiguration.isRequired());
+ viewParameterEntity.setMasked(parameterConfiguration.isMasked());
viewParameterEntity.setViewEntity(viewDefinition);
parameters.add(viewParameterEntity);
}
@@ -658,18 +664,32 @@ public class ViewRegistry {
view = getView(viewConfig.getViewClass(cl), new ViewContextImpl(viewDefinition, this));
}
viewDefinition.setView(view);
+ viewDefinition.setMask(viewConfig.getMasker());
return viewDefinition;
}
// create a new view instance definition
- protected ViewInstanceEntity createViewInstanceDefinition(ViewEntity viewDefinition, InstanceConfig instanceConfig)
- throws ClassNotFoundException, IllegalStateException {
+ protected ViewInstanceEntity createViewInstanceDefinition(ViewConfig viewConfig, ViewEntity viewDefinition, InstanceConfig instanceConfig)
+ throws ClassNotFoundException, IllegalStateException, MaskException {
ViewInstanceEntity viewInstanceDefinition =
new ViewInstanceEntity(viewDefinition, instanceConfig);
+ Masker masker = getMasker(viewConfig.getMaskerClass(viewDefinition.getClassLoader()));
for (PropertyConfig propertyConfig : instanceConfig.getProperties()) {
- viewInstanceDefinition.putProperty(propertyConfig.getKey(), propertyConfig.getValue());
+ ParameterConfig parameterConfig = null;
+ for (ParameterConfig paramConfig : viewConfig.getParameters()) {
+ if (StringUtils.equals(paramConfig.getName(), propertyConfig.getKey())) {
+ parameterConfig = paramConfig;
+ break;
+ }
+ }
+ if (parameterConfig != null && parameterConfig.isMasked()) {
+ viewInstanceDefinition.putProperty(propertyConfig.getKey(),
+ masker.mask(propertyConfig.getValue()));
+ } else {
+ viewInstanceDefinition.putProperty(propertyConfig.getKey(), propertyConfig.getValue());
+ }
}
viewInstanceDefinition.validate(viewDefinition);
@@ -786,6 +806,16 @@ public class ViewRegistry {
return viewInstanceInjector.getInstance(clazz);
}
+ // create masker from given class; probably replace with injector later
+ private static Masker getMasker(Class<? extends Masker> clazz) {
+ try {
+ return clazz.newInstance();
+ } catch (Exception e) {
+ LOG.error("Could not create masker instance", e);
+ }
+ return null;
+ }
+
// remove undeployed views from the ambari db
private void removeUndeployedViews() {
for (ViewEntity viewEntity : viewDAO.findAll()) {
@@ -881,7 +911,7 @@ public class ViewRegistry {
}
// extract the given view archive to the given archive directory
- private ClassLoader extractViewArchive(File viewArchive, File archiveDir)
+ private ClassLoader extractViewArchive(File viewArchive, File archiveDir)
throws IOException {
// Skip if the archive has already been extracted
@@ -890,7 +920,7 @@ public class ViewRegistry {
String archivePath = archiveDir.getAbsolutePath();
LOG.info("Creating archive folder " + archivePath + ".");
-
+
if (archiveDir.mkdir()) {
JarFile viewJarFile = helper.getJarFile(viewArchive);
Enumeration enumeration = viewJarFile.entries();
@@ -933,7 +963,7 @@ public class ViewRegistry {
}
// get a class loader for the given archive directory
- private ClassLoader getArchiveClassLoader(File archiveDir)
+ private ClassLoader getArchiveClassLoader(File archiveDir)
throws MalformedURLException {
String archivePath = archiveDir.getAbsolutePath();
@@ -960,7 +990,7 @@ public class ViewRegistry {
}
}
- // include the archive directory
+ // include the archive directory
urlList.add(archiveDir.toURI().toURL());
return URLClassLoader.newInstance(urlList.toArray(new URL[urlList.size()]));
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 97c9e22..827b5e7 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
@@ -42,6 +42,11 @@ public class ParameterConfig {
private boolean required;
/**
+ * Indicates whether or not the parameter is masked when persisted.
+ */
+ private boolean masked;
+
+ /**
* Get the parameter name.
*
* @return the name
@@ -67,4 +72,13 @@ public class ParameterConfig {
public boolean isRequired() {
return required;
}
+
+ /**
+ * Indicates whether or not the parameter is masked when persisted.
+ *
+ * @return true if the parameter is masked; false otherwise
+ */
+ public boolean isMasked() {
+ return masked;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
index 1e29f5d..e084918 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
@@ -18,12 +18,16 @@
package org.apache.ambari.server.view.configuration;
+import org.apache.ambari.server.view.DefaultMasker;
+import org.apache.ambari.view.Masker;
import org.apache.ambari.view.View;
+import org.apache.commons.lang.StringUtils;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+
import java.util.Collections;
import java.util.List;
@@ -70,6 +74,17 @@ public class ViewConfig {
private Class<? extends View> viewClass = null;
/**
+ * The masker class name for parameters.
+ */
+ @XmlElement(name="masker-class")
+ private String masker;
+
+ /**
+ * The mask class.
+ */
+ private Class<? extends Masker> maskerClass = null;
+
+ /**
* The list of view parameters.
*/
@XmlElement(name="parameter")
@@ -150,7 +165,7 @@ public class ViewConfig {
/**
* Get the view class.
*
- * @param cl the class loader
+ * @param cl the class loader
*
* @return the view class
*
@@ -164,6 +179,34 @@ public class ViewConfig {
}
/**
+ * Get the masker class name.
+ * @return the masker class name
+ */
+ public String getMasker() {
+ return masker;
+ }
+
+ /**
+ * Get the masker class.
+ *
+ * @param cl the class loader
+ *
+ * @return the masker class
+ *
+ * @throws ClassNotFoundException if the class can not be loaded
+ */
+ public Class<? extends Masker> getMaskerClass(ClassLoader cl) throws ClassNotFoundException {
+ if (maskerClass == null) {
+ if (StringUtils.isBlank(masker)) {
+ maskerClass = DefaultMasker.class;
+ } else {
+ maskerClass = cl.loadClass(masker).asSubclass(Masker.class);
+ }
+ }
+ return maskerClass;
+ }
+
+ /**
* Get the list of view parameters.
*
* @return the list of parameters
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 8d73866..f12c5d1 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -62,11 +62,11 @@ CREATE TABLE hostgroup (blueprint_name VARCHAR(255) NOT NULL, name VARCHAR(255)
CREATE TABLE hostgroup_component (blueprint_name VARCHAR(255) NOT NULL, hostgroup_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(blueprint_name, hostgroup_name, name));
CREATE TABLE blueprint_configuration (blueprint_name VARCHAR(255) NOT NULL, type_name VARCHAR(255) NOT NULL, config_data VARCHAR(32000) NOT NULL , PRIMARY KEY(blueprint_name, type_name));
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, PRIMARY KEY(blueprint_name, hostgroup_name, type_name));
-CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), PRIMARY KEY(view_name));
+CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), mask VARCHAR(255), 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, view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, label VARCHAR(255), description VARCHAR(255), visible CHAR(1), icon VARCHAR(255), icon64 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(255), required CHAR(1), PRIMARY KEY(view_name, name));
+CREATE TABLE viewparameter (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description 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));
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 c8b4ba7..3620788 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -52,11 +52,11 @@ CREATE TABLE hostgroup (blueprint_name VARCHAR2(255) NOT NULL, name VARCHAR2(255
CREATE TABLE hostgroup_component (blueprint_name VARCHAR2(255) NOT NULL, hostgroup_name VARCHAR2(255) NOT NULL, name VARCHAR2(255) NOT NULL, PRIMARY KEY(blueprint_name, hostgroup_name, name));
CREATE TABLE blueprint_configuration (blueprint_name VARCHAR2(255) NOT NULL, type_name VARCHAR2(255) NOT NULL, config_data CLOB NOT NULL , PRIMARY KEY(blueprint_name, type_name));
CREATE TABLE hostgroup_configuration (blueprint_name VARCHAR2(255) NOT NULL, hostgroup_name VARCHAR2(255) NOT NULL, type_name VARCHAR2(255) NOT NULL, config_data CLOB NOT NULL, PRIMARY KEY(blueprint_name, hostgroup_name, type_name));
-CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), PRIMARY KEY(view_name));
+CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), mask VARCHAR(255), PRIMARY KEY(view_name));
CREATE TABLE viewinstancedata (view_instance_id NUMBER(19), 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 NUMBER(19), view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, label VARCHAR(255), description VARCHAR(255), visible CHAR(1), icon VARCHAR(255), icon64 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(255), required CHAR(1), PRIMARY KEY(view_name, name));
+CREATE TABLE viewparameter (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description 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 NUMBER(19) 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));
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 c020a66..8c1cf3b 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -85,11 +85,11 @@ CREATE TABLE hostgroup_component (blueprint_name VARCHAR(255) NOT NULL, hostgrou
CREATE TABLE blueprint_configuration (blueprint_name varchar(255) NOT NULL, type_name varchar(255) NOT NULL, config_data varchar(32000) NOT NULL , PRIMARY KEY(blueprint_name, type_name));
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, PRIMARY KEY(blueprint_name, hostgroup_name, type_name));
-CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), PRIMARY KEY(view_name));
+CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), mask VARCHAR(255), 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, view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, label VARCHAR(255), description VARCHAR(255), visible CHAR(1), icon VARCHAR(255), icon64 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(255), required CHAR(1), PRIMARY KEY(view_name, name));
+CREATE TABLE viewparameter (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description 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));
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 a8b1048..6ac6558 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
@@ -132,11 +132,11 @@ GRANT ALL PRIVILEGES ON TABLE ambari.hostgroup_component TO :username;
GRANT ALL PRIVILEGES ON TABLE ambari.blueprint_configuration TO :username;
GRANT ALL PRIVILEGES ON TABLE ambari.hostgroup_configuration TO :username;
-CREATE TABLE ambari.viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), PRIMARY KEY(view_name));
+CREATE TABLE ambari.viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), icon VARCHAR(255), icon64 VARCHAR(255), archive VARCHAR(255), mask VARCHAR(255), PRIMARY KEY(view_name));
CREATE TABLE ambari.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 ambari.viewinstance (view_instance_id BIGINT, view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, label VARCHAR(255), description VARCHAR(255), visible CHAR(1), icon VARCHAR(255), icon64 VARCHAR(255), PRIMARY KEY(view_instance_id));
CREATE TABLE ambari.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 ambari.viewparameter (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(255), required CHAR(1), PRIMARY KEY(view_name, name));
+CREATE TABLE ambari.viewparameter (view_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(255), required CHAR(1), masked CHAR(1), PRIMARY KEY(view_name, name));
CREATE TABLE ambari.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 ambari.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));
GRANT ALL PRIVILEGES ON TABLE ambari.viewmain TO :username;
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java
index 7101ef9..dfda132 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java
@@ -19,6 +19,7 @@
package org.apache.ambari.server.upgrade;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
@@ -58,7 +59,11 @@ public class UpgradeCatalog170Test {
expect(configuration.getDatabaseUrl()).andReturn(Configuration.JDBC_IN_MEMORY_URL).anyTimes();
Capture<DBAccessor.DBColumnInfo> clusterConfigAttributesColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+ Capture<DBAccessor.DBColumnInfo> maskColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+ Capture<DBAccessor.DBColumnInfo> maskedColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+ setViewExpectations(dbAccessor, maskColumnCapture);
+ setViewParameterExpectations(dbAccessor, maskedColumnCapture);
setClusterConfigExpectations(dbAccessor, clusterConfigAttributesColumnCapture);
dbAccessor.executeSelect(anyObject(String.class));
expectLastCall().andReturn(resultSet).anyTimes();
@@ -78,6 +83,8 @@ public class UpgradeCatalog170Test {
verify(dbAccessor, configuration, resultSet);
assertClusterConfigColumns(clusterConfigAttributesColumnCapture);
+ assertViewColumns(maskColumnCapture);
+ assertViewParameterColumns(maskedColumnCapture);
}
@Test
@@ -125,5 +132,39 @@ public class UpgradeCatalog170Test {
final DBAccessor dbAccessor = createNiceMock(DBAccessor.class);
UpgradeCatalog upgradeCatalog = getUpgradeCatalog(dbAccessor);
Assert.assertEquals("1.6.1", upgradeCatalog.getSourceVersion());
- }
+ }
+
+ private void setViewExpectations(DBAccessor dbAccessor,
+ Capture<DBAccessor.DBColumnInfo> maskColumnCapture)
+ throws SQLException {
+
+ dbAccessor.addColumn(eq("viewmain"), capture(maskColumnCapture));
+ }
+
+ private void setViewParameterExpectations(DBAccessor dbAccessor,
+ Capture<DBAccessor.DBColumnInfo> maskedColumnCapture)
+ throws SQLException {
+
+ dbAccessor.addColumn(eq("viewparameter"), capture(maskedColumnCapture));
+ }
+
+ private void assertViewColumns(
+ Capture<DBAccessor.DBColumnInfo> maskColumnCapture) {
+ DBAccessor.DBColumnInfo column = maskColumnCapture.getValue();
+ assertEquals("mask", column.getName());
+ assertEquals(255, (int) column.getLength());
+ assertEquals(String.class, column.getType());
+ assertNull(column.getDefaultValue());
+ assertTrue(column.isNullable());
+ }
+
+ private void assertViewParameterColumns(
+ Capture<DBAccessor.DBColumnInfo> maskedColumnCapture) {
+ DBAccessor.DBColumnInfo column = maskedColumnCapture.getValue();
+ assertEquals("masked", column.getName());
+ assertEquals(1, (int) column.getLength());
+ assertEquals(Character.class, column.getType());
+ assertNull(column.getDefaultValue());
+ assertTrue(column.isNullable());
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-server/src/test/java/org/apache/ambari/server/view/DefaultMaskerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/DefaultMaskerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/DefaultMaskerTest.java
new file mode 100644
index 0000000..7fde6b7
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/DefaultMaskerTest.java
@@ -0,0 +1,47 @@
+/**
+ * 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 junit.framework.Assert;
+
+import org.apache.ambari.server.view.DefaultMasker;
+import org.junit.Test;
+
+/**
+ * DefaultMasker test.
+ */
+public class DefaultMaskerTest {
+ private DefaultMasker masker = new DefaultMasker();
+
+ @Test
+ public void testMask() throws Exception {
+ final String source = "unmasked";
+ final String masked = masker.mask(source);
+ Assert.assertNotNull(masked);
+ Assert.assertTrue(masked.length() > 0);
+ }
+
+ @Test
+ public void testMaskUnmask() throws Exception {
+ final String source = "unmasked";
+ final String masked = masker.mask(source);
+ final String unmasked = masker.unmask(masked);
+ Assert.assertEquals(source, unmasked);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 5358162..6bddf08 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
@@ -25,6 +25,7 @@ import org.apache.ambari.server.orm.entities.ViewEntityTest;
import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
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.junit.Assert;
import org.junit.Test;
@@ -77,7 +78,7 @@ public class ViewContextImplTest {
ViewInstanceEntity viewInstanceDefinition = new ViewInstanceEntity(viewDefinition, instanceConfig);
ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
viewInstanceDefinition.putProperty("p1", "v1");
- viewInstanceDefinition.putProperty("p2", "v2");
+ viewInstanceDefinition.putProperty("p2", new DefaultMasker().mask("v2"));
viewInstanceDefinition.putProperty("p3", "v3");
ViewContextImpl viewContext = new ViewContextImpl(viewInstanceDefinition, viewRegistry);
@@ -96,18 +97,22 @@ public class ViewContextImplTest {
replay(instanceConfig);
ViewEntity viewDefinition = createNiceMock(ViewEntity.class);
expect(viewDefinition.getCommonName()).andReturn("View").times(2);
+ expect(viewDefinition.getClassLoader()).andReturn(ViewContextImplTest.class.getClassLoader()).anyTimes();
+ expect(viewDefinition.getConfiguration()).andReturn(ViewConfigTest.getConfig()).anyTimes();
replay(viewDefinition);
ViewInstanceEntity viewInstanceDefinition = createMockBuilder(ViewInstanceEntity.class)
.addMockedMethod("getUsername")
.addMockedMethod("getName")
+ .addMockedMethod("getViewEntity")
.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);
replay(viewInstanceDefinition);
ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
viewInstanceDefinition.putProperty("p1", "/tmp/some/path/${username}");
- viewInstanceDefinition.putProperty("p2", "/tmp/path/$viewName");
+ viewInstanceDefinition.putProperty("p2", new DefaultMasker().mask("/tmp/path/$viewName"));
viewInstanceDefinition.putProperty("p3", "/path/$instanceName");
viewInstanceDefinition.putProperty("p4", "/path/to/${unspecified_parameter}");
viewInstanceDefinition.putProperty("p5", "/path/to/${incorrect_parameter");
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 7069d37..e3350bc 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
@@ -55,6 +55,15 @@ public class ParameterConfigTest {
Assert.assertEquals(false, parameters.get(1).isRequired());
}
+ @Test
+ public void testIsMasked() throws Exception {
+ List<ParameterConfig> parameters = getParameterConfigs();
+
+ Assert.assertEquals(2, parameters.size());
+ Assert.assertEquals(false, parameters.get(0).isMasked());
+ Assert.assertEquals(true, parameters.get(1).isMasked());
+ }
+
public static List<ParameterConfig> getParameterConfigs() throws JAXBException {
ViewConfig viewConfig = ViewConfigTest.getConfig();
return viewConfig.getParameters ();
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/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 bb4ad0c..ba40027 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
@@ -48,6 +48,7 @@ public class ViewConfigTest {
" <version>1.0.0</version>\n" +
" <icon64>/this/is/the/icon/url/icon64.png</icon64>\n" +
" <icon>/this/is/the/icon/url/icon.png</icon>\n" +
+ " <masker-class>org.apache.ambari.server.view.DefaultMasker</masker-class>" +
" <parameter>\n" +
" <name>p1</name>\n" +
" <description>Parameter 1.</description>\n" +
@@ -57,6 +58,7 @@ public class ViewConfigTest {
" <name>p2</name>\n" +
" <description>Parameter 2.</description>\n" +
" <required>false</required>\n" +
+ " <masked>true</masked>" +
" </parameter>\n" +
" <resource>\n" +
" <name>resource</name>\n" +
@@ -145,6 +147,12 @@ public class ViewConfigTest {
}
@Test
+ public void testMasker() throws Exception {
+ ViewConfig config = getConfig();
+ Assert.assertEquals("org.apache.ambari.server.view.DefaultMasker", config.getMasker());
+ }
+
+ @Test
public void testGetView() throws Exception {
ViewConfig config = getConfig(view_class_xml);
Assert.assertEquals("ViewImpl", config.getView());
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-views/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-views/pom.xml b/ambari-views/pom.xml
index e4fcb4a..23cb784 100644
--- a/ambari-views/pom.xml
+++ b/ambari-views/pom.xml
@@ -48,6 +48,10 @@
<artifactId>jersey-core</artifactId>
<version>1.8</version>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
</dependencies>
<build>
<plugins>
@@ -126,14 +130,14 @@
<exclude>**/*.json</exclude>
</excludes>
</configuration>
- <executions>
- <execution>
- <phase>test</phase>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
+ <executions>
+ <execution>
+ <phase>test</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
@@ -152,4 +156,3 @@
</build>
</project>
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-views/src/main/java/org/apache/ambari/view/MaskException.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/MaskException.java b/ambari-views/src/main/java/org/apache/ambari/view/MaskException.java
new file mode 100644
index 0000000..b976d4a
--- /dev/null
+++ b/ambari-views/src/main/java/org/apache/ambari/view/MaskException.java
@@ -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.
+ */
+package org.apache.ambari.view;
+
+/**
+ * Indicates that a mask exception occurred.
+ */
+public class MaskException extends Exception {
+ /**
+ * Constructor.
+ *
+ * @param msg message
+ * @param throwable root exception
+ */
+ public MaskException(String msg, Throwable throwable) {
+ super(msg, throwable);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-views/src/main/java/org/apache/ambari/view/Masker.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/Masker.java b/ambari-views/src/main/java/org/apache/ambari/view/Masker.java
new file mode 100644
index 0000000..31d22f1
--- /dev/null
+++ b/ambari-views/src/main/java/org/apache/ambari/view/Masker.java
@@ -0,0 +1,43 @@
+/**
+ * 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;
+
+/**
+ * Masker for view parameters.
+ */
+public interface Masker {
+
+ /**
+ * Get a masked version of the given string.
+ *
+ * @param value the value to be masked
+ * @return the masked value
+ * @throws MaskException error happened during masking process
+ */
+ public String mask(String value) throws MaskException;
+
+ /**
+ * Get the original string from a masked string.
+ *
+ * @param value the value to be unmasked
+ * @return the unmasked value
+ * @throws MaskException error happened during unmasking process
+ */
+ public String unmask(String value) throws MaskException;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-views/src/main/java/org/apache/ambari/view/PersistenceException.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/PersistenceException.java b/ambari-views/src/main/java/org/apache/ambari/view/PersistenceException.java
index 6e32940..e8959b4 100644
--- a/ambari-views/src/main/java/org/apache/ambari/view/PersistenceException.java
+++ b/ambari-views/src/main/java/org/apache/ambari/view/PersistenceException.java
@@ -19,7 +19,7 @@
package org.apache.ambari.view;
/**
- * View persistence exception. Indicates that an error occurred while
+ * View persistence exception. Indicates that an error occurred while
* persisting a view or view data.
*/
public class PersistenceException extends Exception {
http://git-wip-us.apache.org/repos/asf/ambari/blob/01e9e760/ambari-views/src/main/java/org/apache/ambari/view/ViewDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/ViewDefinition.java b/ambari-views/src/main/java/org/apache/ambari/view/ViewDefinition.java
index 8389033..e519526 100644
--- a/ambari-views/src/main/java/org/apache/ambari/view/ViewDefinition.java
+++ b/ambari-views/src/main/java/org/apache/ambari/view/ViewDefinition.java
@@ -43,4 +43,11 @@ public interface ViewDefinition {
* @return the version
*/
public String getVersion();
+
+ /**
+ * Get the mask class name.
+ *
+ * @return the mask class name.
+ */
+ public String getMask();
}