http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java index c9794d8..dcfd00f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java @@ -207,6 +207,10 @@ public class ComponentInfo { this.dependencies = dependencies; } + public void setAutoDeploy(AutoDeployInfo autoDeploy) { + this.autoDeploy = autoDeploy; + } + public AutoDeployInfo getAutoDeploy() { return autoDeploy; } @@ -226,4 +230,48 @@ public class ComponentInfo { public void setClientsToUpdateConfigs(List<String> clientsToUpdateConfigs) { this.clientsToUpdateConfigs = clientsToUpdateConfigs; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ComponentInfo that = (ComponentInfo) o; + + if (deleted != that.deleted) return false; + if (autoDeploy != null ? !autoDeploy.equals(that.autoDeploy) : that.autoDeploy != null) return false; + if (cardinality != null ? !cardinality.equals(that.cardinality) : that.cardinality != null) return false; + if (category != null ? !category.equals(that.category) : that.category != null) return false; + if (clientConfigFiles != null ? !clientConfigFiles.equals(that.clientConfigFiles) : that.clientConfigFiles != null) + return false; + if (commandScript != null ? !commandScript.equals(that.commandScript) : that.commandScript != null) return false; + if (configDependencies != null ? !configDependencies.equals(that.configDependencies) : that.configDependencies != null) + return false; + if (customCommands != null ? !customCommands.equals(that.customCommands) : that.customCommands != null) + return false; + if (dependencies != null ? !dependencies.equals(that.dependencies) : that.dependencies != null) return false; + if (displayName != null ? !displayName.equals(that.displayName) : that.displayName != null) return false; + if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (clientConfigFiles != null ? !clientConfigFiles.equals(that.clientConfigFiles) : + that.clientConfigFiles != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (displayName != null ? displayName.hashCode() : 0); + result = 31 * result + (category != null ? category.hashCode() : 0); + result = 31 * result + (deleted ? 1 : 0); + result = 31 * result + (cardinality != null ? cardinality.hashCode() : 0); + result = 31 * result + (commandScript != null ? commandScript.hashCode() : 0); + result = 31 * result + (clientConfigFiles != null ? clientConfigFiles.hashCode() : 0); + result = 31 * result + (customCommands != null ? customCommands.hashCode() : 0); + result = 31 * result + (dependencies != null ? dependencies.hashCode() : 0); + result = 31 * result + (autoDeploy != null ? autoDeploy.hashCode() : 0); + result = 31 * result + (configDependencies != null ? configDependencies.hashCode() : 0); + result = 31 * result + (clientConfigFiles != null ? clientConfigFiles.hashCode() : 0); + return result; + } }
http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java index e15a62a..d4cbd4e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java @@ -417,13 +417,13 @@ public class ConfigHelper { * @param propertyName */ public Set<String> findConfigTypesByPropertyName(StackId stackId, String propertyName, String clusterName) throws AmbariException { - StackInfo stack = ambariMetaInfo.getStackInfo(stackId.getStackName(), + StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); Set<String> result = new HashSet<String>(); for(Service service : clusters.getCluster(clusterName).getServices().values()) { - Set<PropertyInfo> stackProperties = ambariMetaInfo.getProperties(stack.getName(), stack.getVersion(), service.getName()); + Set<PropertyInfo> stackProperties = ambariMetaInfo.getServiceProperties(stack.getName(), stack.getVersion(), service.getName()); Set<PropertyInfo> stackLevelProperties = ambariMetaInfo.getStackProperties(stack.getName(), stack.getVersion()); stackProperties.addAll(stackLevelProperties); @@ -440,18 +440,17 @@ public class ConfigHelper { } public Set<String> getPropertyValuesWithPropertyType(StackId stackId, PropertyType propertyType, Cluster cluster) throws AmbariException { - StackInfo stack = ambariMetaInfo.getStackInfo(stackId.getStackName(), + StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); Set<String> result = new HashSet<String>(); for(Service service : cluster.getServices().values()) { - Set<PropertyInfo> stackProperties = ambariMetaInfo.getProperties(stack.getName(), stack.getVersion(), service.getName()); - - for (PropertyInfo stackProperty : stackProperties) { - if(stackProperty.getPropertyTypes().contains(propertyType)) { - String stackPropertyConfigType = fileNameToConfigType(stackProperty.getFilename()); - result.add(cluster.getDesiredConfigByType(stackPropertyConfigType).getProperties().get(stackProperty.getName())); + Set<PropertyInfo> serviceProperties = ambariMetaInfo.getServiceProperties(stack.getName(), stack.getVersion(), service.getName()); + for (PropertyInfo serviceProperty : serviceProperties) { + if(serviceProperty.getPropertyTypes().contains(propertyType)) { + String stackPropertyConfigType = fileNameToConfigType(serviceProperty.getFilename()); + result.add(cluster.getDesiredConfigByType(stackPropertyConfigType).getProperties().get(serviceProperty.getName())); } } } @@ -470,15 +469,15 @@ public class ConfigHelper { public String getPropertyValueFromStackDefenitions(Cluster cluster, String configType, String propertyName) throws AmbariException { StackId stackId = cluster.getCurrentStackVersion(); - StackInfo stack = ambariMetaInfo.getStackInfo(stackId.getStackName(), + StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); - for(ServiceInfo serviceInfo:stack.getServices()) { - Set<PropertyInfo> stackProperties = ambariMetaInfo.getProperties(stack.getName(), stack.getVersion(), serviceInfo.getName()); - Set<PropertyInfo> stackLevelProperties = ambariMetaInfo.getStackProperties(stack.getName(), stack.getVersion()); - stackProperties.addAll(stackLevelProperties); + for(ServiceInfo serviceInfo:stack.getServices()) { + Set<PropertyInfo> serviceProperties = ambariMetaInfo.getServiceProperties(stack.getName(), stack.getVersion(), serviceInfo.getName()); + Set<PropertyInfo> stackProperties = ambariMetaInfo.getStackProperties(stack.getName(), stack.getVersion()); + serviceProperties.addAll(stackProperties); - for (PropertyInfo stackProperty : stackProperties) { + for (PropertyInfo stackProperty : serviceProperties) { String stackPropertyConfigType = fileNameToConfigType(stackProperty.getFilename()); if(stackProperty.getName().equals(propertyName) && stackPropertyConfigType.equals(configType)) { @@ -493,13 +492,12 @@ public class ConfigHelper { public ServiceInfo getPropertyOwnerService(Cluster cluster, String configType, String propertyName) throws AmbariException { StackId stackId = cluster.getCurrentStackVersion(); - StackInfo stack = ambariMetaInfo.getStackInfo(stackId.getStackName(), - stackId.getStackVersion()); + StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); for(ServiceInfo serviceInfo:stack.getServices()) { - Set<PropertyInfo> stackProperties = ambariMetaInfo.getProperties(stack.getName(), stack.getVersion(), serviceInfo.getName()); + Set<PropertyInfo> serviceProperties = ambariMetaInfo.getServiceProperties(stack.getName(), stack.getVersion(), serviceInfo.getName()); - for (PropertyInfo stackProperty : stackProperties) { + for (PropertyInfo stackProperty : serviceProperties) { String stackPropertyConfigType = fileNameToConfigType(stackProperty.getFilename()); if(stackProperty.getName().equals(propertyName) && stackPropertyConfigType.equals(configType)) { @@ -514,16 +512,14 @@ public class ConfigHelper { public Set<PropertyInfo> getServiceProperties(Cluster cluster, String serviceName) throws AmbariException { StackId stackId = cluster.getCurrentStackVersion(); - StackInfo stack = ambariMetaInfo.getStackInfo(stackId.getStackName(), - stackId.getStackVersion()); + StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); - return ambariMetaInfo.getProperties(stack.getName(), stack.getVersion(), serviceName); + return ambariMetaInfo.getServiceProperties(stack.getName(), stack.getVersion(), serviceName); } public Set<PropertyInfo> getStackProperties(Cluster cluster) throws AmbariException { StackId stackId = cluster.getCurrentStackVersion(); - StackInfo stack = ambariMetaInfo.getStackInfo(stackId.getStackName(), - stackId.getStackVersion()); + StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); return ambariMetaInfo.getStackProperties(stack.getName(), stack.getVersion()); } @@ -654,14 +650,14 @@ public class ConfigHelper { if (!actual.containsKey(type)) { // desired is set, but actual is not - if (!serviceInfo.hasConfigType(type)) { + if (!serviceInfo.hasConfigDependency(type)) { stale = componentInfo != null && componentInfo.hasConfigType(type); } else if (type.equals(Configuration.GLOBAL_CONFIG_TAG)) { // find out if the keys are stale by first checking the target service, // then all services Collection<String> keys = mergeKeyNames(cluster, type, tags.values()); - if (serviceInfo.hasPropertyFor(type, keys) || !hasPropertyFor(stackId, type, keys)) { + if (serviceInfo.hasDependencyAndPropertyFor(type, keys) || !hasPropertyFor(stackId, type, keys)) { stale = true; } } else { @@ -680,11 +676,11 @@ public class ConfigHelper { // to the service Collection<String> changed = findChangedKeys(cluster, type, tags.values(), actualTags.values()); - if (serviceInfo.hasPropertyFor(type, changed)) { + if (serviceInfo.hasDependencyAndPropertyFor(type, changed)) { stale = true; } } else { - stale = serviceInfo.hasConfigType(type) || componentInfo.hasConfigType(type); + stale = serviceInfo.hasConfigDependency(type) || componentInfo.hasConfigType(type); } } } @@ -726,7 +722,7 @@ public class ConfigHelper { for (ServiceInfo svc : ambariMetaInfo.getServices(stack.getStackName(), stack.getStackVersion()).values()) { - if (svc.hasPropertyFor(type, keys)) + if (svc.hasDependencyAndPropertyFor(type, keys)) return true; } http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java index 58e6e4c..e3db662 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/DependencyInfo.java @@ -143,4 +143,30 @@ public class DependencyInfo { ", auto-deploy=" + m_autoDeploy.isEnabled() + "]"; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DependencyInfo that = (DependencyInfo) o; + + if (componentName != null ? !componentName.equals(that.componentName) : that.componentName != null) return false; + if (m_autoDeploy != null ? !m_autoDeploy.equals(that.m_autoDeploy) : that.m_autoDeploy != null) return false; + if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (scope != null ? !scope.equals(that.scope) : that.scope != null) return false; + if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (scope != null ? scope.hashCode() : 0); + result = 31 * result + (serviceName != null ? serviceName.hashCode() : 0); + result = 31 * result + (componentName != null ? componentName.hashCode() : 0); + result = 31 * result + (m_autoDeploy != null ? m_autoDeploy.hashCode() : 0); + return result; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java index 45ea1f9..a31e42c 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java @@ -25,6 +25,7 @@ import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; import com.google.inject.persist.Transactional; import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.ObjectNotFoundException; import org.apache.ambari.server.ServiceComponentHostNotFoundException; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.controller.ServiceComponentResponse; @@ -88,10 +89,12 @@ public class ServiceComponentImpl implements ServiceComponent { this.hostComponents = new HashMap<String, ServiceComponentHost>(); StackId stackId = service.getDesiredStackVersion(); - ComponentInfo compInfo = ambariMetaInfo.getComponentCategory( - stackId.getStackName(), stackId.getStackVersion(), service.getName(), - componentName); - if (compInfo == null) { + try { + ComponentInfo compInfo = ambariMetaInfo.getComponent(stackId.getStackName(), + stackId.getStackVersion(), service.getName(), componentName); + this.isClientComponent = compInfo.isClient(); + this.isMasterComponent = compInfo.isMaster(); + } catch (ObjectNotFoundException e) { throw new RuntimeException("Trying to create a ServiceComponent" + " not recognized in stack info" + ", clusterName=" + service.getCluster().getClusterName() @@ -99,9 +102,6 @@ public class ServiceComponentImpl implements ServiceComponent { + ", componentName=" + componentName + ", stackInfo=" + stackId.getStackId()); } - this.isClientComponent = compInfo.isClient(); - this.isMasterComponent = compInfo.isMaster(); - init(); } @@ -130,10 +130,13 @@ public class ServiceComponentImpl implements ServiceComponent { } StackId stackId = service.getDesiredStackVersion(); - ComponentInfo compInfo = ambariMetaInfo.getComponentCategory( - stackId.getStackName(), stackId.getStackVersion(), service.getName(), - getName()); - if (compInfo == null) { + try { + ComponentInfo compInfo = ambariMetaInfo.getComponent( + stackId.getStackName(), stackId.getStackVersion(), service.getName(), + getName()); + this.isClientComponent = compInfo.isClient(); + this.isMasterComponent = compInfo.isMaster(); + } catch (ObjectNotFoundException e) { throw new AmbariException("Trying to create a ServiceComponent" + " not recognized in stack info" + ", clusterName=" + service.getCluster().getClusterName() @@ -141,8 +144,6 @@ public class ServiceComponentImpl implements ServiceComponent { + ", componentName=" + getName() + ", stackInfo=" + stackId.getStackId()); } - this.isClientComponent = compInfo.isClient(); - this.isMasterComponent = compInfo.isMaster(); persisted = true; } http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java index bb5057f..4b4a305 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java @@ -107,7 +107,7 @@ public class ServiceImpl implements Service { StackId stackId = cluster.getDesiredStackVersion(); setDesiredStackVersion(stackId); - ServiceInfo sInfo = ambariMetaInfo.getServiceInfo(stackId.getStackName(), + ServiceInfo sInfo = ambariMetaInfo.getService(stackId.getStackName(), stackId.getStackVersion(), serviceName); isClientOnlyService = sInfo.isClientOnlyService(); @@ -145,7 +145,7 @@ public class ServiceImpl implements Service { } StackId stackId = getDesiredStackVersion(); - ServiceInfo sInfo = ambariMetaInfo.getServiceInfo(stackId.getStackName(), + ServiceInfo sInfo = ambariMetaInfo.getService(stackId.getStackName(), stackId.getStackVersion(), getName()); isClientOnlyService = sInfo.isClientOnlyService(); http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java index ae746d6..9277ec6 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java @@ -74,7 +74,7 @@ public class ServiceInfo { @XmlElementWrapper(name="excluded-config-types") @XmlElement(name="config-type") - private Set<String> excludedConfigTypes; + private Set<String> excludedConfigTypes = new HashSet<String>(); @XmlTransient private Map<String, Map<String, Map<String, String>>> configTypes; @@ -84,7 +84,13 @@ public class ServiceInfo { @JsonIgnore @XmlElement(name = "restartRequiredAfterChange") - private Boolean restartRequiredAfterChange; + private Boolean restartRequiredAfterChange; + + @XmlElement(name = "extends") + private String parent; + + @XmlTransient + private volatile Map<String, PropertyInfo> requiredProperties; public Boolean isRestartRequiredAfterChange() { return restartRequiredAfterChange; @@ -137,7 +143,7 @@ public class ServiceInfo { @XmlElementWrapper(name="requiredServices") @XmlElement(name="service") - private List<String> requiredServices; + private List<String> requiredServices = new ArrayList<String>(); /** * Meaning: stores subpath from stack root to exact directory, that contains @@ -164,6 +170,14 @@ public class ServiceInfo { this.name = name; } + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + public String getDisplayName() { return displayName; } @@ -205,7 +219,7 @@ public class ServiceInfo { } /** * Finds ComponentInfo by component name - * @param componentName + * @param componentName name of the component * @return ComponentInfo componentName or null */ public ComponentInfo getComponentByName(String componentName){ @@ -229,65 +243,112 @@ public class ServiceInfo { } public ComponentInfo getClientComponent() { - if (components == null || components.isEmpty()) { - return null; - } - for (ComponentInfo compInfo : components) { - if (compInfo.isClient()) { - return compInfo; + ComponentInfo client = null; + + if (components != null) { + for (ComponentInfo compInfo : components) { + if (compInfo.isClient()) { + client = compInfo; + break; + } } } - return components.get(0); + return client; } @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("Service name:" + name + "\nversion:" + version + - "\ncomment:" + comment); + sb.append("Service name:"); + sb.append(name); + sb.append("\nversion:"); + sb.append(version); + sb.append("\ncomment:"); + sb.append(comment); //for (PropertyInfo property : getProperties()) { // sb.append("\tProperty name=" + property.getName() + //"\nproperty value=" + property.getValue() + "\ndescription=" + property.getDescription()); //} for (ComponentInfo component : getComponents()) { sb.append("\n\n\nComponent:\n"); - sb.append("name=" + component.getName()); - sb.append("\tcategory=" + component.getCategory()); + sb.append("name="); + sb.append(component.getName()); + sb.append("\tcategory="); + sb.append(component.getCategory()); } return sb.toString(); } - - public Map<String, Map<String, Map<String, String>>> getConfigTypes() { - if (configTypes == null) configTypes = new HashMap<String, Map<String, Map<String, String>>>(); - return configTypes; + + /** + * Obtain the config types associated with this service. + * The returned map is an unmodifiable view. + * @return unmodifiable map of config types associated with this service + */ + public synchronized Map<String, Map<String, Map<String, String>>> getConfigTypeAttributes() { + return configTypes == null ? + Collections.<String, Map<String, Map<String, String>>>emptyMap() : + Collections.unmodifiableMap(configTypes); } - public void setConfigTypes(Map<String, Map<String, Map<String, String>>> configTypes) { - this.configTypes = configTypes; + /** + * Add the given type and set it's attributes. + * If the type is marked for exclusion, it will not be added. + * + * @param type configuration type + * @param typeAttributes attributes associated with the type + */ + public synchronized void setTypeAttributes(String type, Map<String, Map<String, String>> typeAttributes) { + if (this.configTypes == null) { + configTypes = new HashMap<String, Map<String, Map<String, String>>>(); + } + + if (! excludedConfigTypes.contains(type)) { + configTypes.put(type, typeAttributes); + } } /** + * Set all types and associated attributes. Any previously existing types and + * attributes are removed prior to setting the new values. + * + * @param types map of type attributes + */ + public synchronized void setAllConfigAttributes(Map<String, Map<String, Map<String, String>>> types) { + configTypes = new HashMap<String, Map<String, Map<String, String>>>(); + for (Map.Entry<String, Map<String, Map<String, String>>> entry : types.entrySet()) { + setTypeAttributes(entry.getKey(), entry.getValue()); + } + } + + /** + * Determine of the service has a dependency on the provided configuration type. * @param type the config type - * @return <code>true</code> if the service defines the supplied type + * @return <code>true</code> if the service defines a dependency on the provided type */ - public boolean hasConfigType(String type) { + public boolean hasConfigDependency(String type) { return configDependencies != null && configDependencies.contains(type); } /** - * The purpose of this method is to determine if a service has a property - * defined in a supplied set: - * <ul> - * <li>If the type is not defined for the service, then no property can exist.</li> - * <li>If the type is defined, then check each supplied property for existence.</li> - * </ul> + * Determine if the service contains the specified config type + * @param type config type to check + * @return true if the service has the specified config type; false otherwise + */ + public boolean hasConfigType(String type) { + return configTypes != null && configTypes.containsKey(type); + } + + /** + * Determine if the service has a dependency on the provided type and contains any of the provided properties. + * This can be used in determining if a property is stale. + * @param type the config type * @param keyNames the names of all the config keys for the given type * @return <code>true</code> if the config is stale */ - public boolean hasPropertyFor(String type, Collection<String> keyNames) { - if (!hasConfigType(type)) + public boolean hasDependencyAndPropertyFor(String type, Collection<String> keyNames) { + if (!hasConfigDependency(type)) return false; buildConfigLayout(); @@ -371,7 +432,7 @@ public class ServiceInfo { /** * Exposes (and initializes on first use) map of os-specific details. - * @return + * @return map of OS specific details keyed by family */ public Map<String, ServiceOsSpecific> getOsSpecifics() { if (serviceOsSpecificsMap == null) { @@ -487,4 +548,24 @@ public class ServiceInfo { public void setExcludedConfigTypes(Set<String> excludedConfigTypes) { this.excludedConfigTypes = excludedConfigTypes; } + + //todo: ensure that required properties are never modified... + public Map<String, PropertyInfo> getRequiredProperties() { + Map<String, PropertyInfo> result = requiredProperties; + if (result == null) { + synchronized(this) { + result = requiredProperties; + if (result == null) { + requiredProperties = result = new HashMap<String, PropertyInfo>(); + List<PropertyInfo> properties = getProperties(); + for (PropertyInfo propertyInfo : properties) { + if (propertyInfo.isRequireInput()) { + result.put(propertyInfo.getName(), propertyInfo); + } + } + } + } + } + return result; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java index a143ba1..d81c182 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java @@ -62,6 +62,28 @@ public class ServiceOsSpecific { this.packages.addAll(packages); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ServiceOsSpecific that = (ServiceOsSpecific) o; + + if (osFamily != null ? !osFamily.equals(that.osFamily) : that.osFamily != null) return false; + if (packages != null ? !packages.equals(that.packages) : that.packages != null) return false; + if (repo != null ? !repo.equals(that.repo) : that.repo != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = osFamily != null ? osFamily.hashCode() : 0; + result = 31 * result + (repo != null ? repo.hashCode() : 0); + result = 31 * result + (packages != null ? packages.hashCode() : 0); + return result; + } + /** * The <code>repo</code> tag. It has different set of fields compared to * <link>org.apache.ambari.server.state.RepositoryInfo</link>, @@ -110,6 +132,29 @@ public class ServiceOsSpecific { return reponame; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Repo repo = (Repo) o; + + if (baseurl != null ? !baseurl.equals(repo.baseurl) : repo.baseurl != null) return false; + if (mirrorslist != null ? !mirrorslist.equals(repo.mirrorslist) : repo.mirrorslist != null) return false; + if (repoid != null ? !repoid.equals(repo.repoid) : repo.repoid != null) return false; + if (reponame != null ? !reponame.equals(repo.reponame) : repo.reponame != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = baseurl != null ? baseurl.hashCode() : 0; + result = 31 * result + (mirrorslist != null ? mirrorslist.hashCode() : 0); + result = 31 * result + (repoid != null ? repoid.hashCode() : 0); + result = 31 * result + (reponame != null ? reponame.hashCode() : 0); + return result; + } } @@ -130,6 +175,21 @@ public class ServiceOsSpecific { } public Package() { } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Package that = (Package) o; + + return name.equals(that.name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/Stack.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Stack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Stack.java deleted file mode 100644 index 92b799d..0000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/Stack.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 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.state; - -import org.apache.ambari.server.controller.StackResponse; - -public class Stack { - - private String stackName; - - public Stack(String stackName) { - setStackName(stackName); - } - - public String getStackName() { - return stackName; - } - - public void setStackName(String stackName) { - this.stackName = stackName; - } - - @Override - public int hashCode() { - return stackName.hashCode(); - } - - @Override - public boolean equals(Object obj) { - - if (obj == null) - return false; - - if (!(obj instanceof Stack)) { - return false; - } - if (this == obj) { - return true; - } - Stack stack = (Stack) obj; - return getStackName().equals(stack.getStackName()); - } - - - public StackResponse convertToResponse() - { - return new StackResponse(getStackName()); - } -} http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java index 64782cc..f19cf81 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java @@ -19,11 +19,14 @@ package org.apache.ambari.server.state; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ambari.server.controller.StackVersionResponse; +import org.apache.ambari.server.state.stack.UpgradePack; public class StackInfo implements Comparable<StackInfo>{ private String name; @@ -32,11 +35,12 @@ public class StackInfo implements Comparable<StackInfo>{ private boolean active; private String rcoFileLocation; private List<RepositoryInfo> repositories; - private List<ServiceInfo> services; + private Collection<ServiceInfo> services; private String parentStackVersion; // stack-level properties private List<PropertyInfo> properties; private Map<String, Map<String, Map<String, String>>> configTypes; + private Map<String, UpgradePack> upgradePacks; /** * Meaning: stores subpath from stack root to exact hooks folder for stack. These hooks are @@ -71,12 +75,23 @@ public class StackInfo implements Comparable<StackInfo>{ this.repositories = repositories; } - public synchronized List<ServiceInfo> getServices() { + public synchronized Collection<ServiceInfo> getServices() { if (services == null) services = new ArrayList<ServiceInfo>(); return services; } - public synchronized void setServices(List<ServiceInfo> services) { + public ServiceInfo getService(String name) { + Collection<ServiceInfo> services = getServices(); + for (ServiceInfo service : services) { + if (service.getName().equals(name)) { + return service; + } + } + //todo: exception? + return null; + } + + public synchronized void setServices(Collection<ServiceInfo> services) { this.services = services; } @@ -89,14 +104,43 @@ public class StackInfo implements Comparable<StackInfo>{ this.properties = properties; } - public Map<String, Map<String, Map<String, String>>> getConfigTypes() { - if (configTypes == null) configTypes = new HashMap<String, Map<String, Map<String, String>>>(); - return configTypes; + /** + * Obtain the config types associated with this stack. + * The returned map is an unmodifiable view. + * @return copy of the map of config types associated with this stack + */ + public synchronized Map<String, Map<String, Map<String, String>>> getConfigTypeAttributes() { + return configTypes == null ? + Collections.<String, Map<String, Map<String, String>>>emptyMap() : + Collections.unmodifiableMap(configTypes); } - public void setConfigTypes( - Map<String, Map<String, Map<String, String>>> configTypes) { - this.configTypes = configTypes; + + /** + * Add the given type and set it's attributes. + * + * @param type configuration type + * @param typeAttributes attributes associated with the type + */ + public synchronized void setConfigTypeAttributes(String type, Map<String, Map<String, String>> typeAttributes) { + if (this.configTypes == null) { + configTypes = new HashMap<String, Map<String, Map<String, String>>>(); + } + // todo: no exclusion mechanism for stack config types + configTypes.put(type, typeAttributes); + } + + /** + * Set all types and associated attributes. Any previously existing types and + * attributes are removed prior to setting the new values. + * + * @param types map of type attributes + */ + public synchronized void setAllConfigAttributes(Map<String, Map<String, Map<String, String>>> types) { + configTypes = new HashMap<String, Map<String, Map<String, String>>>(); + for (Map.Entry<String, Map<String, Map<String, String>>> entry : types.entrySet()) { + setConfigTypeAttributes(entry.getKey(), entry.getValue()); + } } @Override @@ -106,14 +150,16 @@ public class StackInfo implements Comparable<StackInfo>{ if (services != null) { sb.append("\n\t\tService:"); for (ServiceInfo service : services) { - sb.append("\t\t" + service.toString()); + sb.append("\t\t"); + sb.append(service); } } if (repositories != null) { sb.append("\n\t\tRepositories:"); for (RepositoryInfo repository : repositories) { - sb.append("\t\t" + repository.toString()); + sb.append("\t\t"); + sb.append(repository.toString()); } } @@ -123,9 +169,7 @@ public class StackInfo implements Comparable<StackInfo>{ @Override public int hashCode() { - int result = 1; - result = 31 + name.hashCode() + version.hashCode(); - return result; + return 31 + name.hashCode() + version.hashCode(); } @Override @@ -143,7 +187,7 @@ public class StackInfo implements Comparable<StackInfo>{ public StackVersionResponse convertToResponse() { return new StackVersionResponse(getVersion(), getMinUpgradeVersion(), - isActive(), getParentStackVersion(), getConfigTypes()); + isActive(), getParentStackVersion(), getConfigTypeAttributes()); } public String getMinUpgradeVersion() { @@ -186,25 +230,47 @@ public class StackInfo implements Comparable<StackInfo>{ this.stackHooksFolder = stackHooksFolder; } - @Override - public int compareTo(StackInfo o) { - String myId = name + "-" + version; - String oId = o.name + "-" + o.version; - return myId.compareTo(oId); - } - /** - * @param path the path to the upgrades folder + * Set the path of the stack upgrade directory. + * + * @param path the path to the upgrades directory */ public void setUpgradesFolder(String path) { upgradesFolder = path; } /** + * Obtain the path of the upgrades folder or null if directory doesn't exist. + * * @return the upgrades folder, or {@code null} if not set */ public String getUpgradesFolder() { return upgradesFolder; } + /** + * Set upgrade packs. + * + * @param upgradePacks map of upgrade packs + */ + public void setUpgradePacks(Map<String, UpgradePack> upgradePacks) { + this.upgradePacks = upgradePacks; + } + + /** + * Obtain all stack upgrade packs. + * + * @return map of upgrade pack name to upgrade pack or {@code null} of no packs + */ + public Map<String, UpgradePack> getUpgradePacks() { + return upgradePacks; + } + + + @Override + public int compareTo(StackInfo o) { + String myId = name + "-" + version; + String oId = o.name + "-" + o.version; + return myId.compareTo(oId); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java index d22e250..30dceb0 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java @@ -268,11 +268,11 @@ public class ClusterImpl implements Cluster { String serviceName = entry.getKey(); ServiceInfo serviceInfo = entry.getValue(); //collect config types for service - Set<PropertyInfo> properties = ambariMetaInfo.getProperties(desiredStackVersion.getStackName(), desiredStackVersion.getStackVersion(), serviceName); + Set<PropertyInfo> properties = ambariMetaInfo.getServiceProperties(desiredStackVersion.getStackName(), + desiredStackVersion.getStackVersion(), serviceName); for (PropertyInfo property : properties) { String configType = ConfigHelper.fileNameToConfigType(property.getFilename()); - if (serviceInfo.getExcludedConfigTypes() == null || - !serviceInfo.getExcludedConfigTypes().contains(configType)) { + if (serviceInfo.hasConfigType(configType)) { serviceConfigTypes.put(serviceName, configType); } } @@ -359,7 +359,7 @@ public class ClusterImpl implements Cluster { for (ClusterServiceEntity serviceEntity : clusterEntity.getClusterServiceEntities()) { StackId stackId = getCurrentStackVersion(); try { - if (ambariMetaInfo.getServiceInfo(stackId.getStackName(), stackId.getStackVersion(), + if (ambariMetaInfo.getService(stackId.getStackName(), stackId.getStackVersion(), serviceEntity.getServiceName()) != null) { services.put(serviceEntity.getServiceName(), serviceFactory.createExisting(this, serviceEntity)); } http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java index 6e58267..e7db9d3 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java @@ -30,7 +30,7 @@ import org.apache.ambari.server.api.util.TreeNodeImpl; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.internal.ResourceImpl; import org.apache.ambari.server.controller.spi.Resource; -import org.apache.ambari.server.state.PropertyInfo; +import org.apache.ambari.server.state.ServiceInfo; import org.junit.Test; import java.net.InetAddress; @@ -103,9 +103,13 @@ public class ClusterBlueprintRendererTest { AmbariManagementController controller = createMock(AmbariManagementController.class); AmbariMetaInfo stackInfo = createNiceMock(AmbariMetaInfo.class); + ServiceInfo hdfsService = new ServiceInfo(); + hdfsService.setName("HDFS"); + ServiceInfo mrService = new ServiceInfo(); + mrService.setName("MAPREDUCE"); - expect(stackInfo.getRequiredProperties("HDP", "1.3.3", "HDFS")).andReturn(Collections.<String, PropertyInfo>emptyMap()); - expect(stackInfo.getRequiredProperties("HDP", "1.3.3", "MAPREDUCE")).andReturn(Collections.<String, PropertyInfo>emptyMap()); + expect(stackInfo.getService("HDP", "1.3.3", "HDFS")).andReturn(hdfsService); + expect(stackInfo.getService("HDP", "1.3.3", "MAPREDUCE")).andReturn(mrService); Result result = new ResultImpl(true); createClusterResultTree(result.getResultTree()); http://git-wip-us.apache.org/repos/asf/ambari/blob/2fc7adec/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java index e7b946d..4d08d6f 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java @@ -18,6 +18,10 @@ package org.apache.ambari.server.api.services; +import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reset; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -26,30 +30,33 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; -import java.lang.reflect.Method; +import java.lang.reflect.Field; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Set; -import javax.persistence.EntityManager; -import javax.xml.bind.JAXBException; - +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.util.Modules; import junit.framework.Assert; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.StackAccessException; -import org.apache.ambari.server.api.util.StackExtensionHelper; +import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.events.publishers.AmbariEventPublisher; import org.apache.ambari.server.metadata.ActionMetadata; +import org.apache.ambari.server.metadata.AgentAlertDefinitions; import org.apache.ambari.server.orm.GuiceJpaInitializer; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.OrmTestHelper; import org.apache.ambari.server.orm.dao.AlertDefinitionDAO; +import org.apache.ambari.server.orm.dao.MetainfoDAO; import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; +import org.apache.ambari.server.orm.entities.MetainfoEntity; +import org.apache.ambari.server.stack.StackManager; import org.apache.ambari.server.state.AutoDeployInfo; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; @@ -60,15 +67,16 @@ import org.apache.ambari.server.state.OperatingSystemInfo; import org.apache.ambari.server.state.PropertyInfo; import org.apache.ambari.server.state.RepositoryInfo; import org.apache.ambari.server.state.ServiceInfo; -import org.apache.ambari.server.state.Stack; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.StackInfo; import org.apache.ambari.server.state.alert.AlertDefinition; import org.apache.ambari.server.state.alert.MetricSource; +import org.apache.ambari.server.state.alert.AlertDefinitionFactory; import org.apache.ambari.server.state.alert.PortSource; import org.apache.ambari.server.state.alert.Reporting; import org.apache.ambari.server.state.alert.Source; import org.apache.ambari.server.state.stack.MetricDefinition; +import org.apache.ambari.server.state.stack.OsFamily; import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; @@ -78,9 +86,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.util.Modules; + +import javax.persistence.EntityManager; +import javax.xml.bind.JAXBException; public class AmbariMetaInfoTest { @@ -112,7 +120,9 @@ public class AmbariMetaInfoTest { private static final String HADOOP_ENV_FILE_NAME = "hadoop-env.xml"; private static final String HDFS_LOG4J_FILE_NAME = "hdfs-log4j.xml"; - private Injector injector; + //private Injector injector; + + //todo: add fail() for cases where an exception is expected such as getService, getComponent ... @Rule @@ -120,22 +130,7 @@ public class AmbariMetaInfoTest { @Before public void before() throws Exception { - injector = Guice.createInjector(Modules.override( - new InMemoryDefaultTestModule()).with(new MockModule())); - - injector.getInstance(GuiceJpaInitializer.class); - injector.getInstance(EntityManager.class); - - File stackRoot = new File("src/test/resources/stacks"); - LOG.info("Stacks file " + stackRoot.getAbsolutePath()); - metaInfo = new AmbariMetaInfo(stackRoot, new File("target/version")); - metaInfo.injector = injector; - - try { - metaInfo.init(); - } catch(Exception e) { - LOG.info("Error in initializing ", e); - } + metaInfo = createAmbariMetaInfo(new File("src/test/resources/stacks"), new File("target/version"), true); } public class MockModule extends AbstractModule { @@ -145,16 +140,6 @@ public class AmbariMetaInfoTest { } } - @Test - public void getComponentCategory() throws AmbariException { - ComponentInfo componentInfo = metaInfo.getComponentCategory(STACK_NAME_HDP, - STACK_VERSION_HDP, SERVICE_NAME_HDFS, SERVICE_COMPONENT_NAME); - assertNotNull(componentInfo); - componentInfo = metaInfo.getComponentCategory(STACK_NAME_HDP, - STACK_VERSION_HDP, SERVICE_NAME_HDFS, "DATANODE1"); - Assert.assertNotNull(componentInfo); - assertTrue(!componentInfo.isClient()); - } @Test public void getRestartRequiredServicesNames() throws AmbariException { @@ -184,11 +169,13 @@ public class AmbariMetaInfoTest { // Scenario: user has internet and does nothing to repos via api // use the latest String buildDir = tmpFolder.getRoot().getAbsolutePath(); - AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir); + AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true); // The current stack already has (HDP, 2.1.1, redhat6) with valid latest // url ambariMetaInfo.init(); + waitForAllReposToBeResolved(ambariMetaInfo); + List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories( STACK_NAME_HDP, "2.1.1", "redhat6"); assertNotNull(redhat6Repo); @@ -205,7 +192,7 @@ public class AmbariMetaInfoTest { // Scenario: user has no internet and does nothing to repos via api // use the default String buildDir = tmpFolder.getRoot().getAbsolutePath(); - AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir); + AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true); // The current stack already has (HDP, 2.1.1, redhat6). // Deleting the json file referenced by the latestBaseUrl to simulate No @@ -233,7 +220,7 @@ public class AmbariMetaInfoTest { // Scenario: user has internet and but calls to set repos via api // use whatever they set String buildDir = tmpFolder.getRoot().getAbsolutePath(); - AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir); + TestAmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true); // The current stack already has (HDP, 2.1.1, redhat6) // Updating the baseUrl @@ -244,8 +231,19 @@ public class AmbariMetaInfoTest { STACK_NAME_HDP + "-2.1.1"); assertEquals(newBaseUrl, repoInfo.getBaseUrl()); String prevBaseUrl = repoInfo.getDefaultBaseUrl(); + + // mock expectations + MetainfoDAO metainfoDAO = ambariMetaInfo.metaInfoDAO; + reset(metainfoDAO); + MetainfoEntity entity = createNiceMock(MetainfoEntity.class); + expect(metainfoDAO.findByKey("repo:/HDP/2.1.1/redhat6/HDP-2.1.1:baseurl")).andReturn(entity).atLeastOnce(); + expect(entity.getMetainfoValue()).andReturn(newBaseUrl).atLeastOnce(); + replay(metainfoDAO, entity); + ambariMetaInfo.init(); + waitForAllReposToBeResolved(ambariMetaInfo); + List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories( STACK_NAME_HDP, "2.1.1", "redhat6"); assertNotNull(redhat6Repo); @@ -266,8 +264,9 @@ public class AmbariMetaInfoTest { public void testGetRepositoryNoInternetUpdatedBaseUrl() throws Exception { // Scenario: user has no internet and but calls to set repos via api // use whatever they set + String newBaseUrl = "http://myprivate-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.0.6.0"; String buildDir = tmpFolder.getRoot().getAbsolutePath(); - AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir); + TestAmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true); // The current stack already has (HDP, 2.1.1, redhat6). // Deleting the json file referenced by the latestBaseUrl to simulate No @@ -278,15 +277,25 @@ public class AmbariMetaInfoTest { assertTrue(!latestUrlFile.exists()); // Update baseUrl - String newBaseUrl = "http://myprivate-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.0.6.0"; ambariMetaInfo.updateRepoBaseURL("HDP", "2.1.1", "redhat6", "HDP-2.1.1", newBaseUrl); RepositoryInfo repoInfo = ambariMetaInfo.getRepository(STACK_NAME_HDP, "2.1.1", "redhat6", STACK_NAME_HDP + "-2.1.1"); assertEquals(newBaseUrl, repoInfo.getBaseUrl()); String prevBaseUrl = repoInfo.getDefaultBaseUrl(); + + // mock expectations + MetainfoDAO metainfoDAO = ambariMetaInfo.metaInfoDAO; + reset(metainfoDAO); + MetainfoEntity entity = createNiceMock(MetainfoEntity.class); + expect(metainfoDAO.findByKey("repo:/HDP/2.1.1/redhat6/HDP-2.1.1:baseurl")).andReturn(entity).atLeastOnce(); + expect(entity.getMetainfoValue()).andReturn(newBaseUrl).atLeastOnce(); + replay(metainfoDAO, entity); + ambariMetaInfo.init(); + waitForAllReposToBeResolved(ambariMetaInfo); + List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories( STACK_NAME_HDP, "2.1.1", "redhat6"); assertNotNull(redhat6Repo); @@ -324,24 +333,6 @@ public class AmbariMetaInfoTest { assertFalse(invalid); } - /** - * Method: getSupportedConfigs(String stackName, String version, String - * serviceName) - */ - @Test - public void getSupportedConfigs() throws Exception { - - Map<String, Map<String, String>> configsAll = metaInfo.getSupportedConfigs( - STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS); - Set<String> filesKeys = configsAll.keySet(); - for (String file : filesKeys) { - Map<String, String> configs = configsAll.get(file); - Set<String> propertyKeys = configs.keySet(); - assertNotNull(propertyKeys); - assertFalse(propertyKeys.size() == 0); - } - } - @Test public void testServiceNameUsingComponentName() throws AmbariException { String serviceName = metaInfo.getComponentToService(STACK_NAME_HDP, @@ -374,31 +365,19 @@ public class AmbariMetaInfoTest { */ @Test public void getServiceInfo() throws Exception { - ServiceInfo si = metaInfo.getServiceInfo(STACK_NAME_HDP, STACK_VERSION_HDP, + ServiceInfo si = metaInfo.getService(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS); assertNotNull(si); } @Test public void testConfigDependencies() throws Exception { - ServiceInfo serviceInfo = metaInfo.getServiceInfo(STACK_NAME_HDP, EXT_STACK_NAME, - SERVICE_NAME_MAPRED2); + ServiceInfo serviceInfo = metaInfo.getService(STACK_NAME_HDP, EXT_STACK_NAME, + SERVICE_NAME_MAPRED2); assertNotNull(serviceInfo); assertTrue(!serviceInfo.getConfigDependencies().isEmpty()); } - /** - * Method: getSupportedServices(String stackName, String version) - */ - @Test - public void getSupportedServices() throws Exception { - List<ServiceInfo> services = metaInfo.getSupportedServices(STACK_NAME_HDP, - STACK_VERSION_HDP); - assertNotNull(services); - assertFalse(services.size() == 0); - - } - @Test public void testGetRepos() throws Exception { Map<String, List<RepositoryInfo>> repos = metaInfo.getRepository( @@ -447,7 +426,7 @@ public class AmbariMetaInfoTest { * @throws Exception */ public void testGlobalMapping() throws Exception { - ServiceInfo sinfo = metaInfo.getServiceInfo("HDP", + ServiceInfo sinfo = metaInfo.getService("HDP", "0.2", "HDFS"); List<PropertyInfo> pinfo = sinfo.getProperties(); /** check all the config knobs and make sure the global one is there **/ @@ -459,7 +438,7 @@ public class AmbariMetaInfoTest { } } Assert.assertTrue(checkforglobal); - sinfo = metaInfo.getServiceInfo("HDP", + sinfo = metaInfo.getService("HDP", "0.2", "MAPREDUCE"); boolean checkforhadoopheapsize = false; pinfo = sinfo.getProperties(); @@ -479,8 +458,9 @@ public class AmbariMetaInfoTest { File stackRoot = new File("src/test/resources/stacks"); File stackRootTmp = new File(buildDir + "/ambari-metaInfo"); stackRootTmp.mkdir(); FileUtils.copyDirectory(stackRoot, stackRootTmp); - AmbariMetaInfo ambariMetaInfo = new AmbariMetaInfo(stackRootTmp, new File("target/version")); - ambariMetaInfo.injector = injector; + AmbariMetaInfo ambariMetaInfo = createAmbariMetaInfo(stackRootTmp, new File("target/version"), true); + //todo + //ambariMetaInfo.injector = injector; File f1, f2, f3; f1 = new File(stackRootTmp.getAbsolutePath() + "/001.svn"); f1.createNewFile(); f2 = new File(stackRootTmp.getAbsolutePath() + "/abcd.svn/001.svn"); f2.mkdirs(); f2.createNewFile(); @@ -492,10 +472,8 @@ public class AmbariMetaInfoTest { // Tests the stack is loaded as expected getServices(); getComponentsByService(); - getComponentCategory(); - getSupportedConfigs(); // Check .svn is not part of the stack but abcd.svn is - Assert.assertNotNull(ambariMetaInfo.getStackInfo("abcd.svn", "001.svn")); + Assert.assertNotNull(ambariMetaInfo.getStack("abcd.svn", "001.svn")); Assert.assertFalse(ambariMetaInfo.isSupportedStack(".svn", "")); Assert.assertFalse(ambariMetaInfo.isSupportedStack(".svn", "")); @@ -511,7 +489,6 @@ public class AmbariMetaInfoTest { metaInfo.getComponent(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS, NON_EXT_VALUE); } catch (StackAccessException e) { - Assert.assertTrue(e instanceof StackAccessException); } } @@ -530,7 +507,6 @@ public class AmbariMetaInfoTest { try { metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, NON_EXT_VALUE); } catch (StackAccessException e) { - Assert.assertTrue(e instanceof StackAccessException); } } @@ -541,40 +517,25 @@ public class AmbariMetaInfoTest { try { metaInfo.getService(STACK_NAME_HDP, STACK_VERSION_HDP, NON_EXT_VALUE); } catch (StackAccessException e) { - Assert.assertTrue(e instanceof StackAccessException); } } @Test - public void testGetStacksNames() throws Exception { - Set<Stack> stackNames = metaInfo.getStackNames(); - assertEquals(stackNames.size(), STACKS_NAMES_CNT); - assertTrue(stackNames.contains(new Stack(STACK_NAME_HDP))); - assertTrue(stackNames.contains(new Stack(STACK_NAME_XYZ))); - } - - @Test - public void testGetStack() throws Exception { - Stack stack = metaInfo.getStack(STACK_NAME_HDP); - Assert.assertEquals(stack.getStackName(), STACK_NAME_HDP); - try { - metaInfo.getStack(NON_EXT_VALUE); - } catch (StackAccessException e) { - Assert.assertTrue(e instanceof StackAccessException); - } + public void testGetStacks() { + Collection<StackInfo> stacks = metaInfo.getStacks(); + //todo: complete test } @Test public void testGetStackInfo() throws Exception { - StackInfo stackInfo = metaInfo.getStackInfo(STACK_NAME_HDP, STACK_VERSION_HDP); + StackInfo stackInfo = metaInfo.getStack(STACK_NAME_HDP, STACK_VERSION_HDP); Assert.assertEquals(stackInfo.getName(), STACK_NAME_HDP); Assert.assertEquals(stackInfo.getVersion(), STACK_VERSION_HDP); Assert.assertEquals(stackInfo.getMinUpgradeVersion(), STACK_MINIMAL_VERSION_HDP); try { - metaInfo.getStackInfo(STACK_NAME_HDP, NON_EXT_VALUE); + metaInfo.getStack(STACK_NAME_HDP, NON_EXT_VALUE); } catch (StackAccessException e) { - Assert.assertTrue(e instanceof StackAccessException); } } @@ -589,7 +550,7 @@ public class AmbariMetaInfoTest { @Test public void testGetProperties() throws Exception { - Set<PropertyInfo> properties = metaInfo.getProperties(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS); + Set<PropertyInfo> properties = metaInfo.getServiceProperties(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS); Assert.assertEquals(properties.size(), PROPERTIES_CNT); } @@ -605,7 +566,6 @@ public class AmbariMetaInfoTest { try { metaInfo.getPropertiesByName(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS, NON_EXT_VALUE); } catch (StackAccessException e) { - Assert.assertTrue(e instanceof StackAccessException); } } @@ -636,7 +596,6 @@ public class AmbariMetaInfoTest { try { metaInfo.getOperatingSystem(STACK_NAME_HDP, STACK_VERSION_HDP, NON_EXT_VALUE); } catch (StackAccessException e) { - Assert.assertTrue(e instanceof StackAccessException); } } @@ -656,9 +615,9 @@ public class AmbariMetaInfoTest { @Test public void testExtendedStackDefinition() throws Exception { - StackInfo stackInfo = metaInfo.getStackInfo(STACK_NAME_HDP, EXT_STACK_NAME); + StackInfo stackInfo = metaInfo.getStack(STACK_NAME_HDP, EXT_STACK_NAME); Assert.assertTrue(stackInfo != null); - List<ServiceInfo> serviceInfos = stackInfo.getServices(); + Collection<ServiceInfo> serviceInfos = stackInfo.getServices(); Assert.assertFalse(serviceInfos.isEmpty()); Assert.assertTrue(serviceInfos.size() > 1); ServiceInfo deletedService = null; @@ -740,86 +699,8 @@ public class AmbariMetaInfoTest { } @Test - public void testGetParentStacksInOrder() throws Exception { - List<StackInfo> allStacks = metaInfo.getSupportedStacks(); - StackInfo stackInfo = metaInfo.getStackInfo(STACK_NAME_HDP, EXT_STACK_NAME); - StackInfo newStack = new StackInfo(); - newStack.setName(STACK_NAME_HDP); - newStack.setVersion("2.0.99"); - newStack.setParentStackVersion(EXT_STACK_NAME); - newStack.setActive(true); - newStack.setRepositories(stackInfo.getRepositories()); - allStacks.add(newStack); - - Method method = StackExtensionHelper.class.getDeclaredMethod - ("getParentStacksInOrder", Collection.class); - method.setAccessible(true); - StackExtensionHelper helper = new StackExtensionHelper(injector, metaInfo.getStackRoot()); - helper.fillInfo(); - Map<String, List<StackInfo>> stacks = - (Map<String, List<StackInfo>>) method.invoke(helper, allStacks); - - Assert.assertNotNull(stacks.get("2.0.99")); - // Verify order - LinkedList<String> target = new LinkedList<String>(); - target.add("2.0.5"); - target.add("2.0.6"); - target.add("2.0.99"); - LinkedList<String> actual = new LinkedList<String>(); - LinkedList<StackInfo> parents = (LinkedList<StackInfo>) stacks.get("2.0.99"); - parents.addFirst(newStack); - ListIterator lt = parents.listIterator(parents.size()); - while (lt.hasPrevious()) { - StackInfo stack = (StackInfo) lt.previous(); - actual.add(stack.getVersion()); - } - org.junit.Assert.assertArrayEquals("Order of stack extension not " + - "preserved.", target.toArray(), actual.toArray()); - } - - @Test - public void testGetApplicableServices() throws Exception { - StackExtensionHelper helper = new StackExtensionHelper(injector, - metaInfo.getStackRoot()); - helper.fillInfo(); - List<ServiceInfo> allServices = helper.getAllApplicableServices(metaInfo - .getStackInfo(STACK_NAME_HDP, EXT_STACK_NAME)); - - ServiceInfo testService = null; - ServiceInfo existingService = null; - for (ServiceInfo serviceInfo : allServices) { - if (serviceInfo.getName().equals("YARN")) { - testService = serviceInfo; - } else if (serviceInfo.getName().equals("MAPREDUCE2")) { - existingService = serviceInfo; - } - } - - Assert.assertNotNull(testService); - Assert.assertNotNull(existingService); - - PropertyInfo testProperty = null; - PropertyInfo existingProperty = null; - for (PropertyInfo property : testService.getProperties()) { - if (property.getName().equals("new-yarn-property")) { - testProperty = property; - } - } - for (PropertyInfo property : existingService.getProperties()) { - if (property.getName().equals("mapreduce.map.log.level")) { - existingProperty = property; - } - } - - Assert.assertNotNull(testProperty); - Assert.assertEquals("some-value", testProperty.getValue()); - Assert.assertNotNull(existingProperty); - Assert.assertEquals("INFO", existingProperty.getValue()); - } - - @Test public void testPropertyCount() throws Exception { - Set<PropertyInfo> properties = metaInfo.getProperties(STACK_NAME_HDP, STACK_VERSION_HDP_02, SERVICE_NAME_HDFS); + Set<PropertyInfo> properties = metaInfo.getServiceProperties(STACK_NAME_HDP, STACK_VERSION_HDP_02, SERVICE_NAME_HDFS); // 3 empty properties Assert.assertEquals(103, properties.size()); } @@ -828,12 +709,13 @@ public class AmbariMetaInfoTest { public void testBadStack() throws Exception { File stackRoot = new File("src/test/resources/bad-stacks"); LOG.info("Stacks file " + stackRoot.getAbsolutePath()); - AmbariMetaInfo mi = new AmbariMetaInfo(stackRoot, new File("target/version")); - mi.injector = injector; + try { - mi.init(); - } catch(Exception e) { - assertTrue(JAXBException.class.isInstance(e)); + createAmbariMetaInfo(stackRoot, new File("target/version"), true); + fail("Exception expected due to bad stack"); + } catch(AmbariException e) { + e.printStackTrace(); + assertTrue(e.getCause() instanceof JAXBException); } } @@ -1262,13 +1144,13 @@ public class AmbariMetaInfoTest { @Test public void testHooksDirInheritance() throws Exception { // Test hook dir determination in parent - StackInfo stackInfo = metaInfo.getStackInfo(STACK_NAME_HDP, "2.0.6"); + StackInfo stackInfo = metaInfo.getStack(STACK_NAME_HDP, "2.0.6"); Assert.assertEquals("HDP/2.0.6/hooks", stackInfo.getStackHooksFolder()); // Test hook dir inheritance - stackInfo = metaInfo.getStackInfo(STACK_NAME_HDP, "2.0.7"); + stackInfo = metaInfo.getStack(STACK_NAME_HDP, "2.0.7"); Assert.assertEquals("HDP/2.0.6/hooks", stackInfo.getStackHooksFolder()); // Test hook dir override - stackInfo = metaInfo.getStackInfo(STACK_NAME_HDP, "2.0.8"); + stackInfo = metaInfo.getStack(STACK_NAME_HDP, "2.0.8"); Assert.assertEquals("HDP/2.0.8/hooks", stackInfo.getStackHooksFolder()); } @@ -1317,21 +1199,21 @@ public class AmbariMetaInfoTest { public void testComponentCommandScriptInheritance() throws Exception { // Test command script determination in parent ComponentInfo component = metaInfo.getComponent(STACK_NAME_HDP, - "2.0.7", "HDFS", "HDFS_CLIENT"); + "2.0.7", "HDFS", "HDFS_CLIENT"); Assert.assertEquals("scripts/hdfs_client.py", component.getCommandScript().getScript()); component = metaInfo.getComponent(STACK_NAME_HDP, - "2.0.7", "HBASE", "HBASE_MASTER"); + "2.0.7", "HBASE", "HBASE_MASTER"); Assert.assertEquals("scripts/hbase_master.py", component.getCommandScript().getScript()); // Test command script inheritance component = metaInfo.getComponent(STACK_NAME_HDP, - "2.0.8", "HBASE", "HBASE_MASTER"); + "2.0.8", "HBASE", "HBASE_MASTER"); Assert.assertEquals("scripts/hbase_master.py", component.getCommandScript().getScript()); // Test command script override component = metaInfo.getComponent(STACK_NAME_HDP, - "2.0.8", "HDFS", "HDFS_CLIENT"); + "2.0.8", "HDFS", "HDFS_CLIENT"); Assert.assertEquals("scripts/hdfs_client_overridden.py", component.getCommandScript().getScript()); } @@ -1484,6 +1366,18 @@ public class AmbariMetaInfoTest { @Test public void testLatestRepo() throws Exception { + // ensure that all of the latest repo retrieval tasks have completed + StackManager sm = metaInfo.getStackManager(); + int maxWait = 45000; + int waitTime = 0; + while (waitTime < maxWait && ! sm.haveAllRepoUrlsBeenResolved()) { + Thread.sleep(5); + waitTime += 5; + } + + if (waitTime >= maxWait) { + fail("Latest Repo tasks did not complete"); + } for (RepositoryInfo ri : metaInfo.getRepositories("HDP", "2.1.1", "centos6")) { Assert.assertEquals( @@ -1651,6 +1545,8 @@ public class AmbariMetaInfoTest { assertTrue(ignoreHost.isHostIgnored()); } + + //todo: refactor test to use mocks instead of injector /** * Tests merging stack-based with existing definitions works * @@ -1658,7 +1554,19 @@ public class AmbariMetaInfoTest { */ @Test public void testAlertDefinitionMerging() throws Exception { + Injector injector = Guice.createInjector(Modules.override( + new InMemoryDefaultTestModule()).with(new MockModule())); + + injector.getInstance(GuiceJpaInitializer.class); + injector.getInstance(EntityManager.class); injector.getInstance(OrmTestHelper.class).createCluster(); + + metaInfo.alertDefinitionDao = injector.getInstance(AlertDefinitionDAO.class); + Class<?> c = metaInfo.getClass().getSuperclass(); + Field f = c.getDeclaredField("agentAlertDefinitions"); + f.setAccessible(true); + f.set(metaInfo, injector.getInstance(AgentAlertDefinitions.class)); + Clusters clusters = injector.getInstance(Clusters.class); Cluster cluster = clusters.getClusterById(1); cluster.setDesiredStackVersion( @@ -1700,15 +1608,102 @@ public class AmbariMetaInfoTest { } } - private AmbariMetaInfo setupTempAmbariMetaInfo(String buildDir) + private TestAmbariMetaInfo setupTempAmbariMetaInfo(String buildDir, boolean replayMocks) throws Exception { File stackRootTmp = new File(buildDir + "/ambari-metaInfo"); File stackRoot = new File("src/test/resources/stacks"); stackRootTmp.mkdir(); FileUtils.copyDirectory(stackRoot, stackRootTmp); - AmbariMetaInfo ambariMetaInfo = new AmbariMetaInfo(stackRootTmp, new File( - "target/version")); - injector.injectMembers(ambariMetaInfo); + TestAmbariMetaInfo ambariMetaInfo = createAmbariMetaInfo(stackRootTmp, new File( + "target/version"), replayMocks); + return ambariMetaInfo; } + + private TestAmbariMetaInfo createAmbariMetaInfo(File stackRoot, File versionFile, boolean replayMocks) throws Exception { + TestAmbariMetaInfo metaInfo = new TestAmbariMetaInfo(stackRoot, versionFile); + if (replayMocks) { + metaInfo.replayAllMocks(); + + try { + metaInfo.init(); + } catch(Exception e) { + LOG.info("Error in initializing ", e); + throw e; + } + waitForAllReposToBeResolved(metaInfo); + } + + return metaInfo; + } + + private void waitForAllReposToBeResolved(AmbariMetaInfo metaInfo) throws Exception { + int maxWait = 45000; + int waitTime = 0; + StackManager sm = metaInfo.getStackManager(); + while (waitTime < maxWait && ! sm.haveAllRepoUrlsBeenResolved()) { + Thread.sleep(5); + waitTime += 5; + } + + if (waitTime >= maxWait) { + fail("Latest Repo tasks did not complete"); + } + } + + private static class TestAmbariMetaInfo extends AmbariMetaInfo { + + MetainfoDAO metaInfoDAO; + AlertDefinitionDAO alertDefinitionDAO; + AlertDefinitionFactory alertDefinitionFactory; + OsFamily osFamily; + + public TestAmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception { + super(stackRoot, serverVersionFile); + // MetainfoDAO + metaInfoDAO = createNiceMock(MetainfoDAO.class); + Class<?> c = getClass().getSuperclass(); + Field f = c.getDeclaredField("metaInfoDAO"); + f.setAccessible(true); + f.set(this, metaInfoDAO); + + // ActionMetadata + ActionMetadata actionMetadata = new ActionMetadata(); + f = c.getDeclaredField("actionMetadata"); + f.setAccessible(true); + f.set(this, actionMetadata); + + //AlertDefinitionDAO + alertDefinitionDAO = createNiceMock(AlertDefinitionDAO.class); + f = c.getDeclaredField("alertDefinitionDao"); + f.setAccessible(true); + f.set(this, alertDefinitionDAO); + + //AlertDefinitionFactory + //alertDefinitionFactory = createNiceMock(AlertDefinitionFactory.class); + alertDefinitionFactory = new AlertDefinitionFactory(); + f = c.getDeclaredField("alertDefinitionFactory"); + f.setAccessible(true); + f.set(this, alertDefinitionFactory); + + //AmbariEventPublisher + AmbariEventPublisher ambariEventPublisher = new AmbariEventPublisher(); + f = c.getDeclaredField("eventPublisher"); + f.setAccessible(true); + f.set(this, ambariEventPublisher); + + //OSFamily + Configuration config = createNiceMock(Configuration.class); + expect(config.getSharedResourcesDirPath()).andReturn("./src/test/resources").anyTimes(); + replay(config); + osFamily = new OsFamily(config); + f = c.getDeclaredField("os_family"); + f.setAccessible(true); + f.set(this, osFamily); + } + + public void replayAllMocks() { + replay(metaInfoDAO, alertDefinitionDAO); + } + } }