This is an automated email from the ASF dual-hosted git repository. ncole pushed a commit to branch branch-feature-AMBARI-14714 in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714 by this push: new 36a64f6 [Ambari 23318] API Addition for Upgrade Plan (#744) 36a64f6 is described below commit 36a64f699c9fedc05b09ced1a22cc6e4e69d18e2 Author: ncole <nc...@hortonworks.com> AuthorDate: Wed Mar 21 15:24:05 2018 -0400 [Ambari 23318] API Addition for Upgrade Plan (#744) * [AMBARI-23318] API Addition for Upgrade Plan * API Addition for Upgrade Plan - update for review comments --- .../api/resources/ResourceInstanceFactoryImpl.java | 5 + .../ambari/server/api/services/ClusterService.java | 18 +- .../server/api/services/UpgradePlanService.java | 114 +++++++ .../controller/internal/DefaultProviderModule.java | 2 + .../internal/UpgradePlanResourceProvider.java | 341 +++++++++++++++++++++ .../ambari/server/controller/spi/Resource.java | 2 + .../ambari/server/orm/dao/UpgradePlanDAO.java | 31 ++ .../orm/entities/UpgradePlanDetailEntity.java | 118 +++++++ .../server/orm/entities/UpgradePlanEntity.java | 244 +++++++++++++++ .../src/main/resources/Ambari-DDL-Derby-CREATE.sql | 30 +- .../src/main/resources/Ambari-DDL-MySQL-CREATE.sql | 25 ++ .../main/resources/Ambari-DDL-Oracle-CREATE.sql | 25 ++ .../main/resources/Ambari-DDL-Postgres-CREATE.sql | 26 +- .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 26 ++ .../main/resources/Ambari-DDL-SQLServer-CREATE.sql | 26 +- .../src/main/resources/META-INF/persistence.xml | 2 + .../internal/UpgradePlanResourceProviderTest.java | 148 +++++++++ 17 files changed, 1178 insertions(+), 5 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java index 259ef70..d7e7fda 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java @@ -453,6 +453,11 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory { Resource.Type.UpgradeItem, "upgrade_item", "upgrade_items", Resource.Type.Task); break; + case UpgradePlan: + resourceDefinition = new SimpleResourceDefinition( + Resource.Type.UpgradePlan, "upgrade_plan", "upgrade_plans"); + break; + case UpgradeSummary: resourceDefinition = new SimpleResourceDefinition( Resource.Type.UpgradeSummary, "upgrade_summary", "upgrade_summary"); diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java index 31af4e0..140f916 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java @@ -767,6 +767,22 @@ public class ClusterService extends BaseService { } /** + * Gets the services for upgrade plans. + * + * @param request the request + * @param clusterName the cluster name + * + * @return the upgrade plan services + */ + @Path("{clusterName}/upgrade_plans") + public UpgradePlanService getUpgradePlanService( + @Context javax.ws.rs.core.Request request, + @PathParam("clusterName") String clusterName) { + return new UpgradePlanService(clusterName); + } + + + /** * Gets a list of upgrade summaries. * * @param request the request @@ -780,7 +796,7 @@ public class ClusterService extends BaseService { @PathParam("clusterName") String clusterName) { return new UpgradeSummaryService(clusterName); } - + /** * Gets the pre-upgrade checks service. * diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpgradePlanService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpgradePlanService.java new file mode 100644 index 0000000..256addd --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpgradePlanService.java @@ -0,0 +1,114 @@ +/* + * 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.api.services; + +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.ambari.annotations.ApiIgnore; +import org.apache.ambari.server.api.resources.ResourceInstance; +import org.apache.ambari.server.controller.spi.Resource; + +/** + * Endpoint for cluster upgrade plans. + */ +public class UpgradePlanService extends BaseService { + + private String m_clusterName = null; + + /** + * Constructor. + * + * @param clusterName the cluster name (not {@code null}). + */ + UpgradePlanService(String clusterName) { + m_clusterName = clusterName; + } + + @POST @ApiIgnore // until documented + @Produces(MediaType.TEXT_PLAIN) + public Response createPlan(String body, + @Context HttpHeaders headers, + @Context UriInfo ui) { + return handleRequest(headers, body, ui, Request.Type.POST, + createResourceInstance(null)); + } + + @GET @ApiIgnore // until documented + @Produces(MediaType.TEXT_PLAIN) + public Response getPlans( @Context HttpHeaders headers, + @Context UriInfo ui) { + return handleRequest(headers, null, ui, Request.Type.GET, + createResourceInstance(null)); + } + + @GET @ApiIgnore // until documented + @Path("{upgradePlanId}") + @Produces(MediaType.TEXT_PLAIN) + public Response getPlan(@Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("upgradePlanId") Long id) { + return handleRequest(headers, null, ui, Request.Type.GET, + createResourceInstance(id)); + } + + @PUT @ApiIgnore // until documented + @Path("{upgradePlanId}") + @Produces(MediaType.TEXT_PLAIN) + public Response updatePlan(String body, @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("upgradePlanId") Long id) { + return handleRequest(headers, body, ui, Request.Type.PUT, + createResourceInstance(id)); + } + + @DELETE @ApiIgnore // until documented + @Path("{upgradePlanId}") + @Produces(MediaType.TEXT_PLAIN) + public Response deleteUpgradePlan(String body, @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("upgradePlanId") Long id) { + return handleRequest(headers, body, ui, Request.Type.DELETE, + createResourceInstance(id)); + } + + /** + * @param upgradePlanId the upgrade plan id + * @return the resource instance + */ + private ResourceInstance createResourceInstance(Long upgradePlanId) { + Map<Resource.Type, String> mapIds = new HashMap<>(); + mapIds.put(Resource.Type.Cluster, m_clusterName); + + if (null != upgradePlanId) { + mapIds.put(Resource.Type.UpgradePlan, upgradePlanId.toString()); + } + + return createResource(Resource.Type.UpgradePlan, mapIds); + } +} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java index ceeee92..8a4a385 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java @@ -114,6 +114,8 @@ public class DefaultProviderModule extends AbstractProviderModule { return new UpgradeGroupResourceProvider(managementController); case UpgradeItem: return new UpgradeItemResourceProvider(managementController); + case UpgradePlan: + return new UpgradePlanResourceProvider(managementController); case UpgradeSummary: return new UpgradeSummaryResourceProvider(managementController); case PreUpgradeCheck: diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradePlanResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradePlanResourceProvider.java new file mode 100644 index 0000000..13117cb --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradePlanResourceProvider.java @@ -0,0 +1,341 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ambari.server.controller.internal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.StaticallyInject; +import org.apache.ambari.server.controller.AmbariManagementController; +import org.apache.ambari.server.controller.spi.NoSuchParentResourceException; +import org.apache.ambari.server.controller.spi.NoSuchResourceException; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.spi.Request; +import org.apache.ambari.server.controller.spi.RequestStatus; +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; +import org.apache.ambari.server.controller.spi.SystemException; +import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; +import org.apache.ambari.server.controller.utilities.PropertyHelper; +import org.apache.ambari.server.orm.dao.UpgradePlanDAO; +import org.apache.ambari.server.orm.entities.UpgradePlanDetailEntity; +import org.apache.ambari.server.orm.entities.UpgradePlanEntity; +import org.apache.ambari.server.security.authorization.RoleAuthorization; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.stack.upgrade.Direction; +import org.apache.ambari.server.state.stack.upgrade.UpgradeType; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.BooleanUtils; +import org.apache.commons.lang.StringUtils; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import com.google.inject.Inject; + +/** + * Manages upgrade plans. + */ +@StaticallyInject +public class UpgradePlanResourceProvider extends AbstractControllerResourceProvider { + + private static final String UPGRADE_PLAN = "UpgradePlan" + PropertyHelper.EXTERNAL_PATH_SEP; + + protected static final String UPGRADE_PLAN_ID = UPGRADE_PLAN + "id"; + protected static final String UPGRADE_PLAN_CLUSTER_NAME = UPGRADE_PLAN + "cluster_name"; + + public static final String UPGRADE_PLAN_TYPE = UPGRADE_PLAN + "upgrade_type"; + public static final String UPGRADE_PLAN_DIRECTION = UPGRADE_PLAN + "direction"; + public static final String UPGRADE_PLAN_SKIP_FAILURES = UPGRADE_PLAN + "skip_failures"; + public static final String UPGRADE_PLAN_SKIP_PREREQUISITE_CHECKS = UPGRADE_PLAN + "skip_prerequisite_checks"; + public static final String UPGRADE_PLAN_SKIP_SERVICE_CHECKS = UPGRADE_PLAN + "skip_service_checks"; + public static final String UPGRADE_PLAN_SKIP_SERVICE_CHECK_FAILURES = UPGRADE_PLAN + "skip_service_check_failures"; + public static final String UPGRADE_PLAN_FAIL_ON_CHECK_WARNINGS = UPGRADE_PLAN + "fail_on_check_warnings"; + + public static final String UPGRADE_PLAN_SERVICE_GROUPS = UPGRADE_PLAN + "servicegroups"; + + private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = ImmutableMap.<Resource.Type, String>builder() + .put(Resource.Type.UpgradePlan, UPGRADE_PLAN_ID) + .put(Resource.Type.Cluster, UPGRADE_PLAN_CLUSTER_NAME) + .build(); + + private static final Set<String> PK_PROPERTY_IDS = Sets.newHashSet(KEY_PROPERTY_IDS.values()); + + private static final Set<String> PROPERTY_IDS = Sets.newHashSet( + UPGRADE_PLAN_ID, + UPGRADE_PLAN_CLUSTER_NAME, + UPGRADE_PLAN_TYPE, + UPGRADE_PLAN_DIRECTION, + UPGRADE_PLAN_SKIP_FAILURES, + UPGRADE_PLAN_SKIP_PREREQUISITE_CHECKS, + UPGRADE_PLAN_SKIP_SERVICE_CHECKS, + UPGRADE_PLAN_SKIP_SERVICE_CHECK_FAILURES, + UPGRADE_PLAN_FAIL_ON_CHECK_WARNINGS, + UPGRADE_PLAN_SERVICE_GROUPS); + + /** + * Used to deserialize the repository JSON into an object. + */ + @Inject + private static Gson s_gson; + + @Inject + private static UpgradePlanDAO s_upgradePlanDAO; + + /** + * Constructor. + * + * @param controller the controller + */ + UpgradePlanResourceProvider(AmbariManagementController controller) { + super(Resource.Type.UpgradePlan, PROPERTY_IDS, KEY_PROPERTY_IDS, controller); + + setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.CLUSTER_UPGRADE_DOWNGRADE_STACK)); + } + + @Override + public RequestStatus createResourcesAuthorized(final Request request) + throws SystemException, + UnsupportedPropertyException, ResourceAlreadyExistsException, + NoSuchParentResourceException { + + Set<Map<String, Object>> propertyMaps = request.getProperties(); + + if (propertyMaps.size() > 1) { + throw new IllegalArgumentException("Cannot create more than one Upgrade Plan at a time"); + } + + Map<String, Object> propertyMap = propertyMaps.iterator().next(); + + // !!! i hate you, framework + @SuppressWarnings("unchecked") + Set<Map<String, Object>> groupMaps = (Set<Map<String, Object>>) propertyMap.get( + UPGRADE_PLAN_SERVICE_GROUPS); + String json = s_gson.toJson(groupMaps); + + java.lang.reflect.Type listType = new TypeToken<ArrayList<ServiceGroupJson>>(){}.getType(); + List<ServiceGroupJson> l = s_gson.fromJson(json, listType); + + UpgradePlanEntity entity = toEntity(propertyMap, l); + + s_upgradePlanDAO.create(entity); + + notifyCreate(Resource.Type.UpgradePlan, request); + + Resource res = new ResourceImpl(Resource.Type.UpgradePlan); + res.setProperty(UPGRADE_PLAN_ID, entity.getId()); + + return new RequestStatusImpl(null, Collections.singleton(res)); + } + + @Override + public Set<Resource> getResourcesAuthorized(Request request, Predicate predicate) + throws SystemException, UnsupportedPropertyException, + NoSuchResourceException, NoSuchParentResourceException { + + Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate); + List<UpgradePlanEntity> entities = new ArrayList<>(); + Set<Resource> results = new LinkedHashSet<>(); + + for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) { + String clusterName = (String) propertyMap.get(UPGRADE_PLAN_CLUSTER_NAME); + String upgradePlanIdStr = (String) propertyMap.get(UPGRADE_PLAN_ID); + + if (StringUtils.isNotEmpty(upgradePlanIdStr)) { + Long upgradePlanId = Long.valueOf(upgradePlanIdStr); + UpgradePlanEntity entity = s_upgradePlanDAO.findByPK(upgradePlanId); + + if (null == entity) { + throw new NoSuchResourceException(String.format("Could not find upgrade plan %s", + upgradePlanIdStr)); + } + + results.add(toResource(entity, requestPropertyIds, clusterName)); + } else { + // find all plans + entities.addAll(s_upgradePlanDAO.findAll()); + + entities.forEach(entity -> { + results.add(toResource(entity, requestPropertyIds, clusterName)); + }); + } + } + + return results; + } + + @Override + public RequestStatus updateResourcesAuthorized(final Request request, + Predicate predicate) + throws SystemException, UnsupportedPropertyException, + NoSuchResourceException, NoSuchParentResourceException { + + throw new SystemException("Upgrade plans cannot be modified"); + } + + @Override + public RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate) + throws SystemException, UnsupportedPropertyException, + NoSuchResourceException, NoSuchParentResourceException { + throw new SystemException("Upgrade plans cannot be removed"); + } + + @Override + protected Set<String> getPKPropertyIds() { + return PK_PROPERTY_IDS; + } + + /** + * Creates an entity from a request + * @param propertyMap + * the property map containing values + * @param serviceGroupJsons + * the collection of service groups parsed from the request + * @return the entity represeting the request + * + * @throws SystemException + */ + private UpgradePlanEntity toEntity(Map<String, Object> propertyMap, Collection<ServiceGroupJson> serviceGroupJsons) + throws SystemException { + Arrays.asList(UPGRADE_PLAN_CLUSTER_NAME, UPGRADE_PLAN_TYPE, UPGRADE_PLAN_DIRECTION).stream() + .forEach(property -> { + if (!propertyMap.containsKey(property)) { + throw new IllegalArgumentException( + String.format("Property %s is required for an upgrade plan", property)); + } + }); + + if (CollectionUtils.isEmpty(serviceGroupJsons)) { + throw new IllegalArgumentException("Service groups must be provided"); + } + + String clusterName = propertyMap.get(UPGRADE_PLAN_CLUSTER_NAME).toString(); + Cluster cluster = null; + try { + cluster = getManagementController().getClusters().getCluster(clusterName); + } catch (AmbariException e) { + throw new SystemException(String.format("Could not load cluster %s", clusterName), e); + } + + String upgradeTypeName = propertyMap.get(UPGRADE_PLAN_TYPE).toString(); + UpgradeType upgradeType = UpgradeType.valueOf(upgradeTypeName); + + String directionName = propertyMap.get(UPGRADE_PLAN_DIRECTION).toString(); + Direction direction = Direction.valueOf(directionName); + + UpgradePlanEntity entity = new UpgradePlanEntity(); + + entity.setClusterId(cluster.getClusterId()); + entity.setUpgradeType(upgradeType); + entity.setDirection(direction); + + if (propertyMap.containsKey(UPGRADE_PLAN_FAIL_ON_CHECK_WARNINGS)) { + boolean failOn = BooleanUtils.toBoolean(propertyMap.get(UPGRADE_PLAN_FAIL_ON_CHECK_WARNINGS).toString()); + entity.setFailOnPrerequisiteWarnings(failOn); + } + + if (propertyMap.containsKey(UPGRADE_PLAN_SKIP_FAILURES)) { + boolean skip = BooleanUtils.toBoolean(propertyMap.get(UPGRADE_PLAN_SKIP_FAILURES).toString()); + entity.setSkipFailures(skip); + } + + if (propertyMap.containsKey(UPGRADE_PLAN_SKIP_PREREQUISITE_CHECKS)) { + boolean skip = BooleanUtils.toBoolean(propertyMap.get(UPGRADE_PLAN_SKIP_PREREQUISITE_CHECKS).toString()); + entity.setSkipPrerequisiteChecks(skip); + } + + if (propertyMap.containsKey(UPGRADE_PLAN_SKIP_SERVICE_CHECK_FAILURES)) { + boolean skip = BooleanUtils.toBoolean(propertyMap.get(UPGRADE_PLAN_SKIP_SERVICE_CHECK_FAILURES).toString()); + entity.setSkipPrerequisiteChecks(skip); + } + + if (propertyMap.containsKey(UPGRADE_PLAN_SKIP_SERVICE_CHECKS)) { + boolean skip = BooleanUtils.toBoolean(propertyMap.get(UPGRADE_PLAN_SKIP_SERVICE_CHECKS).toString()); + entity.setSkipServiceChecks(skip); + } + + List<UpgradePlanDetailEntity> details = new ArrayList<>(); + + serviceGroupJsons.forEach(serviceGroupJson -> { + if (null == serviceGroupJson.mpackTargetId || null == serviceGroupJson.serviceGroupId) { + return; + } + + UpgradePlanDetailEntity detail = new UpgradePlanDetailEntity(); + detail.setMpackTargetId(serviceGroupJson.mpackTargetId); + detail.setServiceGroupId(serviceGroupJson.serviceGroupId); + + details.add(detail); + }); + + entity.setDetails(details); + + return entity; + } + + /** + * Converts an entity to a resource + * @param upgradePlan + * the upgrade plan entity + * @param requestedIds + * the requested ids + * @param clusterName + * the cluster name + * @return the resource + */ + private Resource toResource(UpgradePlanEntity upgradePlan, Set<String> requestedIds, + String clusterName) { + ResourceImpl resource = new ResourceImpl(Resource.Type.UpgradePlan); + + setResourceProperty(resource, UPGRADE_PLAN_CLUSTER_NAME, clusterName, requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_ID, upgradePlan.getId(), requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_DIRECTION, upgradePlan.getDirection(), requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_FAIL_ON_CHECK_WARNINGS, upgradePlan.isFailOnPrerequisiteWarnings(), requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_SKIP_FAILURES, upgradePlan.isSkipFailures(), requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_SKIP_PREREQUISITE_CHECKS, upgradePlan.isSkipPrerequisiteChecks(), requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_SKIP_SERVICE_CHECK_FAILURES, upgradePlan.isSkipServiceCheckFailures(), requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_SKIP_SERVICE_CHECKS, upgradePlan.isSkipServiceChecks(), requestedIds); + setResourceProperty(resource, UPGRADE_PLAN_SERVICE_GROUPS, upgradePlan.getDetails(), requestedIds); + + return resource; + } + + + /** + * An object representing the service groups in a request. + */ + private static class ServiceGroupJson { + @SerializedName("service_group_id") + private Long serviceGroupId; + + @SerializedName("mpack_target_id") + private Long mpackTargetId; + + } + +} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java index 9077f35..57f7e28 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java @@ -159,6 +159,7 @@ public interface Resource { Upgrade, UpgradeGroup, UpgradeItem, + UpgradePlan, UpgradeSummary, PreUpgradeCheck, Stage, @@ -297,6 +298,7 @@ public interface Resource { public static final Type Upgrade = InternalType.Upgrade.getType(); public static final Type UpgradeGroup = InternalType.UpgradeGroup.getType(); public static final Type UpgradeItem = InternalType.UpgradeItem.getType(); + public static final Type UpgradePlan = InternalType.UpgradePlan.getType(); public static final Type UpgradeSummary = InternalType.UpgradeSummary.getType(); public static final Type PreUpgradeCheck = InternalType.PreUpgradeCheck.getType(); public static final Type Stage = InternalType.Stage.getType(); diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradePlanDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradePlanDAO.java new file mode 100644 index 0000000..68f662e --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradePlanDAO.java @@ -0,0 +1,31 @@ +/* + * 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.dao; + +import org.apache.ambari.server.orm.entities.UpgradePlanEntity; + +/** + * DAO used to manage upgrade plans + */ +public class UpgradePlanDAO extends CrudDAO<UpgradePlanEntity, Long> { + + public UpgradePlanDAO() { + super(UpgradePlanEntity.class); + } + +} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradePlanDetailEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradePlanDetailEntity.java new file mode 100644 index 0000000..7b7c501 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradePlanDetailEntity.java @@ -0,0 +1,118 @@ +/* + * 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.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.google.common.base.Objects; + +/** + * Models a single upgrade plan that can be used to invoke an Upgrade. + */ +@Table(name = "upgrade_plan_detail") +@Entity +@TableGenerator(name = "upgrade_plan_detail_id_generator", + table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", + pkColumnValue = "upgrade_plan_detail_id_seq", + initialValue = 0) +public class UpgradePlanDetailEntity { + + @Id + @Column(name = "id", nullable = false, insertable = true, updatable = false) + @GeneratedValue(strategy = GenerationType.TABLE, generator = "upgrade_plan_detail_id_generator") + private Long id; + + @Column(name = "upgrade_plan_id", nullable = false, insertable = false, updatable = false) + private Long upgradePlanId; + + @Column(name = "service_group_id", nullable = false, insertable = true, updatable = true) + private Long serviceGroupId; + + @Column(name = "mpack_target_id", nullable = false, insertable = true, updatable = true) + private Long mpackTargetId; + + @ManyToOne + @JoinColumn(name = "upgrade_plan_id", referencedColumnName = "id", nullable = false) + private UpgradePlanEntity upgradePlanEntity; + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param planId the id + */ + public void setId(Long planId) { + id = planId; + } + + /** + * @return the id of the service group to be upgraded + */ + public long getServiceGroupId() { + return serviceGroupId; + } + + /** + * @param id the service group id to upgrade + */ + public void setServiceGroupId(long id) { + serviceGroupId = id; + } + + /** + * @return the target mpack id + */ + public long getMpackTargetId() { + return mpackTargetId; + } + + /** + * @param id the target mpack id + */ + public void setMpackTargetId(long id) { + mpackTargetId = id; + } + + /** + * @param plan the owning upgrade plan + */ + void setUpgradePlanEntity(UpgradePlanEntity plan) { + upgradePlanEntity = plan; + } + + + @Override + public String toString() { + return Objects.toStringHelper(this).omitNullValues() + .add("id", id) + .toString(); + } + +} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradePlanEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradePlanEntity.java new file mode 100644 index 0000000..403b536 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradePlanEntity.java @@ -0,0 +1,244 @@ +/* + * 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.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import org.apache.ambari.server.state.stack.upgrade.Direction; +import org.apache.ambari.server.state.stack.upgrade.UpgradeType; +import org.apache.commons.lang.ObjectUtils; + +import com.google.common.base.Objects; + +/** + * Models a single upgrade plan that can be used to invoke an Upgrade. + */ +@Table(name = "upgrade_plan") +@Entity +@TableGenerator(name = "upgrade_plan_id_generator", + table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", + pkColumnValue = "upgrade_plan_id_seq", + initialValue = 0) +public class UpgradePlanEntity { + + @Id + @Column(name = "id", nullable = false, insertable = true, updatable = false) + @GeneratedValue(strategy = GenerationType.TABLE, generator = "upgrade_plan_id_generator") + private Long id; + + @Column(name = "cluster_id", nullable = false, insertable = true, updatable = false) + private Long clusterId; + + @Column(name = "upgrade_type", nullable = false) + @Enumerated(value = EnumType.STRING) + private UpgradeType upgradeType = UpgradeType.ROLLING; + + @Column(name = "direction", nullable=false) + @Enumerated(value = EnumType.STRING) + private Direction direction = Direction.UPGRADE; + + @Column(name = "skip_failures", nullable = false) + private short skipFailures = (short) 0; + + @Column(name = "skip_sc_failures", nullable = false) + private short skipServiceCheckFailures = (short) 0; + + @Column(name = "skip_prechecks", nullable = false) + private short skipPrerequisiteChecks = (short) 0; + + @Column(name = "fail_on_precheck_warnings", nullable = false) + private short failOnPrerequisiteWarnings = (short) 0; + + @Column(name = "skip_service_checks", nullable = false) + private short skipServiceChecks = (short) 0; + + @OneToMany(mappedBy = "upgradePlanEntity", cascade = { CascadeType.ALL }) + private List<UpgradePlanDetailEntity> upgradePlanDetails; + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param planId the id + */ + public void setId(Long planId) { + id = planId; + } + + /** + * @return the cluster id + */ + public long getClusterId() { + return clusterId; + } + + /** + * @param id the cluster id + */ + public void setClusterId(long id) { + clusterId = id; + } + + /** + * @return the direction + */ + public Direction getDirection() { + return direction; + } + + /** + * @param direction the direction + */ + public void setDirection(Direction direction) { + this.direction = direction; + } + + /** + * @return the upgrade type + */ + public UpgradeType getUpgradeType() { + return upgradeType; + } + + /** + * @param type the upgrade type + */ + public void setUpgradeType(UpgradeType type) { + upgradeType = type; + } + + /** + * @return if failures should be skipped + */ + public boolean isSkipFailures() { + return skipFailures != 0; + } + + /** + * @param skip {@code true} to skip failures that are not service check based + */ + public void setSkipFailures(boolean skip) { + skipFailures = skip ? (short) 1 : (short) 0; + } + + /** + * @return if service check failures can be auto-skipped + */ + public boolean isSkipServiceCheckFailures() { + return skipServiceCheckFailures != 0; + } + + /** + * @param skip {@code true} to skip service check failures + */ + public void setSkipServiceCheckFailures(boolean skip) { + skipServiceCheckFailures = skip ? (short) 1 : (short) 0; + } + + /** + * @return if prerequiste checks are skipped + */ + public boolean isSkipPrerequisiteChecks() { + return skipPrerequisiteChecks != 0; + } + + /** + * @param skip {@code true} to skip prerequiste checks + */ + public void setSkipPrerequisiteChecks(boolean skip) { + skipPrerequisiteChecks = skip ? (short) 1 : (short) 0; + } + + /** + * @return if precheck warnings should result in a failure + */ + public boolean isFailOnPrerequisiteWarnings() { + return failOnPrerequisiteWarnings != 0; + } + + /** + * @param fail {@code true} to treat prerequisite warnings as failures + */ + public void setFailOnPrerequisiteWarnings(boolean fail) { + failOnPrerequisiteWarnings = fail ? (short) 1 : (short) 0; + } + + /** + * @return if service checks should be skipped + */ + public boolean isSkipServiceChecks() { + return skipServiceChecks != 0; + } + + /** + * @param skip {@code true} to skip service checks + */ + public void setSkipServiceChecks(boolean skip) { + skipServiceChecks = skip ? (short) 1 : (short) 0; + } + + /** + * @return the plan details + */ + public List<UpgradePlanDetailEntity> getDetails() { + return upgradePlanDetails; + } + + /** + * @param details the plan details + */ + public void setDetails(List<UpgradePlanDetailEntity> details) { + for (UpgradePlanDetailEntity entity : details) { + entity.setUpgradePlanEntity(this); + } + + upgradePlanDetails = details; + } + + + @Override + public int hashCode() { + return ObjectUtils.hashCode(id); + } + + @Override + public String toString() { + return Objects.toStringHelper(this).omitNullValues() + .add("id", id) + .add("upgrade_type", upgradeType) + .add("direction", direction) + .toString(); + } + +} 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 d7f4e00..377b14b 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql @@ -1046,6 +1046,28 @@ CREATE TABLE upgrade_history( CONSTRAINT UQ_upgrade_hist_srvc_grp UNIQUE (upgrade_id, service_group_id) ); +CREATE TABLE upgrade_plan( + id BIGINT NOT NULL, + cluster_id BIGINT NOT NULL, + upgrade_type VARCHAR(255) DEFAULT 'ROLLING' NOT NULL, + direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL, + skip_failures SMALLINT DEFAULT 0 NOT NULL, + skip_sc_failures SMALLINT DEFAULT 0 NOT NULL, + skip_prechecks SMALLINT DEFAULT 0 NOT NULL, + fail_on_precheck_warnings SMALLINT DEFAULT 0 NOT NULL, + skip_service_checks SMALLINT DEFAULT 0 NOT NULL, + CONSTRAINT PK_upgrade_plan PRIMARY KEY (id) +); + +CREATE TABLE upgrade_plan_detail ( + id BIGINT NOT NULL, + upgrade_plan_id BIGINT NOT NULL, + service_group_id BIGINT NOT NULL, + mpack_target_id BIGINT NOT NULL, + CONSTRAINT PK_upgrade_plan_detail PRIMARY KEY (id), + CONSTRAINT FK_upgrade_det_upgrade_plan FOREIGN KEY (upgrade_plan_id) REFERENCES upgrade_plan (id) +); + CREATE TABLE ambari_operation_history( id BIGINT NOT NULL, from_version VARCHAR(255) NOT NULL, @@ -1319,12 +1341,16 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) union all select 'upgrade_group_id_seq', 0 FROM SYSIBM.SYSDUMMY1 union all + select 'upgrade_item_id_seq', 0 FROM SYSIBM.SYSDUMMY1 + union all + select 'upgrade_plan_id_seq', 0 FROM SYSIBM.SYSDUMMY1 + union all + select 'upgrade_plan_detail_id_seq', 0 FROM SYSIBM.SYSDUMMY1 + union all select 'widget_id_seq', 0 FROM SYSIBM.SYSDUMMY1 union all select 'widget_layout_id_seq', 0 FROM SYSIBM.SYSDUMMY1 union all - select 'upgrade_item_id_seq', 0 FROM SYSIBM.SYSDUMMY1 - union all select 'stack_id_seq', 0 FROM SYSIBM.SYSDUMMY1 union all select 'mpack_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 78d424d..b298ded 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -1063,6 +1063,29 @@ CREATE TABLE upgrade_history( CONSTRAINT UQ_upgrade_hist_srvc_grp UNIQUE (upgrade_id, service_group_id) ); +CREATE TABLE upgrade_plan ( + id BIGINT NOT NULL, + cluster_id BIGINT NOT NULL, + upgrade_type VARCHAR(255) DEFAULT 'ROLLING' NOT NULL, + direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL, + skip_failures SMALLINT DEFAULT 0 NOT NULL, + skip_sc_failures SMALLINT DEFAULT 0 NOT NULL, + skip_prechecks SMALLINT DEFAULT 0 NOT NULL, + fail_on_precheck_warnings SMALLINT DEFAULT 0 NOT NULL, + skip_service_checks SMALLINT DEFAULT 0 NOT NULL, + CONSTRAINT PK_upgrade_plan PRIMARY KEY (id) +); + +CREATE TABLE upgrade_plan_detail ( + id BIGINT NOT NULL, + upgrade_plan_id BIGINT NOT NULL, + service_group_id BIGINT NOT NULL, + mpack_target_id BIGINT NOT NULL, + CONSTRAINT PK_upgrade_plan_detail PRIMARY KEY (id), + CONSTRAINT FK_upgrade_det_upgrade_plan FOREIGN KEY (upgrade_plan_id) REFERENCES upgrade_plan (id) +); + + CREATE TABLE ambari_operation_history( id BIGINT NOT NULL, from_version VARCHAR(255) NOT NULL, @@ -1295,6 +1318,8 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES ('upgrade_id_seq', 0), ('upgrade_group_id_seq', 0), ('upgrade_item_id_seq', 0), + ('upgrade_plan_id_seq', 0), + ('upgrade_plan_detail_id_seq', 0), ('stack_id_seq', 0), ('mpack_id_seq', 0), ('registry_id_seq', 0), 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 9e6fb9e..ca1f8cb 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -1041,6 +1041,29 @@ CREATE TABLE upgrade_history( CONSTRAINT UQ_upgrade_hist_srvc_grp UNIQUE (upgrade_id, service_group_id) ); +CREATE TABLE upgrade_plan ( + id NUMBER(19) NOT NULL, + cluster_id NUMBER(19) NOT NULL, + upgrade_type VARCHAR2(255) DEFAULT 'ROLLING' NOT NULL, + direction VARCHAR2(255) DEFAULT 'UPGRADE' NOT NULL, + skip_failures SMALLINT DEFAULT 0 NOT NULL, + skip_sc_failures SMALLINT DEFAULT 0 NOT NULL, + skip_prechecks SMALLINT DEFAULT 0 NOT NULL, + fail_on_precheck_warnings SMALLINT DEFAULT 0 NOT NULL, + skip_service_checks SMALLINT DEFAULT 0 NOT NULL, + CONSTRAINT PK_upgrade_plan PRIMARY KEY (id) +); + +CREATE TABLE upgrade_plan_detail ( + id NUMBER(19) NOT NULL, + upgrade_plan_id NUMBER(19) NOT NULL, + service_group_id NUMBER(19) NOT NULL, + mpack_target_id NUMBER(19) NOT NULL, + CONSTRAINT PK_upgrade_plan_detail PRIMARY KEY (id), + CONSTRAINT FK_upgrade_det_upgrade_plan FOREIGN KEY (upgrade_plan_id) REFERENCES upgrade_plan (id) +); + + CREATE TABLE ambari_operation_history( id NUMBER(19) NOT NULL, from_version VARCHAR2(255) NOT NULL, @@ -1273,6 +1296,8 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('repo_defini INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_group_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_item_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_plan_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_plan_detail_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('stack_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('mpack_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('registry_id_seq', 0); 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 3ac3e56..c42f9e9 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -1046,6 +1046,28 @@ CREATE TABLE upgrade_history( CONSTRAINT UQ_upgrade_hist_srvc_grp UNIQUE (upgrade_id, service_group_id) ); +CREATE TABLE upgrade_plan ( + id BIGINT NOT NULL, + cluster_id BIGINT NOT NULL, + upgrade_type VARCHAR(255) DEFAULT 'ROLLING' NOT NULL, + direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL, + skip_failures SMALLINT DEFAULT 0 NOT NULL, + skip_sc_failures SMALLINT DEFAULT 0 NOT NULL, + skip_prechecks SMALLINT DEFAULT 0 NOT NULL, + fail_on_precheck_warnings SMALLINT DEFAULT 0 NOT NULL, + skip_service_checks SMALLINT DEFAULT 0 NOT NULL, + CONSTRAINT PK_upgrade_plan PRIMARY KEY (id) +); + +CREATE TABLE upgrade_plan_detail ( + id BIGINT NOT NULL, + upgrade_plan_id BIGINT NOT NULL, + service_group_id BIGINT NOT NULL, + mpack_target_id BIGINT NOT NULL, + CONSTRAINT PK_upgrade_plan_detail PRIMARY KEY (id), + CONSTRAINT FK_upgrade_det_upgrade_plan FOREIGN KEY (upgrade_plan_id) REFERENCES upgrade_plan (id) +); + CREATE TABLE ambari_operation_history( id BIGINT NOT NULL, from_version VARCHAR(255) NOT NULL, @@ -1274,9 +1296,11 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) VALUES ('service_config_id_seq', 1), ('upgrade_id_seq', 0), ('upgrade_group_id_seq', 0), + ('upgrade_item_id_seq', 0), + ('upgrade_plan_id_seq', 0), + ('upgrade_plan_detail_id_seq', 0), ('widget_id_seq', 0), ('widget_layout_id_seq', 0), - ('upgrade_item_id_seq', 0), ('stack_id_seq', 0), ('mpack_id_seq',0), ('registry_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 805aa1a..c8aca19 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql @@ -1041,6 +1041,30 @@ CREATE TABLE upgrade_history( CONSTRAINT UQ_upgrade_hist_srvc_grp UNIQUE (upgrade_id, service_group_id) ); + +CREATE TABLE upgrade_plan ( + id NUMERIC(19) NOT NULL, + cluster_id NUMERIC(19) NOT NULL, + upgrade_type VARCHAR(255) NOT NULL DEFAULT 'ROLLING', + direction VARCHAR(255) NOT NULL DEFAULT 'UPGRADE', + skip_failures SMALLINT NOT NULL DEFAULT 0, + skip_sc_failures SMALLINT NOT NULL DEFAULT 0, + skip_prechecks SMALLINT NOT NULL DEFAULT 0, + fail_on_precheck_warnings SMALLINT NOT NULL DEFAULT 0, + skip_service_checks SMALLINT NOT NULL DEFAULT 0, + CONSTRAINT PK_upgrade_plan PRIMARY KEY (id) +); + +CREATE TABLE upgrade_plan_detail ( + id NUMERIC(19) NOT NULL, + upgrade_plan_id NUMERIC(19) NOT NULL, + service_group_id NUMERIC(19) NOT NULL, + mpack_target_id NUMERIC(19) NOT NULL, + CONSTRAINT PK_upgrade_plan_detail PRIMARY KEY (id), + CONSTRAINT FK_upgrade_det_upgrade_plan FOREIGN KEY (upgrade_plan_id) REFERENCES upgrade_plan (id) +); + + CREATE TABLE ambari_operation_history( id NUMERIC(19) NOT NULL, from_version VARCHAR(255) NOT NULL, @@ -1273,6 +1297,8 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('repo_defini INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_group_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_item_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_plan_id_seq', 0); +INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_plan_detail_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('stack_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('mpack_id_seq', 0); INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('registry_id_seq', 0); 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 43ec9dc..103a2b7 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql @@ -1064,6 +1064,28 @@ CREATE TABLE upgrade_history( CONSTRAINT UQ_upgrade_hist_srvc_grp UNIQUE (upgrade_id, service_group_id) ); +CREATE TABLE upgrade_plan ( + id BIGINT NOT NULL, + cluster_id BIGINT NOT NULL, + upgrade_type VARCHAR(255) DEFAULT 'ROLLING' NOT NULL, + direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL, + skip_failures SMALLINT DEFAULT 0 NOT NULL, + skip_sc_failures SMALLINT DEFAULT 0 NOT NULL, + skip_prechecks SMALLINT DEFAULT 0 NOT NULL, + fail_on_precheck_warnings SMALLINT DEFAULT 0 NOT NULL, + skip_service_checks SMALLINT DEFAULT 0 NOT NULL, + CONSTRAINT PK_upgrade_plan PRIMARY KEY (id) +); + +CREATE TABLE upgrade_plan_detail ( + id BIGINT NOT NULL, + upgrade_plan_id BIGINT NOT NULL, + service_group_id BIGINT NOT NULL, + mpack_target_id BIGINT NOT NULL, + CONSTRAINT PK_upgrade_plan_detail PRIMARY KEY (id), + CONSTRAINT FK_upgrade_det_upgrade_plan FOREIGN KEY (upgrade_plan_id) REFERENCES upgrade_plan (id) +); + CREATE TABLE ambari_operation_history( id BIGINT NOT NULL, from_version VARCHAR(255) NOT NULL, @@ -1301,9 +1323,11 @@ BEGIN TRANSACTION ('service_config_id_seq', 1), ('upgrade_id_seq', 0), ('upgrade_group_id_seq', 0), + ('upgrade_item_id_seq', 0), + ('upgrade_plan_id_seq', 0), + ('upgrade_plan_detail_id_seq', 0), ('widget_id_seq', 0), ('widget_layout_id_seq', 0), - ('upgrade_item_id_seq', 0), ('stack_id_seq', 0), ('mpack_id_seq', 0), ('registry_id_seq', 0), diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml index 331fd0f..19efd06 100644 --- a/ambari-server/src/main/resources/META-INF/persistence.xml +++ b/ambari-server/src/main/resources/META-INF/persistence.xml @@ -87,6 +87,8 @@ <class>org.apache.ambari.server.orm.entities.UpgradeGroupEntity</class> <class>org.apache.ambari.server.orm.entities.UpgradeItemEntity</class> <class>org.apache.ambari.server.orm.entities.UpgradeHistoryEntity</class> + <class>org.apache.ambari.server.orm.entities.UpgradePlanEntity</class> + <class>org.apache.ambari.server.orm.entities.UpgradePlanDetailEntity</class> <class>org.apache.ambari.server.orm.entities.UserEntity</class> <class>org.apache.ambari.server.orm.entities.UserAuthenticationEntity</class> <class>org.apache.ambari.server.orm.entities.WidgetEntity</class> diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradePlanResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradePlanResourceProviderTest.java new file mode 100644 index 0000000..2063642 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradePlanResourceProviderTest.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ambari.server.controller.internal; + +import static org.easymock.EasyMock.anyString; +import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Collections; +import java.util.Map; + +import org.apache.ambari.server.H2DatabaseCleaner; +import org.apache.ambari.server.controller.AmbariManagementController; +import org.apache.ambari.server.controller.spi.Request; +import org.apache.ambari.server.controller.spi.RequestStatus; +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.utilities.PropertyHelper; +import org.apache.ambari.server.orm.GuiceJpaInitializer; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.orm.dao.UpgradePlanDAO; +import org.apache.ambari.server.orm.entities.UpgradePlanDetailEntity; +import org.apache.ambari.server.orm.entities.UpgradePlanEntity; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Clusters; +import org.apache.ambari.server.state.stack.upgrade.Direction; +import org.apache.ambari.server.state.stack.upgrade.UpgradeType; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; +import com.google.inject.Binder; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.util.Modules; + +/** + * UpgradePlanResourceProvider tests. + */ +public class UpgradePlanResourceProviderTest { + + private Injector injector; + private AmbariManagementController amc; + private UpgradePlanDAO planDAO; + + @Before + public void before() throws Exception { + Cluster cluster = createNiceMock(Cluster.class); + expect(cluster.getClusterName()).andReturn("c1").atLeastOnce(); + expect(cluster.getClusterId()).andReturn(1L).anyTimes(); + + Clusters clusters = createNiceMock(Clusters.class); + expect(clusters.getCluster(anyString())).andReturn(cluster).atLeastOnce(); + + amc = createNiceMock(AmbariManagementController.class); + + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + + replay(cluster, clusters, amc); + + // Create an injector which will inject the mocks + injector = Guice.createInjector(Modules.override(new InMemoryDefaultTestModule()).with(new MockModule())); + injector.getInstance(GuiceJpaInitializer.class); + + planDAO = injector.getInstance(UpgradePlanDAO.class); + } + + @After + public void after() throws Exception { + H2DatabaseCleaner.clearDatabaseAndStopPersistenceService(injector); + injector = null; + } + + @Test + public void testCreateResources() throws Exception { + + UpgradePlanResourceProvider provider = createProvider(amc); + + Map<String, Object> serviceGroups = ImmutableMap.<String, Object>builder() + .put("service_group_id", 4L) + .put("mpack_target_id", 2L) + .build(); + + Map<String, Object> requestMap = ImmutableMap.<String, Object>builder() + .put(UpgradePlanResourceProvider.UPGRADE_PLAN_CLUSTER_NAME, "c1") + .put(UpgradePlanResourceProvider.UPGRADE_PLAN_TYPE, UpgradeType.ROLLING.name()) + .put(UpgradePlanResourceProvider.UPGRADE_PLAN_DIRECTION, Direction.UPGRADE.name()) + .put(UpgradePlanResourceProvider.UPGRADE_PLAN_SERVICE_GROUPS, Sets.newHashSet(serviceGroups)) + .build(); + + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestMap), null); + + RequestStatus requestStatus = provider.createResourcesAuthorized(request); + + assertEquals(1, requestStatus.getAssociatedResources().size()); + + Resource resource = requestStatus.getAssociatedResources().iterator().next(); + Long id = (Long) resource.getPropertyValue(UpgradePlanResourceProvider.UPGRADE_PLAN_ID); + assertNotNull(id); + + UpgradePlanEntity entity = planDAO.findByPK(id); + assertNotNull(entity); + assertEquals(1, entity.getDetails().size()); + + UpgradePlanDetailEntity detail = entity.getDetails().iterator().next(); + assertEquals(4L, detail.getServiceGroupId()); + assertEquals(2L, detail.getMpackTargetId()); + } + + + /** + * @param amc + * @return the provider + */ + private UpgradePlanResourceProvider createProvider(AmbariManagementController amc) { + return new UpgradePlanResourceProvider(amc); + } + + /** + * Mock module that will bind UpgradeHelper to a mock instance. + */ + private class MockModule implements Module { + @Override + public void configure(Binder binder) { + binder.bind(AmbariManagementController.class).toInstance(amc); + } + } +} -- To stop receiving notification emails like this one, please contact nc...@apache.org.