http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigApplicationEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigApplicationEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigApplicationEntity.java new file mode 100644 index 0000000..cae46e3 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigApplicationEntity.java @@ -0,0 +1,102 @@ +/* + * 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.orm.entities; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "serviceconfigapplication") +@TableGenerator(name = "service_config_application_id_generator", + table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "value" + , pkColumnValue = "service_config_application_id_seq" + , initialValue = 1 + , allocationSize = 1 +) +public class ServiceConfigApplicationEntity { + @Id + @Column(name = "apply_id") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "service_config_application_id_generator") + private Long applyId; + + @Basic + @Column(name = "service_config_id", updatable = false, insertable = false, nullable = false) + private Long serviceConfigId; + + @Basic + @Column(name = "apply_timestamp") + private Long applyTimestamp; + + @Basic + @Column(name = "user_name") + private String user; + + @ManyToOne + @JoinColumn(name = "service_config_id", referencedColumnName = "service_config_id") + private ServiceConfigEntity serviceConfigEntity; + + + public Long getApplyId() { + return applyId; + } + + public void setApplyId(Long applyId) { + this.applyId = applyId; + } + + public Long getServiceConfigId() { + return serviceConfigId; + } + + public void setServiceConfigId(Long serviceConfigId) { + this.serviceConfigId = serviceConfigId; + } + + public Long getApplyTimestamp() { + return applyTimestamp; + } + + public void setApplyTimestamp(Long applyTimestamp) { + this.applyTimestamp = applyTimestamp; + } + + public ServiceConfigEntity getServiceConfigEntity() { + return serviceConfigEntity; + } + + public void setServiceConfigEntity(ServiceConfigEntity serviceConfigEntity) { + this.serviceConfigEntity = serviceConfigEntity; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } +}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java new file mode 100644 index 0000000..2727388 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java @@ -0,0 +1,146 @@ +/* + * 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.orm.entities; + +import javax.persistence.Basic; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import java.util.List; + +@Entity +@Table(name = "serviceconfig") +@TableGenerator(name = "service_config_id_generator", + table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "value" + , pkColumnValue = "service_config_id_seq" + , initialValue = 1 + , allocationSize = 1 +) +public class ServiceConfigEntity { + @Id + @Column(name = "service_config_id") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "service_config_id_generator") + private Long serviceConfigId; + + @Basic + @Column(name = "cluster_id", insertable = false, updatable = false, nullable = false) + private Long clusterId; + + @Basic + @Column(name = "service_name", nullable = false) + private String serviceName; + + @Basic + @Column(name = "version", nullable = false) + private Long version; + + @Basic + @Column(name = "create_timestamp", nullable = false) + private Long createTimestamp = System.currentTimeMillis(); + + @OneToMany(mappedBy = "serviceConfigEntity", cascade = CascadeType.ALL) + private List<ServiceConfigApplicationEntity> serviceConfigApplicationEntities; + + @ManyToMany + @JoinTable( + name = "serviceconfigmapping", + joinColumns = {@JoinColumn(name = "service_config_id", referencedColumnName = "service_config_id")}, + inverseJoinColumns = {@JoinColumn(name = "config_id", referencedColumnName = "config_id")} + ) + private List<ClusterConfigEntity> clusterConfigEntities; + + @ManyToOne + @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false) + private ClusterEntity clusterEntity; + + public Long getServiceConfigId() { + return serviceConfigId; + } + + public void setServiceConfigId(Long serviceConfigId) { + this.serviceConfigId = serviceConfigId; + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public Long getVersion() { + return version; + } + + public void setVersion(Long version) { + this.version = version; + } + + public Long getCreateTimestamp() { + return createTimestamp; + } + + public void setCreateTimestamp(Long create_timestamp) { + this.createTimestamp = create_timestamp; + } + + + public List<ServiceConfigApplicationEntity> getServiceConfigApplicationEntities() { + return serviceConfigApplicationEntities; + } + + public void setServiceConfigApplicationEntities(List<ServiceConfigApplicationEntity> serviceConfigApplicationEntities) { + this.serviceConfigApplicationEntities = serviceConfigApplicationEntities; + } + + public List<ClusterConfigEntity> getClusterConfigEntities() { + return clusterConfigEntities; + } + + public void setClusterConfigEntities(List<ClusterConfigEntity> clusterConfigEntities) { + this.clusterConfigEntities = clusterConfigEntities; + } + + public Long getClusterId() { + return clusterId; + } + + public void setClusterId(Long clusterId) { + this.clusterId = clusterId; + } + + public ClusterEntity getClusterEntity() { + return clusterEntity; + } + + public void setClusterEntity(ClusterEntity clusterEntity) { + this.clusterEntity = clusterEntity; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java index 97290ff..1d74038 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java @@ -24,12 +24,11 @@ import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import com.google.common.collect.ListMultimap; -import com.google.inject.persist.Transactional; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.controller.ClusterResponse; import org.apache.ambari.server.state.configgroup.ConfigGroup; -import org.apache.ambari.server.state.fsm.InvalidStateTransitionException; import org.apache.ambari.server.state.scheduler.RequestExecution; +import org.apache.ambari.server.controller.ServiceConfigVersionResponse; public interface Cluster { @@ -91,7 +90,7 @@ public interface Cluster { * Set desired stack version * @param stackVersion */ - public void setDesiredStackVersion(StackId stackVersion); + public void setDesiredStackVersion(StackId stackVersion) throws AmbariException; /** * Get current stack version @@ -157,11 +156,33 @@ public interface Cluster { * Adds and sets a DESIRED configuration to be applied to a cluster. There * can be only one selected config per type. * @param user the user making the change for audit purposes - * @param config the {@link Config} object to set as desired + * @param config the {@link org.apache.ambari.server.state.Config} object to set as desired * @return <code>true</code> if the config was added, or <code>false</code> * if the config is already set as the current */ - public boolean addDesiredConfig(String user, Config config); + public ServiceConfigVersionResponse addDesiredConfig(String user, Config config); + + /** + * Apply specified service config version (rollback) + * @param serviceName service name + * @param version service config version + * @param user the user making the change for audit purposes + * @return true if service config version applied + * @throws AmbariException + */ + boolean setServiceConfigVersion(String serviceName, Long version, String user) throws AmbariException; + + /** + * Get currently active service config versions for stack services + * @return + */ + Map<String, ServiceConfigVersionResponse> getActiveServiceConfigVersions(); + + /** + * Get service config version history + * @return + */ + List<ServiceConfigVersionResponse> getServiceConfigVersions(); /** * Gets the desired (and selected) config by type. @@ -298,6 +319,13 @@ public interface Cluster { public void deleteRequestExecution(Long id) throws AmbariException; /** + * Get next version of specified config type + * @param type config type + * @return next version of config + */ + Long getNextConfigVersion(String type); + + /** * Bulk handle service component host events * * @param eventMap serviceName - event mapping http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java index 194a3ad..bdfe1bd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java @@ -34,7 +34,13 @@ public interface Config { /** * @return Version Tag this config instance is mapped to */ - public String getVersionTag(); + public String getTag(); + + /** + * + * @return version of config by type + */ + public Long getVersion(); /** * @return Properties that define this config instance @@ -50,7 +56,13 @@ public interface Config { * Change the version tag * @param versionTag */ - public void setVersionTag(String versionTag); + public void setTag(String versionTag); + + /** + * Set config version + * @param version + */ + public void setVersion(Long version); /** * Replace properties with new provided set @@ -71,6 +83,12 @@ public interface Config { public void updateProperties(Map<String, String> properties); /** + * Ger service config versions containing this config + * @return + */ + List<Long> getServiceConfigVersions(); + + /** * Delete certain properties * @param properties Property keys to be deleted */ http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/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 3afc918..81c3c38 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 @@ -45,7 +45,6 @@ import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.ConfigurationRequest; import org.apache.ambari.server.orm.dao.ClusterDAO; import org.apache.ambari.server.orm.entities.ClusterConfigEntity; -import org.apache.ambari.server.orm.entities.ClusterConfigEntityPK; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** @@ -110,7 +109,7 @@ public class ConfigHelper { for (Entry<String, DesiredConfig> clusterEntry : clusterDesired.entrySet()) { String type = clusterEntry.getKey(); - String tag = clusterEntry.getValue().getVersion(); + String tag = clusterEntry.getValue().getTag(); // 1) start with cluster config Config config = cluster.getConfig(type, tag); @@ -120,7 +119,7 @@ public class ConfigHelper { Map<String, String> tags = new LinkedHashMap<String, String>(); - tags.put(CLUSTER_DEFAULT_TAG, config.getVersionTag()); + tags.put(CLUSTER_DEFAULT_TAG, config.getTag()); // AMBARI-3672. Only consider Config groups for override tags // tags -> (configGroupId, versionTag) @@ -374,12 +373,8 @@ public class ConfigHelper { Set<String> globalVersions = cluster.getConfigsByType(type).keySet(); for(String version:globalVersions) { - ClusterConfigEntityPK clusterConfigEntityPK = new ClusterConfigEntityPK(); - clusterConfigEntityPK.setClusterId(cluster.getClusterId()); - clusterConfigEntityPK.setTag(version); - clusterConfigEntityPK.setType(type); ClusterConfigEntity clusterConfigEntity = clusterDAO.findConfig - (clusterConfigEntityPK); + (cluster.getClusterId(), type, version); clusterDAO.removeConfig(clusterConfigEntity); } http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java index a7feb0b..1972739 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java @@ -18,12 +18,10 @@ package org.apache.ambari.server.state; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import org.apache.ambari.server.orm.dao.ClusterDAO; +import org.apache.ambari.server.orm.dao.ServiceConfigDAO; import org.apache.ambari.server.orm.entities.ClusterConfigEntity; import org.apache.ambari.server.orm.entities.ClusterEntity; @@ -33,12 +31,15 @@ import com.google.inject.Injector; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; import com.google.inject.persist.Transactional; +import org.apache.ambari.server.orm.entities.ServiceConfigEntity; public class ConfigImpl implements Config { + public static final String GENERATED_TAG_PREFIX = "generatedTag_"; private Cluster cluster; private String type; - private String versionTag; + private String tag; + private Long version; private Map<String, String> properties; private Map<String, Map<String, String>> propertiesAttributes; private ClusterConfigEntity entity; @@ -47,6 +48,9 @@ public class ConfigImpl implements Config { private ClusterDAO clusterDAO; @Inject private Gson gson; + @Inject + private ServiceConfigDAO serviceConfigDAO; + @AssistedInject public ConfigImpl(@Assisted Cluster cluster, @Assisted String type, @Assisted Map<String, String> properties, @@ -63,7 +67,8 @@ public class ConfigImpl implements Config { public ConfigImpl(@Assisted Cluster cluster, @Assisted ClusterConfigEntity entity, Injector injector) { this.cluster = cluster; this.type = entity.getType(); - this.versionTag = entity.getTag(); + this.tag = entity.getTag(); + this.version = entity.getVersion(); this.entity = entity; injector.injectMembers(this); } @@ -81,8 +86,13 @@ public class ConfigImpl implements Config { } @Override - public synchronized String getVersionTag() { - return versionTag; + public synchronized String getTag() { + return tag; + } + + @Override + public synchronized Long getVersion() { + return version; } @Override @@ -105,8 +115,13 @@ public class ConfigImpl implements Config { } @Override - public synchronized void setVersionTag(String versionTag) { - this.versionTag = versionTag; + public synchronized void setTag(String tag) { + this.tag = tag; + } + + @Override + public synchronized void setVersion(Long version) { + this.version = version; } @Override @@ -125,6 +140,14 @@ public class ConfigImpl implements Config { } @Override + public synchronized List<Long> getServiceConfigVersions() { + if (cluster == null || type == null || version == null) { + return Collections.emptyList(); + } + return serviceConfigDAO.getServiceConfigVersionsByConfig(cluster.getClusterId(), type, version); + } + + @Override public synchronized void deleteProperties(List<String> properties) { for (String key : properties) { this.properties.remove(key); @@ -136,12 +159,20 @@ public class ConfigImpl implements Config { public synchronized void persist() { ClusterEntity clusterEntity = clusterDAO.findById(cluster.getClusterId()); + + if (this.version == null) { + this.version = cluster.getNextConfigVersion(type); + } + if (this.tag == null) { + tag = GENERATED_TAG_PREFIX + version; + } ClusterConfigEntity entity = new ClusterConfigEntity(); entity.setClusterEntity(clusterEntity); - entity.setClusterId(Long.valueOf(cluster.getClusterId())); + entity.setClusterId(cluster.getClusterId()); entity.setType(type); - entity.setTag(getVersionTag()); + entity.setVersion(version); + entity.setTag(getTag()); entity.setTimestamp(new Date().getTime()); entity.setData(gson.toJson(getProperties())); http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigVersionHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigVersionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigVersionHelper.java new file mode 100644 index 0000000..a7e9b5a --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigVersionHelper.java @@ -0,0 +1,52 @@ +/* + * 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 java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Utility class to manage config versions for cluster + */ +public class ConfigVersionHelper { + + ConcurrentMap<String, AtomicLong> versionCounters = new ConcurrentHashMap<String, AtomicLong>(); + + public ConfigVersionHelper(Map<String, Long> configTypeLastVersions) { + for (Map.Entry<String, Long> entry : configTypeLastVersions.entrySet()) { + String type = entry.getKey(); + Long version = entry.getValue(); + versionCounters.put(type, new AtomicLong(version)); + } + } + + public long getNextVersion(String key) { + AtomicLong version = versionCounters.get(key); + if (version == null) { + version = new AtomicLong(); + AtomicLong tmp = versionCounters.putIfAbsent(key, version); + if (tmp != null) { + version = tmp; + } + } + return version.incrementAndGet(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java index 38ad201..0635284 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java @@ -30,26 +30,27 @@ import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion; */ public class DesiredConfig { - private String versionTag; + private String tag; private String serviceName; private String user; + private Long version; private List<HostOverride> hostOverrides = new ArrayList<HostOverride>(); /** - * Sets the version tag - * @param version the version tag + * Sets the tag + * @param tag the tag */ - public void setVersion(String version) { - versionTag = version; + public void setTag(String tag) { + this.tag = tag; } /** - * Gets the version tag - * @return the version tag + * Gets the tag + * @return the tag */ @JsonProperty("tag") - public String getVersion() { - return versionTag; + public String getTag() { + return tag; } /** @@ -104,10 +105,20 @@ public class DesiredConfig { public List<HostOverride> getHostOverrides() { return hostOverrides; } - + + @JsonProperty("version") + public Long getVersion() { + return version; + } + + public void setVersion(Long version) { + this.version = version; + } + /** * Used to represent an override on a host. */ + //TODO include changes for config versions public static class HostOverride { private String hostName; private String versionOverrideTag; @@ -130,7 +141,7 @@ public class DesiredConfig { } /** - * @return the override version tag + * @return the override tag tag */ @JsonProperty("tag") public String getVersionTag() { @@ -143,7 +154,7 @@ public class DesiredConfig { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{"); - sb.append("version=").append(versionTag); + sb.append("tag=").append(tag); if (null != serviceName) sb.append(", service=").append(serviceName); if (null != hostOverrides && hostOverrides.size() > 0) { http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/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 d2f4871..99141a3 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 @@ -36,17 +36,25 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.persistence.RollbackException; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.ObjectNotFoundException; +import org.apache.ambari.server.ParentObjectNotFoundException; import org.apache.ambari.server.ServiceComponentHostNotFoundException; import org.apache.ambari.server.ServiceNotFoundException; +import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.controller.ClusterResponse; +import org.apache.ambari.server.controller.ConfigurationResponse; import org.apache.ambari.server.controller.MaintenanceStateHelper; +import org.apache.ambari.server.orm.RequiresSession; import org.apache.ambari.server.orm.cache.ConfigGroupHostMapping; import org.apache.ambari.server.orm.cache.HostConfigMapping; import org.apache.ambari.server.orm.dao.ClusterDAO; import org.apache.ambari.server.orm.dao.ClusterStateDAO; import org.apache.ambari.server.orm.dao.ConfigGroupHostMappingDAO; import org.apache.ambari.server.orm.dao.HostConfigMappingDAO; +import org.apache.ambari.server.orm.dao.ServiceConfigDAO; import org.apache.ambari.server.orm.entities.ClusterConfigEntity; import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity; import org.apache.ambari.server.orm.entities.ClusterEntity; @@ -54,29 +62,16 @@ import org.apache.ambari.server.orm.entities.ClusterServiceEntity; import org.apache.ambari.server.orm.entities.ClusterStateEntity; import org.apache.ambari.server.orm.entities.ConfigGroupEntity; import org.apache.ambari.server.orm.entities.RequestScheduleEntity; -import org.apache.ambari.server.state.Alert; -import org.apache.ambari.server.state.Cluster; -import org.apache.ambari.server.state.ClusterHealthReport; -import org.apache.ambari.server.state.Clusters; -import org.apache.ambari.server.state.Config; -import org.apache.ambari.server.state.ConfigFactory; -import org.apache.ambari.server.state.ConfigHelper; -import org.apache.ambari.server.state.DesiredConfig; -import org.apache.ambari.server.state.Host; -import org.apache.ambari.server.state.HostHealthStatus; -import org.apache.ambari.server.state.MaintenanceState; -import org.apache.ambari.server.state.Service; -import org.apache.ambari.server.state.ServiceComponent; -import org.apache.ambari.server.state.ServiceComponentHost; -import org.apache.ambari.server.state.ServiceComponentHostEvent; -import org.apache.ambari.server.state.ServiceFactory; -import org.apache.ambari.server.state.StackId; -import org.apache.ambari.server.state.State; +import org.apache.ambari.server.orm.entities.ServiceConfigApplicationEntity; +import org.apache.ambari.server.orm.entities.ServiceConfigEntity; +import org.apache.ambari.server.state.*; import org.apache.ambari.server.state.configgroup.ConfigGroup; import org.apache.ambari.server.state.configgroup.ConfigGroupFactory; import org.apache.ambari.server.state.fsm.InvalidStateTransitionException; import org.apache.ambari.server.state.scheduler.RequestExecution; import org.apache.ambari.server.state.scheduler.RequestExecutionFactory; +import org.apache.ambari.server.controller.ServiceConfigVersionResponse; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -134,7 +129,9 @@ public class ClusterImpl implements Cluster { private ClusterEntity clusterEntity; - private Set<Alert> clusterAlerts = new HashSet<Alert>(); + private Set<Alert> clusterAlerts = new HashSet<Alert>(); + + private final ConfigVersionHelper configVersionHelper; @Inject private ClusterDAO clusterDAO; @@ -158,12 +155,18 @@ public class ClusterImpl implements Cluster { private ConfigHelper configHelper; @Inject private MaintenanceStateHelper maintenanceStateHelper; + @Inject + private AmbariMetaInfo ambariMetaInfo; + @Inject + private ServiceConfigDAO serviceConfigDAO; private volatile boolean svcHostsLoaded = false; + private volatile Multimap<String, String> serviceConfigTypes; + @Inject public ClusterImpl(@Assisted ClusterEntity clusterEntity, - Injector injector) { + Injector injector) throws AmbariException { injector.injectMembers(this); this.clusterEntity = clusterEntity; @@ -186,14 +189,59 @@ public class ClusterImpl implements Cluster { allConfigs.get(entity.getType()).put(entity.getTag(), config); } } + + if (desiredStackVersion != null && !StringUtils.isEmpty(desiredStackVersion.getStackName()) && ! + StringUtils.isEmpty(desiredStackVersion.getStackVersion())) { + loadServiceConfigTypes(); + } + + configVersionHelper = new ConfigVersionHelper(getConfigLastVersions()); } + @Override public ReadWriteLock getClusterGlobalLock() { return clusterGlobalLock; } + public void loadServiceConfigTypes() throws AmbariException { + try { + serviceConfigTypes = collectServiceConfigTypesMapping(); + } catch (AmbariException e) { + LOG.error("Cannot load stack info:", e); + throw e; + } + LOG.info("Service config types loaded: {}", serviceConfigTypes); + } + + /** + * Construct config type to service name mapping + * @throws AmbariException when stack or its part not found + */ + private Multimap<String, String> collectServiceConfigTypesMapping() throws AmbariException { + Multimap<String, String> serviceConfigTypes = HashMultimap.create(); + + Map<String, ServiceInfo> serviceInfoMap = null; + try { + serviceInfoMap = ambariMetaInfo.getServices(desiredStackVersion.getStackName(), desiredStackVersion.getStackVersion()); + } catch (ParentObjectNotFoundException e) { + LOG.error("Service config versioning disabled due to exception: ", e); + return serviceConfigTypes; + } + for (String serviceName : serviceInfoMap.keySet()) { + //collect config types for service + Set<PropertyInfo> properties = ambariMetaInfo.getProperties(desiredStackVersion.getStackName(), desiredStackVersion.getStackVersion(), serviceName); + for (PropertyInfo property : properties) { + int extIndex = property.getFilename().indexOf(AmbariMetaInfo.SERVICE_CONFIG_FILE_NAME_POSTFIX); + String configType = property.getFilename().substring(0, extIndex); + serviceConfigTypes.put(serviceName, configType); + } + } + + return serviceConfigTypes; + } + /** * Make sure we load all the service host components. * We need this for live status checks. @@ -888,7 +936,7 @@ public class ClusterImpl implements Cluster { } @Override - public void setDesiredStackVersion(StackId stackVersion) { + public void setDesiredStackVersion(StackId stackVersion) throws AmbariException { clusterGlobalLock.readLock().lock(); try { readWriteLock.writeLock().lock(); @@ -903,6 +951,7 @@ public class ClusterImpl implements Cluster { this.desiredStackVersion = stackVersion; clusterEntity.setDesiredStackVersion(gson.toJson(stackVersion)); clusterDAO.merge(clusterEntity); + loadServiceConfigTypes(); } finally { readWriteLock.writeLock().unlock(); } @@ -1053,16 +1102,14 @@ public class ClusterImpl implements Cluster { readWriteLock.writeLock().lock(); try { if (config.getType() == null - || config.getType().isEmpty() - || config.getVersionTag() == null - || config.getVersionTag().isEmpty()) { - // TODO throw error + || config.getType().isEmpty()) { + throw new IllegalArgumentException("Config type cannot be empty"); } if (!allConfigs.containsKey(config.getType())) { allConfigs.put(config.getType(), new HashMap<String, Config>()); } - allConfigs.get(config.getType()).put(config.getVersionTag(), config); + allConfigs.get(config.getType()).put(config.getTag(), config); } finally { readWriteLock.writeLock().unlock(); } @@ -1277,8 +1324,7 @@ public class ClusterImpl implements Cluster { } @Override - @Transactional - public boolean addDesiredConfig(String user, Config config) { + public ServiceConfigVersionResponse addDesiredConfig(String user, Config config) { if (null == user) throw new NullPointerException("User must be specified."); @@ -1289,39 +1335,21 @@ public class ClusterImpl implements Cluster { Config currentDesired = getDesiredConfigByType(config.getType()); // do not set if it is already the current - if (null != currentDesired && currentDesired.getVersionTag().equals(config.getVersionTag())) { - return false; - } - - Collection<ClusterConfigMappingEntity> entities = clusterEntity.getConfigMappingEntities(); - - for (ClusterConfigMappingEntity e : entities) { - if (e.isSelected() > 0 && e.getType().equals(config.getType())) { - e.setSelected(0); - } + if (null != currentDesired && currentDesired.getTag().equals(config.getTag())) { + return null; } - ClusterConfigMappingEntity entity = new ClusterConfigMappingEntity(); - entity.setClusterEntity(clusterEntity); - entity.setClusterId(clusterEntity.getClusterId()); - entity.setCreateTimestamp(Long.valueOf(System.currentTimeMillis())); - entity.setSelected(1); - entity.setUser(user); - entity.setType(config.getType()); - entity.setVersion(config.getVersionTag()); - entities.add(entity); + ServiceConfigVersionResponse serviceConfigVersionResponse = + applyConfig(config.getType(), config.getTag(), user); - clusterDAO.merge(clusterEntity); configHelper.invalidateStaleConfigsCache(); - return true; + return serviceConfigVersionResponse; } finally { readWriteLock.writeLock().unlock(); } } finally { clusterGlobalLock.readLock().unlock(); } - - } @Override @@ -1337,8 +1365,9 @@ public class ClusterImpl implements Cluster { if (e.isSelected() > 0) { DesiredConfig c = new DesiredConfig(); c.setServiceName(null); - c.setVersion(e.getVersion()); + c.setTag(e.getTag()); c.setUser(e.getUser()); + c.setVersion(allConfigs.get(e.getType()).get(e.getTag()).getVersion()); map.put(e.getType(), c); types.add(e.getType()); @@ -1366,8 +1395,233 @@ public class ClusterImpl implements Cluster { } finally { clusterGlobalLock.readLock().unlock(); } + } + + @Override + public boolean setServiceConfigVersion(String serviceName, Long version, String user) throws AmbariException { + if (null == user) + throw new NullPointerException("User must be specified."); + + clusterGlobalLock.writeLock().lock(); + try { + readWriteLock.writeLock().lock(); + try { + applyServiceConfigVersion(serviceName, version, user); + + return true; + } finally { + readWriteLock.writeLock().unlock(); + } + } finally { + clusterGlobalLock.readLock().unlock(); + } + } + + @Override + public Map<String, ServiceConfigVersionResponse> getActiveServiceConfigVersions() { + clusterGlobalLock.readLock().lock(); + try { + readWriteLock.readLock().lock(); + try { + Map<String, ServiceConfigVersionResponse> result = new HashMap<String, ServiceConfigVersionResponse>(); + for (String serviceName : serviceConfigTypes.keySet()) { + ServiceConfigVersionResponse activeServiceConfigVersion = getActiveServiceConfigVersion(serviceName); + if (activeServiceConfigVersion != null) { + result.put(serviceName, activeServiceConfigVersion); + } + } + return result; + } finally { + readWriteLock.readLock().unlock(); + } + } finally { + clusterGlobalLock.readLock().unlock(); + } + } + + @Override + @RequiresSession + public List<ServiceConfigVersionResponse> getServiceConfigVersions() { + clusterGlobalLock.readLock().lock(); + try { + readWriteLock.readLock().lock(); + try { + List<ServiceConfigVersionResponse> serviceConfigVersionResponses = new ArrayList<ServiceConfigVersionResponse>(); + for (ServiceConfigApplicationEntity applicationEntity : serviceConfigDAO.getServiceConfigApplications(getClusterId())) { + ServiceConfigVersionResponse serviceConfigVersionResponse = new ServiceConfigVersionResponse(); + + ServiceConfigEntity serviceConfigEntity = applicationEntity.getServiceConfigEntity(); + + + serviceConfigVersionResponse.setClusterName(getClusterName()); + serviceConfigVersionResponse.setServiceName(serviceConfigEntity.getServiceName()); + serviceConfigVersionResponse.setVersion(serviceConfigEntity.getVersion()); + serviceConfigVersionResponse.setCreateTime(serviceConfigEntity.getCreateTimestamp()); + serviceConfigVersionResponse.setApplyTime(applicationEntity.getApplyTimestamp()); + serviceConfigVersionResponse.setUserName(applicationEntity.getUser()); + serviceConfigVersionResponse.setConfigurations(new ArrayList<ConfigurationResponse>()); + + List<ClusterConfigEntity> clusterConfigEntities = serviceConfigEntity.getClusterConfigEntities(); + for (ClusterConfigEntity clusterConfigEntity : clusterConfigEntities) { + Config config = allConfigs.get(clusterConfigEntity.getType()).get(clusterConfigEntity.getTag()); + serviceConfigVersionResponse.getConfigurations().add(new ConfigurationResponse(getClusterName(), + config.getType(), config.getTag(), config.getVersion(), config.getProperties(), + config.getPropertiesAttributes())); + } + + serviceConfigVersionResponses.add(serviceConfigVersionResponse); + } + + return serviceConfigVersionResponses; + } finally { + readWriteLock.readLock().unlock(); + } + } finally { + clusterGlobalLock.readLock().unlock(); + } + } + + @RequiresSession + ServiceConfigVersionResponse getActiveServiceConfigVersion(String serviceName) { + ServiceConfigApplicationEntity lastApplication = serviceConfigDAO.getLastApplication(getClusterId(), serviceName); + if (lastApplication == null) { + LOG.warn("No active service config version found for service {}", serviceName); + return null; + } + ServiceConfigVersionResponse serviceConfigVersionResponse = new ServiceConfigVersionResponse(); + ServiceConfigEntity serviceConfigEntity = lastApplication.getServiceConfigEntity(); + serviceConfigVersionResponse.setClusterName(getClusterName()); + serviceConfigVersionResponse.setServiceName(serviceConfigEntity.getServiceName()); + serviceConfigVersionResponse.setVersion(serviceConfigEntity.getVersion()); + serviceConfigVersionResponse.setCreateTime(serviceConfigEntity.getCreateTimestamp()); + serviceConfigVersionResponse.setApplyTime(lastApplication.getApplyTimestamp()); + serviceConfigVersionResponse.setUserName(lastApplication.getUser()); + return serviceConfigVersionResponse; + } + + @Transactional + void applyServiceConfigVersion(String serviceName, Long serviceConfigVersion, String user) throws AmbariException { + ServiceConfigEntity serviceConfigEntity = serviceConfigDAO.findByServiceAndVersion(serviceName, serviceConfigVersion); + if (serviceConfigEntity == null) { + throw new ObjectNotFoundException("Service config version with serviceName={} and version={} not found"); + } + + //disable all configs related to service + Collection<String> configTypes = serviceConfigTypes.get(serviceName); + for (ClusterConfigMappingEntity entity : clusterEntity.getConfigMappingEntities()) { + if (configTypes.contains(entity.getType()) && entity.isSelected() > 0) { + entity.setSelected(0); + } + } + clusterDAO.merge(clusterEntity); + + for (ClusterConfigEntity configEntity : serviceConfigEntity.getClusterConfigEntities()) { + selectConfig(configEntity.getType(), configEntity.getTag(), user); + } + + ServiceConfigApplicationEntity applicationEntity = new ServiceConfigApplicationEntity(); + applicationEntity.setApplyTimestamp(System.currentTimeMillis()); + applicationEntity.setServiceConfigEntity(serviceConfigEntity); + applicationEntity.setUser(user); + + serviceConfigEntity.getServiceConfigApplicationEntities().add(applicationEntity); + + serviceConfigDAO.merge(serviceConfigEntity); + } + + @Transactional + void selectConfig(String type, String tag, String user) { + Collection<ClusterConfigMappingEntity> entities = clusterEntity.getConfigMappingEntities(); + + //disable previous config + for (ClusterConfigMappingEntity e : entities) { + if (e.isSelected() > 0 && e.getType().equals(type)) { + e.setSelected(0); + } + } + + ClusterConfigMappingEntity entity = new ClusterConfigMappingEntity(); + entity.setClusterEntity(clusterEntity); + entity.setClusterId(clusterEntity.getClusterId()); + entity.setCreateTimestamp(System.currentTimeMillis()); + entity.setSelected(1); + entity.setUser(user); + entity.setType(type); + entity.setTag(tag); + entities.add(entity); + + clusterDAO.merge(clusterEntity); + + } + + @Transactional + ServiceConfigVersionResponse applyConfig(String type, String tag, String user) { + + selectConfig(type, tag, user); + + String serviceName = null; + //find service name for config type + for (Entry<String, String> entry : serviceConfigTypes.entries()) { + if (StringUtils.equals(entry.getValue(), type)) { + serviceName = entry.getKey(); + break; + } + } + + if (serviceName == null) { + LOG.error("No service found for config type '{}', service config version not created"); + return null; + } else { + return createServiceConfigVersion(serviceName, user); + } + + } + + private ServiceConfigVersionResponse createServiceConfigVersion(String serviceName, String user) { + //create next service config version + ServiceConfigEntity serviceConfigEntity = new ServiceConfigEntity(); + serviceConfigEntity.setServiceName(serviceName); + serviceConfigEntity.setClusterEntity(clusterEntity); + serviceConfigEntity.setVersion(configVersionHelper.getNextVersion(serviceName)); + + //set first default application + serviceConfigEntity.setServiceConfigApplicationEntities(new ArrayList<ServiceConfigApplicationEntity>()); + ServiceConfigApplicationEntity serviceConfigApplicationEntity = new ServiceConfigApplicationEntity(); + serviceConfigApplicationEntity.setApplyTimestamp(serviceConfigEntity.getCreateTimestamp()); + serviceConfigApplicationEntity.setServiceConfigEntity(serviceConfigEntity); + serviceConfigApplicationEntity.setUser(user); + serviceConfigEntity.getServiceConfigApplicationEntities().add(serviceConfigApplicationEntity); + + List<ClusterConfigEntity> configEntities = new ArrayList<ClusterConfigEntity>(); + serviceConfigEntity.setClusterConfigEntities(configEntities); + + //add configs from this service + Collection<String> configTypes = serviceConfigTypes.get(serviceName); + for (ClusterConfigMappingEntity mappingEntity : clusterEntity.getConfigMappingEntities()) { + if (mappingEntity.isSelected() > 0 && configTypes.contains(mappingEntity.getType())) { + ClusterConfigEntity configEntity = + clusterDAO.findConfig(getClusterId(), mappingEntity.getType(), mappingEntity.getTag()); + if (configEntity != null) { + configEntities.add(configEntity); + } else { + LOG.error("Desired cluster config type={}, tag={} is not present in database," + + " unable to add to service config version"); + } + } + } + + serviceConfigDAO.create(serviceConfigEntity); + + ServiceConfigVersionResponse response = new ServiceConfigVersionResponse(); + response.setUserName(user); + response.setClusterName(getClusterName()); + response.setVersion(serviceConfigEntity.getVersion()); + response.setServiceName(serviceConfigEntity.getServiceName()); + response.setCreateTime(serviceConfigEntity.getCreateTimestamp()); + response.setApplyTime(serviceConfigApplicationEntity.getApplyTimestamp()); + return response; } @Override @@ -1378,7 +1632,7 @@ public class ClusterImpl implements Cluster { try { for (ClusterConfigMappingEntity e : clusterEntity.getConfigMappingEntities()) { if (e.isSelected() > 0 && e.getType().equals(configType)) { - return getConfig(e.getType(), e.getVersion()); + return getConfig(e.getType(), e.getTag()); } } @@ -1410,7 +1664,7 @@ public class ClusterImpl implements Cluster { for (HostConfigMapping mappingEntity : mappingEntities) { DesiredConfig desiredConfig = new DesiredConfig(); - desiredConfig.setVersion(mappingEntity.getVersion()); + desiredConfig.setTag(mappingEntity.getVersion()); desiredConfig.setServiceName(mappingEntity.getServiceName()); desiredConfig.setUser(mappingEntity.getUser()); @@ -1433,6 +1687,32 @@ public class ClusterImpl implements Cluster { return getHostsDesiredConfigs(hostnames); } + @Override + public Long getNextConfigVersion(String type) { + return configVersionHelper.getNextVersion(type); + } + + private Map<String, Long> getConfigLastVersions() { + Map<String, Long> maxVersions = new HashMap<String, Long>(); + //config versions + for (Entry<String, Map<String, Config>> mapEntry : allConfigs.entrySet()) { + String type = mapEntry.getKey(); + Long lastVersion = 0L; + for (Entry<String, Config> configEntry : mapEntry.getValue().entrySet()) { + Long version = configEntry.getValue().getVersion(); + if (version > lastVersion) { + lastVersion = version; + } + } + maxVersions.put(type, lastVersion); + } + + //service config versions + maxVersions.putAll(serviceConfigDAO.findMaxVersions(getClusterId())); + + return maxVersions; + } + @Transactional @Override public List<ServiceComponentHostEvent> processServiceComponentHostEvents(ListMultimap<String, ServiceComponentHostEvent> eventMap) { http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java index f858264..023d530 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java @@ -615,6 +615,8 @@ public class ClustersImpl implements Clusters { hostClusterMap.get(hostname).remove(cluster); clusterHostMap.get(clusterName).remove(host); + host.refresh(); + cluster.refresh(); deleteConfigGroupHostMapping(hostname); http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java index 9a3e85b..fa06c07 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java @@ -26,16 +26,13 @@ import com.google.inject.persist.Transactional; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.DuplicateResourceException; import org.apache.ambari.server.controller.ConfigGroupResponse; -import org.apache.ambari.server.controller.internal.ConfigGroupResourceProvider; import org.apache.ambari.server.controller.internal.ConfigurationResourceProvider; -import org.apache.ambari.server.controller.utilities.PropertyHelper; import org.apache.ambari.server.orm.dao.ClusterDAO; import org.apache.ambari.server.orm.dao.ConfigGroupConfigMappingDAO; import org.apache.ambari.server.orm.dao.ConfigGroupDAO; import org.apache.ambari.server.orm.dao.ConfigGroupHostMappingDAO; import org.apache.ambari.server.orm.dao.HostDAO; import org.apache.ambari.server.orm.entities.ClusterConfigEntity; -import org.apache.ambari.server.orm.entities.ClusterConfigEntityPK; import org.apache.ambari.server.orm.entities.ClusterEntity; import org.apache.ambari.server.orm.entities.ConfigGroupConfigMappingEntity; import org.apache.ambari.server.orm.entities.ConfigGroupEntity; @@ -369,12 +366,8 @@ public class ConfigGroupImpl implements ConfigGroup { if (configurations != null && !configurations.isEmpty()) { for (Config config : configurations.values()) { - ClusterConfigEntityPK clusterConfigEntityPK = new ClusterConfigEntityPK(); - clusterConfigEntityPK.setClusterId(cluster.getClusterId()); - clusterConfigEntityPK.setTag(config.getVersionTag()); - clusterConfigEntityPK.setType(config.getType()); ClusterConfigEntity clusterConfigEntity = clusterDAO.findConfig - (clusterConfigEntityPK); + (cluster.getClusterId(), config.getType(), config.getTag()); if (clusterConfigEntity == null) { // Create configuration @@ -382,13 +375,16 @@ public class ConfigGroupImpl implements ConfigGroup { clusterConfigEntity.setClusterId(clusterEntity.getClusterId()); clusterConfigEntity.setClusterEntity(clusterEntity); clusterConfigEntity.setType(config.getType()); - clusterConfigEntity.setTag(config.getVersionTag()); + clusterConfigEntity.setTag(config.getTag()); + clusterConfigEntity.setVersion(cluster.getNextConfigVersion(config.getType())); clusterConfigEntity.setData(gson.toJson(config.getProperties())); if (null != config.getPropertiesAttributes()) { clusterConfigEntity.setAttributes(gson.toJson(config.getPropertiesAttributes())); } clusterConfigEntity.setTimestamp(System.currentTimeMillis()); + //TODO why not use config.persist() here? + // TODO: Is locking necessary and functional ? cluster.getClusterGlobalLock().writeLock().lock(); try { @@ -471,10 +467,10 @@ public class ConfigGroupImpl implements ConfigGroup { try { if (configurations != null && !configurations.isEmpty()) { for (Config c : configurations.values()) { - if (c.getType().equals(config.getType()) && c.getVersionTag().equals - (config.getVersionTag())) { + if (c.getType().equals(config.getType()) && c.getTag().equals + (config.getTag())) { throw new DuplicateResourceException("Config " + config.getType() + - " with tag " + config.getVersionTag() + " is already associated " + + " with tag " + config.getTag() + " is already associated " + "with Config Group " + configGroupEntity.getGroupName()); } } @@ -504,7 +500,7 @@ public class ConfigGroupImpl implements ConfigGroup { configMap.put(ConfigurationResourceProvider .CONFIGURATION_CONFIG_TYPE_PROPERTY_ID, config.getType()); configMap.put(ConfigurationResourceProvider - .CONFIGURATION_CONFIG_TAG_PROPERTY_ID, config.getVersionTag()); + .CONFIGURATION_CONFIG_TAG_PROPERTY_ID, config.getTag()); configObjMap.add(configMap); } http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java index c1aa492..619859c 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java @@ -1150,7 +1150,7 @@ public class HostImpl implements Host { throw new NullPointerException("User must be specified."); HostConfigMapping exist = getDesiredConfigEntity(clusterId, config.getType()); - if (null != exist && exist.getVersion().equals(config.getVersionTag())) { + if (null != exist && exist.getVersion().equals(config.getTag())) { if (!selected) { exist.setSelected(0); hostConfigMappingDAO.merge(exist); @@ -1175,7 +1175,7 @@ public class HostImpl implements Host { hostConfigMapping.setSelected(1); hostConfigMapping.setUser(user); hostConfigMapping.setType(config.getType()); - hostConfigMapping.setVersion(config.getVersionTag()); + hostConfigMapping.setVersion(config.getTag()); hostConfigMappingDAO.create(hostConfigMapping); } @@ -1196,7 +1196,7 @@ public class HostImpl implements Host { clusterId, hostEntity.getHostName())) { DesiredConfig dc = new DesiredConfig(); - dc.setVersion(e.getVersion()); + dc.setTag(e.getVersion()); dc.setServiceName(e.getServiceName()); dc.setUser(e.getUser()); map.put(e.getType(), dc); @@ -1217,7 +1217,7 @@ public class HostImpl implements Host { for (Map.Entry<String, DesiredConfig> desiredConfigEntry : cluster.getDesiredConfigs().entrySet()) { HostConfig hostConfig = new HostConfig(); - hostConfig.setDefaultVersionTag(desiredConfigEntry.getValue().getVersion()); + hostConfig.setDefaultVersionTag(desiredConfigEntry.getValue().getTag()); hostConfigMap.put(desiredConfigEntry.getKey(), hostConfig); } @@ -1235,11 +1235,11 @@ public class HostImpl implements Host { hostConfig = new HostConfig(); hostConfigMap.put(configType, hostConfig); hostConfig.setDefaultVersionTag(cluster.getDesiredConfigByType - (configType).getVersionTag()); + (configType).getTag()); } Config config = configEntry.getValue(); hostConfig.getConfigGroupOverrides().put(configGroup.getId(), - config.getVersionTag()); + config.getTag()); } } } @@ -1306,4 +1306,4 @@ public class HostImpl implements Host { } - \ No newline at end of file + http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java index 1178bab..e697fbd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java @@ -231,12 +231,12 @@ public abstract class AbstractUpgradeCatalog implements UpgradeCatalog { if (baseConfig != null) { String authName = "ambari-upgrade"; - if (cluster.addDesiredConfig(authName, baseConfig)) { - String oldConfigString = (oldConfig != null) ? " from='" + oldConfig.getVersionTag() + "'" : ""; + if (cluster.addDesiredConfig(authName, baseConfig) != null) { + String oldConfigString = (oldConfig != null) ? " from='" + oldConfig.getTag() + "'" : ""; LOG.info("cluster '" + cluster.getClusterName() + "' " + "changed by: '" + authName + "'; " + "type='" + baseConfig.getType() + "' " - + "tag='" + baseConfig.getVersionTag() + "'" + + "tag='" + baseConfig.getTag() + "'" + oldConfigString); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java index c7de486..451cd6d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java @@ -36,7 +36,6 @@ import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.KeyValueDAO; import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO; import org.apache.ambari.server.orm.entities.ClusterConfigEntity; -import org.apache.ambari.server.orm.entities.ClusterConfigEntityPK; import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity; import org.apache.ambari.server.orm.entities.ClusterEntity; import org.apache.ambari.server.orm.entities.ClusterServiceEntity; @@ -694,11 +693,7 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog { if (configTypes != null) { for (String configType : configTypes) { if (configType.contains(log4jConfigTypeContains)) { - ClusterConfigEntityPK configEntityPK = new ClusterConfigEntityPK(); - configEntityPK.setClusterId(clusterId); - configEntityPK.setType(configType); - configEntityPK.setTag(defaultVersionTag); - ClusterConfigEntity configEntity = clusterDAO.findConfig(configEntityPK); + ClusterConfigEntity configEntity = clusterDAO.findConfig(clusterId, configType, defaultVersionTag); if (configEntity == null) { String filename = configType + ".xml"; @@ -732,7 +727,7 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog { Long.valueOf(System.currentTimeMillis())); clusterConfigMappingEntity.setSelected(1); clusterConfigMappingEntity.setUser(defaultUser); - clusterConfigMappingEntity.setVersion(configEntity.getTag()); + clusterConfigMappingEntity.setTag(configEntity.getTag()); entities.add(clusterConfigMappingEntity); clusterDAO.merge(clusterEntity); } @@ -762,11 +757,7 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog { List<ClusterEntity> clusterEntities = clusterDAO.findAll(); for (ClusterEntity clusterEntity : clusterEntities) { Long clusterId = clusterEntity.getClusterId(); - ClusterConfigEntityPK configEntityPK = new ClusterConfigEntityPK(); - configEntityPK.setClusterId(clusterId); - configEntityPK.setType("hdfs-exclude-file"); - configEntityPK.setTag(value.trim()); - ClusterConfigEntity configEntity = clusterDAO.findConfig(configEntityPK); + ClusterConfigEntity configEntity = clusterDAO.findConfig(clusterId, "hdfs-exclude-file", value.trim()); if (configEntity != null) { String configData = configEntity.getData(); if (configData != null) { http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/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 cf51a49..3777b75 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -27,7 +27,10 @@ delimiter ; # USE @schema; CREATE TABLE clusters (cluster_id BIGINT NOT NULL, cluster_info VARCHAR(255) NOT NULL, cluster_name VARCHAR(100) NOT NULL UNIQUE, provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT', desired_cluster_state VARCHAR(255) NOT NULL, desired_stack_version VARCHAR(255) NOT NULL, PRIMARY KEY (cluster_id)); -CREATE TABLE clusterconfig (version_tag VARCHAR(255) NOT NULL, type_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, config_data LONGTEXT NOT NULL, config_attributes LONGTEXT, create_timestamp BIGINT NOT NULL, PRIMARY KEY (version_tag, type_name, cluster_id)); +CREATE TABLE clusterconfig (config_id BIGINT NOT NULL, version_tag VARCHAR(255) NOT NULL, type_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, config_data LONGTEXT NOT NULL, config_attributes LONGTEXT, create_timestamp BIGINT NOT NULL, PRIMARY KEY (config_id)); +CREATE TABLE serviceconfig (service_config_id BIGINT NOT NULL, cluster_id BIGINT NOT NULL, service_name VARCHAR(255) NOT NULL, version BIGINT NOT NULL, create_timestamp BIGINT NOT NULL, PRIMARY KEY (service_config_id)); +CREATE TABLE serviceconfigmapping (service_config_id BIGINT NOT NULL, config_id BIGINT NOT NULL, PRIMARY KEY(service_config_id, config_id)); +CREATE TABLE serviceconfigapplication (apply_id BIGINT NOT NULL, service_config_id BIGINT NOT NULL, apply_timestamp BIGINT NOT NULL, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY(apply_id)); CREATE TABLE clusterservices (service_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, service_enabled INTEGER NOT NULL, PRIMARY KEY (service_name, cluster_id)); CREATE TABLE clusterstate (cluster_id BIGINT NOT NULL, current_cluster_state VARCHAR(255) NOT NULL, current_stack_version VARCHAR(255) NOT NULL, PRIMARY KEY (cluster_id)); CREATE TABLE hostcomponentdesiredstate (cluster_id BIGINT NOT NULL, component_name VARCHAR(255) NOT NULL, desired_stack_version VARCHAR(255) NOT NULL, desired_state VARCHAR(255) NOT NULL, host_name VARCHAR(255) NOT NULL, service_name VARCHAR(255) NOT NULL, admin_state VARCHAR(32), maintenance_state VARCHAR(32) NOT NULL DEFAULT 'ACTIVE', restart_required TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY (cluster_id, component_name, host_name, service_name)); @@ -137,6 +140,12 @@ ALTER TABLE viewinstance ADD CONSTRAINT FK_viewinstance_resource_id FOREIGN KEY ALTER TABLE adminprivilege ADD CONSTRAINT FK_privilege_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); +ALTER TABLE clusterconfig ADD CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag); +ALTER TABLE clusterconfig ADD CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version); +ALTER TABLE serviceconfig ADD CONSTRAINT UQ_scv_service_version UNIQUE (cluster_id, service_name, version); +ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); +ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id); +ALTER TABLE serviceconfigapplication ADD CONSTRAINT FK_scva_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); INSERT INTO ambari_sequences(sequence_name, value) values ('cluster_id_seq', 1); @@ -156,6 +165,9 @@ INSERT INTO ambari_sequences(sequence_name, value) values ('principal_type_id_se INSERT INTO ambari_sequences(sequence_name, value) values ('principal_id_seq', 2); INSERT INTO ambari_sequences(sequence_name, value) values ('permission_id_seq', 5); INSERT INTO ambari_sequences(sequence_name, value) values ('privilege_id_seq', 1); +INSERT INTO ambari_sequences(sequence_name, value) values ('config_id_seq', 1); +INSERT INTO ambari_sequences(sequence_name, value) values ('service_config_id_seq', 1); +INSERT INTO ambari_sequences(sequence_name, value) values ('service_config_application_id_seq', 1); insert into adminresourcetype (resource_type_id, resource_type_name) select 1, 'AMBARI' http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/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 c05affd..1db44bc 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -17,7 +17,10 @@ -- CREATE TABLE clusters (cluster_id NUMBER(19) NOT NULL, cluster_info VARCHAR2(255) NULL, cluster_name VARCHAR2(100) NOT NULL UNIQUE, provisioning_state VARCHAR2(255) DEFAULT 'INIT' NOT NULL, desired_cluster_state VARCHAR2(255) NULL, desired_stack_version VARCHAR2(255) NULL, PRIMARY KEY (cluster_id)); -CREATE TABLE clusterconfig (version_tag VARCHAR2(255) NOT NULL, type_name VARCHAR2(255) NOT NULL, cluster_id NUMBER(19) NOT NULL, config_data CLOB NOT NULL, config_attributes CLOB, create_timestamp NUMBER(19) NOT NULL, PRIMARY KEY (version_tag, type_name, cluster_id)); +CREATE TABLE clusterconfig (config_id NUMBER(19) NOT NULL, version_tag VARCHAR2(255) NOT NULL, type_name VARCHAR2(255) NOT NULL, cluster_id NUMBER(19) NOT NULL, config_data CLOB NOT NULL, config_attributes CLOB, create_timestamp NUMBER(19) NOT NULL, PRIMARY KEY (config_id)); +CREATE TABLE serviceconfig (service_config_id NUMBER(19) NOT NULL, cluster_id NUMBER(19) NOT NULL, service_name VARCHAR(255) NOT NULL, version NUMBER(19) NOT NULL, create_timestamp NUMBER(19) NOT NULL, PRIMARY KEY (service_config_id)); +CREATE TABLE serviceconfigmapping (service_config_id BIGINT NOT NULL, config_id BIGINT NOT NULL, PRIMARY KEY(service_config_id, config_id)); +CREATE TABLE serviceconfigapplication (apply_id NUMBER(19) NOT NULL, service_config_id NUMBER(19) NOT NULL, apply_timestamp NUMBER(19) NOT NULL, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY(apply_id)); CREATE TABLE clusterservices (service_name VARCHAR2(255) NOT NULL, cluster_id NUMBER(19) NOT NULL, service_enabled NUMBER(10) NOT NULL, PRIMARY KEY (service_name, cluster_id)); CREATE TABLE clusterstate (cluster_id NUMBER(19) NOT NULL, current_cluster_state VARCHAR2(255) NULL, current_stack_version VARCHAR2(255) NULL, PRIMARY KEY (cluster_id)); CREATE TABLE hostcomponentdesiredstate (cluster_id NUMBER(19) NOT NULL, component_name VARCHAR2(255) NOT NULL, desired_stack_version VARCHAR2(255) NULL, desired_state VARCHAR2(255) NOT NULL, host_name VARCHAR2(255) NOT NULL, service_name VARCHAR2(255) NOT NULL, admin_state VARCHAR2(32) NULL, maintenance_state VARCHAR2(32) NOT NULL, restart_required NUMBER(1) DEFAULT 0 NOT NULL, PRIMARY KEY (cluster_id, component_name, host_name, service_name)); @@ -127,6 +130,12 @@ ALTER TABLE viewinstance ADD CONSTRAINT FK_viewinstance_resource_id FOREIGN KEY ALTER TABLE adminprivilege ADD CONSTRAINT FK_privilege_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); +ALTER TABLE clusterconfig ADD CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag); +ALTER TABLE clusterconfig ADD CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version); +ALTER TABLE serviceconfig ADD CONSTRAINT UQ_scv_service_version UNIQUE (cluster_id, service_name, version); +ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); +ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id); +ALTER TABLE serviceconfigapplication ADD CONSTRAINT FK_scva_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); INSERT INTO ambari_sequences(sequence_name, value) values ('host_role_command_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, value) values ('user_id_seq', 1); @@ -145,6 +154,9 @@ INSERT INTO ambari_sequences(sequence_name, value) values ('principal_type_id_se INSERT INTO ambari_sequences(sequence_name, value) values ('principal_id_seq', 2); INSERT INTO ambari_sequences(sequence_name, value) values ('permission_id_seq', 5); INSERT INTO ambari_sequences(sequence_name, value) values ('privilege_id_seq', 1); +INSERT INTO ambari_sequences(sequence_name, value) values ('config_id_seq', 1); +INSERT INTO ambari_sequences(sequence_name, value) values ('service_config_id_seq', 1); +INSERT INTO ambari_sequences(sequence_name, value) values ('service_config_application_id_seq', 1); INSERT INTO metainfo("metainfo_key", "metainfo_value") values ('version', '${ambariVersion}'); http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/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 82335e3..1c5629e 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -19,10 +19,16 @@ ------create tables ang grant privileges to db user--------- CREATE TABLE clusters (cluster_id BIGINT NOT NULL, cluster_info VARCHAR(255) NOT NULL, cluster_name VARCHAR(100) NOT NULL UNIQUE, provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT', desired_cluster_state VARCHAR(255) NOT NULL, desired_stack_version VARCHAR(255) NOT NULL, PRIMARY KEY (cluster_id)); -CREATE TABLE clusterconfig (version_tag VARCHAR(255) NOT NULL, type_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, config_data VARCHAR(32000) NOT NULL, config_attributes VARCHAR(32000), create_timestamp BIGINT NOT NULL, PRIMARY KEY (cluster_id, type_name, version_tag)); +CREATE TABLE clusterconfig (config_id BIGINT NOT NULL, version_tag VARCHAR(255) NOT NULL, version BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, config_data VARCHAR(32000) NOT NULL, config_attributes VARCHAR(32000), create_timestamp BIGINT NOT NULL, PRIMARY KEY (config_id)); CREATE TABLE clusterconfigmapping (cluster_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, version_tag VARCHAR(255) NOT NULL, create_timestamp BIGINT NOT NULL, selected INTEGER NOT NULL DEFAULT 0, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY (cluster_id, type_name, create_timestamp)); +CREATE TABLE serviceconfig (service_config_id BIGINT NOT NULL, cluster_id BIGINT NOT NULL, service_name VARCHAR(255) NOT NULL, version BIGINT NOT NULL, create_timestamp BIGINT NOT NULL, PRIMARY KEY (service_config_id)); + +CREATE TABLE serviceconfigmapping (service_config_id BIGINT NOT NULL, config_id BIGINT NOT NULL, PRIMARY KEY(service_config_id, config_id)); + +CREATE TABLE serviceconfigapplication (apply_id BIGINT NOT NULL, service_config_id BIGINT NOT NULL, apply_timestamp BIGINT NOT NULL, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY(apply_id)); + CREATE TABLE clusterservices (service_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, service_enabled INTEGER NOT NULL, PRIMARY KEY (service_name, cluster_id)); CREATE TABLE clusterstate (cluster_id BIGINT NOT NULL, current_cluster_state VARCHAR(255) NOT NULL, current_stack_version VARCHAR(255) NOT NULL, PRIMARY KEY (cluster_id)); @@ -160,6 +166,12 @@ ALTER TABLE viewinstance ADD CONSTRAINT FK_viewinstance_resource_id FOREIGN KEY ALTER TABLE adminprivilege ADD CONSTRAINT FK_privilege_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); +ALTER TABLE clusterconfig ADD CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag); +ALTER TABLE clusterconfig ADD CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version); +ALTER TABLE serviceconfig ADD CONSTRAINT UQ_scv_service_version UNIQUE (cluster_id, service_name, version); +ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); +ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id); +ALTER TABLE serviceconfigapplication ADD CONSTRAINT FK_scva_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); -- Alerting Framework CREATE TABLE alert_definition ( @@ -307,7 +319,13 @@ BEGIN; union all select 'alert_notice_id_seq', 0 union all - select 'alert_current_id_seq', 0; + select 'alert_current_id_seq', 0 + union all + select 'config_id_seq', 1 + union all + select 'service_config_id_seq', 1 + union all + select 'service_config_application_id_seq', 1; INSERT INTO adminresourcetype (resource_type_id, resource_type_name) SELECT 1, 'AMBARI' http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/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 45b83c5..c2c29b1 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 @@ -31,12 +31,21 @@ ALTER ROLE :username SET search_path TO 'ambari'; CREATE TABLE ambari.clusters (cluster_id BIGINT NOT NULL, cluster_info VARCHAR(255) NOT NULL, cluster_name VARCHAR(100) NOT NULL UNIQUE, provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT', desired_cluster_state VARCHAR(255) NOT NULL, desired_stack_version VARCHAR(255) NOT NULL, PRIMARY KEY (cluster_id)); GRANT ALL PRIVILEGES ON TABLE ambari.clusters TO :username; -CREATE TABLE ambari.clusterconfig (version_tag VARCHAR(255) NOT NULL, type_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, config_data VARCHAR(32000) NOT NULL, config_attributes VARCHAR(32000), create_timestamp BIGINT NOT NULL, PRIMARY KEY (cluster_id, type_name, version_tag)); +CREATE TABLE ambari.clusterconfig (config_id BIGINT NOT NULL, version_tag VARCHAR(255) NOT NULL, version BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, config_data VARCHAR(32000) NOT NULL, config_attributes VARCHAR(32000), create_timestamp BIGINT NOT NULL, PRIMARY KEY (config_id)); GRANT ALL PRIVILEGES ON TABLE ambari.clusterconfig TO :username; CREATE TABLE ambari.clusterconfigmapping (cluster_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, version_tag VARCHAR(255) NOT NULL, create_timestamp BIGINT NOT NULL, selected INTEGER NOT NULL DEFAULT 0, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY (cluster_id, type_name, create_timestamp)); GRANT ALL PRIVILEGES ON TABLE ambari.clusterconfigmapping TO :username; +CREATE TABLE ambari.serviceconfig (service_config_id BIGINT NOT NULL, cluster_id BIGINT NOT NULL, service_name VARCHAR(255) NOT NULL, version BIGINT NOT NULL, create_timestamp BIGINT NOT NULL, PRIMARY KEY (service_config_id)); +GRANT ALL PRIVILEGES ON TABLE ambari.serviceconfig TO :username; + +CREATE TABLE ambari.serviceconfigmapping (service_config_id BIGINT NOT NULL, config_id BIGINT NOT NULL, PRIMARY KEY(service_config_id, config_id)); +GRANT ALL PRIVILEGES ON TABLE ambari.serviceconfigmapping TO :username; + +CREATE TABLE ambari.serviceconfigapplication (apply_id BIGINT NOT NULL, service_config_id BIGINT NOT NULL, apply_timestamp BIGINT NOT NULL, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY(apply_id)); +GRANT ALL PRIVILEGES ON TABLE ambari.serviceconfigapplication TO :username; + CREATE TABLE ambari.clusterservices (service_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, service_enabled INTEGER NOT NULL, PRIMARY KEY (service_name, cluster_id)); GRANT ALL PRIVILEGES ON TABLE ambari.clusterservices TO :username; @@ -212,6 +221,12 @@ ALTER TABLE ambari.viewinstance ADD CONSTRAINT FK_viewinst_view_name FOREIGN KEY ALTER TABLE ambari.viewinstanceproperty ADD CONSTRAINT FK_viewinstprop_view_name FOREIGN KEY (view_name, view_instance_name) REFERENCES ambari.viewinstance(view_name, name); ALTER TABLE ambari.viewinstancedata ADD CONSTRAINT FK_viewinstdata_view_name FOREIGN KEY (view_instance_id, view_name, view_instance_name) REFERENCES ambari.viewinstance(view_instance_id, view_name, name); ALTER TABLE ambari.viewentity ADD CONSTRAINT FK_viewentity_view_name FOREIGN KEY (view_name, view_instance_name) REFERENCES ambari.viewinstance(view_name, name); +ALTER TABLE ambari.clusterconfig ADD CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag); +ALTER TABLE ambari.clusterconfig ADD CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version); +ALTER TABLE ambari.serviceconfig ADD CONSTRAINT UQ_scv_service_version UNIQUE (cluster_id, service_name, version); +ALTER TABLE ambari.serviceconfigmapping ADD CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES ambari.serviceconfig(service_config_id); +ALTER TABLE ambari.serviceconfigmapping ADD CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES ambari.clusterconfig(config_id); +ALTER TABLE ambari.serviceconfigapplication ADD CONSTRAINT FK_scva_scv FOREIGN KEY (service_config_id) REFERENCES ambari.serviceconfig(service_config_id); ALTER TABLE ambari.adminresource ADD CONSTRAINT FK_resource_resource_type_id FOREIGN KEY (resource_type_id) REFERENCES ambari.adminresourcetype(resource_type_id); ALTER TABLE ambari.adminprincipal ADD CONSTRAINT FK_principal_principal_type_id FOREIGN KEY (principal_type_id) REFERENCES ambari.adminprincipaltype(principal_type_id); ALTER TABLE ambari.adminpermission ADD CONSTRAINT FK_permission_resource_type_id FOREIGN KEY (resource_type_id) REFERENCES ambari.adminresourcetype(resource_type_id); @@ -379,8 +394,14 @@ INSERT INTO ambari.ambari_sequences (sequence_name, "value") union all select 'alert_notice_id_seq', 0 union all - select 'alert_current_id_seq', 0; - + select 'alert_current_id_seq', 0 + union all + select 'config_id_seq', 1 + union all + select 'service_config_id_seq', 1 + union all + select 'service_config_application_id_seq', 1; + INSERT INTO ambari.adminresourcetype (resource_type_id, resource_type_name) SELECT 1, 'AMBARI' http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/resources/META-INF/persistence.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml index ea79c7a..3fb5ef9 100644 --- a/ambari-server/src/main/resources/META-INF/persistence.xml +++ b/ambari-server/src/main/resources/META-INF/persistence.xml @@ -68,6 +68,8 @@ <class>org.apache.ambari.server.orm.entities.PrincipalEntity</class> <class>org.apache.ambari.server.orm.entities.PermissionEntity</class> <class>org.apache.ambari.server.orm.entities.PrivilegeEntity</class> + <class>org.apache.ambari.server.orm.entities.ServiceConfigEntity</class> + <class>org.apache.ambari.server.orm.entities.ServiceConfigApplicationEntity</class> <properties> <!--<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost/ambari" />--> http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/resources/key_properties.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/key_properties.json b/ambari-server/src/main/resources/key_properties.json index 4e9c379..3c63ccb 100644 --- a/ambari-server/src/main/resources/key_properties.json +++ b/ambari-server/src/main/resources/key_properties.json @@ -26,6 +26,10 @@ "Cluster": "Config/cluster_name", "Configuration": "Config/type" }, + "ServiceConfigVersion" : { + "Cluster" : "cluster_name", + "ServiceConfigVersion" : "service_name" + }, "Action": { "Action": "Actions/action_name" }, http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/main/resources/properties.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json index 237f646..697a44c 100644 --- a/ambari-server/src/main/resources/properties.json +++ b/ambari-server/src/main/resources/properties.json @@ -6,6 +6,7 @@ "Clusters/version", "Clusters/state", "Clusters/desired_configs", + "Clusters/desired_serviceconfigversions", "Clusters/total_hosts", "Clusters/health_report", "_" @@ -81,7 +82,16 @@ "Configuration":[ "Config/tag", "Config/type", - "Config/cluster_name" + "Config/cluster_name", + "Config/version" + ], + "ServiceConfigVersion":[ + "ServiceConfigVersion/cluster_name", + "ServiceConfigVersion/service_name", + "ServiceConfigVersion/serviceconfigversion", + "ServiceConfigVersion/createtime", + "ServiceConfigVersion/appliedtime", + "ServiceConfigVersion/user" ], "ConfigGroup": [ "ConfigGroup/id", http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java index bcac30a..b19d1c0 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperTest.java @@ -129,22 +129,22 @@ public class ExecutionCommandWrapperTest { //Cluster level global config Config globalConfig = configFactory.createNew(cluster1, GLOBAL_CONFIG, GLOBAL_CLUSTER, CONFIG_ATTRIBUTES); - globalConfig.setVersionTag(CLUSTER_VERSION_TAG); + globalConfig.setTag(CLUSTER_VERSION_TAG); cluster1.addConfig(globalConfig); //Cluster level service config Config serviceSiteConfigCluster = configFactory.createNew(cluster1, SERVICE_SITE_CONFIG, SERVICE_SITE_CLUSTER, CONFIG_ATTRIBUTES); - serviceSiteConfigCluster.setVersionTag(CLUSTER_VERSION_TAG); + serviceSiteConfigCluster.setTag(CLUSTER_VERSION_TAG); cluster1.addConfig(serviceSiteConfigCluster); //Service level service config Config serviceSiteConfigService = configFactory.createNew(cluster1, SERVICE_SITE_CONFIG, SERVICE_SITE_SERVICE, CONFIG_ATTRIBUTES); - serviceSiteConfigService.setVersionTag(SERVICE_VERSION_TAG); + serviceSiteConfigService.setTag(SERVICE_VERSION_TAG); cluster1.addConfig(serviceSiteConfigService); //Host level service config Config serviceSiteConfigHost = configFactory.createNew(cluster1, SERVICE_SITE_CONFIG, SERVICE_SITE_HOST, CONFIG_ATTRIBUTES); - serviceSiteConfigHost.setVersionTag(HOST_VERSION_TAG); + serviceSiteConfigHost.setTag(HOST_VERSION_TAG); cluster1.addConfig(serviceSiteConfigHost); ActionDBAccessor db = injector.getInstance(ActionDBAccessorImpl.class); http://git-wip-us.apache.org/repos/asf/ambari/blob/ce402002/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java index e860c8e..8ec1ed8 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java @@ -125,7 +125,7 @@ public class TestHeartbeatMonitor { ConfigFactory configFactory = injector.getInstance(ConfigFactory.class); Config config = configFactory.createNew(cluster, "hadoop-env", new HashMap<String,String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>()); - config.setVersionTag("version1"); + config.setTag("version1"); cluster.addConfig(config); cluster.addDesiredConfig("_test", config); @@ -216,7 +216,7 @@ public class TestHeartbeatMonitor { new HashMap<String, String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>()); - config.setVersionTag("version1"); + config.setTag("version1"); cluster.addConfig(config); cluster.addDesiredConfig("_test", config);