Repository: ambari Updated Branches: refs/heads/trunk 7e33ea589 -> ddf020dd6
AMBARI-9133 - Views: min and max version (tbeerbower) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ddf020dd Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ddf020dd Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ddf020dd Branch: refs/heads/trunk Commit: ddf020dd6102b1918a0d9e1c669f3e54765cd344 Parents: 7e33ea5 Author: tbeerbower <tbeerbo...@hortonworks.com> Authored: Mon Jan 19 13:57:48 2015 -0500 Committer: tbeerbower <tbeerbo...@hortonworks.com> Committed: Mon Jan 19 13:57:58 2015 -0500 ---------------------------------------------------------------------- .../internal/ViewVersionResourceProvider.java | 8 + .../ambari/server/orm/entities/ViewEntity.java | 11 +- .../apache/ambari/server/view/ViewRegistry.java | 95 ++++++++++-- .../server/view/configuration/ViewConfig.java | 30 ++++ .../AmbariPrivilegeResourceProviderTest.java | 2 +- .../ViewPrivilegeResourceProviderTest.java | 2 +- .../server/orm/entities/ViewEntityTest.java | 13 +- .../ambari/server/view/ViewRegistryTest.java | 149 +++++++++++++++++-- .../view/configuration/ViewConfigTest.java | 26 ++++ ambari-views/src/main/resources/view.xsd | 10 ++ 10 files changed, 317 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/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 58cf774..95703fd 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 @@ -49,6 +49,8 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider { public static final String LABEL_PROPERTY_ID = "ViewVersionInfo/label"; public static final String DESCRIPTION_PROPERTY_ID = "ViewVersionInfo/description"; public static final String VERSION_PROPERTY_ID = "ViewVersionInfo/version"; + public static final String MIN_AMBARI_VERSION_PROPERTY_ID = "ViewVersionInfo/min_ambari_version"; + public static final String MAX_AMBARI_VERSION_PROPERTY_ID = "ViewVersionInfo/max_ambari_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"; @@ -75,6 +77,8 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider { propertyIds.add(LABEL_PROPERTY_ID); propertyIds.add(DESCRIPTION_PROPERTY_ID); propertyIds.add(VERSION_PROPERTY_ID); + propertyIds.add(MIN_AMBARI_VERSION_PROPERTY_ID); + propertyIds.add(MAX_AMBARI_VERSION_PROPERTY_ID); propertyIds.add(PARAMETERS_PROPERTY_ID); propertyIds.add(ARCHIVE_PROPERTY_ID); propertyIds.add(MASKER_CLASS_PROPERTY_ID); @@ -131,6 +135,10 @@ public class ViewVersionResourceProvider extends AbstractResourceProvider { setResourceProperty(resource, LABEL_PROPERTY_ID, viewDefinition.getLabel(), requestedIds); setResourceProperty(resource, DESCRIPTION_PROPERTY_ID, viewDefinition.getDescription(), requestedIds); setResourceProperty(resource, VERSION_PROPERTY_ID, viewDefinition.getVersion(), requestedIds); + setResourceProperty(resource, MIN_AMBARI_VERSION_PROPERTY_ID, + viewDefinition.getConfiguration().getMinAmbariVersion(), requestedIds); + setResourceProperty(resource, MAX_AMBARI_VERSION_PROPERTY_ID, + viewDefinition.getConfiguration().getMaxAmbariVersion(), requestedIds); setResourceProperty(resource, PARAMETERS_PROPERTY_ID, viewDefinition.getConfiguration().getParameters(), requestedIds); setResourceProperty(resource, ARCHIVE_PROPERTY_ID, viewDefinition.getArchive(), requestedIds); http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/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 2f83e02..f77c97e 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 @@ -161,7 +161,7 @@ public class ViewEntity implements ViewDefinition { * The associated view configuration. */ @Transient - private final ViewConfig configuration; + private ViewConfig configuration; /** * The Ambari configuration properties. @@ -685,6 +685,15 @@ public class ViewEntity implements ViewDefinition { } /** + * Set the view configuration. + * + * @param configuration the view configuration + */ + public void setConfiguration(ViewConfig configuration) { + this.configuration = configuration; + } + + /** * Get the associated view configuration. * * @return the configuration http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/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 05f9ce1..e422a46 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 @@ -26,6 +26,7 @@ import com.google.inject.persist.Transactional; import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl; import org.apache.ambari.server.api.resources.SubResourceDefinition; import org.apache.ambari.server.api.resources.ViewExternalSubResourceDefinition; +import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.api.services.ViewExternalSubResourceService; import org.apache.ambari.server.api.services.ViewSubResourceService; import org.apache.ambari.server.configuration.ComponentSSLConfiguration; @@ -57,6 +58,7 @@ import org.apache.ambari.server.orm.entities.ViewParameterEntity; import org.apache.ambari.server.orm.entities.ViewResourceEntity; import org.apache.ambari.server.security.SecurityHelper; import org.apache.ambari.server.security.authorization.AmbariGrantedAuthority; +import org.apache.ambari.server.utils.VersionUtils; import org.apache.ambari.server.view.configuration.EntityConfig; import org.apache.ambari.server.view.configuration.InstanceConfig; import org.apache.ambari.server.view.configuration.ParameterConfig; @@ -80,6 +82,7 @@ import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; import javax.inject.Inject; +import javax.inject.Provider; import javax.inject.Singleton; import java.beans.IntrospectionException; import java.io.File; @@ -110,6 +113,7 @@ public class ViewRegistry { private static final String ALL_VIEWS_REG_EXP = ".*"; protected static final int DEFAULT_REQUEST_CONNECT_TIMEOUT = 5000; protected static final int DEFAULT_REQUEST_READ_TIMEOUT = 10000; + private static final String VIEW_AMBARI_VERSION_REGEXP = "^((\\d+\\.)?)*(\\*|\\d+)$"; /** * Thread pool @@ -204,6 +208,12 @@ public class ViewRegistry { ResourceTypeDAO resourceTypeDAO; /** + * Ambari meta info. + */ + @Inject + Provider<AmbariMetaInfo> ambariMetaInfo; + + /** * Ambari configuration. */ @Inject @@ -826,10 +836,11 @@ public class ViewRegistry { } // setup the given view definition - protected ViewEntity setupViewDefinition(ViewEntity viewDefinition, ViewConfig viewConfig, - ClassLoader cl) + protected ViewEntity setupViewDefinition(ViewEntity viewDefinition, ClassLoader cl) throws ClassNotFoundException, IntrospectionException { + ViewConfig viewConfig = viewDefinition.getConfiguration(); + viewDefinition.setClassLoader(cl); List<ParameterConfig> parameterConfigurations = viewConfig.getParameters(); @@ -1275,6 +1286,8 @@ public class ViewRegistry { Set<Runnable> extractionRunnables = new HashSet<Runnable>(); + final String serverVersion = ambariMetaInfo.get().getServerVersion(); + for (final File archiveFile : files) { if (!archiveFile.isDirectory()) { @@ -1302,13 +1315,13 @@ public class ViewRegistry { // always load system views up front if (systemView || !useExecutor || extractedArchiveDirFile.exists()) { // if the archive is already extracted then load the view now - readViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile); + readViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile, serverVersion); } else { // if the archive needs to be extracted then create a runnable to do it extractionRunnables.add(new Runnable() { @Override public void run() { - readViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile); + readViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile, serverVersion); } }); } @@ -1340,7 +1353,8 @@ public class ViewRegistry { // read a view archive private void readViewArchive(ViewEntity viewDefinition, File archiveFile, - File extractedArchiveDirFile) { + File extractedArchiveDirFile, + String serverVersion) { setViewStatus(viewDefinition, ViewEntity.ViewStatus.DEPLOYING, "Deploying " + extractedArchiveDirFile + "."); @@ -1353,19 +1367,22 @@ public class ViewRegistry { ViewConfig viewConfig = archiveUtility.getViewConfigFromExtractedArchive(extractedArchiveDirPath, configuration.isViewValidationEnabled()); - setupViewDefinition(viewDefinition, viewConfig, cl); + viewDefinition.setConfiguration(viewConfig); - Set<ViewInstanceEntity> instanceDefinitions = new HashSet<ViewInstanceEntity>(); + if (checkViewVersions(viewDefinition, serverVersion)) { + setupViewDefinition(viewDefinition, cl); - for (InstanceConfig instanceConfig : viewConfig.getInstances()) { - ViewInstanceEntity instanceEntity = createViewInstanceDefinition(viewConfig, viewDefinition, instanceConfig); - instanceEntity.setXmlDriven(true); - instanceDefinitions.add(instanceEntity); - } - persistView(viewDefinition, instanceDefinitions); + Set<ViewInstanceEntity> instanceDefinitions = new HashSet<ViewInstanceEntity>(); - setViewStatus(viewDefinition, ViewEntity.ViewStatus.DEPLOYED, "Deployed " + extractedArchiveDirPath + "."); + for (InstanceConfig instanceConfig : viewConfig.getInstances()) { + ViewInstanceEntity instanceEntity = createViewInstanceDefinition(viewConfig, viewDefinition, instanceConfig); + instanceEntity.setXmlDriven(true); + instanceDefinitions.add(instanceEntity); + } + persistView(viewDefinition, instanceDefinitions); + setViewStatus(viewDefinition, ViewEntity.ViewStatus.DEPLOYED, "Deployed " + extractedArchiveDirPath + "."); + } } catch (Exception e) { String msg = "Caught exception loading view " + viewDefinition.getName(); @@ -1374,6 +1391,56 @@ public class ViewRegistry { } } + /** + * Check the configured view max and min Ambari versions for the given view entity + * against the given Ambari server version. + * + * @param view the view + * @param serverVersion the server version + * + * @return true if the given server version >= min version && <= max version for the given view + */ + protected boolean checkViewVersions(ViewEntity view, String serverVersion) { + ViewConfig config = view.getConfiguration(); + + return checkViewVersion(view, config.getMinAmbariVersion(), serverVersion, "minimum", 1, "less than") && + checkViewVersion(view, config.getMaxAmbariVersion(), serverVersion, "maximum", -1, "greater than"); + + } + + // check the given version against the actual Ambari server version + private boolean checkViewVersion(ViewEntity view, String version, String serverVersion, String label, + int errValue, String errMsg) { + + if (version != null && !version.isEmpty()) { + + // make sure that the given version is a valid version string + if (!version.matches(VIEW_AMBARI_VERSION_REGEXP)) { + String msg = "The configured " + label + " Ambari version " + version + " for view " + + view.getName() + " is not valid."; + + setViewStatus(view, ViewEntity.ViewStatus.ERROR, msg); + LOG.error(msg); + return false; + } + + int index = version.indexOf('*'); + + int compVal = index == -1 ? VersionUtils.compareVersions(version, serverVersion) : + index > 0 ? VersionUtils.compareVersions(version.substring(0, index), serverVersion, index) : 0; + + if (compVal == errValue) { + String msg = "The Ambari server version " + serverVersion + " is " + errMsg + " the configured " + label + + " Ambari version " + version + " for view " + view.getName(); + + setViewStatus(view, ViewEntity.ViewStatus.ERROR, msg); + LOG.error(msg); + return false; + } + } + return true; + } + // persist the given view and its instances @Transactional private void persistView(ViewEntity viewDefinition, Set<ViewInstanceEntity> instanceDefinitions) throws Exception { http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/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 ea04a21..c617b7f 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 @@ -59,6 +59,18 @@ public class ViewConfig { private String version; /** + * The minimum Ambari version. + */ + @XmlElement(name="min-ambari-version") + private String minAmbariVersion; + + /** + * The maximum Ambari version. + */ + @XmlElement(name="max-ambari-version") + private String maxAmbariVersion; + + /** * The icon path in the view archive. */ private String icon; @@ -173,6 +185,24 @@ public class ViewConfig { } /** + * Get the minimum version of Ambari required to run this view. + * + * @return the minimum Ambari version + */ + public String getMinAmbariVersion() { + return minAmbariVersion; + } + + /** + * Get the maximum version of Ambari that can run this view. + * + * @return the maximum Ambari version + */ + public String getMaxAmbariVersion() { + return maxAmbariVersion; + } + + /** * Get the icon path in the view archive. * * @return the icon path http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProviderTest.java index b9e56ee..a6536c7 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProviderTest.java @@ -98,7 +98,7 @@ public class AmbariPrivilegeResourceProviderTest { @Before public void resetGlobalMocks() { ViewRegistry.initInstance(ViewRegistryTest.getRegistry(viewDAO, viewInstanceDAO, userDAO, - memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null)); + memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null, null)); reset(privilegeDAO, userDAO, groupDAO, principalDAO, permissionDAO, resourceDAO, clusterDAO, handlerList); } http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProviderTest.java index e1a4da3..ed8aed0 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProviderTest.java @@ -90,7 +90,7 @@ public class ViewPrivilegeResourceProviderTest { public void resetGlobalMocks() { ViewRegistry.initInstance(ViewRegistryTest.getRegistry(viewDAO, viewInstanceDAO, userDAO, - memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null)); + memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null, null)); reset(privilegeDAO, userDAO, groupDAO, principalDAO, permissionDAO, resourceDAO, handlerList); } http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java index f93403d..a9ceb93 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/ViewEntityTest.java @@ -47,6 +47,13 @@ import static org.easymock.EasyMock.verify; */ public class ViewEntityTest { + private static String with_ambari_versions = "<view>\n" + + " <name>MY_VIEW</name>\n" + + " <label>My View!</label>\n" + + " <version>1.0.0</version>\n" + + " <min-ambari-version>1.6.1</min-ambari-version>\n" + + " <max-ambari-version>2.0.0</max-ambari-version>\n" + + "</view>"; public static ViewEntity getViewEntity() throws Exception { return getViewEntity(ViewConfigTest.getConfig()); @@ -122,10 +129,14 @@ public class ViewEntityTest { } @Test - public void testGetConfiguration() throws Exception { + public void testSetGetConfiguration() throws Exception { ViewConfig viewConfig = ViewConfigTest.getConfig(); ViewEntity viewDefinition = getViewEntity(viewConfig); Assert.assertEquals(viewConfig, viewDefinition.getConfiguration()); + + ViewConfig newViewConfig = ViewConfigTest.getConfig(with_ambari_versions); + viewDefinition.setConfiguration(newViewConfig); + Assert.assertEquals(newViewConfig, viewDefinition.getConfiguration()); } @Test http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/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 203ea18..14dd4cf 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 @@ -50,8 +50,9 @@ import java.util.jar.JarInputStream; import javax.xml.bind.JAXBException; -import junit.framework.TestListener; +import com.google.inject.Provider; import org.apache.ambari.server.api.resources.SubResourceDefinition; +import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; @@ -172,15 +173,16 @@ public class ViewRegistryTest { private static final SecurityHelper securityHelper = createNiceMock(SecurityHelper.class); private static final Configuration configuration = createNiceMock(Configuration.class); private static final ViewInstanceHandlerList handlerList = createNiceMock(ViewInstanceHandlerList.class); + private static final AmbariMetaInfo ambariMetaInfo = createNiceMock(AmbariMetaInfo.class); @Before public void resetGlobalMocks() { ViewRegistry.initInstance(getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, - resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null)); + resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null, ambariMetaInfo)); reset(viewDAO, resourceDAO, viewInstanceDAO, userDAO, memberDAO, - privilegeDAO, resourceTypeDAO, securityHelper, configuration, handlerList); + privilegeDAO, resourceTypeDAO, securityHelper, configuration, handlerList, ambariMetaInfo); } @Test @@ -333,7 +335,7 @@ public class ViewRegistryTest { TestViewArchiveUtility archiveUtility = new TestViewArchiveUtility(viewConfigs, files, outputStreams, jarFiles); ViewRegistry registry = getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, - resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, archiveUtility); + resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, archiveUtility, ambariMetaInfo); registry.readViewArchives(); @@ -501,7 +503,7 @@ public class ViewRegistryTest { TestViewArchiveUtility archiveUtility = new TestViewArchiveUtility(viewConfigs, files, outputStreams, jarFiles); ViewRegistry registry = getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, - resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, archiveUtility); + resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, archiveUtility, ambariMetaInfo); registry.readViewArchives(); @@ -603,7 +605,9 @@ public class ViewRegistryTest { ViewRegistry registry = ViewRegistry.getInstance(); - registry.setupViewDefinition(viewDefinition, config, getClass().getClassLoader()); + viewDefinition.setConfiguration(config); + + registry.setupViewDefinition(viewDefinition, getClass().getClassLoader()); Map<Resource.Type, ResourceProvider> providerMap = registry.getResourceProviders(); @@ -682,7 +686,9 @@ public class ViewRegistryTest { ViewRegistry registry = ViewRegistry.getInstance(); - registry.setupViewDefinition(viewDefinition, config, getClass().getClassLoader()); + viewDefinition.setConfiguration(config); + + registry.setupViewDefinition(viewDefinition, getClass().getClassLoader()); Set<SubResourceDefinition> subResourceDefinitions = registry.getSubResourceDefinitions(viewDefinition.getCommonName(), viewDefinition.getVersion()); @@ -1245,6 +1251,117 @@ public class ViewRegistryTest { } @Test + public void testCheckViewVersions() { + ViewRegistry registry = ViewRegistry.getInstance(); + ViewEntity viewEntity = createNiceMock(ViewEntity.class); + + ViewConfig config = createNiceMock(ViewConfig.class); + + expect(viewEntity.getConfiguration()).andReturn(config).anyTimes(); + + // null, null + expect(config.getMinAmbariVersion()).andReturn(null); + expect(config.getMaxAmbariVersion()).andReturn(null); + + // 1.0.0, 3.0.0 + expect(config.getMinAmbariVersion()).andReturn("1.0.0"); + expect(config.getMaxAmbariVersion()).andReturn("3.0.0"); + + // 1.0.0, 1.5 + expect(config.getMinAmbariVersion()).andReturn("1.0.0"); + expect(config.getMaxAmbariVersion()).andReturn("1.5"); + + // 2.5 + expect(config.getMinAmbariVersion()).andReturn("2.5"); + + // null, 3.0.0 + expect(config.getMinAmbariVersion()).andReturn(null); + expect(config.getMaxAmbariVersion()).andReturn("3.0.0"); + + // 1.0.0, null + expect(config.getMinAmbariVersion()).andReturn("1.0.0"); + expect(config.getMaxAmbariVersion()).andReturn(null); + + // 1.0.0, * + expect(config.getMinAmbariVersion()).andReturn("1.0.0"); + expect(config.getMaxAmbariVersion()).andReturn("*"); + + // *, 3.0.0 + expect(config.getMinAmbariVersion()).andReturn("*"); + expect(config.getMaxAmbariVersion()).andReturn("3.0.0"); + + // 1.0.0, 2.* + expect(config.getMinAmbariVersion()).andReturn("1.0.0"); + expect(config.getMaxAmbariVersion()).andReturn("2.*"); + + // 1.*, 3.0.0 + expect(config.getMinAmbariVersion()).andReturn("1.*"); + expect(config.getMaxAmbariVersion()).andReturn("3.0.0"); + + // 1.0.0, 2.1.* + expect(config.getMinAmbariVersion()).andReturn("1.0.0"); + expect(config.getMaxAmbariVersion()).andReturn("2.1.*"); + + // 1.5.*, 3.0.0 + expect(config.getMinAmbariVersion()).andReturn("1.5.*"); + expect(config.getMaxAmbariVersion()).andReturn("3.0.0"); + + // 1.0.0, 1.9.9.* + expect(config.getMinAmbariVersion()).andReturn("1.0.0"); + expect(config.getMaxAmbariVersion()).andReturn("1.9.9.*"); + + // 2.0.0.1.*, 3.0.0 + expect(config.getMinAmbariVersion()).andReturn("2.0.0.1.*"); + + replay(viewEntity, config); + + // null, null + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.0.0, 3.0.0 + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.0.0, 1.5 + Assert.assertFalse(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 2.5, 3.0.0 + Assert.assertFalse(registry.checkViewVersions(viewEntity, "2.0.0")); + + // null, 3.0.0 + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.0.0, null + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.0.0, * + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // *, 3.0.0 + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.0.0, 2.* + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.*, 3.0.0 + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.0.0, 2.1.* + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.5.*, 3.0.0 + Assert.assertTrue(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 1.0.0, 1.9.9.* + Assert.assertFalse(registry.checkViewVersions(viewEntity, "2.0.0")); + + // 2.0.0.1.*, 3.0.0 + Assert.assertFalse(registry.checkViewVersions(viewEntity, "2.0.0")); + + verify(viewEntity, config); + + } + + @Test public void testExtractViewArchive() throws Exception { File viewDir = createNiceMock(File.class); @@ -1436,7 +1553,9 @@ public class ViewRegistryTest { PrivilegeDAO privilegeDAO, ResourceDAO resourceDAO, ResourceTypeDAO resourceTypeDAO, SecurityHelper securityHelper, ViewInstanceHandlerList handlerList, - ViewExtractor viewExtractor, ViewArchiveUtility archiveUtility) { + ViewExtractor viewExtractor, + ViewArchiveUtility archiveUtility, + AmbariMetaInfo ambariMetaInfo) { ViewRegistry instance = new ViewRegistry(); @@ -1454,6 +1573,14 @@ public class ViewRegistryTest { instance.archiveUtility = archiveUtility == null ? new ViewArchiveUtility() : archiveUtility; instance.extractor.archiveUtility = instance.archiveUtility; + final AmbariMetaInfo finalMetaInfo = ambariMetaInfo; + instance.ambariMetaInfo = new Provider<AmbariMetaInfo>() { + @Override + public AmbariMetaInfo get() { + return finalMetaInfo; + } + }; + return instance; } @@ -1461,11 +1588,11 @@ public class ViewRegistryTest { ClassLoader cl, String archivePath) throws Exception{ ViewRegistry registry = getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, - resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null); + resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null, null); ViewEntity viewDefinition = new ViewEntity(viewConfig, ambariConfig, archivePath); - registry.setupViewDefinition(viewDefinition, viewConfig, cl); + registry.setupViewDefinition(viewDefinition, cl); return viewDefinition; } @@ -1473,7 +1600,7 @@ public class ViewRegistryTest { public static ViewInstanceEntity getViewInstanceEntity(ViewEntity viewDefinition, InstanceConfig instanceConfig) throws Exception { ViewRegistry registry = getRegistry(viewDAO, viewInstanceDAO, userDAO, memberDAO, privilegeDAO, - resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null); + resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null, null); ViewInstanceEntity viewInstanceDefinition = new ViewInstanceEntity(viewDefinition, instanceConfig); http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/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 50a1223..75ab10a 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 @@ -139,6 +139,14 @@ public class ViewConfigTest { " <system>false</system>\n" + "</view>"; + private static String with_ambari_versions = "<view>\n" + + " <name>MY_VIEW</name>\n" + + " <label>My View!</label>\n" + + " <version>1.0.0</version>\n" + + " <min-ambari-version>1.6.1</min-ambari-version>\n" + + " <max-ambari-version>2.0.0</max-ambari-version>\n" + + "</view>"; + @Test public void testGetName() throws Exception { ViewConfig config = getConfig(); @@ -247,6 +255,24 @@ public class ViewConfigTest { Assert.assertFalse(config.isSystem()); } + @Test + public void testGetMinAmbariVersion() throws Exception { + ViewConfig config = getConfig(); + Assert.assertNull(config.getMinAmbariVersion()); + + config = getConfig(with_ambari_versions); + Assert.assertEquals("1.6.1", config.getMinAmbariVersion()); + } + + @Test + public void testGetMaxAmbariVersion() throws Exception { + ViewConfig config = getConfig(); + Assert.assertNull(config.getMaxAmbariVersion()); + + config = getConfig(with_ambari_versions); + Assert.assertEquals("2.0.0", config.getMaxAmbariVersion()); + } + public static ViewConfig getConfig() throws JAXBException { return getConfig(xml); } http://git-wip-us.apache.org/repos/asf/ambari/blob/ddf020dd/ambari-views/src/main/resources/view.xsd ---------------------------------------------------------------------- diff --git a/ambari-views/src/main/resources/view.xsd b/ambari-views/src/main/resources/view.xsd index f4d65c4..e994faf 100644 --- a/ambari-views/src/main/resources/view.xsd +++ b/ambari-views/src/main/resources/view.xsd @@ -235,6 +235,16 @@ <xs:documentation>The version of the view.</xs:documentation> </xs:annotation> </xs:element> + <xs:element type="xs:string" name="min-ambari-version" minOccurs="0" maxOccurs="1"> + <xs:annotation> + <xs:documentation>The minimum version of Ambari server required to run this view.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element type="xs:string" name="max-ambari-version" minOccurs="0" maxOccurs="1"> + <xs:annotation> + <xs:documentation>The maximum version of Ambari server that can run this view.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element type="xs:string" name="description" minOccurs="0" maxOccurs="1"> <xs:annotation> <xs:documentation>The description of the view.</xs:documentation>