You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2016/03/11 21:20:33 UTC
ambari git commit: AMBARI-15330. Bubble up errors during RU/EU
(alejandro)
Repository: ambari
Updated Branches:
refs/heads/trunk be9d76ed0 -> 0f0d77660
AMBARI-15330. Bubble up errors during RU/EU (alejandro)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0f0d7766
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0f0d7766
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0f0d7766
Branch: refs/heads/trunk
Commit: 0f0d7766017d697f8e1e19be476743516f360b4f
Parents: be9d76e
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Thu Mar 10 14:45:35 2016 -0800
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Fri Mar 11 12:20:16 2016 -0800
----------------------------------------------------------------------
.../server/actionmanager/HostRoleStatus.java | 9 +
.../resources/ResourceInstanceFactoryImpl.java | 5 +
.../server/api/services/ClusterService.java | 15 +
.../api/services/UpgradeSummaryService.java | 83 +++++
.../internal/DefaultProviderModule.java | 2 +
.../internal/TaskResourceProvider.java | 29 ++
.../controller/internal/UpgradeSummary.java | 77 ++++
.../UpgradeSummaryResourceProvider.java | 202 +++++++++++
.../ambari/server/controller/spi/Resource.java | 2 +
.../server/orm/dao/HostRoleCommandDAO.java | 37 ++
.../orm/entities/HostRoleCommandEntity.java | 2 +
.../ambari/server/state/UpgradeHelper.java | 27 ++
.../UpgradeSummaryResourceProviderTest.java | 360 +++++++++++++++++++
13 files changed, 850 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleStatus.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleStatus.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleStatus.java
index 52523c7..f5ba1c6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleStatus.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleStatus.java
@@ -84,6 +84,8 @@ public enum HostRoleStatus {
private static List<HostRoleStatus> HOLDING_STATES = Arrays.asList(HOLDING, HOLDING_FAILED,
HOLDING_TIMEDOUT);
+ public static List<HostRoleStatus> SCHEDULED_STATES = Arrays.asList(PENDING, QUEUED, IN_PROGRESS);
+
/**
* The {@link HostRoleStatus}s that represent any commands which are
* considered to be "Failed".
@@ -92,6 +94,13 @@ public enum HostRoleStatus {
SKIPPED_FAILED);
/**
+ * The {@link HostRoleStatus}s that represent the current commands that failed during stack upgrade.
+ * This is not used to indicate commands that failed and then skipped.
+ */
+ public static EnumSet<HostRoleStatus> STACK_UPGRADE_FAILED_STATUSES = EnumSet.of(FAILED, HOLDING_FAILED,
+ HOLDING_TIMEDOUT);
+
+ /**
* The {@link HostRoleStatus}s that represent any commands which are
* considered to be "In Progress".
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
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 3526e23..d10b7a8 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
@@ -346,6 +346,11 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
Resource.Type.UpgradeItem, "upgrade_item", "upgrade_items", Resource.Type.Task);
break;
+ case UpgradeSummary:
+ resourceDefinition = new SimpleResourceDefinition(
+ Resource.Type.UpgradeSummary, "upgrade_summary", "upgrade_summary");
+ break;
+
case PreUpgradeCheck:
resourceDefinition = new SimpleResourceDefinition(Resource.Type.PreUpgradeCheck, "rolling_upgrade_check", "rolling_upgrade_checks");
break;
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
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 7200b83..8e9b771 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
@@ -576,6 +576,21 @@ public class ClusterService extends BaseService {
}
/**
+ * Gets a list of upgrade summaries.
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the upgrade summary service
+ */
+ @Path("{clusterName}/upgrade_summary")
+ public UpgradeSummaryService getUpgradeSummaryService(
+ @Context javax.ws.rs.core.Request request,
+ @PathParam("clusterName") String clusterName) {
+ return new UpgradeSummaryService(clusterName);
+ }
+
+ /**
* Gets the pre-upgrade checks service.
*
* @param request the request
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpgradeSummaryService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpgradeSummaryService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpgradeSummaryService.java
new file mode 100644
index 0000000..b8b3e86
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpgradeSummaryService.java
@@ -0,0 +1,83 @@
+/**
+ * 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 org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import javax.ws.rs.GET;
+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.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Endpoint for a detailed summary of the cluster upgrades.
+ */
+public class UpgradeSummaryService extends BaseService {
+
+ private String m_clusterName = null;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterName the cluster name (not {@code null}).
+ */
+ UpgradeSummaryService(String clusterName) {
+ m_clusterName = clusterName;
+ }
+
+ @GET
+ @Produces("text/plain")
+ public Response getUpgradeSummaries(@Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, null, ui, Request.Type.GET,
+ createResourceInstance(null));
+ }
+
+ @GET
+ @Path("{requestId}")
+ @Produces("text/plain")
+ public Response getUpgradeSummary(@Context HttpHeaders headers,
+ @Context UriInfo ui,
+ @PathParam("requestId") Long requestId) {
+ return handleRequest(headers, null, ui, Request.Type.GET,
+ createResourceInstance(requestId));
+ }
+
+ /**
+ * @param requestId the upgrade's request Id
+ * @return the resource instance
+ */
+ private ResourceInstance createResourceInstance(Long requestId) {
+ Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>();
+ mapIds.put(Resource.Type.Cluster, m_clusterName);
+
+ if (null != requestId) {
+ mapIds.put(Resource.Type.UpgradeSummary, requestId.toString());
+ }
+
+ return createResource(Resource.Type.UpgradeSummary, mapIds);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
----------------------------------------------------------------------
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 d1d3fe6..c7dc117 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
@@ -102,6 +102,8 @@ public class DefaultProviderModule extends AbstractProviderModule {
return new UpgradeGroupResourceProvider(managementController);
case UpgradeItem:
return new UpgradeItemResourceProvider(managementController);
+ case UpgradeSummary:
+ return new UpgradeSummaryResourceProvider(managementController);
case ClusterStackVersion:
return new ClusterStackVersionResourceProvider(managementController);
case PreUpgradeCheck:
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java
index 510d6fb..cb8a343 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java
@@ -81,6 +81,35 @@ public class TaskResourceProvider extends AbstractControllerResourceProvider {
TASK_ID_PROPERTY_ID}));
/**
+ * The property ids for a task resource.
+ */
+ static final Set<String> PROPERTY_IDS = new HashSet<String>();
+
+ // These are static so that they can be referenced by other classes such as UpgradeSummaryResourceProvider.java
+ static {
+ // properties
+ PROPERTY_IDS.add(TASK_CLUSTER_NAME_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_REQUEST_ID_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_ID_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_STAGE_ID_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_HOST_NAME_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_ROLE_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_COMMAND_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_STATUS_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_EXIT_CODE_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_STDERR_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_STOUT_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_OUTPUTLOG_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_ERRORLOG_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_STRUCT_OUT_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_START_TIME_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_END_TIME_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_ATTEMPT_CNT_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_COMMAND_DET_PROPERTY_ID);
+ PROPERTY_IDS.add(TASK_CUST_CMD_NAME_PROPERTY_ID);
+ }
+
+ /**
* Used for querying tasks.
*/
@Inject
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummary.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummary.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummary.java
new file mode 100644
index 0000000..f0f6914
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummary.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+
+/**
+ * Represents a detailed summary of an upgrade, including the most recent failed task in order to bubble up errors.
+ */
+public class UpgradeSummary {
+ private String displayText;
+ private Long requestId;
+ private Long stageId;
+ private Long taskId;
+ private String hostName;
+ private HostRoleCommandEntity failedTask;
+
+ public UpgradeSummary(String displayText, Long requestId, Long stageId, Long taskId, String hostName, HostRoleCommandEntity failedTask) {
+ this.displayText = displayText;
+ this.requestId = requestId;
+ this.stageId = stageId;
+ this.taskId = taskId;
+ this.hostName = hostName;
+ this.failedTask = failedTask;
+ }
+
+ public Long getStageId() {
+ return stageId;
+ }
+
+ public Long getTaskId() {
+ return taskId;
+ }
+
+ public UpgradeSummary(HostRoleCommandEntity hrc) {
+ this("", hrc.getRequestId(), hrc.getStageId(), hrc.getTaskId(), hrc.getHostName(), hrc);
+
+ // Construct a message to display on the UI.
+ displayText = "Failed";
+ if (hrc.getCommandDetail() != null) {
+ displayText += " calling " + hrc.getCommandDetail();
+ }
+ if (hrc.getHostName() != null) {
+ displayText += " on host " + hrc.getHostName();
+ }
+ }
+
+ /**
+ * Get the error message to display.
+ */
+ public String getDisplayText() {
+ return this.displayText;
+ }
+
+ /**
+ * Get the failed task if it exists.
+ * @return The failed task if it exists, otherwise null.
+ */
+ public HostRoleCommandEntity getFailedTask() {
+ return failedTask;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProvider.java
new file mode 100644
index 0000000..cf4b08f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProvider.java
@@ -0,0 +1,202 @@
+/**
+ * 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 com.google.inject.Inject;
+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.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.dao.UpgradeDAO;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.orm.entities.UpgradeEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.UpgradeHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+/**
+ * Get a summary of an upgrade request.
+ */
+@StaticallyInject
+public class UpgradeSummaryResourceProvider extends AbstractControllerResourceProvider {
+ protected static final String UPGRADE_SUMMARY_CLUSTER_NAME = "UpgradeSummary/cluster_name";
+ protected static final String UPGRADE_SUMMARY_REQUEST_ID = "UpgradeSummary/request_id";
+
+ protected static final String UPGRADE_SUMMARY_FAIL_REASON = PropertyHelper.getPropertyId("UpgradeSummary", "fail_reason");
+
+ private static final Set<String> PK_PROPERTY_IDS = new HashSet<String>(
+ Arrays.asList(UPGRADE_SUMMARY_REQUEST_ID, UPGRADE_SUMMARY_CLUSTER_NAME));
+ private static final Set<String> PROPERTY_IDS = new HashSet<String>();
+ private static Map<String, String> TASK_MAPPED_IDS = new HashMap<String, String>();
+
+ private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<Resource.Type, String>();
+
+ @Inject
+ private static UpgradeDAO s_upgradeDAO = null;
+
+ @Inject
+ private static HostRoleCommandDAO s_hostRoleCommandDAO = null;
+
+ /**
+ * Used to request a resource for a given task.
+ */
+ @Inject
+ private static UpgradeHelper s_upgradeHelper;
+
+ static {
+ // Properties
+ PROPERTY_IDS.add(UPGRADE_SUMMARY_CLUSTER_NAME);
+ PROPERTY_IDS.add(UPGRADE_SUMMARY_REQUEST_ID);
+ PROPERTY_IDS.add(UPGRADE_SUMMARY_FAIL_REASON);
+
+ // Inherit all of the properties from a Task as well to return data about the current task if it failed.
+ for (String p : TaskResourceProvider.PROPERTY_IDS) {
+ TASK_MAPPED_IDS.put(p, p.replace("Tasks/", "UpgradeSummary/failed_task/"));
+ }
+ PROPERTY_IDS.addAll(TASK_MAPPED_IDS.values());
+
+ // Keys
+ KEY_PROPERTY_IDS.put(Resource.Type.UpgradeSummary, UPGRADE_SUMMARY_REQUEST_ID);
+ KEY_PROPERTY_IDS.put(Resource.Type.Cluster, UPGRADE_SUMMARY_CLUSTER_NAME);
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(UpgradeSummaryResourceProvider.class);
+
+ /**
+ * Constructor.
+ *
+ * @param controller the controller
+ */
+ public UpgradeSummaryResourceProvider(AmbariManagementController controller) {
+ super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
+ }
+
+ @Override
+ public RequestStatus createResources(final Request request) throws SystemException,
+ UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException {
+
+ throw new UnsupportedOperationException("Resource only supports GET operation.");
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate) throws SystemException,
+ UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ Set<Resource> resources = new HashSet<Resource>();
+ Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate);
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ String clusterName = (String) propertyMap.get(UPGRADE_SUMMARY_CLUSTER_NAME);
+
+ if (null == clusterName || clusterName.isEmpty()) {
+ throw new IllegalArgumentException(
+ "The cluster name is required when querying for upgrades");
+ }
+
+ Cluster cluster;
+ try {
+ cluster = getManagementController().getClusters().getCluster(clusterName);
+ } catch (AmbariException e) {
+ throw new NoSuchResourceException(
+ String.format("Cluster %s could not be loaded", clusterName));
+ }
+
+ List<UpgradeEntity> upgrades = new ArrayList<UpgradeEntity>();
+ String upgradeRequestIdStr = (String) propertyMap.get(UPGRADE_SUMMARY_REQUEST_ID);
+ if (null != upgradeRequestIdStr) {
+ UpgradeEntity upgrade = s_upgradeDAO.findUpgradeByRequestId(Long.valueOf(upgradeRequestIdStr));
+
+ if (null != upgrade) {
+ upgrades.add(upgrade);
+ }
+ } else {
+ upgrades = s_upgradeDAO.findUpgrades(cluster.getClusterId());
+ }
+
+ for (UpgradeEntity entity : upgrades) {
+ Resource resource = new ResourceImpl(Resource.Type.UpgradeSummary);
+ Long upgradeRequestId = entity.getRequestId();
+
+ setResourceProperty(resource, UPGRADE_SUMMARY_CLUSTER_NAME, clusterName, requestPropertyIds);
+ setResourceProperty(resource, UPGRADE_SUMMARY_REQUEST_ID, entity.getRequestId(), requestPropertyIds);
+
+ HostRoleCommandEntity mostRecentFailure = s_hostRoleCommandDAO.findMostRecentFailure(upgradeRequestId);
+
+ String displayText = null;
+ HostRoleCommandEntity failedTask = null;
+ if (mostRecentFailure != null) {
+ UpgradeSummary summary = new UpgradeSummary(mostRecentFailure);
+ displayText = summary.getDisplayText();
+ failedTask = summary.getFailedTask();
+
+ Resource taskResource = s_upgradeHelper.getTaskResource(clusterName, failedTask.getRequestId(),
+ failedTask.getStageId(), failedTask.getTaskId());
+
+ // Include properties from the failed task.
+ if (taskResource != null) {
+ for (Map.Entry<String, String> property : TASK_MAPPED_IDS.entrySet()) {
+ String taskPropertyId = property.getKey();
+ String upgradeSummaryPropertyId = property.getValue();
+
+ setResourceProperty(resource, upgradeSummaryPropertyId, taskResource.getPropertyValue(taskPropertyId), requestPropertyIds);
+ }
+ }
+ }
+ setResourceProperty(resource, UPGRADE_SUMMARY_FAIL_REASON, displayText, requestPropertyIds);
+ resources.add(resource);
+ }
+ }
+
+ return resources;
+ }
+
+ @Override
+ public RequestStatus updateResources(final Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException,
+ NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Resource only supports GET operation.");
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate) throws SystemException,
+ UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Resource only supports GET operation.");
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return PK_PROPERTY_IDS;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
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 e79f300..85fd649 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
@@ -138,6 +138,7 @@ public interface Resource {
Upgrade,
UpgradeGroup,
UpgradeItem,
+ UpgradeSummary,
PreUpgradeCheck,
Stage,
StackArtifact,
@@ -251,6 +252,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 UpgradeSummary = InternalType.UpgradeSummary.getType();
public static final Type PreUpgradeCheck = InternalType.PreUpgradeCheck.getType();
public static final Type Stage = InternalType.Stage.getType();
public static final Type StackArtifact = InternalType.StackArtifact.getType();
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
index b48ffa8..f5b1cb4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
@@ -23,6 +23,7 @@ import static org.apache.ambari.server.orm.dao.DaoUtils.ORACLE_LIST_LIMIT;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -689,6 +690,42 @@ public class HostRoleCommandDAO {
}
}
+ /**
+ * During Rolling and Express Upgrade, want to bubble up the error of the most recent failure, i.e., greatest
+ * task id, assuming that there are no other completed tasks after it.
+ * @param requestId upgrade request id
+ * @return Most recent task failure during stack upgrade, or null if one doesn't exist.
+ */
+ public HostRoleCommandEntity findMostRecentFailure(Long requestId) {
+ TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createNamedQuery(
+ "HostRoleCommandEntity.findTasksByStatusesOrderByIdDesc", HostRoleCommandEntity.class);
+
+ query.setParameter("requestId", requestId);
+ query.setParameter("statuses", HostRoleStatus.STACK_UPGRADE_FAILED_STATUSES);
+ List results = query.getResultList();
+
+ if (!results.isEmpty()) {
+ HostRoleCommandEntity candidate = (HostRoleCommandEntity) results.get(0);
+
+ // Ensure that there are no other completed tasks in a future stage to avoid returning an old error.
+ // During Express Upgrade, we can run multiple commands in the same stage, so it's possible to have
+ // COMPLETED tasks in the failed task's stage.
+ // During Rolling Upgrade, we run exactly one command per stage.
+ TypedQuery<Number> numberAlreadyRanTasksInFutureStage = entityManagerProvider.get().createNamedQuery(
+ "HostRoleCommandEntity.findNumTasksAlreadyRanInStage", Number.class);
+
+ numberAlreadyRanTasksInFutureStage.setParameter("requestId", requestId);
+ numberAlreadyRanTasksInFutureStage.setParameter("taskId", candidate.getTaskId());
+ numberAlreadyRanTasksInFutureStage.setParameter("stageId", candidate.getStageId());
+ numberAlreadyRanTasksInFutureStage.setParameter("statuses", HostRoleStatus.SCHEDULED_STATES);
+
+ Number result = daoUtils.selectSingle(numberAlreadyRanTasksInFutureStage);
+ if (result.longValue() == 0L) {
+ return candidate;
+ }
+ }
+ return null;
+ }
/**
* Updates the {@link HostRoleCommandEntity#isFailureAutoSkipped()} flag for
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
index 1674175..19f0602 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
@@ -61,6 +61,8 @@ import org.apache.commons.lang.ArrayUtils;
)
@NamedQueries({
@NamedQuery(name = "HostRoleCommandEntity.findCountByCommandStatuses", query = "SELECT COUNT(command.taskId) FROM HostRoleCommandEntity command WHERE command.status IN :statuses"),
+ @NamedQuery(name = "HostRoleCommandEntity.findTasksByStatusesOrderByIdDesc", query = "SELECT task FROM HostRoleCommandEntity task WHERE task.requestId = :requestId AND task.status IN :statuses ORDER BY task.taskId DESC"),
+ @NamedQuery(name = "HostRoleCommandEntity.findNumTasksAlreadyRanInStage", query = "SELECT COUNT(task.taskId) FROM HostRoleCommandEntity task WHERE task.requestId = :requestId AND task.taskId > :taskId AND task.stageId > :stageId AND task.status NOT IN :statuses"),
@NamedQuery(name = "HostRoleCommandEntity.findByCommandStatuses", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.status IN :statuses ORDER BY command.requestId, command.stageId"),
@NamedQuery(name = "HostRoleCommandEntity.findByHostId", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.hostId=:hostId"),
@NamedQuery(name = "HostRoleCommandEntity.findByHostRole", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.hostEntity.hostName=:hostName AND command.requestId=:requestId AND command.stageId=:stageId AND command.role=:role ORDER BY command.taskId"),
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
index 2ac4d25..66272e3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
@@ -31,6 +31,7 @@ import java.util.regex.Pattern;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.internal.StageResourceProvider;
+import org.apache.ambari.server.controller.internal.TaskResourceProvider;
import org.apache.ambari.server.controller.predicate.AndPredicate;
import org.apache.ambari.server.controller.spi.ClusterController;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
@@ -706,6 +707,32 @@ public class UpgradeHelper {
}
/**
+ * Get a single resource for the task with the given parameters.
+ * @param clusterName Cluster Name
+ * @param requestId Request Id
+ * @param stageId Stage Id
+ * @param taskId Task Id
+ * @return Single task resource that matches the predicates, otherwise, null.
+ */
+ public Resource getTaskResource(String clusterName, Long requestId, Long stageId, Long taskId)
+ throws UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException, SystemException {
+ ClusterController clusterController = ClusterControllerHelper.getClusterController();
+
+ Request request = PropertyHelper.getReadRequest();
+
+ Predicate p1 = new PredicateBuilder().property(TaskResourceProvider.TASK_CLUSTER_NAME_PROPERTY_ID).equals(clusterName).toPredicate();
+ Predicate p2 = new PredicateBuilder().property(TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(requestId.toString()).toPredicate();
+ Predicate p3 = new PredicateBuilder().property(TaskResourceProvider.TASK_STAGE_ID_PROPERTY_ID).equals(stageId.toString()).toPredicate();
+ Predicate p4 = new PredicateBuilder().property(TaskResourceProvider.TASK_ID_PROPERTY_ID).equals(taskId.toString()).toPredicate();
+
+ QueryResponse response = clusterController.getResources(Resource.Type.Task,
+ request, new AndPredicate(p1, p2, p3, p4));
+
+ Set<Resource> task = response.getResources();
+ return task.size() == 1 ? task.iterator().next() : null;
+ }
+
+ /**
* Helper to set service and component display names on the context
* @param context the context to update
* @param service the service name
http://git-wip-us.apache.org/repos/asf/ambari/blob/0f0d7766/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProviderTest.java
new file mode 100644
index 0000000..eccc1ed
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeSummaryResourceProviderTest.java
@@ -0,0 +1,360 @@
+/**
+ * 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 com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.persist.PersistService;
+import com.google.inject.persist.Transactional;
+import com.google.inject.util.Modules;
+import junit.framework.Assert;
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.actionmanager.ServiceComponentHostEventWrapper;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariServer;
+import org.apache.ambari.server.controller.predicate.AndPredicate;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+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.OrmTestHelper;
+import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.dao.RequestDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.dao.StageDAO;
+import org.apache.ambari.server.orm.dao.UpgradeDAO;
+import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.RequestEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.orm.entities.StageEntity;
+import org.apache.ambari.server.orm.entities.UpgradeEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.UpgradeHelper;
+import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
+import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpInProgressEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyLong;
+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.assertTrue;
+
+/**
+ * UpgradeSummaryResourceProvider tests.
+ */
+public class UpgradeSummaryResourceProviderTest {
+
+ private HostDAO hostDAO;
+ private StackDAO stackDAO;
+ private RepositoryVersionDAO repoVersionDAO;
+ private UpgradeDAO upgradeDAO;
+ private RequestDAO requestDAO;
+ private StageDAO stageDAO;
+ private HostRoleCommandDAO hrcDAO;
+
+ @Inject
+ private UpgradeHelper m_upgradeHelper;
+
+ private Injector injector;
+ private Clusters clusters;
+ private OrmTestHelper helper;
+ private AmbariManagementController amc;
+
+ private String clusterName = "c1";
+
+ @Before
+ public void before() throws Exception {
+ m_upgradeHelper = createNiceMock(UpgradeHelper.class);
+
+ // Create an injector which will inject the mocks
+ injector = Guice.createInjector(Modules.override(new InMemoryDefaultTestModule()).with(new MockModule()));
+ injector.getInstance(GuiceJpaInitializer.class);
+ helper = injector.getInstance(OrmTestHelper.class);
+ amc = injector.getInstance(AmbariManagementController.class);
+
+ Field field = AmbariServer.class.getDeclaredField("clusterController");
+ field.setAccessible(true);
+ field.set(null, amc);
+
+ hostDAO = injector.getInstance(HostDAO.class);
+ stackDAO = injector.getInstance(StackDAO.class);
+ repoVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
+ upgradeDAO = injector.getInstance(UpgradeDAO.class);
+ requestDAO = injector.getInstance(RequestDAO.class);
+ stageDAO = injector.getInstance(StageDAO.class);
+ hrcDAO = injector.getInstance(HostRoleCommandDAO.class);
+ }
+
+ @After
+ public void after() {
+ injector.getInstance(PersistService.class).stop();
+ injector = null;
+ }
+
+ /**
+ * Create a Cluster called c1 on HDP 2.2.0 with a single ZOOKEEPER_SERVER on Host h1
+ */
+ public void createCluster() throws Exception {
+ StackEntity stackEntity = stackDAO.find("HDP", "2.2.0");
+
+ RepositoryVersionEntity repoVersionEntity = new RepositoryVersionEntity();
+ repoVersionEntity.setDisplayName("For Stack Version 2.2.0");
+ repoVersionEntity.setOperatingSystems("");
+ repoVersionEntity.setStack(stackEntity);
+ repoVersionEntity.setVersion("2.2.0.0");
+ repoVersionDAO.create(repoVersionEntity);
+
+ clusters = injector.getInstance(Clusters.class);
+
+ StackId stackId = new StackId("HDP-2.2.0");
+ clusters.addCluster(clusterName, stackId);
+ Cluster cluster = clusters.getCluster("c1");
+
+ helper.getOrCreateRepositoryVersion(stackId, stackId.getStackVersion());
+ cluster.createClusterVersion(stackId, stackId.getStackVersion(), "admin", RepositoryVersionState.INSTALLING);
+
+ clusters.addHost("h1");
+ Host host = clusters.getHost("h1");
+ Map<String, String> hostAttributes = new HashMap<String, String>();
+ hostAttributes.put("os_family", "redhat");
+ hostAttributes.put("os_release_version", "6.4");
+ host.setHostAttributes(hostAttributes);
+ host.setState(HostState.HEALTHY);
+ host.persist();
+
+ clusters.mapHostToCluster("h1", "c1");
+
+ // add a single ZOOKEEPER server
+ Service service = cluster.addService("ZOOKEEPER");
+ service.setDesiredStackVersion(cluster.getDesiredStackVersion());
+ service.persist();
+
+ ServiceComponent component = service.addServiceComponent("ZOOKEEPER_SERVER");
+ ServiceComponentHost sch = component.addServiceComponentHost("h1");
+ sch.setVersion("2.2.0.0");
+
+ component = service.addServiceComponent("ZOOKEEPER_CLIENT");
+ sch = component.addServiceComponentHost("h1");
+ sch.setVersion("2.2.0.0");
+ }
+
+ /**
+ * Create a request, stage, and completed task.
+ * @param cluster
+ * @param upgradeRequestId
+ * @param stageId
+ */
+ @Transactional
+ private void createCommands(Cluster cluster, Long upgradeRequestId, Long stageId) {
+ HostEntity h1 = hostDAO.findByName("h1");
+ ServiceComponentHostEvent event = new ServiceComponentHostOpInProgressEvent("ZOOKEEPER_SERVER", "h1", 1L);
+ ServiceComponentHostEventWrapper eventWrapper = new ServiceComponentHostEventWrapper(event);
+
+ RequestEntity requestEntity = new RequestEntity();
+ requestEntity.setRequestId(upgradeRequestId);
+ requestEntity.setClusterId(cluster.getClusterId());
+ requestEntity.setStatus(HostRoleStatus.PENDING);
+ requestDAO.create(requestEntity);
+
+ // Create the stage and add it to the request
+ StageEntity stageEntity = new StageEntity();
+ stageEntity.setRequest(requestEntity);
+ stageEntity.setClusterId(cluster.getClusterId());
+ stageEntity.setRequestId(upgradeRequestId);
+ stageEntity.setStageId(stageId);
+ requestEntity.setStages(Collections.singletonList(stageEntity));
+ stageDAO.create(stageEntity);
+ requestDAO.merge(requestEntity);
+
+ // Create the task and add it to the stage
+ HostRoleCommandEntity hrc1 = new HostRoleCommandEntity();
+
+ hrc1.setStage(stageEntity);
+ hrc1.setStatus(HostRoleStatus.COMPLETED);
+ hrc1.setRole(Role.ZOOKEEPER_SERVER);
+ hrc1.setRoleCommand(RoleCommand.RESTART);
+ hrc1.setHostEntity(h1);
+
+ stageEntity.setHostRoleCommands(new ArrayList<HostRoleCommandEntity>());
+ stageEntity.getHostRoleCommands().add(hrc1);
+ h1.getHostRoleCommandEntities().add(hrc1);
+
+ hrcDAO.create(hrc1);
+ hostDAO.merge(h1);
+ }
+
+ /**
+ * Test UpgradeSummaryResourceProvider on several cases.
+ * 1. Incorrect cluster name throws exception
+ * 2. Upgrade with no tasks.
+ * 3. Construct Upgrade with a single COMPLETED task. Resource should not have a failed reason.
+ * 4. Append a failed task to the Upgrade. Resource should have a failed reason.
+ * @throws Exception
+ */
+ @Test
+ public void testGetUpgradeSummary() throws Exception {
+ createCluster();
+
+ Cluster cluster = clusters.getCluster(clusterName);
+ ResourceProvider upgradeSummaryResourceProvider = createProvider(amc);
+
+ // Case 1: Incorrect cluster name throws exception
+ Request requestResource = PropertyHelper.getReadRequest();
+ Predicate pBogus = new PredicateBuilder().property(UpgradeSummaryResourceProvider.UPGRADE_SUMMARY_CLUSTER_NAME).equals("bogus name").toPredicate();
+ try {
+ Set<Resource> resources = upgradeSummaryResourceProvider.getResources(requestResource, pBogus);
+ assertTrue("Expected exception to be thrown", false);
+ } catch (Exception e) {
+ ;
+ }
+
+ // Case 2: Upgrade with no tasks.
+ Long upgradeRequestId = 1L;
+
+ Predicate p1 = new PredicateBuilder().property(UpgradeSummaryResourceProvider.UPGRADE_SUMMARY_CLUSTER_NAME).equals(clusterName).toPredicate();
+ Predicate p2 = new PredicateBuilder().property(UpgradeSummaryResourceProvider.UPGRADE_SUMMARY_REQUEST_ID).equals(upgradeRequestId.toString()).toPredicate();
+ Predicate p1And2 = new AndPredicate(p1, p2);
+
+ Set<Resource> resources = upgradeSummaryResourceProvider.getResources(requestResource, p1And2);
+ assertEquals(0, resources.size());
+
+ UpgradeEntity upgrade = new UpgradeEntity();
+ upgrade.setRequestId(upgradeRequestId);
+ upgrade.setClusterId(cluster.getClusterId());
+ upgrade.setId(1L);
+ upgrade.setUpgradePackage("some-name");
+ upgrade.setUpgradeType(UpgradeType.ROLLING);
+ upgrade.setDirection(Direction.UPGRADE);
+ upgrade.setFromVersion("2.2.0.0");
+ upgrade.setToVersion("2.2.0.1");
+ upgradeDAO.create(upgrade);
+
+ // Resource used to make assertions.
+ Resource r;
+
+ resources = upgradeSummaryResourceProvider.getResources(requestResource, p1And2);
+ assertEquals(1, resources.size());
+ r = resources.iterator().next();
+ Assert.assertNull(r.getPropertyValue(UpgradeSummaryResourceProvider.UPGRADE_SUMMARY_FAIL_REASON));
+
+ // Case 3: Construct Upgrade with a single COMPLETED task. Resource should not have a failed reason.
+ Long currentStageId = 1L;
+ createCommands(cluster, upgradeRequestId, currentStageId);
+
+ resources = upgradeSummaryResourceProvider.getResources(requestResource, p1And2);
+ assertEquals(1, resources.size());
+ r = resources.iterator().next();
+ Assert.assertNull(r.getPropertyValue(UpgradeSummaryResourceProvider.UPGRADE_SUMMARY_FAIL_REASON));
+
+ // Case 4: Append a failed task to the Upgrade. Resource should have a failed reason.
+ RequestEntity requestEntity = requestDAO.findByPK(upgradeRequestId);
+ HostEntity h1 = hostDAO.findByName("h1");
+
+ StageEntity nextStage = new StageEntity();
+ nextStage.setRequest(requestEntity);
+ nextStage.setClusterId(cluster.getClusterId());
+ nextStage.setRequestId(upgradeRequestId);
+ nextStage.setStageId(++currentStageId);
+ requestEntity.getStages().add(nextStage);
+ stageDAO.create(nextStage);
+ requestDAO.merge(requestEntity);
+
+ // Create the task and add it to the stage
+ HostRoleCommandEntity hrc2 = new HostRoleCommandEntity();
+
+ hrc2.setStage(nextStage);
+ // Important that it's on its own stage with a FAILED status.
+ hrc2.setStatus(HostRoleStatus.FAILED);
+ hrc2.setRole(Role.ZOOKEEPER_SERVER);
+ hrc2.setRoleCommand(RoleCommand.RESTART);
+ hrc2.setCommandDetail("Restart ZOOKEEPER_SERVER");
+ hrc2.setHostEntity(h1);
+
+ nextStage.setHostRoleCommands(new ArrayList<HostRoleCommandEntity>());
+ nextStage.getHostRoleCommands().add(hrc2);
+ h1.getHostRoleCommandEntities().add(hrc2);
+
+ hrcDAO.create(hrc2);
+ hostDAO.merge(h1);
+ hrc2.setRequestId(upgradeRequestId);
+ hrc2.setStageId(nextStage.getStageId());
+ hrcDAO.merge(hrc2);
+
+ Resource failedTask = new ResourceImpl(Resource.Type.Task);
+ expect(m_upgradeHelper.getTaskResource(anyString(), anyLong(), anyLong(), anyLong())).andReturn(failedTask).anyTimes();
+ replay(m_upgradeHelper);
+
+ resources = upgradeSummaryResourceProvider.getResources(requestResource, p1And2);
+ assertEquals(1, resources.size());
+ r = resources.iterator().next();
+ assertEquals("Failed calling Restart ZOOKEEPER_SERVER on host h1", r.getPropertyValue(UpgradeSummaryResourceProvider.UPGRADE_SUMMARY_FAIL_REASON));
+ }
+
+ /**
+ * @param amc
+ * @return the provider
+ */
+ private UpgradeSummaryResourceProvider createProvider(AmbariManagementController amc) {
+ return new UpgradeSummaryResourceProvider(amc);
+ }
+
+ /**
+ * Mock module that will bind UpgradeHelper to a mock instance.
+ */
+ private class MockModule implements Module {
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(UpgradeHelper.class).toInstance(m_upgradeHelper);
+ }
+ }
+}
\ No newline at end of file