Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 98199186C3 for ; Mon, 1 Feb 2016 21:33:57 +0000 (UTC) Received: (qmail 8996 invoked by uid 500); 1 Feb 2016 21:33:57 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 8966 invoked by uid 500); 1 Feb 2016 21:33:57 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 8957 invoked by uid 99); 1 Feb 2016 21:33:57 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Feb 2016 21:33:57 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 59BC7DFCE4; Mon, 1 Feb 2016 21:33:57 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ncole@apache.org To: commits@ambari.apache.org Message-Id: <1009202994ef446c9a603f0b928214d6@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-14867. Use entities for parent/child repository versions (ncole) Date: Mon, 1 Feb 2016 21:33:57 +0000 (UTC) Repository: ambari Updated Branches: refs/heads/branch-dev-patch-upgrade 73aee31ef -> c84da2493 AMBARI-14867. Use entities for parent/child repository versions (ncole) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c84da249 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c84da249 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c84da249 Branch: refs/heads/branch-dev-patch-upgrade Commit: c84da24939b691951244840e07526a0ed9dee30a Parents: 73aee31 Author: Nate Cole Authored: Mon Feb 1 12:46:26 2016 -0500 Committer: Nate Cole Committed: Mon Feb 1 16:33:19 2016 -0500 ---------------------------------------------------------------------- .../server/configuration/Configuration.java | 83 +++++++--- .../RepositoryVersionResourceProvider.java | 14 ++ .../VersionDefinitionResourceProvider.java | 149 ++++++++++++++--- .../orm/entities/RepositoryVersionEntity.java | 30 ++++ .../main/resources/Ambari-DDL-Derby-CREATE.sql | 1 + .../main/resources/Ambari-DDL-MySQL-CREATE.sql | 1 + .../main/resources/Ambari-DDL-Oracle-CREATE.sql | 1 + .../resources/Ambari-DDL-Postgres-CREATE.sql | 1 + .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 1 + .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 1 + .../resources/Ambari-DDL-SQLServer-CREATE.sql | 1 + .../RepositoryVersionResourceProviderTest.java | 60 ------- .../VersionDefinitionResourceProviderTest.java | 160 +++++++++++++++++++ .../version_definition_resource_provider.xml | 13 +- 14 files changed, 398 insertions(+), 118 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java index d1453a0..55eea7a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java @@ -17,11 +17,20 @@ */ package org.apache.ambari.server.configuration; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.inject.Inject; -import com.google.inject.Singleton; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.security.cert.CertificateException; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; import org.apache.ambari.annotations.Experimental; import org.apache.ambari.annotations.ExperimentalFeature; @@ -34,32 +43,23 @@ import org.apache.ambari.server.orm.entities.StageEntity; import org.apache.ambari.server.security.ClientSecurityType; import org.apache.ambari.server.security.authorization.LdapServerProperties; import org.apache.ambari.server.security.authorization.jwt.JwtAuthenticationProperties; +import org.apache.ambari.server.security.encryption.CertificateUtils; import org.apache.ambari.server.security.encryption.CredentialProvider; import org.apache.ambari.server.state.stack.OsFamily; -import org.apache.ambari.server.security.encryption.CertificateUtils; import org.apache.ambari.server.utils.Parallel; import org.apache.ambari.server.utils.ShellCommandUtil; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.NumberUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import java.security.cert.CertificateException; -import java.security.interfaces.RSAPublicKey; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.inject.Inject; +import com.google.inject.Singleton; /** @@ -545,6 +545,26 @@ public class Configuration { public static final String VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_KEY = "views.http.x-xss-protection"; public static final String VIEWS_HTTP_X_XSS_PROTECTION_HEADER_VALUE_DEFAULT = "1; mode=block"; + /* + * Version Definition URL + */ + /** + * The connection timeout for reading version definitions. + */ + private static final String VERSION_DEFINITION_CONNECT_TIMEOUT = "server.version_definition.connect.timeout.millis"; + /** + * Default connect timeout for reading version definitions. + */ + private static final int VERSION_DEFINITION_CONNECT_TIMEOUT_DEFAULT = 5000; + /** + * The read timeout for reading version definitions. + */ + private static final String VERSION_DEFINITION_READ_TIMEOUT = "server.version_definition.read.timeout.millis"; + /** + * Default read timeout for reading version definitions. + */ + private static final int VERSION_DEFINITION_READ_TIMEOUT_DEFAULT = 5000; + private static final Logger LOG = LoggerFactory.getLogger( Configuration.class); @@ -1929,7 +1949,7 @@ public class Configuration { /** * Get property-providers' thread pool core size. - * + * * @return the property-providers' thread pool core size */ public int getPropertyProvidersThreadPoolCoreSize() { @@ -1939,7 +1959,7 @@ public class Configuration { /** * Get property-providers' thread pool max size. - * + * * @return the property-providers' thread pool max size */ public int getPropertyProvidersThreadPoolMaxSize() { @@ -2472,4 +2492,21 @@ public class Configuration { } return attempts; } + + /** + * @return the connect timeout used when loading a version definition URL. + */ + public int getVersionDefinitionConnectTimeout() { + return NumberUtils.toInt( + properties.getProperty(VERSION_DEFINITION_CONNECT_TIMEOUT), + VERSION_DEFINITION_CONNECT_TIMEOUT_DEFAULT); + } + /** + * @return the read timeout used when loading a version definition URL + */ + public int getVersionDefinitionReadTimeout() { + return NumberUtils.toInt( + properties.getProperty(VERSION_DEFINITION_READ_TIMEOUT), + VERSION_DEFINITION_READ_TIMEOUT_DEFAULT); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java index 873733d..87731c4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java @@ -96,6 +96,9 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc public static final String REPOSITORY_VERSION_RELEASE_COMPATIBLE_WITH = "RepositoryVersions/release/compatible_with"; public static final String REPOSITORY_VERSION_AVAILABLE_SERVICES = "RepositoryVersions/services"; + public static final String REPOSITORY_VERSION_PARENT_ID = "RepositoryVersions/parent_id"; + public static final String REPOSITORY_VERSION_HAS_CHILDREN = "RepositoryVersions/has_children"; + @SuppressWarnings("serial") private static Set pkPropertyIds = new HashSet() { { @@ -116,6 +119,8 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc REPOSITORY_VERSION_RELEASE_COMPATIBLE_WITH, REPOSITORY_VERSION_RELEASE_NOTES, REPOSITORY_VERSION_RELEASE_VERSION, + REPOSITORY_VERSION_PARENT_ID, + REPOSITORY_VERSION_HAS_CHILDREN, REPOSITORY_VERSION_AVAILABLE_SERVICES); @SuppressWarnings("serial") @@ -157,6 +162,7 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc */ public RepositoryVersionResourceProvider() { super(propertyIds, keyPropertyIds); + setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS)); setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS)); setRequiredUpdateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS, RoleAuthorization.AMBARI_EDIT_STACK_REPOS)); @@ -226,6 +232,7 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc final Set requestedIds = getRequestPropertyIds(request, predicate); final Set> propertyMaps = getPropertyMaps(predicate); + List requestedEntities = new ArrayList(); for (Map propertyMap: propertyMaps) { final StackId stackId = getStackInformationFromUrl(propertyMap); @@ -240,6 +247,7 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc throw new SystemException("Repository version should have numerical id"); } final RepositoryVersionEntity entity = repositoryVersionDAO.findByPK(id); + if (entity == null) { throw new NoSuchResourceException("There is no repository version with id " + id); } else { @@ -258,6 +266,12 @@ public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourc setResourceProperty(resource, REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, entity.getVersion(), requestedIds); setResourceProperty(resource, REPOSITORY_VERSION_TYPE_PROPERTY_ID, entity.getType(), requestedIds); + setResourceProperty(resource, REPOSITORY_VERSION_PARENT_ID, entity.getParentId(), requestedIds); + + List children = entity.getChildren(); + setResourceProperty(resource, REPOSITORY_VERSION_HAS_CHILDREN, + null != children && !children.isEmpty(), requestedIds); + final VersionDefinitionXml xml; try { http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java index 4b0d3cc..3533293 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java @@ -17,7 +17,9 @@ */ package org.apache.ambari.server.controller.internal; -import java.net.URL; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -29,6 +31,8 @@ import java.util.Set; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.StaticallyInject; import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.configuration.ComponentSSLConfiguration; +import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.spi.NoSuchParentResourceException; import org.apache.ambari.server.controller.spi.NoSuchResourceException; import org.apache.ambari.server.controller.spi.Predicate; @@ -44,11 +48,13 @@ import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; import org.apache.ambari.server.orm.entities.StackEntity; import org.apache.ambari.server.security.authorization.ResourceType; import org.apache.ambari.server.security.authorization.RoleAuthorization; +import org.apache.ambari.server.state.RepositoryType; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.StackInfo; import org.apache.ambari.server.state.repository.VersionDefinitionXml; import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import com.google.common.collect.Sets; import com.google.inject.Inject; @@ -67,6 +73,7 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc public static final String VERSION_DEF_STACK_NAME = "VersionDefinition/stack_name"; public static final String VERSION_DEF_STACK_VERSION = "VersionDefinition/stack_version"; + protected static final String VERSION_DEF_TYPE_PROPERTY_ID = "VersionDefinition/type"; protected static final String VERSION_DEF_DEFINITION_URL = "VersionDefinition/version_url"; protected static final String VERSION_DEF_FULL_VERSION = "VersionDefinition/repository_version"; @@ -74,7 +81,7 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc protected static final String VERSION_DEF_RELEASE_BUILD = "VersionDefinition/release/build"; protected static final String VERSION_DEF_RELEASE_NOTES = "VersionDefinition/release/notes"; protected static final String VERSION_DEF_RELEASE_COMPATIBLE_WITH = "VersionDefinition/release/compatible_with"; - protected static final String VERSION_DEF_AVAILABLE_SERVICES = "VersionDefinition/services"; + protected static final String VERSION_DEF_AVAILABLE_SERVICES = "VersionDefinition/services"; @Inject private static RepositoryVersionDAO s_repoVersionDAO; @@ -88,6 +95,9 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc @Inject private static StackDAO s_stackDAO; + @Inject + private static Configuration s_configuration; + /** * Key property ids */ @@ -141,12 +151,13 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc Set> requestProperties = request.getProperties(); if (requestProperties.size() > 1) { - throw new SystemException("Cannot process more than one file per request"); + throw new IllegalArgumentException("Cannot process more than one file per request"); } final Map properties = requestProperties.iterator().next(); + if (!properties.containsKey(VERSION_DEF_DEFINITION_URL)) { - throw new SystemException(String.format("%s is required", VERSION_DEF_DEFINITION_URL)); + throw new IllegalArgumentException(String.format("%s is required", VERSION_DEF_DEFINITION_URL)); } RepositoryVersionEntity entity = createResources(new Command() { @@ -155,11 +166,15 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc String definitionUrl = (String) properties.get(VERSION_DEF_DEFINITION_URL); - RepositoryVersionEntity entity = toRepositoryVersionEntity(definitionUrl); + XmlHolder holder = loadXml(definitionUrl); + + RepositoryVersionEntity entity = toRepositoryVersionEntity(holder); RepositoryVersionResourceProvider.validateRepositoryVersion(s_repoVersionDAO, s_metaInfo.get(), entity); + checkForParent(holder, entity); + s_repoVersionDAO.create(entity); return entity; @@ -220,6 +235,62 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc throw new SystemException("Cannot delete Version Definitions"); } + /** + * In the case of a patch, check if there is a parent repo. + * @param entity the entity to check + */ + private void checkForParent(XmlHolder holder, RepositoryVersionEntity entity) throws AmbariException { + if (entity.getType() != RepositoryType.PATCH) { + return; + } + + List entities = s_repoVersionDAO.findByStack(entity.getStackId()); + if (entities.isEmpty()) { + throw new AmbariException(String.format("Patch %s was uploaded, but there are no repositories for %s", + entity.getVersion(), entity.getStackId().toString())); + } + + List matching = new ArrayList<>(); + + boolean emptyCompatible = StringUtils.isBlank(holder.xml.release.compatibleWith); + + for (RepositoryVersionEntity candidate : entities) { + String baseVersion = candidate.getVersion(); + if (baseVersion.lastIndexOf('-') > -1) { + baseVersion = baseVersion.substring(0, baseVersion.lastIndexOf('-')); + } + + if (emptyCompatible) { + if (baseVersion.equals(holder.xml.release.version)) { + matching.add(candidate); + } + } else { + if (baseVersion.matches(holder.xml.release.compatibleWith)) { + matching.add(candidate); + } + } + } + + if (matching.isEmpty()) { + String format = "No versions matched pattern %s"; + + throw new AmbariException(String.format(format, + emptyCompatible ? holder.xml.release.version : holder.xml.release.compatibleWith)); + } else if (matching.size() > 1) { + Set versions= new HashSet<>(); + for (RepositoryVersionEntity match : matching) { + versions.add(match.getVersion()); + } + + throw new AmbariException(String.format("More than one repository matches patch %s: %s", + entity.getVersion(), StringUtils.join(versions, ", "))); + } + + RepositoryVersionEntity parent = matching.get(0); + + entity.setParent(parent); + } + @Override protected Set getPKPropertyIds() { return PK_PROPERTY_IDS; @@ -230,45 +301,63 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc return ResourceType.AMBARI; } - /** - * Transforms a XML version defintion to an entity - * - * @param definitionUrl the String URL for loading - * @return constructed entity - * @throws AmbariException if some properties are missing or json has incorrect structure - */ - protected RepositoryVersionEntity toRepositoryVersionEntity(String definitionUrl) throws AmbariException { - final VersionDefinitionXml xml; - final String xmlString; + private XmlHolder loadXml(String definitionUrl) throws AmbariException { + XmlHolder holder = new XmlHolder(); + holder.url = definitionUrl; + + int connectTimeout = s_configuration.getVersionDefinitionConnectTimeout(); + int readTimeout = s_configuration.getVersionDefinitionReadTimeout(); + try { - URL url = new URL(definitionUrl); + URI uri = new URI(definitionUrl); + InputStream stream = null; - xmlString = IOUtils.toString(url.openStream(), "UTF-8"); + if (uri.getScheme().equalsIgnoreCase("file")) { + stream = uri.toURL().openStream(); + } else { + URLStreamProvider provider = new URLStreamProvider(connectTimeout, readTimeout, + ComponentSSLConfiguration.instance()); - xml = VersionDefinitionXml.load(xmlString); + stream = provider.readFrom(definitionUrl); + } + + holder.xmlString = IOUtils.toString(stream, "UTF-8"); + holder.xml = VersionDefinitionXml.load(holder.xmlString); } catch (Exception e) { String err = String.format("Could not load url from %s. %s", definitionUrl, e.getMessage()); throw new AmbariException(err, e); } + return holder; + } + + /** + * Transforms a XML version defintion to an entity + * + * @param definitionUrl the String URL for loading + * @return constructed entity + * @throws AmbariException if some properties are missing or json has incorrect structure + */ + protected RepositoryVersionEntity toRepositoryVersionEntity(XmlHolder holder) throws AmbariException { + // !!! TODO validate parsed object graph RepositoryVersionEntity entity = new RepositoryVersionEntity(); - StackId stackId = new StackId(xml.release.stackId); + StackId stackId = new StackId(holder.xml.release.stackId); StackEntity stackEntity = s_stackDAO.find(stackId.getStackName(), stackId.getStackVersion()); entity.setStack(stackEntity); entity.setOperatingSystems(s_repoVersionHelper.get().serializeOperatingSystems( - xml.repositoryInfo.getRepositories())); - entity.setVersion(xml.release.getFullVersion()); - entity.setDisplayName(stackId, xml.release); - entity.setType(xml.release.repositoryType); - entity.setVersionUrl(definitionUrl); - entity.setVersionXml(xmlString); - entity.setVersionXsd(xml.xsdLocation); + holder.xml.repositoryInfo.getRepositories())); + entity.setVersion(holder.xml.release.getFullVersion()); + entity.setDisplayName(stackId, holder.xml.release); + entity.setType(holder.xml.release.repositoryType); + entity.setVersionUrl(holder.url); + entity.setVersionXml(holder.xmlString); + entity.setVersionXsd(holder.xml.xsdLocation); return entity; } @@ -327,5 +416,13 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc return resource; } + /** + * Convenience class to hold the xml String representation, the url, and the parsed object. + */ + private static class XmlHolder { + String url = null; + String xmlString = null; + VersionDefinitionXml xml = null; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java index fa2f905..4af4216 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java @@ -33,6 +33,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.Lob; +import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; @@ -124,6 +125,13 @@ public class RepositoryVersionEntity { @Column(name="version_xsd", insertable = true, updatable = true) private String versionXsd; + @ManyToOne + @JoinColumn(name = "parent_id") + private RepositoryVersionEntity parent; + + @OneToMany(mappedBy = "parent") + private List children; + // ----- RepositoryVersionEntity ------------------------------------------------------- public RepositoryVersionEntity() { @@ -389,4 +397,26 @@ public class RepositoryVersionEntity { return false; } + /** + * @param parent + */ + public void setParent(RepositoryVersionEntity entity) { + parent = entity; + parent.children.add(this); + } + + /** + * @return the repositories that are denoted children + */ + public List getChildren() { + return children; + } + + /** + * @return the parentId, or {@code null} if the entity is already a parent + */ + public Long getParentId() { + return null == parent ? null : parent.getId(); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql index a43211c..d873122 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql @@ -554,6 +554,7 @@ CREATE TABLE repo_version ( version_url VARCHAR(1024), version_xml CLOB, version_xsd VARCHAR(512), + parent_id BIGINT, PRIMARY KEY(repo_version_id) ); http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/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 1941331..705436c 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -562,6 +562,7 @@ CREATE TABLE repo_version ( version_url VARCHAR(1024), version_xml MEDIUMTEXT, version_xsd VARCHAR(512), + parent_id BIGINT, PRIMARY KEY(repo_version_id) ); http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/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 75d2a4b..10785b9 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -551,6 +551,7 @@ CREATE TABLE repo_version ( version_url VARCHAR(1024), version_xml CLOB, version_xsd VARCHAR(512), + parent_id NUMBER(19), PRIMARY KEY(repo_version_id) ); http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/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 1a6c9c6..54f5404 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -555,6 +555,7 @@ CREATE TABLE repo_version ( version_url VARCHAR(1024), version_xml VARCHAR TEXT, version_xsd VARCHAR(512), + parent_id BIGINT, PRIMARY KEY(repo_version_id) ); http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/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 efaa7a9..f0302f5 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 @@ -624,6 +624,7 @@ CREATE TABLE ambari.repo_version ( version_url VARCHAR(1024), version_xml TEXT, version_xsd VARCHAR(512), + parent_id BIGINT, PRIMARY KEY(repo_version_id) ); GRANT ALL PRIVILEGES ON TABLE ambari.repo_version TO :username; http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql index 267a1f0..fba786f 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql @@ -552,6 +552,7 @@ CREATE TABLE repo_version ( version_url VARCHAR(1024), version_xml TEXT, version_xsd VARCHAR(512), + parent_id NUMERIC(19), PRIMARY KEY(repo_version_id) ); http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql index 828a3a3..a5c60c7 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql @@ -656,6 +656,7 @@ CREATE TABLE repo_version ( version_url VARCHAR(1024), version_xml VARCHAR(MAX), version_xsd VARCHAR(512), + parent_id BIGINT, PRIMARY KEY CLUSTERED (repo_version_id) ); http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java index f3cf954..e031fc8 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java @@ -18,7 +18,6 @@ package org.apache.ambari.server.controller.internal; -import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -33,8 +32,6 @@ import org.apache.ambari.server.controller.ResourceProviderFactory; import org.apache.ambari.server.controller.predicate.AndPredicate; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.spi.Request; -import org.apache.ambari.server.controller.spi.RequestStatus; -import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.utilities.PredicateBuilder; import org.apache.ambari.server.controller.utilities.PropertyHelper; @@ -277,64 +274,7 @@ public class RepositoryVersionResourceProviderTest { Assert.assertEquals(1, provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)).size()); } - @Test - public void testCreateResourcesWithUrl() throws Exception { - Authentication authentication = TestAuthenticationFactory.createAdministrator(); - SecurityContextHolder.getContext().setAuthentication(authentication); - - File file = new File("src/test/resources/version_definition_resource_provider.xml"); - - final ResourceProvider versionProvider = new VersionDefinitionResourceProvider(); - final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider(); - final Set> propertySet = new LinkedHashSet>(); - final Map properties = new LinkedHashMap(); - properties.put(VersionDefinitionResourceProvider.VERSION_DEF_DEFINITION_URL, file.toURI().toURL().toString()); - propertySet.add(properties); - - final Predicate predicateStackName = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID).equals("HDP").toPredicate(); - final Predicate predicateStackVersion = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID).equals("1.1").toPredicate(); - Request getRequest = PropertyHelper.getReadRequest(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID); - Assert.assertEquals(0, provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)).size()); - - final Request createRequest = PropertyHelper.getCreateRequest(propertySet, null); - RequestStatus status = versionProvider.createResources(createRequest); - Assert.assertEquals(1, status.getAssociatedResources().size()); - - getRequest = PropertyHelper.getReadRequest("VersionDefinition"); - Set results = versionProvider.getResources(getRequest, null); - Assert.assertEquals(1, results.size()); - - results = provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)); - Assert.assertEquals(1, results.size()); - - getRequest = PropertyHelper.getReadRequest( - RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, - RepositoryVersionResourceProvider.REPOSITORY_VERSION_ID_PROPERTY_ID, - RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, - RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, - RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, - "RepositoryVersions/release", - "RepositoryVersions/services", - RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID, - RepositoryVersionResourceProvider.SUBRESOURCE_REPOSITORIES_PROPERTY_ID); - - results = provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)); - Assert.assertEquals(1, results.size()); - - Resource r = results.iterator().next(); - Map> map = r.getPropertiesMap(); - Assert.assertTrue(map.containsKey("RepositoryVersions")); - - Map vals = map.get("RepositoryVersions"); - Assert.assertEquals("1.1.7.1-1234", vals.get("repository_version")); - - Assert.assertTrue(map.containsKey("RepositoryVersions/release")); - vals = map.get("RepositoryVersions/release"); - Assert.assertEquals("1234", vals.get("build")); - Assert.assertEquals("2.3.4.[1-9]", vals.get("compatible_with")); - Assert.assertEquals("http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.3.4/", vals.get("notes")); - } @Test http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java new file mode 100644 index 0000000..dbac1b4 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java @@ -0,0 +1,160 @@ +/** + * 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.controller.internal; + +import java.io.File; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.controller.ResourceProviderFactory; +import org.apache.ambari.server.controller.predicate.AndPredicate; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.spi.Request; +import org.apache.ambari.server.controller.spi.RequestStatus; +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.spi.ResourceProvider; +import org.apache.ambari.server.controller.utilities.PredicateBuilder; +import org.apache.ambari.server.controller.utilities.PropertyHelper; +import org.apache.ambari.server.orm.GuiceJpaInitializer; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; +import org.apache.ambari.server.orm.dao.StackDAO; +import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; +import org.apache.ambari.server.orm.entities.StackEntity; +import org.apache.ambari.server.security.TestAuthenticationFactory; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.persist.PersistService; + +/** + * Tests the VersionDefinitionResourceProvider class + */ +public class VersionDefinitionResourceProviderTest { + private Injector injector; + + @Before + public void before() throws Exception { + injector = Guice.createInjector(new InMemoryDefaultTestModule()); + injector.getInstance(GuiceJpaInitializer.class); + + AmbariMetaInfo ami = injector.getInstance(AmbariMetaInfo.class); + ami.init(); + + StackDAO stackDao = injector.getInstance(StackDAO.class); + StackEntity stack = stackDao.find("HDP", "2.2.0"); + + RepositoryVersionEntity entity = new RepositoryVersionEntity(); + entity.setStack(stack); + entity.setDisplayName("2.2.0.0"); + entity.setVersion("2.3.4.4-1234"); + + RepositoryVersionDAO dao = injector.getInstance(RepositoryVersionDAO.class); + dao.create(entity); + + } + + @After + public void after() throws Exception { + injector.getInstance(PersistService.class).stop(); + } + + @Test + public void testWithParent() throws Exception { + Authentication authentication = TestAuthenticationFactory.createAdministrator(); + SecurityContextHolder.getContext().setAuthentication(authentication); + + File file = new File("src/test/resources/version_definition_resource_provider.xml"); + + final ResourceProvider versionProvider = new VersionDefinitionResourceProvider(); + final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class) + .getRepositoryVersionResourceProvider(); + + final Set> propertySet = new LinkedHashSet>(); + final Map properties = new LinkedHashMap(); + properties.put(VersionDefinitionResourceProvider.VERSION_DEF_DEFINITION_URL, + file.toURI().toURL().toString()); + propertySet.add(properties); + + + final Request createRequest = PropertyHelper.getCreateRequest(propertySet, null); + RequestStatus status = versionProvider.createResources(createRequest); + Assert.assertEquals(1, status.getAssociatedResources().size()); + + Request getRequest = PropertyHelper.getReadRequest("VersionDefinition"); + Set results = versionProvider.getResources(getRequest, null); + Assert.assertEquals(1, results.size()); + + final Predicate predicateStackName = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID).equals("HDP").toPredicate(); + final Predicate predicateStackVersion = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID).equals("2.2.0").toPredicate(); + + results = provider.getResources(getRequest, + new AndPredicate(predicateStackName, predicateStackVersion)); + Assert.assertEquals(1, results.size()); + + getRequest = PropertyHelper.getReadRequest( + RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, + RepositoryVersionResourceProvider.REPOSITORY_VERSION_ID_PROPERTY_ID, + RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, + RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, + RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, + RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID, + RepositoryVersionResourceProvider.SUBRESOURCE_REPOSITORIES_PROPERTY_ID, + "RepositoryVersions/release", "RepositoryVersions/services", + "RepositoryVersions/has_children", "RepositoryVersions/parent_id"); + + results = provider.getResources(getRequest, + new AndPredicate(predicateStackName, predicateStackVersion)); + Assert.assertEquals(2, results.size()); + + Resource r = null; + for (Resource result : results) { + if (result.getPropertyValue("RepositoryVersions/repository_version").equals("2.2.0.8-5678")) { + r = result; + break; + } + } + + Assert.assertNotNull(r); + Map> map = r.getPropertiesMap(); + Assert.assertTrue(map.containsKey("RepositoryVersions")); + + Map vals = map.get("RepositoryVersions"); + + Assert.assertEquals("2.2.0.8-5678", vals.get("repository_version")); + Assert.assertNotNull(vals.get("parent_id")); + Assert.assertEquals(Boolean.FALSE, vals.get("has_children")); + + + Assert.assertTrue(map.containsKey("RepositoryVersions/release")); + vals = map.get("RepositoryVersions/release"); + Assert.assertEquals("5678", vals.get("build")); + Assert.assertEquals("2.3.4.[1-9]", vals.get("compatible_with")); + Assert.assertEquals("http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.3.4/", + vals.get("notes")); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/c84da249/ambari-server/src/test/resources/version_definition_resource_provider.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/version_definition_resource_provider.xml b/ambari-server/src/test/resources/version_definition_resource_provider.xml index 735f91d..55cd1c1 100644 --- a/ambari-server/src/test/resources/version_definition_resource_provider.xml +++ b/ambari-server/src/test/resources/version_definition_resource_provider.xml @@ -21,9 +21,9 @@ PATCH - HDP-1.1 - 1.1.7.1 - 1234 + HDP-2.2.0 + 2.2.0.8 + 5678 2.3.4.[1-9] http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.3.4/ @@ -54,17 +54,12 @@ HDP-UTILS - + http://public-repo-1.hortonworks.com/HDP/centos7/2.x/updates/2.3.0.0 HDP-2.3 HDP - - http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos7 - HDP-UTILS-1.1.0.20 - HDP-UTILS -