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 <[email protected]>
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
[email protected].