Repository: ambari Updated Branches: refs/heads/trunk f3bd5cc8c -> 1b72f6df7
AMBARI-6777. Views: view.xml instance changes are not picked up on redeploy. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1b72f6df Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1b72f6df Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1b72f6df Branch: refs/heads/trunk Commit: 1b72f6df78a8e683256ed0654146deb59e341490 Parents: f3bd5cc Author: Siddharth Wagle <[email protected]> Authored: Wed Aug 13 12:45:35 2014 -0700 Committer: Siddharth Wagle <[email protected]> Committed: Wed Aug 13 12:45:35 2014 -0700 ---------------------------------------------------------------------- .../ambari/server/controller/AmbariServer.java | 4 +- .../internal/PrivilegeResourceProvider.java | 14 +- .../internal/ViewPrivilegeResourceProvider.java | 5 +- .../server/orm/entities/ViewInstanceEntity.java | 25 +++ .../server/upgrade/UpgradeCatalog170.java | 2 + .../apache/ambari/server/view/ViewRegistry.java | 224 ++++++++++++++----- .../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 +- .../ambari/server/view/ViewRegistryTest.java | 69 ++++-- 11 files changed, 265 insertions(+), 86 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java index e6eab3f..98556f9 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java @@ -68,6 +68,7 @@ import org.apache.ambari.server.orm.dao.PermissionDAO; import org.apache.ambari.server.orm.dao.PrincipalDAO; import org.apache.ambari.server.orm.dao.PrivilegeDAO; import org.apache.ambari.server.orm.dao.ResourceDAO; +import org.apache.ambari.server.orm.dao.ResourceTypeDAO; import org.apache.ambari.server.orm.dao.UserDAO; import org.apache.ambari.server.orm.dao.ViewDAO; import org.apache.ambari.server.orm.dao.ViewInstanceDAO; @@ -539,7 +540,8 @@ public class AmbariServer { ClusterPrivilegeResourceProvider.init(injector.getInstance(ClusterDAO.class)); ViewRegistry.init(injector.getInstance(ViewDAO.class), injector.getInstance(ViewInstanceDAO.class), injector.getInstance(UserDAO.class), injector.getInstance(MemberDAO.class), - injector.getInstance(PrivilegeDAO.class), injector.getInstance(SecurityHelper.class)); + injector.getInstance(PrivilegeDAO.class), injector.getInstance(SecurityHelper.class), + injector.getInstance(ResourceDAO.class), injector.getInstance(ResourceTypeDAO.class)); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java index 60d6396..d8fce4d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java @@ -142,8 +142,9 @@ public abstract class PrivilegeResourceProvider<T> extends AbstractResourceProvi * @param properties the set of properties * * @return the entities + * @throws AmbariException if resource entities were not found */ - public abstract Map<Long, T> getResourceEntities(Map<String, Object> properties); + public abstract Map<Long, T> getResourceEntities(Map<String, Object> properties) throws AmbariException; /** * Get the id for the resource specified by predicate. @@ -183,7 +184,12 @@ public abstract class PrivilegeResourceProvider<T> extends AbstractResourceProvi } for (Map<String, Object> properties : propertyMaps) { - Map<Long, T> resourceEntities = getResourceEntities(properties); + Map<Long, T> resourceEntities; + try { + resourceEntities = getResourceEntities(properties); + } catch (AmbariException e) { + throw new SystemException("Could not get resource list from request", e); + } resourceIds.addAll(resourceEntities.keySet()); @@ -319,9 +325,7 @@ public abstract class PrivilegeResourceProvider<T> extends AbstractResourceProvi PrivilegeEntity entity = new PrivilegeEntity(); String permissionName = (String) properties.get(PERMISSION_NAME_PROPERTY_ID); ResourceEntity resourceEntity = resourceDAO.findById(resourceId); - PermissionEntity permission = getPermission(permissionName, resourceEntity); - if (permission == null) { throw new AmbariException("Can't find a permission named " + permissionName + " for the resource."); @@ -331,7 +335,6 @@ public abstract class PrivilegeResourceProvider<T> extends AbstractResourceProvi String principalName = (String) properties.get(PRINCIPAL_NAME_PROPERTY_ID); String principalType = (String) properties.get(PRINCIPAL_TYPE_PROPERTY_ID); - if (PrincipalTypeEntity.GROUP_PRINCIPAL_TYPE_NAME.equalsIgnoreCase(principalType)) { GroupEntity groupEntity = groupDAO.findGroupByName(principalName); if (groupEntity != null) { @@ -381,7 +384,6 @@ public abstract class PrivilegeResourceProvider<T> extends AbstractResourceProvi throw new AmbariException("Can't grant " + entity.getPermission().getResourceType().getName() + " permission on a " + entity.getResource().getResourceType().getName() + " resource."); } - privilegeDAO.create(entity); return null; } http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java index 57eb28e..ea4acef 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java @@ -101,7 +101,7 @@ public class ViewPrivilegeResourceProvider extends PrivilegeResourceProvider<Vie // ----- PrivilegeResourceProvider ----------------------------------------- @Override - public Map<Long, ViewInstanceEntity> getResourceEntities(Map<String, Object> properties) { + public Map<Long, ViewInstanceEntity> getResourceEntities(Map<String, Object> properties) throws AmbariException { ViewRegistry viewRegistry = ViewRegistry.getInstance(); String viewName = (String) properties.get(PRIVILEGE_VIEW_NAME_PROPERTY_ID); @@ -112,6 +112,9 @@ public class ViewPrivilegeResourceProvider extends PrivilegeResourceProvider<Vie ViewInstanceEntity viewInstanceEntity = viewRegistry.getInstanceDefinition(viewName, viewVersion, instanceName); + if (viewInstanceEntity == null) { + throw new AmbariException("View instance " + instanceName + " of " + viewName + viewVersion + " was not found"); + } return Collections.singletonMap(viewInstanceEntity.getResource().getId(), viewInstanceEntity); } http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 2878dd6..3f1cd8f 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 @@ -123,6 +123,13 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { private String icon64; /** + * The XML driven instance flag. + */ + @Column(name="xml_driven") + @Basic + private char xmlDriven = 'N'; + + /** * The instance properties. */ @OneToMany(cascade = CascadeType.ALL, mappedBy = "viewInstance") @@ -397,6 +404,24 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { } /** + * Get the xml driven flag. + * + * @return the xml driven flag + */ + public boolean isXmlDriven() { + return xmlDriven == 'y' || xmlDriven == 'Y'; + } + + /** + * Set the xml driven flag. + * + * @param xmlDriven the xml driven flag + */ + public void setXmlDriven(boolean xmlDriven) { + this.xmlDriven = (xmlDriven) ? 'Y' : 'N'; + } + + /** * Get the instance properties. * * @return the instance properties http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 9a0f4ca..bb248ba 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 @@ -191,6 +191,8 @@ public class UpgradeCatalog170 extends AbstractUpgradeCatalog { Integer.class, 1, 1, false)); dbAccessor.addColumn("viewinstance", new DBColumnInfo("resource_id", Long.class, 1, 1, false)); + dbAccessor.addColumn("viewinstance", new DBColumnInfo("xml_driven", + Character.class, 1, null, true)); dbAccessor.addColumn("clusters", new DBColumnInfo("resource_id", Long.class, 1, 1, false)); http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 808de92..0acbb62 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 @@ -18,9 +18,31 @@ package org.apache.ambari.server.view; -import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Injector; +import java.beans.IntrospectionException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl; import org.apache.ambari.server.api.resources.SubResourceDefinition; @@ -31,6 +53,8 @@ import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.orm.dao.MemberDAO; import org.apache.ambari.server.orm.dao.PrivilegeDAO; +import org.apache.ambari.server.orm.dao.ResourceDAO; +import org.apache.ambari.server.orm.dao.ResourceTypeDAO; import org.apache.ambari.server.orm.dao.UserDAO; import org.apache.ambari.server.orm.dao.ViewDAO; import org.apache.ambari.server.orm.dao.ViewInstanceDAO; @@ -72,30 +96,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; -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; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; /** * Registry for view and view instance definitions. @@ -178,6 +181,15 @@ public class ViewRegistry { */ private static SecurityHelper securityHelper; + /** + * Resource data access object. + */ + private static ResourceDAO resourceDAO; + + /** + * Resource type data access object. + */ + private static ResourceTypeDAO resourceTypeDAO; // ----- Constructors ------------------------------------------------------ @@ -388,13 +400,17 @@ public class ViewRegistry { // extract the archive and get the class loader ClassLoader cl = extractViewArchive(archiveFile, helper.getFile(archivePath)); + viewConfig = helper.getViewConfigFromExtractedArchive(archivePath); + ViewEntity viewDefinition = createViewDefinition(viewConfig, configuration, cl, archivePath); Set<ViewInstanceEntity> instanceDefinitions = new HashSet<ViewInstanceEntity>(); for (InstanceConfig instanceConfig : viewConfig.getInstances()) { try { - instanceDefinitions.add(createViewInstanceDefinition(viewConfig, viewDefinition, instanceConfig)); + ViewInstanceEntity instanceEntity = createViewInstanceDefinition(viewConfig, viewDefinition, instanceConfig); + instanceEntity.setXmlDriven(true); + instanceDefinitions.add(instanceEntity); } catch (Exception e) { LOG.error("Caught exception adding view instance for view " + viewDefinition.getViewName(), e); @@ -451,9 +467,11 @@ public class ViewRegistry { } instanceEntity.validate(viewEntity); + ResourceTypeEntity resourceTypeEntity = resourceTypeDAO.findByName(ViewEntity.getViewName(viewName, version)); // create an admin resource to represent this view instance ResourceEntity resourceEntity = new ResourceEntity(); - resourceEntity.setResourceType(viewEntity.getResourceType()); + resourceEntity.setResourceType(resourceTypeEntity); + resourceDAO.create(resourceEntity); instanceEntity.setResource(resourceEntity); @@ -467,6 +485,7 @@ public class ViewRegistry { throw new IllegalStateException(message); } instanceEntity.setViewInstanceId(persistedInstance.getViewInstanceId()); + instanceEntity.setResource(persistedInstance.getResource()); try { // bind the view instance to a view @@ -507,6 +526,9 @@ public class ViewRegistry { ViewInstanceEntity entity = getInstanceDefinition(viewName, version, instanceName); if (entity != null) { + if (entity.isXmlDriven()) { + throw new IllegalStateException("View instances defined via xml can't be updated through api requests"); + } if (LOG.isDebugEnabled()) { LOG.debug("Updating view instance " + viewName + "/" + version + "/" + instanceName); @@ -542,8 +564,9 @@ public class ViewRegistry { * Uninstall a view instance for the view with the given view name. * * @param instanceEntity the view instance entity + * @throws IllegalStateException if the given instance is not in a valid state */ - public void uninstallViewInstance(ViewInstanceEntity instanceEntity) { + public void uninstallViewInstance(ViewInstanceEntity instanceEntity) throws IllegalStateException { ViewEntity viewEntity = getDefinition(instanceEntity.getViewName()); if (viewEntity != null) { @@ -552,7 +575,9 @@ public class ViewRegistry { String version = viewEntity.getVersion(); if (getInstanceDefinition(viewName, version, instanceName) != null) { - + if (instanceEntity.isXmlDriven()) { + throw new IllegalStateException("View instances defined via xml can't be deleted through api requests"); + } if (LOG.isDebugEnabled()) { LOG.debug("Deleting view instance " + viewName + "/" + version + "/" +instanceName); @@ -882,10 +907,6 @@ public class ViewRegistry { setPersistenceEntities(viewInstanceDefinition); - ResourceEntity resourceEntity = new ResourceEntity(); - resourceEntity.setResourceType(viewDefinition.getResourceType()); - viewInstanceDefinition.setResource(resourceEntity); - viewDefinition.addInstanceDefinition(viewInstanceDefinition); } @@ -983,13 +1004,28 @@ public class ViewRegistry { } } - // sync the given view with the db + /** + * Sync given view with data in DB. Ensures that view data in DB is updated, + * all instances changes from xml config are reflected to DB + * + * @param view view config from xml + * @param instanceDefinitions view instances from xml + * @throws Exception + */ private void syncView(ViewEntity view, Set<ViewInstanceEntity> instanceDefinitions) throws Exception { - String viewName = view.getName(); + // get or create an admin resource type to represent this view + ResourceTypeEntity resourceTypeEntity = resourceTypeDAO.findByName(viewName); + if (resourceTypeEntity == null) { + resourceTypeEntity = new ResourceTypeEntity(); + resourceTypeEntity.setName(view.getName()); + resourceTypeDAO.create(resourceTypeEntity); + } + view.setResourceType(resourceTypeEntity); + ViewEntity persistedView = viewDAO.findByName(viewName); // if the view is not yet persisted ... @@ -997,13 +1033,31 @@ public class ViewRegistry { if (LOG.isDebugEnabled()) { LOG.debug("Creating View " + viewName + "."); } + + for( ViewInstanceEntity instance : view.getInstances()) { + + // create an admin resource to represent this view instance + ResourceEntity resourceEntity = new ResourceEntity(); + resourceEntity.setResourceType(resourceTypeEntity); + resourceDAO.create(resourceEntity); + + instance.setResource(resourceEntity); + } // ... merge it - persistedView = viewDAO.merge(view); + viewDAO.merge(view); + + persistedView = viewDAO.findByName(viewName); + if (persistedView == null) { + String message = "View " + viewName + " can not be found."; + + LOG.error(message); + throw new IllegalStateException(message); + } } - Map<String, ViewInstanceEntity> instanceEntityMap = new HashMap<String, ViewInstanceEntity>(); + Map<String, ViewInstanceEntity> xmlInstanceEntityMap = new HashMap<String, ViewInstanceEntity>(); for( ViewInstanceEntity instance : view.getInstances()) { - instanceEntityMap.put(instance.getName(), instance); + xmlInstanceEntityMap.put(instance.getName(), instance); } view.setResourceType(persistedView.getResourceType()); @@ -1016,7 +1070,12 @@ public class ViewRegistry { ViewInstanceEntity instance = view.getInstanceDefinition(instanceName); - instanceEntityMap.remove(instanceName); + if (persistedInstance.isXmlDriven() && !xmlInstanceEntityMap.containsKey(instanceName)) { + instanceDAO.remove(persistedInstance); + xmlInstanceEntityMap.remove(instanceName); + continue; + } + xmlInstanceEntityMap.remove(instanceName); // if the persisted instance is not in the registry ... if (instance == null) { @@ -1027,23 +1086,39 @@ public class ViewRegistry { } instance.setViewInstanceId(persistedInstance.getViewInstanceId()); - // apply the persisted overrides to the in-memory instance - instance.setLabel(persistedInstance.getLabel()); - instance.setDescription(persistedInstance.getDescription()); - instance.setVisible(persistedInstance.isVisible()); - instance.setData(persistedInstance.getData()); - instance.setProperties(persistedInstance.getProperties()); - instance.setEntities(persistedInstance.getEntities()); + if (instance.isXmlDriven()) { + // override db data with data from {@InstanceConfig} + persistedInstance.setLabel(instance.getLabel()); + persistedInstance.setDescription(instance.getDescription()); + persistedInstance.setVisible(instance.isVisible()); + persistedInstance.setIcon(instance.getIcon()); + persistedInstance.setIcon64(instance.getIcon64()); + persistedInstance.setProperties(instance.getProperties()); + + instanceDAO.merge(persistedInstance); + } else { + // apply the persisted overrides to the in-memory instance + view.removeInstanceDefinition(instanceName); + view.addInstanceDefinition(persistedInstance); + } instance.setResource(persistedInstance.getResource()); } - // these instances appear in the archive but have been deleted - // from the db... remove them from the registry - for (ViewInstanceEntity instance : instanceEntityMap.values()) { - view.removeInstanceDefinition(instance.getName()); - instanceDefinitions.remove(instance); + // these instances appear in the archive but not present in the db... add + // them to db and registry + for (ViewInstanceEntity instance : xmlInstanceEntityMap.values()) { + // create an admin resource to represent this view instance + ResourceEntity resourceEntity = new ResourceEntity(); + resourceEntity.setResourceType(resourceTypeEntity); + resourceDAO.create(resourceEntity); + instance.setResource(resourceEntity); + + instanceDAO.merge(instance); + bindViewInstance(view, instance); + instanceDefinitions.add(instance); } + } // ensure that the extracted view archive directory exists @@ -1196,13 +1271,16 @@ public class ViewRegistry { */ public static void init(ViewDAO viewDAO, ViewInstanceDAO instanceDAO, UserDAO userDAO, MemberDAO memberDAO, PrivilegeDAO privilegeDAO, - SecurityHelper securityHelper) { + SecurityHelper securityHelper, ResourceDAO resourceDAO, + ResourceTypeDAO resourceTypeDAO) { setViewDAO(viewDAO); setInstanceDAO(instanceDAO); setUserDAO(userDAO); setMemberDAO(memberDAO); setPrivilegeDAO(privilegeDAO); setSecurityHelper(securityHelper); + setResourceDAO(resourceDAO); + setResourceTypeDAO(resourceTypeDAO); } /** @@ -1259,6 +1337,24 @@ public class ViewRegistry { ViewRegistry.securityHelper = securityHelper; } + /** + * Set the resource DAO. + * + * @param resourceDAO the resource DAO + */ + protected static void setResourceDAO(ResourceDAO resourceDAO) { + ViewRegistry.resourceDAO = resourceDAO; + } + + /** + * Set the resource type DAO. + * + * @param resourceTypeDAO the resource type DAO. + */ + protected static void setResourceTypeDAO(ResourceTypeDAO resourceTypeDAO) { + ViewRegistry.resourceTypeDAO = resourceTypeDAO; + } + // ----- inner class : ViewRegistryHelper ---------------------------------- @@ -1286,6 +1382,26 @@ public class ViewRegistry { } /** + * Get the view configuration from the extracted archive file. + * + * @param archivePath path to extracted archive + * + * @return the associated view configuration + * + * @throws JAXBException if xml is malformed + * @throws FileNotFoundException if xml was not found + */ + public ViewConfig getViewConfigFromExtractedArchive(String archivePath) + throws JAXBException, FileNotFoundException { + + InputStream configStream = new FileInputStream(new File(archivePath + File.separator + VIEW_XML)); + JAXBContext jaxbContext = JAXBContext.newInstance(ViewConfig.class); + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + + return (ViewConfig) jaxbUnmarshaller.unmarshal(configStream); + } + + /** * Get a new file instance for the given path. * * @param path the path http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 b4c7fb6..ff6c8c0 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -69,7 +69,7 @@ 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), version VARCHAR(255), resource_type_id INTEGER NOT NULL, 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, resource_id BIGINT NOT NULL, 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 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(255), visible CHAR(1), icon VARCHAR(255), icon64 VARCHAR(255), xml_driven CHAR(1), 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), 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)); http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 87d0fd9..bdb20b8 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -60,7 +60,7 @@ CREATE TABLE blueprint_configuration (blueprint_name VARCHAR2(255) NOT NULL, typ 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, config_attributes CLOB, PRIMARY KEY(blueprint_name, hostgroup_name, type_name)); CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), resource_type_id NUMBER(10) NOT NULL, 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), resource_id NUMBER(19) NOT NULL, 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 viewinstance (view_instance_id NUMBER(19), resource_id NUMBER(19) NOT NULL, 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), xml_driven CHAR(1), 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), 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)); http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 bec8fd9..1f3b3e5 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -97,7 +97,7 @@ CREATE TABLE hostgroup_configuration (blueprint_name VARCHAR(255) NOT NULL, host CREATE TABLE viewmain (view_name VARCHAR(255) NOT NULL, label VARCHAR(255), version VARCHAR(255), resource_type_id INTEGER NOT NULL, 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, resource_id BIGINT NOT NULL, 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 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(255), visible CHAR(1), icon VARCHAR(255), icon64 VARCHAR(255), xml_driven CHAR(1), 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), 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)); http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 0dd33af..58ad54a 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 @@ -149,7 +149,7 @@ 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), resource_type_id INTEGER NOT NULL, 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, resource_id BIGINT NOT NULL, 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.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(255), visible CHAR(1), icon VARCHAR(255), icon64 VARCHAR(255), xml_driven CHAR(1), 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), 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)); http://git-wip-us.apache.org/repos/asf/ambari/blob/1b72f6df/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 5396eec..5a95ee8 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 @@ -24,6 +24,8 @@ import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.orm.dao.MemberDAO; import org.apache.ambari.server.orm.dao.PrivilegeDAO; +import org.apache.ambari.server.orm.dao.ResourceDAO; +import org.apache.ambari.server.orm.dao.ResourceTypeDAO; import org.apache.ambari.server.orm.dao.UserDAO; import org.apache.ambari.server.orm.dao.ViewDAO; import org.apache.ambari.server.orm.dao.ViewInstanceDAO; @@ -46,13 +48,14 @@ import org.apache.ambari.server.view.events.EventImpl; import org.apache.ambari.server.view.events.EventImplTest; import org.apache.ambari.view.events.Event; import org.apache.ambari.view.events.Listener; -import org.easymock.Capture; +import org.easymock.EasyMock; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import javax.xml.bind.JAXBException; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -70,7 +73,6 @@ import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; @@ -165,8 +167,14 @@ public class ViewRegistryTest { resourceTypeEntity.setName("MY_VIEW{1.0.0}"); ViewDAO vDAO = createMock(ViewDAO.class); + ResourceDAO rDAO = createNiceMock(ResourceDAO.class); + ResourceTypeDAO rtDAO = createNiceMock(ResourceTypeDAO.class); + ViewInstanceDAO viDAO = createNiceMock(ViewInstanceDAO.class); ViewRegistry.setViewDAO(vDAO); + ViewRegistry.setResourceDAO(rDAO); + ViewRegistry.setResourceTypeDAO(rtDAO); + ViewRegistry.setInstanceDAO(viDAO); ViewEntity viewDefinition = ViewEntityTest.getViewEntity(); viewDefinition.setResourceType(resourceTypeEntity); @@ -206,6 +214,7 @@ public class ViewRegistryTest { expect(viewDir.listFiles()).andReturn(new File[]{viewArchive}); expect(viewArchive.isDirectory()).andReturn(false); + expect(viewArchive.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}").anyTimes(); expect(archiveDir.exists()).andReturn(false); expect(archiveDir.getAbsolutePath()).andReturn( @@ -243,16 +252,19 @@ public class ViewRegistryTest { expect(libDir.listFiles()).andReturn(new File[]{fileEntry}); expect(fileEntry.toURI()).andReturn(new URI("file:./")); - Capture<ViewEntity> captureViewEntity = new Capture<ViewEntity>(); - - expect(vDAO.findByName("MY_VIEW{1.0.0}")).andReturn(null); - expect(vDAO.merge(capture(captureViewEntity))).andReturn(viewDefinition); + expect(vDAO.findByName("MY_VIEW{1.0.0}")).andReturn(viewDefinition); expect(vDAO.findAll()).andReturn(Collections.<ViewEntity>emptyList()); + expect(rtDAO.findByName("MY_VIEW{1.0.0}")).andReturn(null); + rtDAO.create(EasyMock.anyObject(ResourceTypeEntity.class)); + EasyMock.expectLastCall().anyTimes(); + + expect(viDAO.merge(EasyMock.anyObject(ViewInstanceEntity.class))).andReturn(null).times(2); + // replay mocks replay(configuration, viewDir, extractedArchiveDir, viewArchive, archiveDir, entryFile, classesDir, - libDir, fileEntry, viewJarFile, enumeration, jarEntry, is, fos, vDAO); + libDir, fileEntry, viewJarFile, enumeration, jarEntry, is, fos, rDAO, rtDAO, vDAO, viDAO); ViewRegistry registry = ViewRegistry.getInstance(); registry.setHelper(new TestViewRegistryHelper(viewConfigs, files, outputStreams, jarFiles)); @@ -260,11 +272,10 @@ public class ViewRegistryTest { Set<ViewInstanceEntity> instanceEntities = registry.readViewArchives(configuration); Assert.assertEquals(2, instanceEntities.size()); - Assert.assertEquals("MY_VIEW", captureViewEntity.getValue().getCommonName()); // verify mocks verify(configuration, viewDir, extractedArchiveDir, viewArchive, archiveDir, entryFile, classesDir, - libDir, fileEntry, viewJarFile, enumeration, jarEntry, is, fos, vDAO); + libDir, fileEntry, viewJarFile, enumeration, jarEntry, is, fos, rDAO, rtDAO, vDAO, viDAO); } @Test @@ -331,6 +342,7 @@ public class ViewRegistryTest { expect(viewDir.listFiles()).andReturn(new File[]{viewArchive}); expect(viewArchive.isDirectory()).andReturn(false); + expect(viewArchive.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}"); expect(archiveDir.exists()).andReturn(false); expect(archiveDir.getAbsolutePath()).andReturn( @@ -368,11 +380,6 @@ public class ViewRegistryTest { expect(libDir.listFiles()).andReturn(new File[]{fileEntry}); expect(fileEntry.toURI()).andReturn(new URI("file:./")); - Capture<ViewEntity> captureViewEntity = new Capture<ViewEntity>(); - - expect(vDAO.findByName("MY_VIEW{1.0.0}")).andReturn(null); - expect(vDAO.merge(capture(captureViewEntity))).andThrow(new IllegalArgumentException("Expected exception.")); - expect(vDAO.findAll()).andReturn(Collections.<ViewEntity>emptyList()); // replay mocks @@ -508,8 +515,10 @@ public class ViewRegistryTest { MemberDAO memberDAO = createNiceMock(MemberDAO.class); PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class); SecurityHelper securityHelper = createNiceMock(SecurityHelper.class); + ResourceDAO rDAO = createNiceMock(ResourceDAO.class); + ResourceTypeDAO rtDAO = createNiceMock(ResourceTypeDAO.class); - ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper); + ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper, rDAO, rtDAO); ViewRegistry registry = ViewRegistry.getInstance(); @@ -548,8 +557,10 @@ public class ViewRegistryTest { MemberDAO memberDAO = createNiceMock(MemberDAO.class); PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class); SecurityHelper securityHelper = createNiceMock(SecurityHelper.class); + ResourceDAO rDAO = createNiceMock(ResourceDAO.class); + ResourceTypeDAO rtDAO = createNiceMock(ResourceTypeDAO.class); - ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper); + ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper, rDAO, rtDAO); ViewRegistry registry = ViewRegistry.getInstance(); @@ -583,8 +594,10 @@ public class ViewRegistryTest { MemberDAO memberDAO = createNiceMock(MemberDAO.class); PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class); SecurityHelper securityHelper = createNiceMock(SecurityHelper.class); + ResourceDAO rDAO = createNiceMock(ResourceDAO.class); + ResourceTypeDAO rtDAO = createNiceMock(ResourceTypeDAO.class); - ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper); + ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper, rDAO, rtDAO); ViewRegistry registry = ViewRegistry.getInstance(); @@ -619,8 +632,10 @@ public class ViewRegistryTest { MemberDAO memberDAO = createNiceMock(MemberDAO.class); PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class); SecurityHelper securityHelper = createNiceMock(SecurityHelper.class); + ResourceDAO rDAO = createNiceMock(ResourceDAO.class); + ResourceTypeDAO rtDAO = createNiceMock(ResourceTypeDAO.class); - ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper); + ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper, rDAO, rtDAO); ViewRegistry registry = ViewRegistry.getInstance(); @@ -663,8 +678,10 @@ public class ViewRegistryTest { MemberDAO memberDAO = createNiceMock(MemberDAO.class); PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class); SecurityHelper securityHelper = createNiceMock(SecurityHelper.class); + ResourceDAO rDAO = createNiceMock(ResourceDAO.class); + ResourceTypeDAO rtDAO = createNiceMock(ResourceTypeDAO.class); - ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper); + ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper, rDAO, rtDAO); ViewRegistry registry = ViewRegistry.getInstance(); @@ -705,8 +722,10 @@ public class ViewRegistryTest { MemberDAO memberDAO = createNiceMock(MemberDAO.class); PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class); SecurityHelper securityHelper = createNiceMock(SecurityHelper.class); + ResourceDAO rDAO = createNiceMock(ResourceDAO.class); + ResourceTypeDAO rtDAO = createNiceMock(ResourceTypeDAO.class); - ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper); + ViewRegistry.init(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, securityHelper, rDAO, rtDAO); ViewRegistry registry = ViewRegistry.getInstance(); @@ -760,6 +779,16 @@ public class ViewRegistryTest { return viewConfigs.get(archiveFile); } + public ViewConfig getViewConfigFromExtractedArchive(String archivePath) + throws JAXBException, FileNotFoundException { + for (File viewConfigKey: viewConfigs.keySet()) { + if (viewConfigKey.getAbsolutePath().equals(archivePath)) { + return viewConfigs.get(viewConfigKey); + } + } + return null; + } + @Override public File getFile(String path) { return files.get(path);
