From 34cda14a302cac1bce2f31d449fb7d0dccc31663 Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Tue, 6 Mar 2018 16:00:31 +0100 Subject: [PATCH 1/8] AMBARI-23130 persist raw cluster provision request and extract stack ids on server restart (benyoka) --- .../internal/BaseClusterRequest.java | 21 +++ .../internal/ClusterResourceProvider.java | 3 +- .../internal/HostResourceProvider.java | 4 +- .../internal/ProvisionClusterRequest.java | 4 +- .../internal/ScaleClusterRequest.java | 3 +- .../orm/entities/TopologyRequestEntity.java | 18 +++ ...BlueprintBasedClusterProvisionRequest.java | 16 +-- .../server/topology/ClusterTopologyImpl.java | 10 +- .../server/topology/PersistedStateImpl.java | 19 ++- .../server/topology/TopologyRequest.java | 12 ++ .../topology/TopologyRequestFactory.java | 2 +- .../topology/TopologyRequestFactoryImpl.java | 5 +- .../server/topology/TopologyRequestUtil.java | 77 +++++++++++ .../resources/Ambari-DDL-Derby-CREATE.sql | 1 + .../resources/Ambari-DDL-Postgres-CREATE.sql | 1 + .../internal/ClusterResourceProviderTest.java | 11 +- .../internal/ProvisionClusterRequestTest.java | 34 ++--- .../internal/ScaleClusterRequestTest.java | 20 +-- .../topology/PersistedStateImplTest.java | 123 ++++++++++++++++++ .../server/topology/TopologyManagerTest.java | 2 +- .../topology/TopologyRequestUtilTest.java | 60 +++++++++ 21 files changed, 388 insertions(+), 58 deletions(-) create mode 100644 ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java create mode 100644 ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java create mode 100644 ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java index 77eafebf4bd..0d243a2f551 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java @@ -29,6 +29,7 @@ import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.utilities.ClusterControllerHelper; +import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.topology.Blueprint; import org.apache.ambari.server.topology.BlueprintFactory; import org.apache.ambari.server.topology.Configuration; @@ -36,6 +37,7 @@ import org.apache.ambari.server.topology.InvalidTopologyTemplateException; import org.apache.ambari.server.topology.SecurityConfiguration; import org.apache.ambari.server.topology.TopologyRequest; +import org.apache.ambari.server.topology.TopologyRequestUtil; /** * Provides common cluster request functionality. @@ -53,6 +55,11 @@ public abstract class BaseClusterRequest implements TopologyRequest { protected ProvisionAction provisionAction; + /** + * The raw request body. We would like to persist it. + */ + protected String rawRequestBody; + /** * cluster id */ @@ -118,6 +125,19 @@ public Map getHostGroupInfo() { return hostGroupInfoMap; } + /** + * @return the raw request body in JSON string + */ + public String getRawRequestBody() { + return rawRequestBody; + } + + @Override + public Set getStackIds() { + return TopologyRequestUtil.getStackIdsFromRequest( + TopologyRequestUtil.getPropertyMap(rawRequestBody)); + } + /** * Validate that all properties specified in the predicate are valid for the Host resource. * @@ -180,6 +200,7 @@ public SecurityConfiguration getSecurityConfiguration() { return securityConfiguration; } + /** * Get the host resource provider instance. * diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java index f03231bfac1..baf64e05e75 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java @@ -533,7 +533,8 @@ private RequestStatusResponse processBlueprintCreate(Map propert ProvisionClusterRequest createClusterRequest; try { - createClusterRequest = topologyRequestFactory.createProvisionClusterRequest(properties, securityConfiguration); + createClusterRequest = + topologyRequestFactory.createProvisionClusterRequest(rawRequestBody, properties, securityConfiguration); } catch (InvalidTopologyTemplateException e) { throw new IllegalArgumentException("Invalid Cluster Creation Template: " + e, e); } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java index 79f4233ebce..412d0c0eac2 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java @@ -1086,7 +1086,9 @@ public static String getHostNameFromProperties(Map properties) { private RequestStatusResponse submitHostRequests(Request request) throws SystemException { ScaleClusterRequest requestRequest; try { - requestRequest = new ScaleClusterRequest(request.getProperties()); + requestRequest = new ScaleClusterRequest( + request.getRequestInfoProperties().get(Request.REQUEST_INFO_BODY_PROPERTY), + request.getProperties()); } catch (InvalidTopologyTemplateException e) { throw new IllegalArgumentException("Invalid Add Hosts Template: " + e, e); } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java index 70b8ab54b34..7a5086d6b48 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java @@ -174,8 +174,10 @@ public class ProvisionClusterRequest extends BaseClusterRequest implements Provi * @param properties request properties * @param securityConfiguration security config related properties */ - public ProvisionClusterRequest(Map properties, SecurityConfiguration securityConfiguration) throws + public ProvisionClusterRequest(String rawRequestBody, Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException { + this.rawRequestBody = rawRequestBody; + setClusterName(String.valueOf(properties.get( ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID))); diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java index 5e5eec8936e..958a3d58fb7 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java @@ -51,7 +51,8 @@ public class ScaleClusterRequest extends BaseClusterRequest { * * @throws InvalidTopologyTemplateException if any validation of properties fails */ - public ScaleClusterRequest(Set> propertySet) throws InvalidTopologyTemplateException { + public ScaleClusterRequest(String rawRequestBody, Set> propertySet) throws InvalidTopologyTemplateException { + this.rawRequestBody = rawRequestBody; for (Map properties : propertySet) { // can only operate on a single cluster per logical request if (getClusterName() == null) { diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java index d28183882ed..86e8aa27af5 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java @@ -75,6 +75,10 @@ public class TopologyRequestEntity { @Column(name = "description", length = 1024, nullable = false) private String description; + @Lob + @Column(name = "raw_request_body", length = 30000, nullable = false) + private String rawRequestBody; + @OneToMany(mappedBy = "topologyRequestEntity", cascade = CascadeType.ALL) private Collection topologyHostGroupEntities; @@ -141,6 +145,20 @@ public void setDescription(String description) { this.description = description; } + /** + * @return the raw request body in JSON + */ + public String getRawRequestBody() { + return rawRequestBody; + } + + /** + * @param rawRequestBody the raw request body in JSON + */ + public void setRawRequestBody(String rawRequestBody) { + this.rawRequestBody = rawRequestBody; + } + public Collection getTopologyHostGroupEntities() { return topologyHostGroupEntities; } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintBasedClusterProvisionRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintBasedClusterProvisionRequest.java index 43f372457ed..22d4bab2e07 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintBasedClusterProvisionRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintBasedClusterProvisionRequest.java @@ -24,7 +24,6 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; -import java.util.stream.Stream; import javax.annotation.Nonnull; @@ -37,7 +36,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; @@ -52,7 +50,7 @@ public class BlueprintBasedClusterProvisionRequest implements Blueprint, Provisi private final ProvisionClusterRequest request; private final Set stackIds; private final StackDefinition stack; - private final Map mpacks; + private final Set mpacks; private final SecurityConfiguration securityConfiguration; public BlueprintBasedClusterProvisionRequest(AmbariContext ambariContext, SecurityConfigurationFactory securityConfigurationFactory, Blueprint blueprint, ProvisionClusterRequest request) { @@ -61,9 +59,9 @@ public BlueprintBasedClusterProvisionRequest(AmbariContext ambariContext, Securi stackIds = ImmutableSet.copyOf(Sets.union(blueprint.getStackIds(), request.getStackIds())); stack = ambariContext.composeStacks(stackIds); - mpacks = ImmutableMap.copyOf( - Stream.concat(blueprint.getMpacks().stream(), request.getMpacks().stream()) - .collect(toMap(MpackInstance::getMpackName, Function.identity()))); + mpacks = ImmutableSet.builder(). + addAll(blueprint.getMpacks()). + addAll(request.getMpacks()).build(); securityConfiguration = processSecurityConfiguration(securityConfigurationFactory); @@ -104,7 +102,7 @@ public Set getStackIds() { @Override public Collection getMpacks() { - return mpacks.values(); + return mpacks; } @Override @@ -166,7 +164,7 @@ public StackDefinition getStack() { public Map> getServicesByMpack() { Map> result = new HashMap<>(); - for (MpackInstance mpack : mpacks.values()) { + for (MpackInstance mpack : mpacks) { Map services = mpack.getServiceInstances().stream() .collect(toMap(ServiceInstance::getName, Function.identity())); result.put(mpack.getMpackName(), services); @@ -179,7 +177,7 @@ public Map> getServicesByMpack() { * whose name is unique across all mpacks. */ public Map getUniqueServices() { - Map map = mpacks.values().stream() + Map map = mpacks.stream() .flatMap(mpack -> mpack.getServiceInstances().stream()) .collect(toMap(ServiceInstance::getName, Function.identity(), (s1, s2) -> null)); map.entrySet().removeIf(e -> e.getValue() == null); // remove non-unique names mapped to null diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java index 95814579f19..1ea1101d0fb 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java @@ -46,6 +46,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; /** * Represents a cluster topology. @@ -68,18 +69,21 @@ public class ClusterTopologyImpl implements ClusterTopology { private final BlueprintBasedClusterProvisionRequest provisionRequest; private final String defaultPassword; private final Map> resolvedComponents; + private final Setting setting; public ClusterTopologyImpl(AmbariContext ambariContext, TopologyRequest topologyRequest) throws InvalidTopologyException { this.ambariContext = ambariContext; this.clusterId = topologyRequest.getClusterId(); this.blueprint = topologyRequest.getBlueprint(); + this.setting = blueprint.getSetting(); this.configuration = topologyRequest.getConfiguration(); configRecommendationStrategy = ConfigRecommendationStrategy.NEVER_APPLY; provisionAction = topologyRequest instanceof BaseClusterRequest ? ((BaseClusterRequest) topologyRequest).getProvisionAction() : INSTALL_AND_START; // FIXME provisionRequest = null; defaultPassword = null; - stackIds = topologyRequest.getBlueprint().getStackIds(); + stackIds = ImmutableSet.copyOf( + Sets.union(topologyRequest.getStackIds(), topologyRequest.getBlueprint().getStackIds())); stack = ambariContext.composeStacks(stackIds); resolvedComponents = ImmutableMap.of(); @@ -104,7 +108,7 @@ public ClusterTopologyImpl( defaultPassword = provisionRequest.getDefaultPassword(); stackIds = request.getStackIds(); stack = request.getStack(); - + setting = request.getSetting(); blueprint.getConfiguration().setParentConfiguration(stack.getConfiguration(getServices())); registerHostGroupInfo(request.getHostGroupInfo()); } @@ -150,7 +154,7 @@ public Configuration getConfiguration() { @Override public Setting getSetting() { - return provisionRequest.getSetting(); + return setting; } @Override diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java index 13c9eff95e6..ae70db467de 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java @@ -23,7 +23,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import javax.inject.Inject; import javax.inject.Singleton; import org.apache.ambari.server.AmbariException; @@ -50,12 +52,12 @@ import org.apache.ambari.server.orm.entities.TopologyRequestEntity; import org.apache.ambari.server.stack.NoSuchStackException; import org.apache.ambari.server.state.Host; +import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.topology.tasks.TopologyTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; -import com.google.inject.Inject; import com.google.inject.persist.Transactional; /** @@ -91,9 +93,6 @@ public class PersistedStateImpl implements PersistedState { @Inject private HostRoleCommandDAO hostRoleCommandDAO; - @Inject - private HostRoleCommandDAO physicalTaskDAO; - @Inject private BlueprintFactory blueprintFactory; @@ -255,6 +254,8 @@ public Map> getAllRequests() { private TopologyRequestEntity toEntity(BaseClusterRequest request) { TopologyRequestEntity entity = new TopologyRequestEntity(); + entity.setRawRequestBody(request.getRawRequestBody()); + //todo: this isn't set for a scaling operation because we had intended to allow multiple //todo: bp's to be used to scale a cluster although this isn't currently supported by //todo: new topology infrastructure @@ -330,7 +331,7 @@ private TopologyHostRequestEntity toEntity(HostRequest request, TopologyLogicalR logicalTaskEntity.setTopologyHostTaskEntity(topologyTaskEntity); Long physicalId = request.getPhysicalTaskId(logicalTaskId); if (physicalId != null) { - logicalTaskEntity.setHostRoleCommandEntity(physicalTaskDAO.findByPK(physicalId)); + logicalTaskEntity.setHostRoleCommandEntity(hostRoleCommandDAO.findByPK(physicalId)); } logicalTaskEntity.setTopologyHostTaskEntity(topologyTaskEntity); } @@ -391,6 +392,7 @@ private static class ReplayedTopologyRequest implements TopologyRequest { private final Configuration configuration; private final Map hostGroupInfoMap = new HashMap<>(); private final ProvisionAction provisionAction; + private final Set stackIds; public ReplayedTopologyRequest(TopologyRequestEntity entity, BlueprintFactory blueprintFactory) { clusterId = entity.getClusterId(); @@ -398,6 +400,8 @@ public ReplayedTopologyRequest(TopologyRequestEntity entity, BlueprintFactory bl description = entity.getDescription(); provisionAction = entity.getProvisionAction(); + stackIds = TopologyRequestUtil.getStackIdsFromRequest(entity.getRawRequestBody()); + try { blueprint = blueprintFactory.getBlueprint(entity.getBlueprintName()); } catch (NoSuchStackException e) { @@ -409,6 +413,11 @@ public ReplayedTopologyRequest(TopologyRequestEntity entity, BlueprintFactory bl parseHostGroupInfo(entity); } + @Override + public Set getStackIds() { + return stackIds; + } + @Override public Long getClusterId() { return clusterId; diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java index 94fcf23e3b1..ffdf1c79ef5 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java @@ -18,7 +18,12 @@ package org.apache.ambari.server.topology; +import static java.util.Collections.emptySet; + import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.state.StackId; /** * A request which is used to create or modify a cluster topology. @@ -70,4 +75,11 @@ enum Type { PROVISION, SCALE, EXPORT } * @return string description of the request */ String getDescription(); + + /** + * @return a set of stack id's if supported by the TopologyRequest. + */ + default Set getStackIds() { + return emptySet(); + } } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java index 751e2d7a851..136be393d48 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java @@ -28,6 +28,6 @@ */ public interface TopologyRequestFactory { - ProvisionClusterRequest createProvisionClusterRequest(Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException; + ProvisionClusterRequest createProvisionClusterRequest(String rawRequestBody, Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException; // todo: use to create other request types } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java index 44f0d1f02ac..50d3fa1226e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java @@ -29,8 +29,7 @@ public class TopologyRequestFactoryImpl implements TopologyRequestFactory { @Override - public ProvisionClusterRequest createProvisionClusterRequest(Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException { - return new ProvisionClusterRequest(properties, securityConfiguration); - + public ProvisionClusterRequest createProvisionClusterRequest(String rawRequestBody, Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException { + return new ProvisionClusterRequest(rawRequestBody, properties, securityConfiguration); } } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java new file mode 100644 index 00000000000..99d7a83c241 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java @@ -0,0 +1,77 @@ +/* + * 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.topology; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Collections.emptyMap; +import static java.util.stream.Collectors.toSet; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.state.StackId; +import org.apache.ambari.server.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class TopologyRequestUtil { + + private static final Logger LOG = LoggerFactory.getLogger(TopologyRequestUtil.class); + public static final String NAME = "name"; + public static final String VERSION = "version"; + + + /** + * @param rawRequestJson The topology request in raw JSON format. Null input is handled gracefully. + * @return a Set of stack id's contained in the request + */ + public static Set getStackIdsFromRequest(String rawRequestJson) { + return getStackIdsFromRequest(getPropertyMap(rawRequestJson)); + } + + + /** + * @param rawRequestMap The topology request in raw JSON format. Null input is handled gracefully. + * @return a Set of stack id's contained in the request + */ + public static Set getStackIdsFromRequest(Map rawRequestMap) { + return rawRequestMap.entrySet().stream(). + filter(e -> "mpack_instances".equals(e.getKey())). + flatMap(e -> ((List>) e.getValue()).stream()). + map(m -> { + checkArgument(m.containsKey(NAME), "Missing mpack name"); + checkArgument(m.containsKey(VERSION), "Missing mpack version"); + return new StackId(m.get(NAME), m.get(VERSION)); + }). + collect(toSet()); + } + + /** + * @param rawRequestJson The topology request in raw JSON format. Null input is handled gracefully. + * @return the request body parsed as map (null is parsed as empty map) + */ + public static Map getPropertyMap(String rawRequestJson) { + return null == rawRequestJson ? + emptyMap() : + JsonUtils.fromJson(rawRequestJson, new TypeReference>() {}); + } +} diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql index c2f83e6755a..1c8dc5fbcaf 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql @@ -874,6 +874,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, + raw_request_body CLOB NOT NULL, cluster_properties VARCHAR(3000), cluster_attributes VARCHAR(3000), description VARCHAR(1024), 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 b3c50070f03..a0996d3adad 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -875,6 +875,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, + raw_request_body TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java index 5e1ba49baab..06d95bd660d 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java @@ -20,6 +20,7 @@ import static org.easymock.EasyMock.anyBoolean; import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.anyString; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; @@ -154,7 +155,7 @@ public void testCreateResource_blueprint_With_ProvisionAction() throws Exception expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null) .once(); - expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest("{}", properties, null)).andReturn(topologyRequest).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes(); @@ -184,7 +185,7 @@ public void testCreateResource_blueprint_withSecurityConfiguration() throws Exce expect(request.getProperties()).andReturn(requestProperties).anyTimes(); expect(request.getRequestInfoProperties()).andReturn(requestInfoProperties).anyTimes(); - expect(topologyFactory.createProvisionClusterRequest(properties, securityConfiguration)).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest(anyString(), eq(properties), eq(securityConfiguration))).andReturn(topologyRequest).once(); expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn (securityConfiguration).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); @@ -208,7 +209,7 @@ public void testCreateResource_blueprint__InvalidRequest() throws Exception { // set expectations expect(request.getProperties()).andReturn(requestProperties).anyTimes(); // throw exception from topology request factory an assert that the correct exception is thrown from resource provider - expect(topologyFactory.createProvisionClusterRequest(properties, null)).andThrow(new InvalidTopologyException + expect(topologyFactory.createProvisionClusterRequest(null, properties, null)).andThrow(new InvalidTopologyException ("test")); replayAll(); @@ -472,7 +473,7 @@ private void testCreateResource_blueprint(Authentication authentication) throws expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null) .once(); - expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest(anyString(), eq(properties), anyObject())).andReturn(topologyRequest).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes(); @@ -803,7 +804,7 @@ public void testCreateResource_blueprint_withRepoVersion() throws Exception { expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null) .once(); - expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest("{}", properties, null)).andReturn(topologyRequest).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes(); diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java index 5ed582f5c3b..3cc48905829 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java @@ -109,7 +109,7 @@ public void testHostNameSpecified() throws Exception { replay(hostResourceProvider); Map properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -160,7 +160,7 @@ public void testHostCountSpecified() throws Exception { replay(hostResourceProvider); Map properties = createBlueprintRequestPropertiesCountOnly(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -211,7 +211,7 @@ public void testHostCountSpecified() throws Exception { @Test public void testMultipleGroups() throws Exception { Map properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -286,7 +286,7 @@ public void test_NoHostGroupInfo() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(properties, null); + new ProvisionClusterRequest(null, properties, null); } @Test @@ -301,7 +301,7 @@ public void test_Creditentials() throws Exception { credentialsSet.add(credentialHashMap); properties.put("credentials", credentialsSet); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getAlias(), "testAlias"); assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getPrincipal(), "testPrincipal"); @@ -326,7 +326,7 @@ public void test_CreditentialsInvalidType() throws Exception { credentialsSet.add(credentialHashMap); properties.put("credentials", credentialsSet); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); } @Test(expected= InvalidTopologyTemplateException.class) @@ -338,7 +338,7 @@ public void test_GroupInfoMissingName() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(properties, null); + new ProvisionClusterRequest(null, properties, null); } @Test(expected= InvalidTopologyTemplateException.class) @@ -350,7 +350,7 @@ public void test_NoHostsInfo() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(properties, null); + new ProvisionClusterRequest(null, properties, null); } @Test(expected = InvalidTopologyTemplateException.class) @@ -370,7 +370,7 @@ public void test_NoHostNameOrHostCount() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(properties, null); + new ProvisionClusterRequest(null, properties, null); } @@ -383,7 +383,7 @@ public void testInvalidPredicateProperty() throws Exception { replay(hostResourceProvider); // should result in an exception due to invalid property in host predicate - new ProvisionClusterRequest(createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME), null); + new ProvisionClusterRequest(null, createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME), null); } @Test(expected = InvalidTopologyTemplateException.class) @@ -395,7 +395,7 @@ public void testHostNameAndCountSpecified() throws Exception { Map properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_count", "5"); // should result in an exception due to both host name and host count being specified - new ProvisionClusterRequest(properties, null); + new ProvisionClusterRequest(null, properties, null); } @Test(expected = InvalidTopologyTemplateException.class) @@ -407,13 +407,13 @@ public void testHostNameAndPredicateSpecified() throws Exception { Map properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_predicate", "Hosts/host_name=myTestHost"); // should result in an exception due to both host name and host count being specified - new ProvisionClusterRequest(properties, null); + new ProvisionClusterRequest(null, properties, null); } @Test public void testQuickLinksProfile_NoDataInRequest() throws Exception { Map properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); assertNull("No quick links profile is expected", request.getQuickLinksProfileJson()); } @@ -424,7 +424,7 @@ public void testQuickLinksProfile_OnlyGlobalFilterDataInRequest() throws Excepti properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_FILTERS_PROPERTY, Sets.newHashSet(QuickLinksProfileBuilderTest.filter(null, null, true))); - ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[{\"visible\":true}],\"services\":[]}", request.getQuickLinksProfileJson()); @@ -439,7 +439,7 @@ public void testQuickLinksProfile_OnlyServiceFilterDataInRequest() throws Except Set> services = Sets.newHashSet(hdfs); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services); - ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}", request.getQuickLinksProfileJson()); @@ -457,7 +457,7 @@ public void testQuickLinksProfile_BothGlobalAndServiceLevelFilters() throws Exce Set> services = Sets.newHashSet(hdfs); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services); - ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); System.out.println(request.getQuickLinksProfileJson()); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[{\"visible\":true}],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}", @@ -470,7 +470,7 @@ public void testQuickLinksProfile_InvalidRequestData() throws Exception { properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, "Hello World!"); - ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); } public static Map createBlueprintRequestProperties(String clusterName, String blueprintName) { diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java index b9f32a03f67..cc02db4e5c0 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java @@ -112,7 +112,7 @@ private void addSingleHostByName(Map props) throws InvalidTopolo reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton(props)); + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton(props)); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); assertEquals(String.format("Scale Cluster '%s' (+%s hosts)", CLUSTER_NAME, "1"), @@ -150,7 +150,7 @@ private void addMultipleHostsByName(Set> propertySet) throws reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(propertySet); + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", propertySet); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); assertEquals(String.format("Scale Cluster '%s' (+%s hosts)", CLUSTER_NAME, "2"), @@ -177,7 +177,7 @@ public void test_basic_hostCount() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton( + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton( createScaleClusterPropertiesGroup1_HostCount(CLUSTER_NAME, BLUEPRINT_NAME))); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); @@ -203,7 +203,7 @@ public void test_basic_hostCount2() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton( + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton( createScaleClusterPropertiesGroup1_HostCount2(CLUSTER_NAME, BLUEPRINT_NAME))); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); @@ -225,7 +225,7 @@ public void test_basic_hostCount2() throws Exception { @Test public void test_basic_hostCountAndPredicate() throws Exception { - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton( + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton( createScaleClusterPropertiesGroup1_HostCountAndPredicate(CLUSTER_NAME, BLUEPRINT_NAME))); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); @@ -252,7 +252,7 @@ public void testMultipleHostGroups() throws Exception { propertySet.add(createScaleClusterPropertiesGroup1_HostCount(CLUSTER_NAME, BLUEPRINT_NAME)); propertySet.add(createScaleClusterPropertiesGroup1_HostName(CLUSTER_NAME, BLUEPRINT_NAME)); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(propertySet); + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", propertySet); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); assertEquals(String.format("Scale Cluster '%s' (+%s hosts)", CLUSTER_NAME, "3"), @@ -300,7 +300,7 @@ public void test_GroupInfoMissingName() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ScaleClusterRequest(Collections.singleton(properties)); + new ScaleClusterRequest("{}", Collections.singleton(properties)); } @Test(expected = InvalidTopologyTemplateException.class) @@ -313,7 +313,7 @@ public void test_NoHostNameOrHostCount() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception because neither host name or host count are specified - new ScaleClusterRequest(Collections.singleton(properties)); + new ScaleClusterRequest("{}", Collections.singleton(properties)); } @@ -326,7 +326,7 @@ public void testInvalidPredicateProperty() throws Exception { replay(hostResourceProvider); // should result in an exception due to invalid property in host predicate - new ScaleClusterRequest(Collections.singleton( + new ScaleClusterRequest("{}", Collections.singleton( createScaleClusterPropertiesGroup1_HostCountAndPredicate(CLUSTER_NAME, BLUEPRINT_NAME))); } @@ -340,7 +340,7 @@ public void testMultipleBlueprints() throws Exception { propertySet.add(createScaleClusterPropertiesGroup1_HostName2(CLUSTER_NAME, "OTHER_BLUEPRINT")); // should result in an exception due to different blueprints being specified - new ScaleClusterRequest(propertySet); + new ScaleClusterRequest("{}", propertySet); } public static Map createScaleClusterPropertiesGroup1_HostName(String clusterName, String blueprintName) { diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java new file mode 100644 index 00000000000..7f6ee4b169a --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java @@ -0,0 +1,123 @@ +/* + * 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.topology; + + +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.newCapture; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reset; +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.Field; + +import org.apache.ambari.server.controller.internal.BaseClusterRequest; +import org.apache.ambari.server.controller.internal.ProvisionAction; +import org.apache.ambari.server.controller.internal.ProvisionClusterRequest; +import org.apache.ambari.server.orm.dao.TopologyRequestDAO; +import org.apache.ambari.server.orm.entities.TopologyRequestEntity; +import org.easymock.Capture; +import org.easymock.EasyMockRunner; +import org.easymock.Mock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.google.common.collect.ImmutableMap; + + +@RunWith(EasyMockRunner.class) +public class PersistedStateImplTest { + + private static final String CLUSTER_REQUEST = + "{'blueprint': 'bp', 'host_groups': [{'name': 'group','host_count': '1' }]}".replace('\'', '"'); + + private static final String BLUEPRINT_NAME = "bp"; + + @Mock + private TopologyRequestDAO topologyRequestDAO; + + @Mock + private BlueprintFactory blueprintFactory; + + @Mock + private Blueprint blueprint; + + @Mock + private ProvisionClusterRequest + request; + + private PersistedStateImpl persistedState; + + @Before + public void init() throws Exception { + expect(blueprint.getName()).andReturn(BLUEPRINT_NAME).anyTimes(); + expect(blueprint.getConfiguration()).andReturn(new Configuration()).anyTimes(); + expect(blueprintFactory.getBlueprint(BLUEPRINT_NAME)).andReturn(blueprint).anyTimes(); + + expect(request.getBlueprint()).andReturn(blueprint).anyTimes(); + expect(request.getRawRequestBody()).andReturn(CLUSTER_REQUEST).anyTimes(); + expect(request.getType()).andReturn(TopologyRequest.Type.PROVISION).anyTimes(); + expect(request.getConfiguration()).andReturn(new Configuration()).anyTimes(); + expect(request.getClusterId()).andReturn(1L).anyTimes(); + expect(request.getDescription()).andReturn("").anyTimes(); + expect(request.getProvisionAction()).andReturn(ProvisionAction.INSTALL_AND_START).anyTimes(); + HostGroupInfo hostGroupInfo = new HostGroupInfo("hostgroup1"); + hostGroupInfo.setConfiguration(new Configuration()); + expect(request.getHostGroupInfo()).andReturn(ImmutableMap.of("hostgroup1", hostGroupInfo)).anyTimes(); + + replay(blueprint, blueprintFactory, request); + + Field blueprintFactoryField = BaseClusterRequest.class.getDeclaredField("blueprintFactory"); + blueprintFactoryField.setAccessible(true); + blueprintFactoryField.set(null, blueprintFactory); + + persistedState = new PersistedStateImpl(); + Field topologyRequestDAOField = PersistedStateImpl.class.getDeclaredField("topologyRequestDAO"); + topologyRequestDAOField.setAccessible(true); + topologyRequestDAOField.set(persistedState, topologyRequestDAO); + } + + @After + public void tearDown() { + reset(topologyRequestDAO, blueprintFactory, blueprint, request); + } + + @Test + public void testPersistTopologyRequest_RawRequestIsSaved() throws Exception { + // Given + Capture entityCapture = newCapture(); + topologyRequestDAO.create(capture(entityCapture)); + expectLastCall().andAnswer(() -> { + entityCapture.getValue().setId(1L); + return null; + }); + replay(topologyRequestDAO); + + // When + persistedState.persistTopologyRequest(request); + + // Then + assertEquals(CLUSTER_REQUEST, entityCapture.getValue().getRawRequestBody()); + } + +} \ No newline at end of file diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java index 9f3a1f04825..89f2f4f7f62 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java @@ -584,7 +584,7 @@ public void testScaleHosts__alreadyExistingHost() throws InvalidTopologyTemplate expect(persistedState.getAllRequests()).andReturn(Collections.emptyMap()).anyTimes(); replayAll(); topologyManager.provisionCluster(request); - topologyManager.scaleHosts(new ScaleClusterRequest(propertySet)); + topologyManager.scaleHosts(new ScaleClusterRequest("{}", propertySet)); Assert.fail("InvalidTopologyException should have been thrown"); } diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java new file mode 100644 index 00000000000..db4046ac277 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java @@ -0,0 +1,60 @@ +/* + * 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.topology; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.apache.ambari.server.state.StackId; +import org.junit.Test; + +import com.google.common.collect.ImmutableSet; + +public class TopologyRequestUtilTest { + + private static final String REQUEST_WITH_MPACK_INSTANCES = + "{ 'mpack_instances' : [ {'name': 'HDPCORE', 'version': '1.0.0-b98'}, {'name': 'EDW', 'version': '1.0.0'} ] }".replace('\'', '"'); + + private static final String REQUEST_WITH_INVALID_MPACK_INSTANCE = + "{ 'mpack_instances' : [ {'name': 'HDPCORE', 'version': '1.0.0-b98'}, {'name': 'EDW'} ] }".replace('\'', '"'); + + private static final String REQUEST_WITHOUT_MPACK_INSTANCE = "{}"; + + + @Test + public void testGetStackIdsFromRawRequest_normalCase() { + assertEquals( + ImmutableSet.of(new StackId("HDPCORE", "1.0.0-b98"), new StackId("EDW", "1.0.0")), + TopologyRequestUtil.getStackIdsFromRequest(REQUEST_WITH_MPACK_INSTANCES)); + } + + @Test + public void testGetStackIdsFromRawRequest_noMpackInstances() { + assertEquals( + Collections.emptySet(), + TopologyRequestUtil.getStackIdsFromRequest(REQUEST_WITHOUT_MPACK_INSTANCE)); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetStackIdsFromRawRequest_wrongMpackInstance() { + TopologyRequestUtil.getStackIdsFromRequest(REQUEST_WITH_INVALID_MPACK_INSTANCE); + } + +} \ No newline at end of file From 2e8c8bfce0fe590accc821fc76e4af6cde996f38 Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Tue, 6 Mar 2018 16:58:15 +0100 Subject: [PATCH 2/8] AMBARI-23130 add columnt to other DDLs + fix DDLs (benyoka) --- .../src/main/resources/Ambari-DDL-MySQL-CREATE.sql | 1 + .../src/main/resources/Ambari-DDL-Oracle-CREATE.sql | 7 ++++--- .../src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 1 + .../src/main/resources/Ambari-DDL-SQLServer-CREATE.sql | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) 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 1ca41884288..852024e66e9 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -904,6 +904,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, + raw_request_body LONGTEXT NOT NULL, cluster_properties LONGTEXT, cluster_attributes LONGTEXT, description VARCHAR(1024), 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 975d0202d46..29b0376f8f7 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -136,7 +136,8 @@ CREATE TABLE servicegroups ( stack_id NUMBER(19) NOT NULL, CONSTRAINT PK_servicegroups PRIMARY KEY (id, cluster_id), CONSTRAINT FK_servicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id), - CONSTRAINT FK_servicegroups_stack_id FOREIGN KEY (stack_id) REFERENCES stack (stack_id)); + CONSTRAINT FK_servicegroups_stack_id FOREIGN KEY (stack_id) REFERENCES stack (stack_id), + CONSTRAINT UQ_TEMP_UNTIL_REAL_PK UNIQUE(id)); CREATE TABLE servicegroupdependencies ( id NUMBER(19) NOT NULL, @@ -208,8 +209,7 @@ CREATE TABLE serviceconfig ( CONSTRAINT PK_serviceconfig PRIMARY KEY (service_config_id), CONSTRAINT FK_serviceconfig_stack_id FOREIGN KEY (stack_id) REFERENCES stack(stack_id), CONSTRAINT FK_serviceconfig_clstr_svc FOREIGN KEY (service_id, service_group_id, cluster_id) REFERENCES clusterservices (id, service_group_id, cluster_id), - CONSTRAINT UQ_scv_service_version UNIQUE (cluster_id, service_id, version), - CONSTRAINT UQ_TEMP_UNTIL_REAL_PK UNIQUE(id)); + CONSTRAINT UQ_scv_service_version UNIQUE (cluster_id, service_id, version) ); CREATE TABLE serviceconfighosts ( service_config_id NUMBER(19) NOT NULL, @@ -882,6 +882,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id NUMBER(19) NOT NULL, bp_name VARCHAR(100) NOT NULL, + raw_request_body CLOB NOT NULL, cluster_properties CLOB, cluster_attributes CLOB, description VARCHAR(1024), diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql index 7f0373adef5..ecab751ac7e 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql @@ -882,6 +882,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id NUMERIC(19) NOT NULL, bp_name VARCHAR(100) NOT NULL, + raw_request_body TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql index fdf6e470504..64762402a01 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql @@ -147,6 +147,7 @@ CREATE TABLE servicegroups ( id BIGINT NOT NULL, service_group_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, + stack_id BIGINT NOT NULL, CONSTRAINT PK_servicegroups PRIMARY KEY (id, cluster_id), CONSTRAINT FK_servicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id), CONSTRAINT FK_servicegroups_stack_id FOREIGN KEY (stack_id) REFERENCES stack (stack_id), @@ -904,6 +905,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, + raw_request_body TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), From 386c582c654e01fd90d4c770385830edafb355c2 Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Wed, 7 Mar 2018 10:16:19 +0100 Subject: [PATCH 3/8] AMBARI-23130 fix review findings (benyoka) --- .../orm/entities/TopologyRequestEntity.java | 2 +- .../server/topology/TopologyRequestUtil.java | 23 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java index 86e8aa27af5..d9ab181d455 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java @@ -76,7 +76,7 @@ public class TopologyRequestEntity { private String description; @Lob - @Column(name = "raw_request_body", length = 30000, nullable = false) + @Column(name = "raw_request_body", length = 100000, nullable = false) private String rawRequestBody; @OneToMany(mappedBy = "topologyRequestEntity", cascade = CascadeType.ALL) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java index 99d7a83c241..1b160a41c36 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java @@ -19,6 +19,7 @@ package org.apache.ambari.server.topology; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.stream.Collectors.toSet; @@ -28,14 +29,14 @@ import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.utils.JsonUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.type.TypeReference; +/** + * Utility functions for topology requests. + */ public class TopologyRequestUtil { - private static final Logger LOG = LoggerFactory.getLogger(TopologyRequestUtil.class); public static final String NAME = "name"; public static final String VERSION = "version"; @@ -54,15 +55,13 @@ public static Set getStackIdsFromRequest(String rawRequestJson) { * @return a Set of stack id's contained in the request */ public static Set getStackIdsFromRequest(Map rawRequestMap) { - return rawRequestMap.entrySet().stream(). - filter(e -> "mpack_instances".equals(e.getKey())). - flatMap(e -> ((List>) e.getValue()).stream()). - map(m -> { - checkArgument(m.containsKey(NAME), "Missing mpack name"); - checkArgument(m.containsKey(VERSION), "Missing mpack version"); - return new StackId(m.get(NAME), m.get(VERSION)); - }). - collect(toSet()); + List> mpackInstances = (List>) + rawRequestMap.getOrDefault("mpack_instances", emptyList()); + return mpackInstances.stream().map(m -> { + checkArgument(m.containsKey(NAME), "Missing mpack name"); + checkArgument(m.containsKey(VERSION), "Missing mpack version"); + return new StackId(m.get(NAME), m.get(VERSION)); + }).collect(toSet()); } /** From fd24060650b04ab713782a64bbbbf94ca8c31c7b Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Fri, 9 Mar 2018 13:02:33 +0100 Subject: [PATCH 4/8] AMBARI-23130 persist only mpack instances instead of the full request --- .../internal/BaseClusterRequest.java | 95 +++++++++++++---- .../internal/ClusterResourceProvider.java | 2 +- .../internal/HostResourceProvider.java | 4 +- .../internal/ProvisionClusterRequest.java | 15 ++- .../internal/ScaleClusterRequest.java | 3 +- .../orm/entities/TopologyRequestEntity.java | 16 +-- .../server/topology/BlueprintFactory.java | 5 +- .../ambari/server/topology/MpackInstance.java | 2 + .../server/topology/PersistedStateImpl.java | 88 ++------------- .../topology/TopologyRequestFactory.java | 2 +- .../topology/TopologyRequestFactoryImpl.java | 4 +- .../server/topology/TopologyRequestUtil.java | 76 ------------- .../apache/ambari/server/utils/JsonUtils.java | 16 +++ .../resources/Ambari-DDL-Derby-CREATE.sql | 2 +- .../resources/Ambari-DDL-MySQL-CREATE.sql | 2 +- .../resources/Ambari-DDL-Oracle-CREATE.sql | 2 +- .../resources/Ambari-DDL-Postgres-CREATE.sql | 2 +- .../Ambari-DDL-SQLAnywhere-CREATE.sql | 2 +- .../resources/Ambari-DDL-SQLServer-CREATE.sql | 2 +- .../internal/ClusterResourceProviderTest.java | 12 +-- .../internal/ProvisionClusterRequestTest.java | 59 ++++++++--- .../internal/ScaleClusterRequestTest.java | 20 ++-- .../topology/ClusterTopologyImplTest.java | 4 + .../topology/PersistedStateImplTest.java | 100 +++++------------- .../server/topology/TopologyManagerTest.java | 2 +- .../topology/TopologyRequestUtilTest.java | 60 ----------- 26 files changed, 223 insertions(+), 374 deletions(-) delete mode 100644 ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java delete mode 100644 ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java index 0d243a2f551..9e63914ff05 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.controller.internal; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -29,7 +31,9 @@ import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.utilities.ClusterControllerHelper; -import org.apache.ambari.server.state.StackId; +import org.apache.ambari.server.orm.entities.TopologyHostGroupEntity; +import org.apache.ambari.server.orm.entities.TopologyHostInfoEntity; +import org.apache.ambari.server.orm.entities.TopologyRequestEntity; import org.apache.ambari.server.topology.Blueprint; import org.apache.ambari.server.topology.BlueprintFactory; import org.apache.ambari.server.topology.Configuration; @@ -37,7 +41,7 @@ import org.apache.ambari.server.topology.InvalidTopologyTemplateException; import org.apache.ambari.server.topology.SecurityConfiguration; import org.apache.ambari.server.topology.TopologyRequest; -import org.apache.ambari.server.topology.TopologyRequestUtil; +import org.apache.ambari.server.utils.JsonUtils; /** * Provides common cluster request functionality. @@ -55,11 +59,6 @@ public abstract class BaseClusterRequest implements TopologyRequest { protected ProvisionAction provisionAction; - /** - * The raw request body. We would like to persist it. - */ - protected String rawRequestBody; - /** * cluster id */ @@ -125,19 +124,6 @@ public Map getHostGroupInfo() { return hostGroupInfoMap; } - /** - * @return the raw request body in JSON string - */ - public String getRawRequestBody() { - return rawRequestBody; - } - - @Override - public Set getStackIds() { - return TopologyRequestUtil.getStackIdsFromRequest( - TopologyRequestUtil.getPropertyMap(rawRequestBody)); - } - /** * Validate that all properties specified in the predicate are valid for the Host resource. * @@ -224,4 +210,73 @@ public ProvisionAction getProvisionAction() { public void setProvisionAction(ProvisionAction provisionAction) { this.provisionAction = provisionAction; } + + /** + * @return the request converted to a {@link TopologyRequestEntity} + */ + public TopologyRequestEntity toEntity() { + TopologyRequestEntity entity = new TopologyRequestEntity(); + + //todo: this isn't set for a scaling operation because we had intended to allow multiple + //todo: bp's to be used to scale a cluster although this isn't currently supported by + //todo: new topology infrastructure + entity.setAction(getType().name()); + if (getBlueprint() != null) { + entity.setBlueprintName(getBlueprint().getName()); + } + + entity.setClusterAttributes(JsonUtils.toJson(getConfiguration().getAttributes())); + entity.setClusterId(getClusterId()); + entity.setClusterProperties(JsonUtils.toJson(getConfiguration().getProperties())); + entity.setDescription(getDescription()); + + if (getProvisionAction() != null) { + entity.setProvisionAction(getProvisionAction()); + } + + // host groups + Collection hostGroupEntities = new ArrayList<>(); + for (HostGroupInfo groupInfo : getHostGroupInfo().values()) { + hostGroupEntities.add(toHostGroupEntity(groupInfo, entity)); + } + entity.setTopologyHostGroupEntities(hostGroupEntities); + + return entity; + } + + private TopologyHostGroupEntity toHostGroupEntity(HostGroupInfo groupInfo, TopologyRequestEntity topologyRequestEntity) { + TopologyHostGroupEntity entity = new TopologyHostGroupEntity(); + entity.setGroupAttributes(JsonUtils.toJson(groupInfo.getConfiguration().getAttributes())); + entity.setGroupProperties(JsonUtils.toJson(groupInfo.getConfiguration().getProperties())); + entity.setName(groupInfo.getHostGroupName()); + entity.setTopologyRequestEntity(topologyRequestEntity); + + // host info + Collection hostInfoEntities = new ArrayList<>(); + entity.setTopologyHostInfoEntities(hostInfoEntities); + + Collection hosts = groupInfo.getHostNames(); + if (hosts.isEmpty()) { + TopologyHostInfoEntity hostInfoEntity = new TopologyHostInfoEntity(); + hostInfoEntity.setTopologyHostGroupEntity(entity); + hostInfoEntity.setHostCount(groupInfo.getRequestedHostCount()); + if (groupInfo.getPredicate() != null) { + hostInfoEntity.setPredicate(groupInfo.getPredicateString()); + } + hostInfoEntities.add(hostInfoEntity); + } else { + for (String hostName : hosts) { + TopologyHostInfoEntity hostInfoEntity = new TopologyHostInfoEntity(); + hostInfoEntity.setTopologyHostGroupEntity(entity); + if (groupInfo.getPredicate() != null) { + hostInfoEntity.setPredicate(groupInfo.getPredicateString()); + } + hostInfoEntity.setFqdn(hostName); + hostInfoEntity.setRackInfo(groupInfo.getHostRackInfo().get(hostName)); + hostInfoEntity.setHostCount(0); + hostInfoEntities.add(hostInfoEntity); + } + } + return entity; + } } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java index baf64e05e75..f0dd5178c78 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java @@ -534,7 +534,7 @@ private RequestStatusResponse processBlueprintCreate(Map propert ProvisionClusterRequest createClusterRequest; try { createClusterRequest = - topologyRequestFactory.createProvisionClusterRequest(rawRequestBody, properties, securityConfiguration); + topologyRequestFactory.createProvisionClusterRequest(properties, securityConfiguration); } catch (InvalidTopologyTemplateException e) { throw new IllegalArgumentException("Invalid Cluster Creation Template: " + e, e); } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java index 18122e9941c..20146e8c874 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java @@ -1087,9 +1087,7 @@ public static String getHostNameFromProperties(Map properties) { private RequestStatusResponse submitHostRequests(Request request) throws SystemException { ScaleClusterRequest requestRequest; try { - requestRequest = new ScaleClusterRequest( - request.getRequestInfoProperties().get(Request.REQUEST_INFO_BODY_PROPERTY), - request.getProperties()); + requestRequest = new ScaleClusterRequest(request.getProperties()); } catch (InvalidTopologyTemplateException e) { throw new IllegalArgumentException("Invalid Add Hosts Template: " + e, e); } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java index 7a5086d6b48..219daf9787a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java @@ -28,6 +28,7 @@ import java.util.Set; import org.apache.ambari.server.api.predicate.InvalidQueryException; +import org.apache.ambari.server.orm.entities.TopologyRequestEntity; import org.apache.ambari.server.security.encryption.CredentialStoreType; import org.apache.ambari.server.stack.NoSuchStackException; import org.apache.ambari.server.state.SecurityType; @@ -46,6 +47,7 @@ import org.apache.ambari.server.topology.NoSuchBlueprintException; import org.apache.ambari.server.topology.ProvisionRequest; import org.apache.ambari.server.topology.SecurityConfiguration; +import org.apache.ambari.server.utils.JsonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -174,9 +176,8 @@ public class ProvisionClusterRequest extends BaseClusterRequest implements Provi * @param properties request properties * @param securityConfiguration security config related properties */ - public ProvisionClusterRequest(String rawRequestBody, Map properties, SecurityConfiguration securityConfiguration) throws - InvalidTopologyTemplateException { - this.rawRequestBody = rawRequestBody; + public ProvisionClusterRequest(Map properties, SecurityConfiguration securityConfiguration) throws + InvalidTopologyTemplateException { setClusterName(String.valueOf(properties.get( ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID))); @@ -535,4 +536,12 @@ public Set getStackIds() { public Collection getMpacks() { return mpackInstances; } + + @Override + public TopologyRequestEntity toEntity() { + TopologyRequestEntity entity = super.toEntity(); + entity.setMpackInstances(JsonUtils.toJson(mpackInstances)); + return entity; + } + } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java index 958a3d58fb7..5e5eec8936e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java @@ -51,8 +51,7 @@ public class ScaleClusterRequest extends BaseClusterRequest { * * @throws InvalidTopologyTemplateException if any validation of properties fails */ - public ScaleClusterRequest(String rawRequestBody, Set> propertySet) throws InvalidTopologyTemplateException { - this.rawRequestBody = rawRequestBody; + public ScaleClusterRequest(Set> propertySet) throws InvalidTopologyTemplateException { for (Map properties : propertySet) { // can only operate on a single cluster per logical request if (getClusterName() == null) { diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java index d9ab181d455..c90ce154154 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java @@ -76,8 +76,8 @@ public class TopologyRequestEntity { private String description; @Lob - @Column(name = "raw_request_body", length = 100000, nullable = false) - private String rawRequestBody; + @Column(name = "mpack_instances", length = 100000, nullable = false) + private String mpackInstances; @OneToMany(mappedBy = "topologyRequestEntity", cascade = CascadeType.ALL) private Collection topologyHostGroupEntities; @@ -146,17 +146,17 @@ public void setDescription(String description) { } /** - * @return the raw request body in JSON + * @return the mpack instance definitions (mpack name, version, uri, nested configurations) as JSON */ - public String getRawRequestBody() { - return rawRequestBody; + public String getMpackInstances() { + return mpackInstances; } /** - * @param rawRequestBody the raw request body in JSON + * @param mpackInstances mpack instance definitions (mpack name, version, uri, nested configurations) as JSON */ - public void setRawRequestBody(String rawRequestBody) { - this.rawRequestBody = rawRequestBody; + public void setMpackInstances(String mpackInstances) { + this.mpackInstances = mpackInstances; } public Collection getTopologyHostGroupEntities() { diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java index 0ac76df322a..b9c01bb5dc1 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java @@ -37,6 +37,7 @@ import static org.apache.ambari.server.controller.internal.BlueprintResourceProvider.STACK_VERSION_PROPERTY_ID; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -126,7 +127,7 @@ public Blueprint createBlueprint(Map properties, SecurityConfigu return new BlueprintImpl(name, hostGroups, stackIds, mpackInstances, configuration, securityConfiguration, setting); } - public static Collection createMpackInstances(Map properties) throws NoSuchStackException { + public static Collection createMpackInstances(Map properties) { if (properties.containsKey(MPACK_INSTANCES_PROPERTY_ID)) { ObjectMapper mapper = new ObjectMapper(); mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); @@ -134,7 +135,7 @@ public static Collection createMpackInstances(Map String mpackInstancesJson = mapper.writeValueAsString(properties.get(MPACK_INSTANCES_PROPERTY_ID)); return mapper.readValue(mpackInstancesJson, new TypeReference>(){}); } catch (IOException ex) { - throw new RuntimeException("Unable to parse mpack instances for blueprint: " + + throw new UncheckedIOException("Unable to parse mpack instances for blueprint: " + String.valueOf(properties.get(BLUEPRINT_NAME_PROPERTY_ID)), ex); } } else { diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java index eeb45b776eb..694fde017c9 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java @@ -157,4 +157,6 @@ public static MpackInstance fromEntity(BlueprintMpackInstanceEntity entity) { } return mpack; } + + } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java index ae70db467de..08f783d544c 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.topology; +import static java.util.stream.Collectors.toSet; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -54,9 +56,11 @@ import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.topology.tasks.TopologyTask; +import org.apache.ambari.server.utils.JsonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.core.type.TypeReference; import com.google.gson.Gson; import com.google.inject.persist.Transactional; @@ -107,7 +111,7 @@ public class PersistedStateImpl implements PersistedState { @Override public PersistedTopologyRequest persistTopologyRequest(BaseClusterRequest request) { - TopologyRequestEntity requestEntity = toEntity(request); + TopologyRequestEntity requestEntity = request.toEntity(); topologyRequestDAO.create(requestEntity); return new PersistedTopologyRequest(requestEntity.getId(), request); } @@ -251,38 +255,6 @@ public Map> getAllRequests() { return allRequests; } - private TopologyRequestEntity toEntity(BaseClusterRequest request) { - TopologyRequestEntity entity = new TopologyRequestEntity(); - - entity.setRawRequestBody(request.getRawRequestBody()); - - //todo: this isn't set for a scaling operation because we had intended to allow multiple - //todo: bp's to be used to scale a cluster although this isn't currently supported by - //todo: new topology infrastructure - entity.setAction(request.getType().name()); - if (request.getBlueprint() != null) { - entity.setBlueprintName(request.getBlueprint().getName()); - } - - entity.setClusterAttributes(attributesAsString(request.getConfiguration().getAttributes())); - entity.setClusterId(request.getClusterId()); - entity.setClusterProperties(propertiesAsString(request.getConfiguration().getProperties())); - entity.setDescription(request.getDescription()); - - if (request.getProvisionAction() != null) { - entity.setProvisionAction(request.getProvisionAction()); - } - - // host groups - Collection hostGroupEntities = new ArrayList<>(); - for (HostGroupInfo groupInfo : request.getHostGroupInfo().values()) { - hostGroupEntities.add(toEntity(groupInfo, entity)); - } - entity.setTopologyHostGroupEntities(hostGroupEntities); - - return entity; - } - private TopologyLogicalRequestEntity toEntity(LogicalRequest request, TopologyRequestEntity topologyRequestEntity) { TopologyLogicalRequestEntity entity = new TopologyLogicalRequestEntity(); @@ -340,51 +312,7 @@ private TopologyHostRequestEntity toEntity(HostRequest request, TopologyLogicalR return entity; } - private TopologyHostGroupEntity toEntity(HostGroupInfo groupInfo, TopologyRequestEntity topologyRequestEntity) { - TopologyHostGroupEntity entity = new TopologyHostGroupEntity(); - entity.setGroupAttributes(attributesAsString(groupInfo.getConfiguration().getAttributes())); - entity.setGroupProperties(propertiesAsString(groupInfo.getConfiguration().getProperties())); - entity.setName(groupInfo.getHostGroupName()); - entity.setTopologyRequestEntity(topologyRequestEntity); - - // host info - Collection hostInfoEntities = new ArrayList<>(); - entity.setTopologyHostInfoEntities(hostInfoEntities); - - Collection hosts = groupInfo.getHostNames(); - if (hosts.isEmpty()) { - TopologyHostInfoEntity hostInfoEntity = new TopologyHostInfoEntity(); - hostInfoEntity.setTopologyHostGroupEntity(entity); - hostInfoEntity.setHostCount(groupInfo.getRequestedHostCount()); - if (groupInfo.getPredicate() != null) { - hostInfoEntity.setPredicate(groupInfo.getPredicateString()); - } - hostInfoEntities.add(hostInfoEntity); - } else { - for (String hostName : hosts) { - TopologyHostInfoEntity hostInfoEntity = new TopologyHostInfoEntity(); - hostInfoEntity.setTopologyHostGroupEntity(entity); - if (groupInfo.getPredicate() != null) { - hostInfoEntity.setPredicate(groupInfo.getPredicateString()); - } - hostInfoEntity.setFqdn(hostName); - hostInfoEntity.setRackInfo(groupInfo.getHostRackInfo().get(hostName)); - hostInfoEntity.setHostCount(0); - hostInfoEntities.add(hostInfoEntity); - } - } - return entity; - } - - private static String propertiesAsString(Map> configurationProperties) { - return jsonSerializer.toJson(configurationProperties); - } - - private static String attributesAsString(Map>> configurationAttributes) { - return jsonSerializer.toJson(configurationAttributes); - } - - private static class ReplayedTopologyRequest implements TopologyRequest { + static final class ReplayedTopologyRequest implements TopologyRequest { private final Long clusterId; private final Type type; private final String description; @@ -400,7 +328,9 @@ public ReplayedTopologyRequest(TopologyRequestEntity entity, BlueprintFactory bl description = entity.getDescription(); provisionAction = entity.getProvisionAction(); - stackIds = TopologyRequestUtil.getStackIdsFromRequest(entity.getRawRequestBody()); + Collection mpackInstances = JsonUtils.fromJson(entity.getMpackInstances(), + new TypeReference>() {}); + stackIds = mpackInstances.stream().map(MpackInstance::getStackId).collect(toSet()); try { blueprint = blueprintFactory.getBlueprint(entity.getBlueprintName()); diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java index 136be393d48..751e2d7a851 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java @@ -28,6 +28,6 @@ */ public interface TopologyRequestFactory { - ProvisionClusterRequest createProvisionClusterRequest(String rawRequestBody, Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException; + ProvisionClusterRequest createProvisionClusterRequest(Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException; // todo: use to create other request types } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java index 50d3fa1226e..62c5ec28c9f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java @@ -29,7 +29,7 @@ public class TopologyRequestFactoryImpl implements TopologyRequestFactory { @Override - public ProvisionClusterRequest createProvisionClusterRequest(String rawRequestBody, Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException { - return new ProvisionClusterRequest(rawRequestBody, properties, securityConfiguration); + public ProvisionClusterRequest createProvisionClusterRequest(Map properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException { + return new ProvisionClusterRequest(properties, securityConfiguration); } } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java deleted file mode 100644 index 1b160a41c36..00000000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestUtil.java +++ /dev/null @@ -1,76 +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.topology; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.stream.Collectors.toSet; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.ambari.server.state.StackId; -import org.apache.ambari.server.utils.JsonUtils; - -import com.fasterxml.jackson.core.type.TypeReference; - -/** - * Utility functions for topology requests. - */ -public class TopologyRequestUtil { - - public static final String NAME = "name"; - public static final String VERSION = "version"; - - - /** - * @param rawRequestJson The topology request in raw JSON format. Null input is handled gracefully. - * @return a Set of stack id's contained in the request - */ - public static Set getStackIdsFromRequest(String rawRequestJson) { - return getStackIdsFromRequest(getPropertyMap(rawRequestJson)); - } - - - /** - * @param rawRequestMap The topology request in raw JSON format. Null input is handled gracefully. - * @return a Set of stack id's contained in the request - */ - public static Set getStackIdsFromRequest(Map rawRequestMap) { - List> mpackInstances = (List>) - rawRequestMap.getOrDefault("mpack_instances", emptyList()); - return mpackInstances.stream().map(m -> { - checkArgument(m.containsKey(NAME), "Missing mpack name"); - checkArgument(m.containsKey(VERSION), "Missing mpack version"); - return new StackId(m.get(NAME), m.get(VERSION)); - }).collect(toSet()); - } - - /** - * @param rawRequestJson The topology request in raw JSON format. Null input is handled gracefully. - * @return the request body parsed as map (null is parsed as empty map) - */ - public static Map getPropertyMap(String rawRequestJson) { - return null == rawRequestJson ? - emptyMap() : - JsonUtils.fromJson(rawRequestJson, new TypeReference>() {}); - } -} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java index 8c6df293652..5dc44efb874 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java @@ -22,6 +22,7 @@ import org.apache.commons.lang.StringUtils; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; @@ -39,6 +40,9 @@ public class JsonUtils { public static JsonParser jsonParser = new JsonParser(); private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper(); + static { + JSON_SERIALIZER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } private static final ObjectWriter JSON_WRITER = JSON_SERIALIZER.writer(); /** @@ -70,6 +74,18 @@ public static T fromJson(String json, TypeReference valueType) } } + public static T fromJson(String json, Class valueType) { + if (null == json) { + return null; + } + try { + return JSON_SERIALIZER.reader(valueType).readValue(json); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + + public static String toJson(Object object) { try { return JSON_WRITER.writeValueAsString(object); diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql index 7d24563ac2e..99c31f4282f 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql @@ -893,7 +893,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - raw_request_body CLOB NOT NULL, + mpack_instances CLOB NOT NULL, cluster_properties VARCHAR(3000), cluster_attributes VARCHAR(3000), description VARCHAR(1024), 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 900e46fa389..2c27bd8539b 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -910,7 +910,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - raw_request_body LONGTEXT NOT NULL, + mpack_instances LONGTEXT NOT NULL, cluster_properties LONGTEXT, cluster_attributes LONGTEXT, description VARCHAR(1024), 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 09d53d32a10..2848d9f38bb 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -888,7 +888,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id NUMBER(19) NOT NULL, bp_name VARCHAR(100) NOT NULL, - raw_request_body CLOB NOT NULL, + mpack_instances CLOB NOT NULL, cluster_properties CLOB, cluster_attributes CLOB, description VARCHAR(1024), 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 6936a61af1b..c727dddd429 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -894,7 +894,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - raw_request_body TEXT NOT NULL, + mpack_instances TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql index 4b709715c16..6428889ac1d 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql @@ -888,7 +888,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id NUMERIC(19) NOT NULL, bp_name VARCHAR(100) NOT NULL, - raw_request_body TEXT NOT NULL, + mpack_instances TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql index 97894481e93..2e45445a83d 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql @@ -911,7 +911,7 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - raw_request_body TEXT NOT NULL, + mpack_instances TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java index 06d95bd660d..ba358f3c121 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java @@ -20,7 +20,6 @@ import static org.easymock.EasyMock.anyBoolean; import static org.easymock.EasyMock.anyObject; -import static org.easymock.EasyMock.anyString; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; @@ -81,7 +80,6 @@ import com.google.gson.Gson; - /** * ClusterResourceProvider tests. */ @@ -155,7 +153,7 @@ public void testCreateResource_blueprint_With_ProvisionAction() throws Exception expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null) .once(); - expect(topologyFactory.createProvisionClusterRequest("{}", properties, null)).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes(); @@ -185,7 +183,7 @@ public void testCreateResource_blueprint_withSecurityConfiguration() throws Exce expect(request.getProperties()).andReturn(requestProperties).anyTimes(); expect(request.getRequestInfoProperties()).andReturn(requestInfoProperties).anyTimes(); - expect(topologyFactory.createProvisionClusterRequest(anyString(), eq(properties), eq(securityConfiguration))).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest(properties, securityConfiguration)).andReturn(topologyRequest).once(); expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn (securityConfiguration).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); @@ -209,7 +207,7 @@ public void testCreateResource_blueprint__InvalidRequest() throws Exception { // set expectations expect(request.getProperties()).andReturn(requestProperties).anyTimes(); // throw exception from topology request factory an assert that the correct exception is thrown from resource provider - expect(topologyFactory.createProvisionClusterRequest(null, properties, null)).andThrow(new InvalidTopologyException + expect(topologyFactory.createProvisionClusterRequest(properties, null)).andThrow(new InvalidTopologyException ("test")); replayAll(); @@ -473,7 +471,7 @@ private void testCreateResource_blueprint(Authentication authentication) throws expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null) .once(); - expect(topologyFactory.createProvisionClusterRequest(anyString(), eq(properties), anyObject())).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest(eq(properties), anyObject())).andReturn(topologyRequest).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes(); @@ -804,7 +802,7 @@ public void testCreateResource_blueprint_withRepoVersion() throws Exception { expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null) .once(); - expect(topologyFactory.createProvisionClusterRequest("{}", properties, null)).andReturn(topologyRequest).once(); + expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once(); expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once(); expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes(); diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java index 3cc48905829..be0682a486c 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java @@ -44,20 +44,26 @@ import java.util.Set; import org.apache.ambari.server.controller.spi.ResourceProvider; +import org.apache.ambari.server.orm.entities.TopologyRequestEntity; import org.apache.ambari.server.security.encryption.CredentialStoreType; +import org.apache.ambari.server.state.SecurityType; import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfileBuilderTest; import org.apache.ambari.server.topology.Blueprint; import org.apache.ambari.server.topology.BlueprintFactory; import org.apache.ambari.server.topology.Configuration; import org.apache.ambari.server.topology.HostGroupInfo; import org.apache.ambari.server.topology.InvalidTopologyTemplateException; +import org.apache.ambari.server.topology.SecurityConfiguration; import org.apache.ambari.server.topology.TopologyRequest; +import org.apache.ambari.server.utils.JsonUtils; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; /** @@ -109,7 +115,7 @@ public void testHostNameSpecified() throws Exception { replay(hostResourceProvider); Map properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -160,7 +166,7 @@ public void testHostCountSpecified() throws Exception { replay(hostResourceProvider); Map properties = createBlueprintRequestPropertiesCountOnly(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -211,7 +217,7 @@ public void testHostCountSpecified() throws Exception { @Test public void testMultipleGroups() throws Exception { Map properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -286,7 +292,7 @@ public void test_NoHostGroupInfo() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(properties, null); } @Test @@ -301,7 +307,7 @@ public void test_Creditentials() throws Exception { credentialsSet.add(credentialHashMap); properties.put("credentials", credentialsSet); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getAlias(), "testAlias"); assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getPrincipal(), "testPrincipal"); @@ -326,7 +332,7 @@ public void test_CreditentialsInvalidType() throws Exception { credentialsSet.add(credentialHashMap); properties.put("credentials", credentialsSet); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null); } @Test(expected= InvalidTopologyTemplateException.class) @@ -338,7 +344,7 @@ public void test_GroupInfoMissingName() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(properties, null); } @Test(expected= InvalidTopologyTemplateException.class) @@ -350,7 +356,7 @@ public void test_NoHostsInfo() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(properties, null); } @Test(expected = InvalidTopologyTemplateException.class) @@ -370,7 +376,7 @@ public void test_NoHostNameOrHostCount() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(properties, null); } @@ -383,7 +389,7 @@ public void testInvalidPredicateProperty() throws Exception { replay(hostResourceProvider); // should result in an exception due to invalid property in host predicate - new ProvisionClusterRequest(null, createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME), null); + new ProvisionClusterRequest(createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME), null); } @Test(expected = InvalidTopologyTemplateException.class) @@ -395,7 +401,7 @@ public void testHostNameAndCountSpecified() throws Exception { Map properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_count", "5"); // should result in an exception due to both host name and host count being specified - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(properties, null); } @Test(expected = InvalidTopologyTemplateException.class) @@ -407,13 +413,13 @@ public void testHostNameAndPredicateSpecified() throws Exception { Map properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_predicate", "Hosts/host_name=myTestHost"); // should result in an exception due to both host name and host count being specified - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(properties, null); } @Test public void testQuickLinksProfile_NoDataInRequest() throws Exception { Map properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); assertNull("No quick links profile is expected", request.getQuickLinksProfileJson()); } @@ -424,7 +430,7 @@ public void testQuickLinksProfile_OnlyGlobalFilterDataInRequest() throws Excepti properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_FILTERS_PROPERTY, Sets.newHashSet(QuickLinksProfileBuilderTest.filter(null, null, true))); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[{\"visible\":true}],\"services\":[]}", request.getQuickLinksProfileJson()); @@ -439,7 +445,7 @@ public void testQuickLinksProfile_OnlyServiceFilterDataInRequest() throws Except Set> services = Sets.newHashSet(hdfs); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}", request.getQuickLinksProfileJson()); @@ -457,7 +463,7 @@ public void testQuickLinksProfile_BothGlobalAndServiceLevelFilters() throws Exce Set> services = Sets.newHashSet(hdfs); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); System.out.println(request.getQuickLinksProfileJson()); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[{\"visible\":true}],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}", @@ -470,7 +476,7 @@ public void testQuickLinksProfile_InvalidRequestData() throws Exception { properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, "Hello World!"); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null); } public static Map createBlueprintRequestProperties(String clusterName, String blueprintName) { @@ -603,4 +609,23 @@ public static Map createBlueprintRequestPropertiesCountOnly(Stri return properties; } + + @Test + public void testToEntity() throws Exception { + Map properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); + List> mpackInstances = + ImmutableList.of( + ImmutableMap.of( + "name", "HDPCORE", + "version", "1.0.0.0", + "service_instances", ImmutableList.of(), + "configurations", ImmutableList.of())); + properties.put("mpack_instances", mpackInstances); + ProvisionClusterRequest request = new ProvisionClusterRequest( + properties, + new SecurityConfiguration(SecurityType.NONE)); + TopologyRequestEntity entity = request.toEntity(); + assertEquals(mpackInstances, JsonUtils.fromJson(entity.getMpackInstances(), List.class)); + } + } diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java index cc02db4e5c0..b9f32a03f67 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ScaleClusterRequestTest.java @@ -112,7 +112,7 @@ private void addSingleHostByName(Map props) throws InvalidTopolo reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton(props)); + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton(props)); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); assertEquals(String.format("Scale Cluster '%s' (+%s hosts)", CLUSTER_NAME, "1"), @@ -150,7 +150,7 @@ private void addMultipleHostsByName(Set> propertySet) throws reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", propertySet); + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(propertySet); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); assertEquals(String.format("Scale Cluster '%s' (+%s hosts)", CLUSTER_NAME, "2"), @@ -177,7 +177,7 @@ public void test_basic_hostCount() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton( + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton( createScaleClusterPropertiesGroup1_HostCount(CLUSTER_NAME, BLUEPRINT_NAME))); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); @@ -203,7 +203,7 @@ public void test_basic_hostCount2() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton( + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton( createScaleClusterPropertiesGroup1_HostCount2(CLUSTER_NAME, BLUEPRINT_NAME))); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); @@ -225,7 +225,7 @@ public void test_basic_hostCount2() throws Exception { @Test public void test_basic_hostCountAndPredicate() throws Exception { - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", Collections.singleton( + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(Collections.singleton( createScaleClusterPropertiesGroup1_HostCountAndPredicate(CLUSTER_NAME, BLUEPRINT_NAME))); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); @@ -252,7 +252,7 @@ public void testMultipleHostGroups() throws Exception { propertySet.add(createScaleClusterPropertiesGroup1_HostCount(CLUSTER_NAME, BLUEPRINT_NAME)); propertySet.add(createScaleClusterPropertiesGroup1_HostName(CLUSTER_NAME, BLUEPRINT_NAME)); - ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest("{}", propertySet); + ScaleClusterRequest scaleClusterRequest = new ScaleClusterRequest(propertySet); assertEquals(TopologyRequest.Type.SCALE, scaleClusterRequest.getType()); assertEquals(String.format("Scale Cluster '%s' (+%s hosts)", CLUSTER_NAME, "3"), @@ -300,7 +300,7 @@ public void test_GroupInfoMissingName() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception - new ScaleClusterRequest("{}", Collections.singleton(properties)); + new ScaleClusterRequest(Collections.singleton(properties)); } @Test(expected = InvalidTopologyTemplateException.class) @@ -313,7 +313,7 @@ public void test_NoHostNameOrHostCount() throws Exception { reset(hostResourceProvider); replay(hostResourceProvider); // should result in an exception because neither host name or host count are specified - new ScaleClusterRequest("{}", Collections.singleton(properties)); + new ScaleClusterRequest(Collections.singleton(properties)); } @@ -326,7 +326,7 @@ public void testInvalidPredicateProperty() throws Exception { replay(hostResourceProvider); // should result in an exception due to invalid property in host predicate - new ScaleClusterRequest("{}", Collections.singleton( + new ScaleClusterRequest(Collections.singleton( createScaleClusterPropertiesGroup1_HostCountAndPredicate(CLUSTER_NAME, BLUEPRINT_NAME))); } @@ -340,7 +340,7 @@ public void testMultipleBlueprints() throws Exception { propertySet.add(createScaleClusterPropertiesGroup1_HostName2(CLUSTER_NAME, "OTHER_BLUEPRINT")); // should result in an exception due to different blueprints being specified - new ScaleClusterRequest("{}", propertySet); + new ScaleClusterRequest(propertySet); } public static Map createScaleClusterPropertiesGroup1_HostName(String clusterName, String blueprintName) { diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterTopologyImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterTopologyImplTest.java index 5e81730e28d..8e961cbb624 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterTopologyImplTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterTopologyImplTest.java @@ -31,11 +31,14 @@ import java.util.Map; import java.util.Set; +import org.apache.ambari.server.state.StackId; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import com.google.common.collect.ImmutableSet; + /** * Unit tests for ClusterTopologyImpl. */ @@ -97,6 +100,7 @@ public void setUp() throws Exception { group4Info.setPredicate(predicate); expect(blueprint.getConfiguration()).andReturn(bpconfiguration).anyTimes(); + expect(blueprint.getStackIds()).andReturn(ImmutableSet.of(new StackId("HDP", "2.6"))).anyTimes(); hostGroupMap.put("group1", group1); hostGroupMap.put("group2", group2); diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java index 7f6ee4b169a..1d1c9df01f8 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java @@ -18,106 +18,54 @@ package org.apache.ambari.server.topology; - -import static org.easymock.EasyMock.capture; +import static java.util.Collections.emptyList; +import static org.easymock.EasyMock.anyString; import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.expectLastCall; -import static org.easymock.EasyMock.newCapture; import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.reset; import static org.junit.Assert.assertEquals; -import java.lang.reflect.Field; - -import org.apache.ambari.server.controller.internal.BaseClusterRequest; import org.apache.ambari.server.controller.internal.ProvisionAction; -import org.apache.ambari.server.controller.internal.ProvisionClusterRequest; -import org.apache.ambari.server.orm.dao.TopologyRequestDAO; import org.apache.ambari.server.orm.entities.TopologyRequestEntity; -import org.easymock.Capture; +import org.apache.ambari.server.state.StackId; import org.easymock.EasyMockRunner; import org.easymock.Mock; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import com.google.common.collect.ImmutableMap; - +import com.google.common.collect.ImmutableSet; @RunWith(EasyMockRunner.class) public class PersistedStateImplTest { - private static final String CLUSTER_REQUEST = - "{'blueprint': 'bp', 'host_groups': [{'name': 'group','host_count': '1' }]}".replace('\'', '"'); - - private static final String BLUEPRINT_NAME = "bp"; - - @Mock - private TopologyRequestDAO topologyRequestDAO; - - @Mock - private BlueprintFactory blueprintFactory; - @Mock - private Blueprint blueprint; + BlueprintFactory blueprintFactory; @Mock - private ProvisionClusterRequest - request; - - private PersistedStateImpl persistedState; + Blueprint blueprint; @Before - public void init() throws Exception { - expect(blueprint.getName()).andReturn(BLUEPRINT_NAME).anyTimes(); - expect(blueprint.getConfiguration()).andReturn(new Configuration()).anyTimes(); - expect(blueprintFactory.getBlueprint(BLUEPRINT_NAME)).andReturn(blueprint).anyTimes(); - - expect(request.getBlueprint()).andReturn(blueprint).anyTimes(); - expect(request.getRawRequestBody()).andReturn(CLUSTER_REQUEST).anyTimes(); - expect(request.getType()).andReturn(TopologyRequest.Type.PROVISION).anyTimes(); - expect(request.getConfiguration()).andReturn(new Configuration()).anyTimes(); - expect(request.getClusterId()).andReturn(1L).anyTimes(); - expect(request.getDescription()).andReturn("").anyTimes(); - expect(request.getProvisionAction()).andReturn(ProvisionAction.INSTALL_AND_START).anyTimes(); - HostGroupInfo hostGroupInfo = new HostGroupInfo("hostgroup1"); - hostGroupInfo.setConfiguration(new Configuration()); - expect(request.getHostGroupInfo()).andReturn(ImmutableMap.of("hostgroup1", hostGroupInfo)).anyTimes(); - - replay(blueprint, blueprintFactory, request); - - Field blueprintFactoryField = BaseClusterRequest.class.getDeclaredField("blueprintFactory"); - blueprintFactoryField.setAccessible(true); - blueprintFactoryField.set(null, blueprintFactory); - - persistedState = new PersistedStateImpl(); - Field topologyRequestDAOField = PersistedStateImpl.class.getDeclaredField("topologyRequestDAO"); - topologyRequestDAOField.setAccessible(true); - topologyRequestDAOField.set(persistedState, topologyRequestDAO); - } - - @After - public void tearDown() { - reset(topologyRequestDAO, blueprintFactory, blueprint, request); + public void setup() { + expect(blueprintFactory.getBlueprint(anyString())).andReturn(blueprint); + expect(blueprint.getConfiguration()).andReturn(new Configuration()); + replay(blueprintFactory, blueprint); } @Test - public void testPersistTopologyRequest_RawRequestIsSaved() throws Exception { - // Given - Capture entityCapture = newCapture(); - topologyRequestDAO.create(capture(entityCapture)); - expectLastCall().andAnswer(() -> { - entityCapture.getValue().setId(1L); - return null; - }); - replay(topologyRequestDAO); - - // When - persistedState.persistTopologyRequest(request); - - // Then - assertEquals(CLUSTER_REQUEST, entityCapture.getValue().getRawRequestBody()); + public void testPersistedTopologyRequest_stackIdsDepersistedCorrectly() { + TopologyRequestEntity entity = new TopologyRequestEntity(); + entity.setAction(TopologyRequest.Type.PROVISION.name()); + entity.setProvisionAction(ProvisionAction.INSTALL_AND_START); + entity.setClusterProperties("{}"); + entity.setClusterAttributes("{}"); + entity.setDescription("Provision Cluster c1"); + entity.setTopologyHostGroupEntities(emptyList()); + entity.setMpackInstances( + "[{'name':'HDPCORE','version':'1.0.0.0','service_instances':[],'configurations':[]}]". + replace('\'', '"')); + PersistedStateImpl.ReplayedTopologyRequest request = + new PersistedStateImpl.ReplayedTopologyRequest(entity, blueprintFactory); + assertEquals(ImmutableSet.of(new StackId("HDPCORE", "1.0.0.0")), request.getStackIds()); } } \ No newline at end of file diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java index 89f2f4f7f62..9f3a1f04825 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java @@ -584,7 +584,7 @@ public void testScaleHosts__alreadyExistingHost() throws InvalidTopologyTemplate expect(persistedState.getAllRequests()).andReturn(Collections.emptyMap()).anyTimes(); replayAll(); topologyManager.provisionCluster(request); - topologyManager.scaleHosts(new ScaleClusterRequest("{}", propertySet)); + topologyManager.scaleHosts(new ScaleClusterRequest(propertySet)); Assert.fail("InvalidTopologyException should have been thrown"); } diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java deleted file mode 100644 index db4046ac277..00000000000 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyRequestUtilTest.java +++ /dev/null @@ -1,60 +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.topology; - -import static org.junit.Assert.assertEquals; - -import java.util.Collections; - -import org.apache.ambari.server.state.StackId; -import org.junit.Test; - -import com.google.common.collect.ImmutableSet; - -public class TopologyRequestUtilTest { - - private static final String REQUEST_WITH_MPACK_INSTANCES = - "{ 'mpack_instances' : [ {'name': 'HDPCORE', 'version': '1.0.0-b98'}, {'name': 'EDW', 'version': '1.0.0'} ] }".replace('\'', '"'); - - private static final String REQUEST_WITH_INVALID_MPACK_INSTANCE = - "{ 'mpack_instances' : [ {'name': 'HDPCORE', 'version': '1.0.0-b98'}, {'name': 'EDW'} ] }".replace('\'', '"'); - - private static final String REQUEST_WITHOUT_MPACK_INSTANCE = "{}"; - - - @Test - public void testGetStackIdsFromRawRequest_normalCase() { - assertEquals( - ImmutableSet.of(new StackId("HDPCORE", "1.0.0-b98"), new StackId("EDW", "1.0.0")), - TopologyRequestUtil.getStackIdsFromRequest(REQUEST_WITH_MPACK_INSTANCES)); - } - - @Test - public void testGetStackIdsFromRawRequest_noMpackInstances() { - assertEquals( - Collections.emptySet(), - TopologyRequestUtil.getStackIdsFromRequest(REQUEST_WITHOUT_MPACK_INSTANCE)); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetStackIdsFromRawRequest_wrongMpackInstance() { - TopologyRequestUtil.getStackIdsFromRequest(REQUEST_WITH_INVALID_MPACK_INSTANCE); - } - -} \ No newline at end of file From 153d56efaa076a47b9985a57fdf7f5287775a2c0 Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Fri, 9 Mar 2018 16:40:31 +0100 Subject: [PATCH 5/8] AMBARI-23130 address review findings (benyoka) --- .../internal/BaseClusterRequest.java | 10 ++++-- .../apache/ambari/server/utils/JsonUtils.java | 36 ++++++++++++++----- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java index 9e63914ff05..4f915984557 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java @@ -244,6 +244,12 @@ public TopologyRequestEntity toEntity() { return entity; } + /** + * Converts a {@link HostGroupInfo} to a {@link TopologyHostGroupEntity} + * @param groupInfo the {@link HostGroupInfo} to convert + * @param topologyRequestEntity the base entity to add the host group to + * @return the resulting {@link TopologyHostGroupEntity} + */ private TopologyHostGroupEntity toHostGroupEntity(HostGroupInfo groupInfo, TopologyRequestEntity topologyRequestEntity) { TopologyHostGroupEntity entity = new TopologyHostGroupEntity(); entity.setGroupAttributes(JsonUtils.toJson(groupInfo.getConfiguration().getAttributes())); @@ -268,9 +274,7 @@ private TopologyHostGroupEntity toHostGroupEntity(HostGroupInfo groupInfo, Topol for (String hostName : hosts) { TopologyHostInfoEntity hostInfoEntity = new TopologyHostInfoEntity(); hostInfoEntity.setTopologyHostGroupEntity(entity); - if (groupInfo.getPredicate() != null) { - hostInfoEntity.setPredicate(groupInfo.getPredicateString()); - } + hostInfoEntity.setPredicate(groupInfo.getPredicateString()); hostInfoEntity.setFqdn(hostName); hostInfoEntity.setRackInfo(groupInfo.getHostRackInfo().get(hostName)); hostInfoEntity.setHostCount(0); diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java index 5dc44efb874..8ff4352a0ae 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/JsonUtils.java @@ -39,16 +39,15 @@ public class JsonUtils { */ public static JsonParser jsonParser = new JsonParser(); - private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper(); - static { - JSON_SERIALIZER.setSerializationInclusion(JsonInclude.Include.NON_NULL); - } + private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper(). + setSerializationInclusion(JsonInclude.Include.NON_NULL); private static final ObjectWriter JSON_WRITER = JSON_SERIALIZER.writer(); /** * Checks if an input string is in valid JSON format * @param jsonString input json string to validate * @return true if the input string is in valid JSON format + * @throws UncheckedIOException when conversion error occurs */ public static boolean isValidJson(String jsonString) { @@ -63,7 +62,15 @@ public static boolean isValidJson(String jsonString) { } } - public static T fromJson(String json, TypeReference valueType) { + /** + * Converts a json String to the object specified by the received type reference + * @param json the json String + * @param valueType the type reference capturing the type of the conversion result + * @param the type of the resulting object + * @return the object depersisted from json + * @throws UncheckedIOException when conversion error occurs + */ + public static T fromJson(String json, TypeReference valueType) throws UncheckedIOException { if (null == json) { return null; } @@ -74,7 +81,15 @@ public static T fromJson(String json, TypeReference valueType) } } - public static T fromJson(String json, Class valueType) { + /** + * Converts a json String to the object specified by the received type reference + * @param json the json String + * @param valueType the class of the conversion result + * @param the type of the resulting object + * @return the object depersisted from json + * @throws UncheckedIOException when conversion error occurs + */ + public static T fromJson(String json, Class valueType) throws UncheckedIOException { if (null == json) { return null; } @@ -85,8 +100,13 @@ public static T fromJson(String json, Class valueType) { } } - - public static String toJson(Object object) { + /** + * Converts an object to json string + * @param object the object to convert + * @return the resulting json + * @throws UncheckedIOException when conversion error occurs + */ + public static String toJson(Object object) throws UncheckedIOException { try { return JSON_WRITER.writeValueAsString(object); } catch (IOException ex) { From 80f0de65980ae844ea59e70e71f8f84381707dd8 Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Tue, 13 Mar 2018 11:49:50 +0100 Subject: [PATCH 6/8] AMBARI-23130 topology request mpack information normalized (benyoka) --- .../internal/ProvisionClusterRequest.java | 8 +- .../BlueprintMpackInstanceEntity.java | 151 +-------------- ...ty.java => MpackInstanceConfigEntity.java} | 16 +- ....java => MpackInstanceConfigEntityPk.java} | 6 +- .../orm/entities/MpackInstanceEntity.java | 182 ++++++++++++++++++ ...y.java => MpackInstanceServiceEntity.java} | 24 +-- ...ity.java => MpackServiceConfigEntity.java} | 16 +- ...k.java => MpackServiceConfigEntityPk.java} | 6 +- .../orm/entities/TopologyRequestEntity.java | 16 +- .../TopologyRequestMpackInstanceEntity.java | 52 +++++ .../ambari/server/topology/BlueprintImpl.java | 7 +- .../ambari/server/topology/MpackInstance.java | 66 +++++-- .../server/topology/PersistedStateImpl.java | 7 +- .../resources/Ambari-DDL-Derby-CREATE.sql | 58 +++--- .../resources/Ambari-DDL-MySQL-CREATE.sql | 30 +-- .../resources/Ambari-DDL-Oracle-CREATE.sql | 30 +-- .../resources/Ambari-DDL-Postgres-CREATE.sql | 30 +-- .../Ambari-DDL-SQLAnywhere-CREATE.sql | 32 +-- .../resources/Ambari-DDL-SQLServer-CREATE.sql | 30 +-- .../main/resources/META-INF/persistence.xml | 8 +- .../ambari/server/H2DatabaseCleaner.java | 2 + .../internal/ProvisionClusterRequestTest.java | 7 +- .../orm/entities/BlueprintEntityTest2.java | 10 +- .../topology/PersistedStateImplTest.java | 9 +- 24 files changed, 476 insertions(+), 327 deletions(-) rename ambari-server/src/main/java/org/apache/ambari/server/orm/entities/{BlueprintMpackConfigEntity.java => MpackInstanceConfigEntity.java} (89%) rename ambari-server/src/main/java/org/apache/ambari/server/orm/entities/{BlueprintMpackConfigEntityPk.java => MpackInstanceConfigEntityPk.java} (89%) create mode 100644 ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java rename ambari-server/src/main/java/org/apache/ambari/server/orm/entities/{BlueprintServiceEntity.java => MpackInstanceServiceEntity.java} (79%) rename ambari-server/src/main/java/org/apache/ambari/server/orm/entities/{BlueprintServiceConfigEntity.java => MpackServiceConfigEntity.java} (87%) rename ambari-server/src/main/java/org/apache/ambari/server/orm/entities/{BlueprintServiceConfigEntityPk.java => MpackServiceConfigEntityPk.java} (88%) create mode 100644 ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestMpackInstanceEntity.java diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java index 219daf9787a..fc692263f9e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java @@ -29,6 +29,7 @@ import org.apache.ambari.server.api.predicate.InvalidQueryException; import org.apache.ambari.server.orm.entities.TopologyRequestEntity; +import org.apache.ambari.server.orm.entities.TopologyRequestMpackInstanceEntity; import org.apache.ambari.server.security.encryption.CredentialStoreType; import org.apache.ambari.server.stack.NoSuchStackException; import org.apache.ambari.server.state.SecurityType; @@ -47,7 +48,6 @@ import org.apache.ambari.server.topology.NoSuchBlueprintException; import org.apache.ambari.server.topology.ProvisionRequest; import org.apache.ambari.server.topology.SecurityConfiguration; -import org.apache.ambari.server.utils.JsonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -540,8 +540,12 @@ public Collection getMpacks() { @Override public TopologyRequestEntity toEntity() { TopologyRequestEntity entity = super.toEntity(); - entity.setMpackInstances(JsonUtils.toJson(mpackInstances)); + mpackInstances.forEach(mpackInstance -> { + TopologyRequestMpackInstanceEntity mpackInstanceEntity = mpackInstance.toMpackInstanceEntity(entity); + entity.getMpackInstances().add(mpackInstanceEntity); + }); return entity; } + } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackInstanceEntity.java index 1d61523a37a..badf251b5c8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackInstanceEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackInstanceEntity.java @@ -18,133 +18,22 @@ package org.apache.ambari.server.orm.entities; -import java.util.ArrayList; -import java.util.Collection; - -import javax.annotation.Nullable; -import javax.persistence.CascadeType; -import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; 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.OneToMany; -import javax.persistence.Table; -import javax.persistence.TableGenerator; /** - * Entity to encapsulate a blueprint's use of an mpack. It contains the mpack name, version, url - * - * - * referencing a management pack from the blueprint. The reference contains the name and - * the version of the mpack, but no direct database reference to the mpack entity as a blueprint - * can be saved without the referenced mpack being present. + * Mpack instance entity for blueprints */ @Entity -@Table(name = "blueprint_mpack_instance") -@TableGenerator(name = "blueprint_mpack_instance_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", - valueColumnName = "sequence_value", pkColumnValue = "blueprint_mpack_instance_id_seq", initialValue = 1) -public class BlueprintMpackInstanceEntity { - @Id - @GeneratedValue(strategy = GenerationType.TABLE, generator = "blueprint_mpack_instance_id_generator") - @Column(name = "id", nullable = false, updatable = false) - private Long id; - - @Column(name = "mpack_name", nullable = false) - private String mpackName; - - @Column(name = "mpack_version", nullable = false) - private String mpackVersion; - - @Column(name = "mpack_uri") - private String mpackUri; - - @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance") - private Collection serviceInstances = new ArrayList<>(); - - @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance") - private Collection configurations = new ArrayList<>(); +@DiscriminatorValue("Blueprint") +public class BlueprintMpackInstanceEntity extends MpackInstanceEntity { @ManyToOne - @JoinColumn(name = "mpack_id", referencedColumnName = "id") - private MpackEntity mpackEntity; - - @ManyToOne - @JoinColumn(name = "blueprint_name", referencedColumnName = "blueprint_name", nullable = false) + @JoinColumn(name = "blueprint_name", referencedColumnName = "blueprint_name") private BlueprintEntity blueprint; - /** - * @return the service instances belonging to this mpack - */ - public Collection getServiceInstances() { - return serviceInstances; - } - - /** - * @param serviceInstances the service instances belonging to this mpack - */ - public void setServiceInstances(Collection serviceInstances) { - this.serviceInstances = serviceInstances; - } - - /** - * @return the name of the mpack - */ - public String getMpackName() { - return mpackName; - } - - /** - * @param mpackName the name of the mpack - */ - public void setMpackName(String mpackName) { - this.mpackName = mpackName; - } - - /** - * @return the version of the mpack - */ - public String getMpackVersion() { - return mpackVersion; - } - - /** - * @param mpackVersion the version of the mpack - */ - public void setMpackVersion(String mpackVersion) { - this.mpackVersion = mpackVersion; - } - - /** - * @return the uri of the mpack - */ - public String getMpackUri() { - return mpackUri; - } - - /** - * @param mpackUri the uri of the mpack - */ - public void setMpackUri(String mpackUri) { - this.mpackUri = mpackUri; - } - - /** - * @return the database id - */ - public Long getId() { - return id; - } - - /** - * @param id the database id - */ - public void setId(Long id) { - this.id = id; - } - /** * @return the blueprint */ @@ -159,32 +48,8 @@ public void setBlueprint(BlueprintEntity blueprint) { this.blueprint = blueprint; } - /** - * @return the mpack level configurations for this mpack - */ - public Collection getConfigurations() { - return configurations; - } - - /** - * @param configurations the mpack level configurations for this mpack - */ - public void setConfigurations(Collection configurations) { - this.configurations = configurations; - } - - /** - * @return the management pack entity associated with this blueprint. Can be {@null} - */ - @Nullable - public MpackEntity getMpackEntity() { - return mpackEntity; - } - - /** - * @param mpackEntity the management pack entity to be associated with this blueprint. - */ - public void setMpackEntity(MpackEntity mpackEntity) { - this.mpackEntity = mpackEntity; + @Override + public String getBlueprintName() { + return blueprint.getBlueprintName(); } } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceConfigEntity.java similarity index 89% rename from ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackConfigEntity.java rename to ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceConfigEntity.java index c1848d1dc8c..445bb74a756 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackConfigEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceConfigEntity.java @@ -30,12 +30,12 @@ import javax.persistence.Table; /** - * Entity to represent an mpack level configuration in the blueprint. + * Entity to represent an mpack level configuration in the blueprint or topology request. */ @Entity -@Table(name = "blueprint_mpack_configuration") -@IdClass(BlueprintMpackConfigEntityPk.class) -public class BlueprintMpackConfigEntity implements BlueprintConfiguration { +@Table(name = "mpack_instance_config") +@IdClass(MpackInstanceConfigEntityPk.class) +public class MpackInstanceConfigEntity implements BlueprintConfiguration { @Id @Column(name = "mpack_instance_id", nullable = false, insertable = false, updatable = false) @@ -57,7 +57,7 @@ public class BlueprintMpackConfigEntity implements BlueprintConfiguration { @ManyToOne @JoinColumn(name = "mpack_instance_id", referencedColumnName = "id", nullable = false) - private BlueprintMpackInstanceEntity mpackInstance; + private MpackInstanceEntity mpackInstance; /** * @return the id of the mpack instance entity this configuration belongs to @@ -101,7 +101,7 @@ public String getConfigData() { */ @Override public String getBlueprintName() { - return getMpackInstance().getBlueprint().getBlueprintName(); + return getMpackInstance().getBlueprintName(); } /** @@ -128,14 +128,14 @@ public void setConfigAttributes(String configAttributes) { /** * @return the mpack instance entity this configuration belongs to */ - public BlueprintMpackInstanceEntity getMpackInstance() { + public MpackInstanceEntity getMpackInstance() { return mpackInstance; } /** * @param mpackInstance the mpack instance entity this configuration belongs to */ - public void setMpackInstance(BlueprintMpackInstanceEntity mpackInstance) { + public void setMpackInstance(MpackInstanceEntity mpackInstance) { this.mpackInstance = mpackInstance; } } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackConfigEntityPk.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceConfigEntityPk.java similarity index 89% rename from ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackConfigEntityPk.java rename to ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceConfigEntityPk.java index 5a95df2af43..a08e7418376 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintMpackConfigEntityPk.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceConfigEntityPk.java @@ -24,9 +24,9 @@ import javax.persistence.Id; /** - * Composite primary key for {@link BlueprintMpackConfigEntity} + * Composite primary key for {@link MpackInstanceConfigEntity} */ -public class BlueprintMpackConfigEntityPk { +public class MpackInstanceConfigEntityPk { @Id @Column(name = "mpack_instance_id", nullable = false, insertable = true, updatable = false) private Long mpackInstanceId; @@ -39,7 +39,7 @@ public class BlueprintMpackConfigEntityPk { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - BlueprintMpackConfigEntityPk that = (BlueprintMpackConfigEntityPk) o; + MpackInstanceConfigEntityPk that = (MpackInstanceConfigEntityPk) o; return Objects.equals(mpackInstanceId, that.mpackInstanceId) && Objects.equals(type, that.type); } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java new file mode 100644 index 00000000000..868bc24a138 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java @@ -0,0 +1,182 @@ +/* + * 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 java.util.ArrayList; +import java.util.Collection; + +import javax.annotation.Nullable; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.DiscriminatorColumn; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +/** + * Entity to encapsulate a blueprint's or cluster template's use of an mpack. It contains the mpack name, version, url + * referencing a management pack from the blueprint. The reference contains the name and + * the version of the mpack, but no direct database reference to the mpack entity as a blueprint + * can be saved without the referenced mpack being present. + */ +@Entity +@Table(name = "mpack_instance") +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name = "owner", length = 20) +@TableGenerator(name = "mpack_instance_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", + valueColumnName = "sequence_value", pkColumnValue = "mpack_instance_id_seq", initialValue = 1) +public abstract class MpackInstanceEntity { + + @Id + @GeneratedValue(strategy = GenerationType.TABLE, generator = "mpack_instance_id_generator") + @Column(name = "id", nullable = false, updatable = false) + private Long id; + + @Column(name = "mpack_name", nullable = false) + private String mpackName; + + @Column(name = "mpack_version", nullable = false) + private String mpackVersion; + + @Column(name = "mpack_uri") + private String mpackUri; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance") + private Collection serviceInstances = new ArrayList<>(); + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance") + private Collection configurations = new ArrayList<>(); + + @ManyToOne + @JoinColumn(name = "mpack_id", referencedColumnName = "id") + private MpackEntity mpackEntity; + + /** + * @return the service instances belonging to this mpack + */ + public Collection getServiceInstances() { + return serviceInstances; + } + + /** + * @param serviceInstances the service instances belonging to this mpack + */ + public void setServiceInstances(Collection serviceInstances) { + this.serviceInstances = serviceInstances; + } + + /** + * @return the name of the mpack + */ + public String getMpackName() { + return mpackName; + } + + /** + * @param mpackName the name of the mpack + */ + public void setMpackName(String mpackName) { + this.mpackName = mpackName; + } + + /** + * @return the version of the mpack + */ + public String getMpackVersion() { + return mpackVersion; + } + + /** + * @param mpackVersion the version of the mpack + */ + public void setMpackVersion(String mpackVersion) { + this.mpackVersion = mpackVersion; + } + + /** + * @return the uri of the mpack + */ + public String getMpackUri() { + return mpackUri; + } + + /** + * @param mpackUri the uri of the mpack + */ + public void setMpackUri(String mpackUri) { + this.mpackUri = mpackUri; + } + + /** + * @return the database id + */ + public Long getId() { + return id; + } + + /** + * @param id the database id + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the blueprint + */ + public abstract String getBlueprintName(); + + /** + * @return the mpack level configurations for this mpack + */ + public Collection getConfigurations() { + return configurations; + } + + /** + * @param configurations the mpack level configurations for this mpack + */ + public void setConfigurations(Collection configurations) { + this.configurations = configurations; + } + + /** + * @return the management pack entity associated with this blueprint. Can be {@null} + */ + @Nullable + public MpackEntity getMpackEntity() { + return mpackEntity; + } + + /** + * @param mpackEntity the management pack entity to be associated with this blueprint. + */ + public void setMpackEntity(MpackEntity mpackEntity) { + this.mpackEntity = mpackEntity; + } + +} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceServiceEntity.java similarity index 79% rename from ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceEntity.java rename to ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceServiceEntity.java index 96ebe0db1a8..844d892498a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceServiceEntity.java @@ -34,24 +34,24 @@ import javax.persistence.TableGenerator; /** - * Entity representing a service instance in multi-service blueprints + * Entity representing a service instance in multi-service blueprints/cluster templates */ @Entity -@Table(name = "blueprint_service") -@TableGenerator(name = "blueprint_service_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", - valueColumnName = "sequence_value", pkColumnValue = "blueprint_service_id_seq", initialValue = 1) -public class BlueprintServiceEntity { +@Table(name = "mpack_instance_service") +@TableGenerator(name = "mpack_inst_svc_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", + valueColumnName = "sequence_value", pkColumnValue = "mpack_inst_svc_id_seq", initialValue = 1) +public class MpackInstanceServiceEntity { @Id - @GeneratedValue(strategy = GenerationType.TABLE, generator = "blueprint_service_id_generator") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "mpack_inst_svc_id_generator") @Column(name = "id", nullable = false, updatable = false) private Long id; @ManyToOne() @JoinColumn(name = "mpack_instance_id", referencedColumnName = "id", nullable = false) - private BlueprintMpackInstanceEntity mpackInstance; + private MpackInstanceEntity mpackInstance; @OneToMany(cascade = CascadeType.ALL, mappedBy = "service") - private Collection configurations = new ArrayList<>(); + private Collection configurations = new ArrayList<>(); private String name; @@ -74,28 +74,28 @@ public void setId(Long id) { /** * @return the mpack instance to the mpack associated with this service */ - public BlueprintMpackInstanceEntity getMpackInstance() { + public MpackInstanceEntity getMpackInstance() { return mpackInstance; } /** * @param mpackInstance the mpack instance to the mpack associated with this service */ - public void setMpackInstance(BlueprintMpackInstanceEntity mpackInstance) { + public void setMpackInstance(MpackInstanceEntity mpackInstance) { this.mpackInstance = mpackInstance; } /** * @return the service instance level configuration entities */ - public Collection getConfigurations() { + public Collection getConfigurations() { return configurations; } /** * @param configurations the service instance level configuration entities */ - public void setConfigurations(Collection configurations) { + public void setConfigurations(Collection configurations) { this.configurations = configurations; } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackServiceConfigEntity.java similarity index 87% rename from ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceConfigEntity.java rename to ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackServiceConfigEntity.java index d3822882b85..368cab0918f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceConfigEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackServiceConfigEntity.java @@ -30,12 +30,12 @@ import javax.persistence.Table; /** - * Entity representing a blueprint service instance configuration + * Entity representing a mpack instance - service instance configuration */ @Entity -@Table(name = "blueprint_service_config") -@IdClass(BlueprintServiceConfigEntityPk.class) -public class BlueprintServiceConfigEntity implements BlueprintConfiguration { +@Table(name = "mpack_service_config") +@IdClass(MpackServiceConfigEntityPk.class) +public class MpackServiceConfigEntity implements BlueprintConfiguration { @Id @Column(name = "service_id", nullable = false, insertable = false, updatable = false) @@ -57,7 +57,7 @@ public class BlueprintServiceConfigEntity implements BlueprintConfiguration { @ManyToOne @JoinColumn(name = "service_id", referencedColumnName = "id", nullable = false) - private BlueprintServiceEntity service; + private MpackInstanceServiceEntity service; /** * @return the database id of the service instance @@ -85,7 +85,7 @@ public String getType() { */ @Override public String getBlueprintName() { - return getService().getMpackInstance().getBlueprint().getBlueprintName(); + return getService().getMpackInstance().getBlueprintName(); } /** @@ -126,14 +126,14 @@ public void setConfigAttributes(String configAttributes) { /** * @return the service instance this configuration belongs to */ - public BlueprintServiceEntity getService() { + public MpackInstanceServiceEntity getService() { return service; } /** * @param service the service instance this configuration belongs to */ - public void setService(BlueprintServiceEntity service) { + public void setService(MpackInstanceServiceEntity service) { this.service = service; } } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceConfigEntityPk.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackServiceConfigEntityPk.java similarity index 88% rename from ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceConfigEntityPk.java rename to ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackServiceConfigEntityPk.java index 6c13fb76f39..c8543665af6 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintServiceConfigEntityPk.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackServiceConfigEntityPk.java @@ -24,9 +24,9 @@ import javax.persistence.Id; /** - * Composite primary key for {@link BlueprintServiceConfigEntity} + * Composite primary key for {@link MpackServiceConfigEntity} */ -public class BlueprintServiceConfigEntityPk { +public class MpackServiceConfigEntityPk { @Id @Column(name = "service_id", nullable = false, insertable = true, updatable = false) @@ -40,7 +40,7 @@ public class BlueprintServiceConfigEntityPk { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - BlueprintServiceConfigEntityPk that = (BlueprintServiceConfigEntityPk) o; + MpackServiceConfigEntityPk that = (MpackServiceConfigEntityPk) o; return Objects.equals(serviceId, that.serviceId) && Objects.equals(type, that.type); } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java index c90ce154154..c23841c897f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestEntity.java @@ -17,6 +17,7 @@ */ package org.apache.ambari.server.orm.entities; +import java.util.ArrayList; import java.util.Collection; import javax.persistence.Basic; @@ -75,16 +76,15 @@ public class TopologyRequestEntity { @Column(name = "description", length = 1024, nullable = false) private String description; - @Lob - @Column(name = "mpack_instances", length = 100000, nullable = false) - private String mpackInstances; - @OneToMany(mappedBy = "topologyRequestEntity", cascade = CascadeType.ALL) private Collection topologyHostGroupEntities; @OneToOne(mappedBy = "topologyRequestEntity", cascade = CascadeType.ALL) private TopologyLogicalRequestEntity topologyLogicalRequestEntity; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "topologyRequest") + private Collection mpackInstances = new ArrayList<>(); + @Column(name = "provision_action", length = 255, nullable = true) @Enumerated(EnumType.STRING) private ProvisionAction provisionAction; @@ -146,16 +146,16 @@ public void setDescription(String description) { } /** - * @return the mpack instance definitions (mpack name, version, uri, nested configurations) as JSON + * @return the mpack instance definitions associated with this topology request */ - public String getMpackInstances() { + public Collection getMpackInstances() { return mpackInstances; } /** - * @param mpackInstances mpack instance definitions (mpack name, version, uri, nested configurations) as JSON + * @param mpackInstances mpack instance definitions */ - public void setMpackInstances(String mpackInstances) { + public void setMpackInstances(Collection mpackInstances) { this.mpackInstances = mpackInstances; } diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestMpackInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestMpackInstanceEntity.java new file mode 100644 index 00000000000..d9e9d751b7a --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/TopologyRequestMpackInstanceEntity.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.orm.entities; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +@Entity +@DiscriminatorValue("TopologyRequest") +public class TopologyRequestMpackInstanceEntity extends MpackInstanceEntity { + + @ManyToOne + @JoinColumn(name = "topology_request_id", referencedColumnName = "id") + private TopologyRequestEntity topologyRequest; + + /** + * @return the topology request + */ + public TopologyRequestEntity getTopologyRequest() { + return topologyRequest; + } + + /** + * @param topologyRequest the topology request + */ + public void setTopologyRequest(TopologyRequestEntity topologyRequest) { + this.topologyRequest = topologyRequest; + } + + @Override + public String getBlueprintName() { + return topologyRequest.getBlueprintName(); + } +} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java index 47e19bafbe7..3ec3175c0cf 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java @@ -34,11 +34,11 @@ import org.apache.ambari.server.orm.entities.BlueprintConfiguration; import org.apache.ambari.server.orm.entities.BlueprintEntity; import org.apache.ambari.server.orm.entities.BlueprintMpackInstanceEntity; -import org.apache.ambari.server.orm.entities.BlueprintServiceEntity; import org.apache.ambari.server.orm.entities.BlueprintSettingEntity; import org.apache.ambari.server.orm.entities.HostGroupComponentEntity; import org.apache.ambari.server.orm.entities.HostGroupConfigEntity; import org.apache.ambari.server.orm.entities.HostGroupEntity; +import org.apache.ambari.server.orm.entities.MpackInstanceServiceEntity; import org.apache.ambari.server.stack.NoSuchStackException; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.utils.JsonUtils; @@ -173,8 +173,7 @@ public BlueprintEntity toEntity() { private void createMpackInstanceEntities(BlueprintEntity entity) { mpacks.forEach(mpack -> { - BlueprintMpackInstanceEntity mpackEntity = mpack.toEntity(); - mpackEntity.setBlueprint(entity); + BlueprintMpackInstanceEntity mpackEntity = mpack.toMpackInstanceEntity(entity); entity.getMpackInstances().add(mpackEntity); }); } @@ -188,7 +187,7 @@ private Collection parseMpacks(BlueprintEntity blueprintEntity) t mpackInstance.setUrl(mpack.getMpackUri()); mpackInstance.setConfiguration(processConfiguration(mpack.getConfigurations())); // TODO: come up with proper mpack -> stack resolution - for(BlueprintServiceEntity serviceEntity: mpack.getServiceInstances()) { + for(MpackInstanceServiceEntity serviceEntity: mpack.getServiceInstances()) { ServiceInstance serviceInstance = new ServiceInstance( serviceEntity.getName(), serviceEntity.getType(), diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java index 694fde017c9..4b57b600e8b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java @@ -22,10 +22,14 @@ import java.util.Collection; import org.apache.ambari.server.controller.internal.Stack; -import org.apache.ambari.server.orm.entities.BlueprintMpackConfigEntity; +import org.apache.ambari.server.orm.entities.BlueprintEntity; import org.apache.ambari.server.orm.entities.BlueprintMpackInstanceEntity; -import org.apache.ambari.server.orm.entities.BlueprintServiceConfigEntity; -import org.apache.ambari.server.orm.entities.BlueprintServiceEntity; +import org.apache.ambari.server.orm.entities.MpackInstanceConfigEntity; +import org.apache.ambari.server.orm.entities.MpackInstanceEntity; +import org.apache.ambari.server.orm.entities.MpackInstanceServiceEntity; +import org.apache.ambari.server.orm.entities.MpackServiceConfigEntity; +import org.apache.ambari.server.orm.entities.TopologyRequestEntity; +import org.apache.ambari.server.orm.entities.TopologyRequestMpackInstanceEntity; import org.apache.ambari.server.state.StackId; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -117,37 +121,59 @@ public void setUrl(String url) { this.url = url; } - public BlueprintMpackInstanceEntity toEntity() { - BlueprintMpackInstanceEntity mpackEntity = new BlueprintMpackInstanceEntity(); - mpackEntity.setMpackUri(url); - mpackEntity.setMpackName(mpackName); - mpackEntity.setMpackVersion(mpackVersion); - Collection mpackConfigEntities = - BlueprintImpl.toConfigEntities(configuration, BlueprintMpackConfigEntity::new); - mpackConfigEntities.forEach( configEntity -> configEntity.setMpackInstance(mpackEntity) ); - mpackEntity.setConfigurations(mpackConfigEntities); + /** + * Converts the mpack instance to a {@link BlueprintMpackInstanceEntity} + * @param blueprintEntity the blueprint entity will be associated to + * @return the resulting entity + */ + public BlueprintMpackInstanceEntity toMpackInstanceEntity(BlueprintEntity blueprintEntity) { + BlueprintMpackInstanceEntity mpackInstanceEntity = new BlueprintMpackInstanceEntity(); + mpackInstanceEntity.setBlueprint(blueprintEntity); + setCommonProperties(mpackInstanceEntity); + return mpackInstanceEntity; + } + + /** + * Converts the mpack instance to a {@link TopologyRequestMpackInstanceEntity} + * @param topologyRequestEntity the topology request entity will be associated to + * @return the resulting entity + */ + public TopologyRequestMpackInstanceEntity toMpackInstanceEntity(TopologyRequestEntity topologyRequestEntity) { + TopologyRequestMpackInstanceEntity mpackInstanceEntity = new TopologyRequestMpackInstanceEntity(); + mpackInstanceEntity.setTopologyRequest(topologyRequestEntity); + setCommonProperties(mpackInstanceEntity); + return mpackInstanceEntity; + } + + private void setCommonProperties(MpackInstanceEntity mpackInstanceEntity) { + mpackInstanceEntity.setMpackUri(url); + mpackInstanceEntity.setMpackName(mpackName); + mpackInstanceEntity.setMpackVersion(mpackVersion); + Collection mpackConfigEntities = + BlueprintImpl.toConfigEntities(configuration, MpackInstanceConfigEntity::new); + mpackConfigEntities.forEach( configEntity -> configEntity.setMpackInstance(mpackInstanceEntity) ); + mpackInstanceEntity.setConfigurations(mpackConfigEntities); getServiceInstances().forEach(serviceInstance -> { - BlueprintServiceEntity serviceEntity = new BlueprintServiceEntity(); + MpackInstanceServiceEntity serviceEntity = new MpackInstanceServiceEntity(); serviceEntity.setName(serviceInstance.getName()); serviceEntity.setType(serviceInstance.getType()); - Collection serviceConfigEntities = - BlueprintImpl.toConfigEntities(serviceInstance.getConfiguration(), BlueprintServiceConfigEntity::new); + Collection serviceConfigEntities = + BlueprintImpl.toConfigEntities(serviceInstance.getConfiguration(), MpackServiceConfigEntity::new); serviceConfigEntities.forEach( configEntity -> configEntity.setService(serviceEntity) ); serviceEntity.setConfigurations(serviceConfigEntities); - mpackEntity.getServiceInstances().add(serviceEntity); - serviceEntity.setMpackInstance(mpackEntity); + mpackInstanceEntity.getServiceInstances().add(serviceEntity); + serviceEntity.setMpackInstance(mpackInstanceEntity); }); - return mpackEntity; } - public static MpackInstance fromEntity(BlueprintMpackInstanceEntity entity) { + public static MpackInstance fromEntity(MpackInstanceEntity entity) { MpackInstance mpack = new MpackInstance(); mpack.setUrl(entity.getMpackUri()); mpack.setMpackName(entity.getMpackName()); mpack.setMpackVersion(entity.getMpackVersion()); mpack.setConfiguration(BlueprintImpl.fromConfigEntities(entity.getConfigurations())); - for (BlueprintServiceEntity serviceEntity: entity.getServiceInstances()) { + for (MpackInstanceServiceEntity serviceEntity: entity.getServiceInstances()) { ServiceInstance serviceInstance = new ServiceInstance(); serviceInstance.setName(serviceEntity.getName()); serviceInstance.setType(serviceEntity.getType()); diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java index 08f783d544c..5c8c63d03e3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java @@ -18,6 +18,7 @@ package org.apache.ambari.server.topology; +import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; import java.util.ArrayList; @@ -56,11 +57,9 @@ import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.topology.tasks.TopologyTask; -import org.apache.ambari.server.utils.JsonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.core.type.TypeReference; import com.google.gson.Gson; import com.google.inject.persist.Transactional; @@ -328,8 +327,8 @@ public ReplayedTopologyRequest(TopologyRequestEntity entity, BlueprintFactory bl description = entity.getDescription(); provisionAction = entity.getProvisionAction(); - Collection mpackInstances = JsonUtils.fromJson(entity.getMpackInstances(), - new TypeReference>() {}); + Collection mpackInstances = entity.getMpackInstances().stream(). + map(e -> MpackInstance.fromEntity(e)).collect(toList()); stackIds = mpackInstances.stream().map(MpackInstance::getStackId).collect(toSet()); try { diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql index 99c31f4282f..892758fa39e 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql @@ -44,16 +44,6 @@ CREATE TABLE stack ( CONSTRAINT FK_mpacks FOREIGN KEY (mpack_id) REFERENCES mpacks(id), CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version)); -CREATE TABLE mpack_host_state ( - id BIGINT NOT NULL, - host_id BIGINT NOT NULL, - mpack_id BIGINT NOT NULL, - state VARCHAR(32) NOT NULL, - CONSTRAINT PK_mpack_host_state PRIMARY KEY (id), - CONSTRAINT FK_mhs_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id), - CONSTRAINT FK_mhs_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks (id), - CONSTRAINT UQ_mpack_host_state UNIQUE(host_id, mpack_id)); - CREATE TABLE extension( extension_id BIGINT NOT NULL, extension_name VARCHAR(255) NOT NULL, @@ -121,6 +111,16 @@ CREATE TABLE hosts ( CONSTRAINT PK_hosts PRIMARY KEY (host_id), CONSTRAINT UQ_hosts_host_name UNIQUE (host_name)); +CREATE TABLE mpack_host_state ( + id BIGINT NOT NULL, + host_id BIGINT NOT NULL, + mpack_id BIGINT NOT NULL, + state VARCHAR(32) NOT NULL, + CONSTRAINT PK_mpack_host_state PRIMARY KEY (id), + CONSTRAINT FK_mhs_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id), + CONSTRAINT FK_mhs_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks (id), + CONSTRAINT UQ_mpack_host_state UNIQUE(host_id, mpack_id)); + CREATE TABLE clustersettings ( id BIGINT NOT NULL, setting_name VARCHAR(255) NOT NULL, @@ -634,40 +634,43 @@ CREATE TABLE blueprint ( security_descriptor_reference VARCHAR(255), CONSTRAINT PK_blueprint PRIMARY KEY (blueprint_name)); -CREATE TABLE blueprint_mpack_instance( +CREATE TABLE mpack_instance( id BIGINT NOT NULL, - blueprint_name VARCHAR(255) NOT NULL, + owner VARCHAR (20) NOT NULL, + blueprint_name VARCHAR(255), + topology_request_id BIGINT, mpack_name VARCHAR(255) NOT NULL, mpack_version VARCHAR(255) NOT NULL, mpack_uri VARCHAR(255), mpack_id BIGINT, CONSTRAINT PK_blueprint_mpack_inst PRIMARY KEY (id), CONSTRAINT FK_mpi_blueprint_name FOREIGN KEY (blueprint_name) REFERENCES blueprint(blueprint_name), + CONSTRAINT FK_mpi_topology_request FOREIGN KEY (topology_request_id) REFERENCES topology_request(id), CONSTRAINT FK_mpi_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks(id)); -CREATE TABLE blueprint_service ( +CREATE TABLE mpack_instance_service ( id BIGINT NOT NULL, mpack_instance_id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, - CONSTRAINT PK_blueprint_service PRIMARY KEY (id), - CONSTRAINT FK_blueprint_svc_mpack_inst FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_svc_id PRIMARY KEY (id), + CONSTRAINT FK_service_mpack_instance FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); -CREATE TABLE blueprint_service_config ( +CREATE TABLE mpack_service_config ( service_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, - config_data VARCHAR(3000) NOT NULL, - config_attributes VARCHAR(3000), - CONSTRAINT PK_bp_svc_conf PRIMARY KEY (service_id, type_name), - CONSTRAINT FK_bp_svc_config_to_service FOREIGN KEY (service_id) REFERENCES blueprint_service (id)); + config_data VARCHAR(30000) NOT NULL, + config_attributes VARCHAR(30000), + CONSTRAINT PK_mpack_svc_conf PRIMARY KEY (service_id, type_name), + CONSTRAINT FK_mpack_svc_config_to_service FOREIGN KEY (service_id) REFERENCES mpack_instance_service (id)); -CREATE TABLE blueprint_mpack_configuration ( +CREATE TABLE mpack_instance_config ( mpack_instance_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, - config_data VARCHAR(3000) NOT NULL, - config_attributes VARCHAR(3000), - CONSTRAINT PK_bp_mpack_conf PRIMARY KEY (mpack_instance_id, type_name), - CONSTRAINT FK_bp_mpack_config_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + config_data VARCHAR(30000) NOT NULL, + config_attributes VARCHAR(30000), + CONSTRAINT PK_mpack_inst_conf PRIMARY KEY (mpack_instance_id, type_name), + CONSTRAINT FK_mpack_inst_conf_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); CREATE TABLE hostgroup ( blueprint_name VARCHAR(255) NOT NULL, @@ -893,7 +896,6 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - mpack_instances CLOB NOT NULL, cluster_properties VARCHAR(3000), cluster_attributes VARCHAR(3000), description VARCHAR(1024), @@ -1373,9 +1375,9 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) union all select 'hostcomponentdesiredstate_id_seq', 0 FROM SYSIBM.SYSDUMMY1 union all - select 'blueprint_service_id_seq', 0 FROM SYSIBM.SYSDUMMY1 + select 'mpack_inst_svc_id_seq', 0 FROM SYSIBM.SYSDUMMY1 union all - select 'blueprint_mpack_instance_id_seq', 0 FROM SYSIBM.SYSDUMMY1 + select 'mpack_instance_id_seq', 0 FROM SYSIBM.SYSDUMMY1 union all select 'hostgroup_component_id_seq', 0 FROM SYSIBM.SYSDUMMY1; 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 2c27bd8539b..5673b0767a1 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -652,40 +652,43 @@ CREATE TABLE blueprint ( security_descriptor_reference VARCHAR(255), CONSTRAINT PK_blueprint PRIMARY KEY (blueprint_name)); -CREATE TABLE blueprint_mpack_instance( +CREATE TABLE mpack_instance( id BIGINT NOT NULL, - blueprint_name VARCHAR(255) NOT NULL, + owner VARCHAR (20) NOT NULL, + blueprint_name VARCHAR(255), + topology_request_id BIGINT, mpack_name VARCHAR(255) NOT NULL, mpack_version VARCHAR(255) NOT NULL, mpack_uri VARCHAR(255), mpack_id BIGINT, CONSTRAINT PK_blueprint_mpack_inst PRIMARY KEY (id), CONSTRAINT FK_mpi_blueprint_name FOREIGN KEY (blueprint_name) REFERENCES blueprint(blueprint_name), + CONSTRAINT FK_mpi_topology_request FOREIGN KEY (topology_request_id) REFERENCES topology_request(id), CONSTRAINT FK_mpi_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks(id)); -CREATE TABLE blueprint_service ( +CREATE TABLE mpack_instance_service ( id BIGINT NOT NULL, mpack_instance_id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, - CONSTRAINT PK_blueprint_service PRIMARY KEY (id), - CONSTRAINT FK_blueprint_svc_mpack_inst FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_svc_id PRIMARY KEY (id), + CONSTRAINT FK_service_mpack_instance FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); -CREATE TABLE blueprint_service_config ( +CREATE TABLE mpack_service_config ( service_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, config_data LONGTEXT NOT NULL, config_attributes LONGTEXT, - CONSTRAINT PK_bp_svc_conf PRIMARY KEY (service_id, type_name), - CONSTRAINT FK_bp_svc_config_to_service FOREIGN KEY (service_id) REFERENCES blueprint_service (id)); + CONSTRAINT PK_mpack_svc_conf PRIMARY KEY (service_id, type_name), + CONSTRAINT FK_mpack_svc_config_to_service FOREIGN KEY (service_id) REFERENCES mpack_instance_service (id)); -CREATE TABLE blueprint_mpack_configuration ( +CREATE TABLE mpack_instance_config ( mpack_instance_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, config_data LONGTEXT NOT NULL, config_attributes LONGTEXT, - CONSTRAINT PK_bp_mpack_conf PRIMARY KEY (mpack_instance_id, type_name), - CONSTRAINT FK_bp_mpack_config_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_conf PRIMARY KEY (mpack_instance_id, type_name), + CONSTRAINT FK_mpack_inst_conf_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); CREATE TABLE hostgroup ( blueprint_name VARCHAR(100) NOT NULL, @@ -910,7 +913,6 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - mpack_instances LONGTEXT NOT NULL, cluster_properties LONGTEXT, cluster_attributes LONGTEXT, description VARCHAR(1024), @@ -1325,8 +1327,8 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES ('remote_cluster_id_seq', 0), ('remote_cluster_service_id_seq', 0), ('hostcomponentdesiredstate_id_seq', 0), - ('blueprint_service_id_seq', 0), - ('blueprint_mpack_instance_id_seq', 0), + ('mpack_inst_svc_id_seq', 0), + ('mpack_instance_id_seq', 0), ('hostgroup_component_id_seq', 0); INSERT INTO adminresourcetype (resource_type_id, resource_type_name) VALUES 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 2848d9f38bb..2f3ebf039c1 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -632,40 +632,43 @@ CREATE TABLE blueprint ( security_descriptor_reference VARCHAR2(255), CONSTRAINT PK_blueprint PRIMARY KEY (blueprint_name)); -CREATE TABLE blueprint_mpack_instance( +CREATE TABLE mpack_instance( id NUMBER(19) NOT NULL, - blueprint_name VARCHAR2(255) NOT NULL, + owner VARCHAR2 (20) NOT NULL, + blueprint_name VARCHAR2(255), + topology_request_id NUMBER(19), mpack_name VARCHAR2(255) NOT NULL, mpack_version VARCHAR2(255) NOT NULL, mpack_uri VARCHAR2(255), mpack_id NUMBER(19), CONSTRAINT PK_blueprint_mpack_inst PRIMARY KEY (id), CONSTRAINT FK_mpi_blueprint_name FOREIGN KEY (blueprint_name) REFERENCES blueprint(blueprint_name), + CONSTRAINT FK_mpi_topology_request FOREIGN KEY (topology_request_id) REFERENCES topology_request(id), CONSTRAINT FK_mpi_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks(id)); -CREATE TABLE blueprint_service ( +CREATE TABLE mpack_instance_service ( id NUMBER(19) NOT NULL, mpack_instance_id NUMBER(19) NOT NULL, name VARCHAR2(255) NOT NULL, type VARCHAR2(255) NOT NULL, - CONSTRAINT PK_blueprint_service PRIMARY KEY (id), - CONSTRAINT FK_blueprint_svc_mpack_inst FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_svc_id PRIMARY KEY (id), + CONSTRAINT FK_service_mpack_instance FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); -CREATE TABLE blueprint_service_config ( +CREATE TABLE mpack_service_config ( service_id NUMBER(19) NOT NULL, type_name VARCHAR2(255) NOT NULL, config_data CLOB NOT NULL, config_attributes CLOB, - CONSTRAINT PK_bp_svc_conf PRIMARY KEY (service_id, type_name), - CONSTRAINT FK_bp_svc_config_to_service FOREIGN KEY (service_id) REFERENCES blueprint_service (id)); + CONSTRAINT PK_mpack_svc_conf PRIMARY KEY (service_id, type_name), + CONSTRAINT FK_mpack_svc_config_to_service FOREIGN KEY (service_id) REFERENCES mpack_instance_service (id)); -CREATE TABLE blueprint_mpack_configuration ( +CREATE TABLE mpack_instance_config ( mpack_instance_id NUMBER(19) NOT NULL, type_name VARCHAR2(255) NOT NULL, config_data CLOB NOT NULL, config_attributes CLOB, - CONSTRAINT PK_bp_mpack_conf PRIMARY KEY (mpack_instance_id, type_name), - CONSTRAINT FK_bp_mpack_config_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_conf PRIMARY KEY (mpack_instance_id, type_name), + CONSTRAINT FK_mpack_inst_conf_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); CREATE TABLE hostgroup ( blueprint_name VARCHAR2(255) NOT NULL, @@ -888,7 +891,6 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id NUMBER(19) NOT NULL, bp_name VARCHAR(100) NOT NULL, - mpack_instances CLOB NOT NULL, cluster_properties CLOB, cluster_attributes CLOB, description VARCHAR(1024), @@ -1303,8 +1305,8 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('ambari_oper INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostcomponentdesiredstate_id_seq', 0); -INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('blueprint_service_id_seq', 0); -INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('blueprint_mpack_instance_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('mpack_inst_svc_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('mpack_instance_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostgroup_component_id_seq', 0); INSERT INTO metainfo("metainfo_key", "metainfo_value") values ('version', '${ambariSchemaVersion}'); 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 c727dddd429..45eb946cdf3 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -634,40 +634,43 @@ CREATE TABLE blueprint ( security_descriptor_reference VARCHAR(255), CONSTRAINT PK_blueprint PRIMARY KEY (blueprint_name)); -CREATE TABLE blueprint_mpack_instance( +CREATE TABLE mpack_instance( id BIGINT NOT NULL, - blueprint_name VARCHAR(255) NOT NULL, + owner VARCHAR (20) NOT NULL, + blueprint_name VARCHAR(255), + topology_request_id BIGINT, mpack_name VARCHAR(255) NOT NULL, mpack_version VARCHAR(255) NOT NULL, mpack_uri VARCHAR(255), mpack_id BIGINT, CONSTRAINT PK_blueprint_mpack_inst PRIMARY KEY (id), CONSTRAINT FK_mpi_blueprint_name FOREIGN KEY (blueprint_name) REFERENCES blueprint(blueprint_name), + CONSTRAINT FK_mpi_topology_request FOREIGN KEY (topology_request_id) REFERENCES topology_request(id), CONSTRAINT FK_mpi_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks(id)); -CREATE TABLE blueprint_service ( +CREATE TABLE mpack_instance_service ( id BIGINT NOT NULL, mpack_instance_id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, - CONSTRAINT PK_blueprint_service PRIMARY KEY (id), - CONSTRAINT FK_blueprint_svc_mpack_inst FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_svc_id PRIMARY KEY (id), + CONSTRAINT FK_service_mpack_instance FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); -CREATE TABLE blueprint_service_config ( +CREATE TABLE mpack_service_config ( service_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, config_data TEXT NOT NULL, config_attributes TEXT, - CONSTRAINT PK_bp_svc_conf PRIMARY KEY (service_id, type_name), - CONSTRAINT FK_bp_svc_config_to_service FOREIGN KEY (service_id) REFERENCES blueprint_service (id)); + CONSTRAINT PK_mpack_svc_conf PRIMARY KEY (service_id, type_name), + CONSTRAINT FK_mpack_svc_config_to_service FOREIGN KEY (service_id) REFERENCES mpack_instance_service (id)); -CREATE TABLE blueprint_mpack_configuration ( +CREATE TABLE mpack_instance_config ( mpack_instance_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, config_data TEXT NOT NULL, config_attributes TEXT, - CONSTRAINT PK_bp_mpack_conf PRIMARY KEY (mpack_instance_id, type_name), - CONSTRAINT FK_bp_mpack_config_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_conf PRIMARY KEY (mpack_instance_id, type_name), + CONSTRAINT FK_mpack_inst_conf_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); CREATE TABLE hostgroup ( blueprint_name VARCHAR(255) NOT NULL, @@ -894,7 +897,6 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - mpack_instances TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), @@ -1304,8 +1306,8 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) VALUES ('ambari_operation_history_id_seq', 0), ('remote_cluster_id_seq', 0), ('remote_cluster_service_id_seq', 0), - ('blueprint_service_id_seq', 0), - ('blueprint_mpack_instance_id_seq', 0), + ('mpack_inst_svc_id_seq', 0), + ('mpack_instance_id_seq', 0), ('hostgroup_component_id_seq', 0), ('repo_os_id_seq', 0), ('repo_definition_id_seq', 0), diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql index 6428889ac1d..774906a8826 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql @@ -630,40 +630,43 @@ CREATE TABLE blueprint ( security_descriptor_reference VARCHAR(255), CONSTRAINT PK_blueprint PRIMARY KEY (blueprint_name)); -CREATE TABLE blueprint_mpack_instance( +CREATE TABLE mpack_instance( id NUMERIC(19) NOT NULL, - blueprint_name VARCHAR(255) NOT NULL, + owner VARCHAR (20) NOT NULL, + blueprint_name VARCHAR(255), + topology_request_id NUMERIC(19), mpack_name VARCHAR(255) NOT NULL, mpack_version VARCHAR(255) NOT NULL, mpack_uri VARCHAR(255), mpack_id NUMERIC(19), CONSTRAINT PK_blueprint_mpack_inst PRIMARY KEY (id), CONSTRAINT FK_mpi_blueprint_name FOREIGN KEY (blueprint_name) REFERENCES blueprint(blueprint_name), + CONSTRAINT FK_mpi_topology_request FOREIGN KEY (topology_request_id) REFERENCES topology_request(id), CONSTRAINT FK_mpi_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks(id)); -CREATE TABLE blueprint_service ( +CREATE TABLE mpack_instance_service ( id NUMERIC(19) NOT NULL, - mpack_instance_id BIGINT NOT NULL, + mpack_instance_id NUMERIC(19) NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, - CONSTRAINT PK_blueprint_service PRIMARY KEY (id), - CONSTRAINT FK_blueprint_svc_mpack_inst FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_svc_id PRIMARY KEY (id), + CONSTRAINT FK_service_mpack_instance FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); -CREATE TABLE blueprint_service_config ( +CREATE TABLE mpack_service_config ( service_id NUMERIC(19) NOT NULL, type_name VARCHAR(255) NOT NULL, config_data TEXT NOT NULL, config_attributes TEXT, - CONSTRAINT PK_bp_svc_conf PRIMARY KEY (service_id, type_name), - CONSTRAINT FK_bp_svc_config_to_service FOREIGN KEY (service_id) REFERENCES blueprint_service (id)); + CONSTRAINT PK_mpack_svc_conf PRIMARY KEY (service_id, type_name), + CONSTRAINT FK_mpack_svc_config_to_service FOREIGN KEY (service_id) REFERENCES mpack_instance_service (id)); -CREATE TABLE blueprint_mpack_configuration ( +CREATE TABLE mpack_instance_config ( mpack_instance_id NUMERIC(19) NOT NULL, type_name VARCHAR(255) NOT NULL, config_data TEXT NOT NULL, config_attributes TEXT, - CONSTRAINT PK_bp_mpack_conf PRIMARY KEY (mpack_instance_id, type_name), - CONSTRAINT FK_bp_mpack_config_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_conf PRIMARY KEY (mpack_instance_id, type_name), + CONSTRAINT FK_mpack_inst_conf_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); CREATE TABLE hostgroup ( blueprint_name VARCHAR(255) NOT NULL, @@ -888,7 +891,6 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id NUMERIC(19) NOT NULL, bp_name VARCHAR(100) NOT NULL, - mpack_instances TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), @@ -1303,8 +1305,8 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('ambari_oper INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostcomponentdesiredstate_id_seq', 0); -INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('blueprint_service_id_seq', 0); -INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('blueprint_mpack_instance_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('mpack_inst_svc_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('mpack_instance_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostgroup_component_id_seq', 0); insert into adminresourcetype (resource_type_id, resource_type_name) diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql index 2e45445a83d..386e88eaef3 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql @@ -639,40 +639,43 @@ CREATE TABLE blueprint ( security_descriptor_reference VARCHAR(255), CONSTRAINT PK_blueprint PRIMARY KEY CLUSTERED (blueprint_name)); -CREATE TABLE blueprint_mpack_instance( +CREATE TABLE mpack_instance( id BIGINT NOT NULL, - blueprint_name VARCHAR(255) NOT NULL, + owner VARCHAR (20) NOT NULL, + blueprint_name VARCHAR(255), + topology_request_id BIGINT, mpack_name VARCHAR(255) NOT NULL, mpack_version VARCHAR(255) NOT NULL, mpack_uri VARCHAR(255), mpack_id BIGINT, CONSTRAINT PK_blueprint_mpack_inst PRIMARY KEY (id), CONSTRAINT FK_mpi_blueprint_name FOREIGN KEY (blueprint_name) REFERENCES blueprint(blueprint_name), + CONSTRAINT FK_mpi_topology_request FOREIGN KEY (topology_request_id) REFERENCES topology_request(id), CONSTRAINT FK_mpi_mpack_id FOREIGN KEY (mpack_id) REFERENCES mpacks(id)); -CREATE TABLE blueprint_service ( +CREATE TABLE mpack_instance_service ( id BIGINT NOT NULL, mpack_instance_id BIGINT NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, - CONSTRAINT PK_blueprint_service PRIMARY KEY (id), - CONSTRAINT FK_blueprint_svc_mpack_inst FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_svc_id PRIMARY KEY (id), + CONSTRAINT FK_service_mpack_instance FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); -CREATE TABLE blueprint_service_config ( +CREATE TABLE mpack_service_config ( service_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, config_data TEXT NOT NULL, config_attributes TEXT, - CONSTRAINT PK_bp_svc_conf PRIMARY KEY (service_id, type_name), - CONSTRAINT FK_bp_svc_config_to_service FOREIGN KEY (service_id) REFERENCES blueprint_service (id)); + CONSTRAINT PK_mpack_svc_conf PRIMARY KEY (service_id, type_name), + CONSTRAINT FK_mpack_svc_config_to_service FOREIGN KEY (service_id) REFERENCES mpack_instance_service (id)); -CREATE TABLE blueprint_mpack_configuration ( +CREATE TABLE mpack_instance_config ( mpack_instance_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, config_data TEXT NOT NULL, config_attributes TEXT, - CONSTRAINT PK_bp_mpack_conf PRIMARY KEY (mpack_instance_id, type_name), - CONSTRAINT FK_bp_mpack_config_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES blueprint_mpack_instance(id)); + CONSTRAINT PK_mpack_inst_conf PRIMARY KEY (mpack_instance_id, type_name), + CONSTRAINT FK_mpack_inst_conf_to_mpack FOREIGN KEY (mpack_instance_id) REFERENCES mpack_instance(id)); CREATE TABLE hostgroup ( blueprint_name VARCHAR(255) NOT NULL, @@ -911,7 +914,6 @@ CREATE TABLE topology_request ( action VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, bp_name VARCHAR(100) NOT NULL, - mpack_instances TEXT NOT NULL, cluster_properties TEXT, cluster_attributes TEXT, description VARCHAR(1024), @@ -1331,8 +1333,8 @@ BEGIN TRANSACTION ('remote_cluster_id_seq', 0), ('remote_cluster_service_id_seq', 0), ('hostcomponentdesiredstate_id_seq', 0), - ('blueprint_service_id_seq', 0), - ('blueprint_mpack_instance_id_seq', 0), + ('mpack_inst_svc_id_seq', 0), + ('mpack_instance_id_seq', 0), ('hostgroup_component_id_seq', 0); insert into adminresourcetype (resource_type_id, resource_type_name) diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml index 79f051e2f7c..331fd0ffba0 100644 --- a/ambari-server/src/main/resources/META-INF/persistence.xml +++ b/ambari-server/src/main/resources/META-INF/persistence.xml @@ -23,10 +23,12 @@ org.apache.ambari.server.orm.entities.BlueprintConfigEntity org.apache.ambari.server.orm.entities.BlueprintSettingEntity org.apache.ambari.server.orm.entities.BlueprintEntity + org.apache.ambari.server.orm.entities.MpackInstanceEntity org.apache.ambari.server.orm.entities.BlueprintMpackInstanceEntity - org.apache.ambari.server.orm.entities.BlueprintMpackConfigEntity - org.apache.ambari.server.orm.entities.BlueprintServiceEntity - org.apache.ambari.server.orm.entities.BlueprintServiceConfigEntity + org.apache.ambari.server.orm.entities.TopologyRequestMpackInstanceEntity + org.apache.ambari.server.orm.entities.MpackInstanceConfigEntity + org.apache.ambari.server.orm.entities.MpackInstanceServiceEntity + org.apache.ambari.server.orm.entities.MpackServiceConfigEntity org.apache.ambari.server.orm.entities.ClusterConfigEntity org.apache.ambari.server.orm.entities.ClusterEntity org.apache.ambari.server.orm.entities.ServiceGroupEntity diff --git a/ambari-server/src/test/java/org/apache/ambari/server/H2DatabaseCleaner.java b/ambari-server/src/test/java/org/apache/ambari/server/H2DatabaseCleaner.java index 047c600a904..14431895656 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/H2DatabaseCleaner.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/H2DatabaseCleaner.java @@ -93,6 +93,8 @@ public class H2DatabaseCleaner { sequenceList.add("host_role_command_id_seq"); sequenceList.add("alert_definition_id_seq"); sequenceList.add("resource_type_id_seq"); + sequenceList.add("mpack_inst_svc_id_seq"); + sequenceList.add("mpack_instance_id_seq"); } public static void clearDatabaseAndStopPersistenceService(Injector injector) throws AmbariException, SQLException { diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java index be0682a486c..8ce6823c3b4 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java @@ -44,6 +44,7 @@ import java.util.Set; import org.apache.ambari.server.controller.spi.ResourceProvider; +import org.apache.ambari.server.orm.entities.MpackInstanceEntity; import org.apache.ambari.server.orm.entities.TopologyRequestEntity; import org.apache.ambari.server.security.encryption.CredentialStoreType; import org.apache.ambari.server.state.SecurityType; @@ -55,7 +56,6 @@ import org.apache.ambari.server.topology.InvalidTopologyTemplateException; import org.apache.ambari.server.topology.SecurityConfiguration; import org.apache.ambari.server.topology.TopologyRequest; -import org.apache.ambari.server.utils.JsonUtils; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -625,7 +625,10 @@ public void testToEntity() throws Exception { properties, new SecurityConfiguration(SecurityType.NONE)); TopologyRequestEntity entity = request.toEntity(); - assertEquals(mpackInstances, JsonUtils.fromJson(entity.getMpackInstances(), List.class)); + assertEquals(1, entity.getMpackInstances().size()); + MpackInstanceEntity mpack = entity.getMpackInstances().iterator().next(); + assertEquals("HDPCORE", mpack.getMpackName()); + assertEquals("1.0.0.0", mpack.getMpackVersion()); } } diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest2.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest2.java index 0e4f61a284b..275bf076023 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest2.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/BlueprintEntityTest2.java @@ -86,7 +86,7 @@ private void verifyBlueprint(BlueprintEntity blueprintEntity) { assertEquals("HDPCORE", mpackInstanceEntity.getMpackName()); assertEquals(1, mpackInstanceEntity.getConfigurations().size()); - BlueprintMpackConfigEntity mpackConfigEntity = + MpackInstanceConfigEntity mpackConfigEntity = mpackInstanceEntity.getConfigurations().iterator().next(); assertEquals("configdata", mpackConfigEntity.getConfigData()); assertEquals("zk-env.sh", mpackConfigEntity.getType()); @@ -107,7 +107,7 @@ private void verifyBlueprint(BlueprintEntity blueprintEntity) { assertEquals("hdfs-site", hostGroupConfig.getType()); assertEquals(1, mpackInstanceEntity.getServiceInstances().size()); - BlueprintServiceEntity service = mpackInstanceEntity.getServiceInstances().iterator().next(); + MpackInstanceServiceEntity service = mpackInstanceEntity.getServiceInstances().iterator().next(); assertEquals("ZK1", service.getName()); assertEquals("ZOOKEEPER", service.getType()); assertSame(mpackInstanceEntity, service.getMpackInstance()); @@ -127,7 +127,7 @@ private BlueprintEntity createTestBlueprint() { mpackInstanceEntity.setMpackVersion("3.0.0.0"); mpackInstanceEntity.setMpackUri("http://hdpcore.org/3.0.0.0"); - BlueprintMpackConfigEntity mpackConfigEntity = new BlueprintMpackConfigEntity(); + MpackInstanceConfigEntity mpackConfigEntity = new MpackInstanceConfigEntity(); mpackConfigEntity.setMpackInstance(mpackInstanceEntity); mpackConfigEntity.setConfigAttributes("attributes"); mpackConfigEntity.setConfigData("configdata"); @@ -159,13 +159,13 @@ private BlueprintEntity createTestBlueprint() { hgComponentEntity2.setServiceName("ZK1"); hostGroupEntity.addComponent(hgComponentEntity2); - BlueprintServiceEntity blueprintService = new BlueprintServiceEntity(); + MpackInstanceServiceEntity blueprintService = new MpackInstanceServiceEntity(); blueprintService.setMpackInstance(mpackInstanceEntity); blueprintService.setName("ZK1"); blueprintService.setType("ZOOKEEPER"); mpackInstanceEntity.getServiceInstances().add(blueprintService); - BlueprintServiceConfigEntity blueprintServiceConfigEntity = new BlueprintServiceConfigEntity(); + MpackServiceConfigEntity blueprintServiceConfigEntity = new MpackServiceConfigEntity(); blueprintServiceConfigEntity.setService(blueprintService); blueprintServiceConfigEntity.setType("hadoop-env"); blueprintServiceConfigEntity.setConfigAttributes("attributes"); diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java index 1d1c9df01f8..96222499646 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/PersistedStateImplTest.java @@ -26,6 +26,7 @@ import org.apache.ambari.server.controller.internal.ProvisionAction; import org.apache.ambari.server.orm.entities.TopologyRequestEntity; +import org.apache.ambari.server.orm.entities.TopologyRequestMpackInstanceEntity; import org.apache.ambari.server.state.StackId; import org.easymock.EasyMockRunner; import org.easymock.Mock; @@ -33,6 +34,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @RunWith(EasyMockRunner.class) @@ -60,9 +62,10 @@ public void testPersistedTopologyRequest_stackIdsDepersistedCorrectly() { entity.setClusterAttributes("{}"); entity.setDescription("Provision Cluster c1"); entity.setTopologyHostGroupEntities(emptyList()); - entity.setMpackInstances( - "[{'name':'HDPCORE','version':'1.0.0.0','service_instances':[],'configurations':[]}]". - replace('\'', '"')); + TopologyRequestMpackInstanceEntity mpackInstanceEntity = new TopologyRequestMpackInstanceEntity(); + mpackInstanceEntity.setMpackName("HDPCORE"); + mpackInstanceEntity.setMpackVersion("1.0.0.0"); + entity.setMpackInstances(ImmutableList.of(mpackInstanceEntity)); PersistedStateImpl.ReplayedTopologyRequest request = new PersistedStateImpl.ReplayedTopologyRequest(entity, blueprintFactory); assertEquals(ImmutableSet.of(new StackId("HDPCORE", "1.0.0.0")), request.getStackIds()); From f1302f740be893f1174e22fd5749cfabffb6cac0 Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Tue, 13 Mar 2018 17:01:42 +0100 Subject: [PATCH 7/8] AMBARI-23130 fix broken unit test (benyoka) --- .../server/api/query/render/ClusterBlueprintRenderer.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java index e34fcb13361..50a41d6d9d8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java @@ -85,12 +85,6 @@ public class ClusterBlueprintRenderer extends BaseRenderer implements Renderer { */ private AmbariManagementController controller = AmbariServer.getController(); - - /** - * MetaInfo used to get stack and mpack information. - */ - private AmbariMetaInfo metaInfo = controller.getAmbariMetaInfo(); - // /** // * Map of configuration type to configuration properties which are required that a user // * input. These properties will be stripped from the exported blueprint. From d28589c9fabe91b00bba3ebdf806a9e1e3b2c1a3 Mon Sep 17 00:00:00 2001 From: Balazs Bence Sari <> Date: Mon, 19 Mar 2018 10:28:24 +0100 Subject: [PATCH 8/8] AMBARI-23130 fix import and review comments --- .../server/api/query/render/ClusterBlueprintRenderer.java | 1 - .../ambari/server/orm/entities/MpackInstanceEntity.java | 4 ++-- .../server/orm/entities/MpackInstanceServiceEntity.java | 2 +- .../org/apache/ambari/server/topology/MpackInstance.java | 6 ++++++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java index 50a41d6d9d8..493ea0ebec6 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java @@ -33,7 +33,6 @@ import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.query.QueryInfo; -import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.api.services.Request; import org.apache.ambari.server.api.services.Result; import org.apache.ambari.server.api.services.ResultImpl; diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java index 868bc24a138..19561087d40 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceEntity.java @@ -65,10 +65,10 @@ public abstract class MpackInstanceEntity { @Column(name = "mpack_uri") private String mpackUri; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance") + @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance", orphanRemoval = true) private Collection serviceInstances = new ArrayList<>(); - @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance") + @OneToMany(cascade = CascadeType.ALL, mappedBy = "mpackInstance", orphanRemoval = true) private Collection configurations = new ArrayList<>(); @ManyToOne diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceServiceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceServiceEntity.java index 844d892498a..e25246a11b5 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceServiceEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackInstanceServiceEntity.java @@ -50,7 +50,7 @@ public class MpackInstanceServiceEntity { @JoinColumn(name = "mpack_instance_id", referencedColumnName = "id", nullable = false) private MpackInstanceEntity mpackInstance; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "service") + @OneToMany(cascade = CascadeType.ALL, mappedBy = "service", orphanRemoval = true) private Collection configurations = new ArrayList<>(); private String name; diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java index 4b57b600e8b..23091b5759f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/MpackInstance.java @@ -145,6 +145,12 @@ public TopologyRequestMpackInstanceEntity toMpackInstanceEntity(TopologyRequestE return mpackInstanceEntity; } + /** + * Used during conversion to {@link MpackInstanceEntity}. Sets the common properties that are shared across all + * {@link MpackInstanceEntity} subclasses. Bidirectional relations are handled for {@link MpackInstanceConfigEntity}, + * {@link MpackInstanceServiceEntity} and {@link MpackServiceConfigEntity} entites. + * @param mpackInstanceEntity the entity to set the properties on + */ private void setCommonProperties(MpackInstanceEntity mpackInstanceEntity) { mpackInstanceEntity.setMpackUri(url); mpackInstanceEntity.setMpackName(mpackName);