Skip to content
Permalink
Browse files
AMBARI-25006. Support component-level provision_action in Add Service…
… request (#2725)
  • Loading branch information
adoroszlai committed Dec 20, 2018
1 parent 3fc52fc commit 1431ab44887c2ff7f9e94f8fcb42e24e3ce33800
Showing 23 changed files with 1,137 additions and 280 deletions.
@@ -66,6 +66,7 @@
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.internal.RequestOperationLevel;
import org.apache.ambari.server.controller.internal.RequestResourceFilter;
import org.apache.ambari.server.controller.internal.RequestResourceProvider;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
@@ -450,8 +451,8 @@ public boolean shouldHostBeRemoved(final String hostname)
commandTimeout = Math.max(60, commandTimeout);
}

if (requestParams != null && requestParams.containsKey("context")) {
String requestContext = requestParams.get("context");
if (requestParams != null && requestParams.containsKey(RequestResourceProvider.CONTEXT)) {
String requestContext = requestParams.get(RequestResourceProvider.CONTEXT);
if (StringUtils.isNotEmpty(requestContext) && requestContext.toLowerCase().contains("rolling-restart")) {
Config clusterEnvConfig = cluster.getDesiredConfigByType("cluster-env");
if (clusterEnvConfig != null) {
@@ -127,6 +127,7 @@
import org.apache.ambari.server.controller.internal.HostComponentResourceProvider;
import org.apache.ambari.server.controller.internal.RequestOperationLevel;
import org.apache.ambari.server.controller.internal.RequestResourceFilter;
import org.apache.ambari.server.controller.internal.RequestResourceProvider;
import org.apache.ambari.server.controller.internal.RequestStageContainer;
import org.apache.ambari.server.controller.internal.URLStreamProvider;
import org.apache.ambari.server.controller.internal.WidgetLayoutResourceProvider;
@@ -276,11 +277,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
LoggerFactory.getLogger(AmbariManagementControllerImpl.class);
private final static Logger configChangeLog = LoggerFactory.getLogger("configchange");

/**
* Property name of request context.
*/
private static final String REQUEST_CONTEXT_PROPERTY = "context";

private static final Type hostAttributesType =
new TypeToken<Map<String, String>>() {}.getType();

@@ -2910,7 +2906,7 @@ protected RequestStageContainer doStageCreation(RequestStageContainer requestSta
String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);

Stage stage = createNewStage(requestStages.getLastStageId(), cluster,
requestStages.getId(), requestProperties.get(REQUEST_CONTEXT_PROPERTY),
requestStages.getId(), requestProperties.get(RequestResourceProvider.CONTEXT),
"{}", null);
boolean skipFailure = false;
if (requestProperties.containsKey(Setting.SETTING_NAME_SKIP_FAILURE) && requestProperties.get(Setting.SETTING_NAME_SKIP_FAILURE).equalsIgnoreCase("true")) {
@@ -3810,7 +3806,7 @@ private void createAndExecuteRefreshIncludeExcludeFilesActionForMasters(Map<Stri
}
LOG.debug("Refresh include/exclude files action will be executed for " + serviceMasterMap);
HashMap<String, String> requestProperties = new HashMap<>();
requestProperties.put("context", "Update Include/Exclude Files for " + serviceMasterMap.keySet().toString());
requestProperties.put(RequestResourceProvider.CONTEXT, "Update Include/Exclude Files for " + serviceMasterMap.keySet().toString());
HashMap<String, String> params = new HashMap<>();
params.put(AmbariCustomCommandExecutionHelper.UPDATE_FILES_ONLY, String.valueOf(isDecommission));

@@ -4164,7 +4160,7 @@ public RequestStatusResponse createAction(ExecuteActionRequest actionRequest,
String requestContext = "";

if (requestProperties != null) {
requestContext = requestProperties.get(REQUEST_CONTEXT_PROPERTY);
requestContext = requestProperties.get(RequestResourceProvider.CONTEXT);
if (requestContext == null) {
// guice needs a non-null value as there is no way to mark this parameter @Nullable
requestContext = "";
@@ -20,6 +20,7 @@
import static org.apache.ambari.server.controller.AmbariManagementControllerImpl.CLUSTER_PHASE_INITIAL_INSTALL;
import static org.apache.ambari.server.controller.AmbariManagementControllerImpl.CLUSTER_PHASE_INITIAL_START;
import static org.apache.ambari.server.controller.AmbariManagementControllerImpl.CLUSTER_PHASE_PROPERTY;
import static org.apache.ambari.server.controller.internal.RequestResourceProvider.CONTEXT;

import java.util.ArrayList;
import java.util.Collection;
@@ -175,8 +176,8 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
public static final String SKIP_INSTALL_FOR_COMPONENTS = "skipInstallForComponents";
public static final String DO_NOT_SKIP_INSTALL_FOR_COMPONENTS = "dontSkipInstallForComponents";
public static final String ALL_COMPONENTS = "ALL";
public static final String SKIP_INSTALL_FOR_ALL_COMPONENTS = joinComponentList(ImmutableSet.of(ALL_COMPONENTS));
public static final String DO_NOT_SKIP_INSTALL_FOR_ANY_COMPONENTS = joinComponentList(ImmutableSet.of());
public static final String FOR_ALL_COMPONENTS = joinComponentList(ImmutableSet.of(ALL_COMPONENTS));
public static final String FOR_NO_COMPONENTS = joinComponentList(ImmutableSet.of());

/**
* maintenance state helper
@@ -394,7 +395,7 @@ public RequestStatusResponse install(String cluster, String hostname, Collection

installProperties.put(DESIRED_STATE, "INSTALLED");
Map<String, String> requestInfo = new HashMap<>();
requestInfo.put("context", String.format("Install components on host %s", hostname));
requestInfo.put(CONTEXT, String.format("Install components on host %s", hostname));
requestInfo.put(CLUSTER_PHASE_PROPERTY, CLUSTER_PHASE_INITIAL_INSTALL);
// although the operation is really for a specific host, the level needs to be set to HostComponent
// to make sure that any service in maintenance mode does not prevent install/start on the new host during scale-up
@@ -452,7 +453,7 @@ public static boolean shouldSkipInstallTaskForComponent(String componentName, bo
CLUSTER_PHASE_INITIAL_INSTALL.equals(requestProperties.get(CLUSTER_PHASE_PROPERTY)) &&
skipInstallForComponents != null &&
(skipInstallForComponents.contains(searchString) ||
(skipInstallForComponents.equals(SKIP_INSTALL_FOR_ALL_COMPONENTS) &&
(skipInstallForComponents.equals(FOR_ALL_COMPONENTS) &&
!requestProperties.get(DO_NOT_SKIP_INSTALL_FOR_COMPONENTS).contains(searchString))
);
}
@@ -470,7 +471,7 @@ public RequestStatusResponse start(String cluster, String hostName, Collection<S
UnsupportedPropertyException, NoSuchParentResourceException {

Map<String, String> requestInfo = new HashMap<>();
requestInfo.put("context", String.format("Start components on host %s", hostName));
requestInfo.put(CONTEXT, String.format("Start components on host %s", hostName));
requestInfo.put(CLUSTER_PHASE_PROPERTY, CLUSTER_PHASE_INITIAL_START);
// see rationale for marking the operation as HostComponent-level at "Install components on host"
requestInfo.putAll(RequestOperationLevel.propertiesFor(Resource.Type.HostComponent, cluster));
@@ -18,27 +18,33 @@

package org.apache.ambari.server.controller.internal;

import java.util.List;

import org.apache.ambari.server.topology.ProvisionStep;

import com.google.common.collect.ImmutableList;

public enum ProvisionAction {
INSTALL_ONLY {
@Override
public boolean skipStart() {
return true;
public List<ProvisionStep> getSteps() {
return ImmutableList.of(ProvisionStep.INSTALL);
}
},
START_ONLY {
@Override
public boolean skipInstall() {
return true;
public List<ProvisionStep> getSteps() {
return ImmutableList.of(ProvisionStep.SKIP_INSTALL, ProvisionStep.START);
}
},
INSTALL_AND_START {
@Override
public List<ProvisionStep> getSteps() {
return ImmutableList.of(ProvisionStep.INSTALL, ProvisionStep.START);
}
},
INSTALL_AND_START, // Default action
;

public boolean skipInstall() {
return false;
}
public abstract List<ProvisionStep> getSteps();

public boolean skipStart() {
return false;
}
}
@@ -39,8 +39,6 @@
import org.apache.ambari.server.RoleCommand;
import org.apache.ambari.server.ServiceNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AddServiceRequest;
import org.apache.ambari.server.controller.AddServiceRequest.OperationType;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.KerberosHelper;
import org.apache.ambari.server.controller.MaintenanceStateHelper;
@@ -80,6 +78,7 @@
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
import org.apache.ambari.server.topology.addservice.AddServiceOrchestrator;
import org.apache.ambari.server.topology.addservice.AddServiceRequest;
import org.apache.ambari.server.utils.LoggingPreconditions;
import org.apache.ambari.spi.RepositoryType;
import org.apache.commons.collections.CollectionUtils;
@@ -1235,7 +1234,7 @@ private void validateCreateRequests(Set<ServiceRequest> requests, Clusters clust
}

private static boolean isAddServiceRequest(Map<String, Object> properties) {
return OperationType.ADD_SERVICE.name().equals(properties.get(OPERATION_TYPE));
return AddServiceRequest.OperationType.ADD_SERVICE.name().equals(properties.get(OPERATION_TYPE));
}

private RequestStatusResponse processAddServiceRequest(Map<String, Object> requestProperties, Map<String, String> requestInfoProperties) throws NoSuchParentResourceException {
@@ -21,6 +21,8 @@
import java.util.LinkedList;
import java.util.List;

import javax.annotation.Nonnull;

import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Resource;

@@ -40,6 +42,10 @@ public Predicate create(Predicate... predicates) {
}

public static Predicate instance(Predicate... predicates) {
return of(Arrays.asList(predicates));
}

public static Predicate of(@Nonnull Iterable<? extends Predicate> predicates) {
List<Predicate> predicateList = new LinkedList<>();

// Simplify the predicate array
@@ -0,0 +1,50 @@
/*
* 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.predicate;

import java.util.Collection;
import java.util.Optional;
import java.util.function.Function;

import org.apache.ambari.server.controller.spi.Predicate;

public class Predicates {

/**
* Creates an {@link OrPredicate} of the given predicates if any.
*
* @param predicates collection of predicates to be OR-ed
* @return {@link Optional} of the {@code OrPredicate} if any predicates are given,
* otherwise an empty {@code Optional}
*/
public static Optional<Predicate> anyOf(Collection<? extends Predicate> predicates) {
return predicates != null && !predicates.isEmpty() ? Optional.of(OrPredicate.of(predicates)) : Optional.empty();
}

/**
* Creates a {@link Function} which, when called, creates an {@link AndPredicate} of
* its input and the {@code presetPredicate}. The function can then be used to transform
* {@code Optional}s or streams.
*
* @param presetPredicate this predicate will be AND-ed with the input to the {@code Function}
* @return the {@code Function}
*/
public static Function<Predicate, Predicate> and(Predicate presetPredicate) {
return predicate -> new AndPredicate(presetPredicate, predicate);
}
}
@@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ambari.server.topology;

import static org.apache.ambari.server.controller.AmbariManagementControllerImpl.CLUSTER_PHASE_INITIAL_INSTALL;
import static org.apache.ambari.server.controller.AmbariManagementControllerImpl.CLUSTER_PHASE_INITIAL_START;
import static org.apache.ambari.server.controller.AmbariManagementControllerImpl.CLUSTER_PHASE_PROPERTY;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.DO_NOT_SKIP_INSTALL_FOR_COMPONENTS;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.FOR_ALL_COMPONENTS;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.FOR_NO_COMPONENTS;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.SKIP_INSTALL_FOR_COMPONENTS;

import java.util.Map;

import org.apache.ambari.server.state.State;

import com.google.common.collect.ImmutableMap;

/**
* Steps of service provisioning.
*/
public enum ProvisionStep {

INSTALL {
@Override
public State getDesiredStateToSet() {
return State.INSTALLED;
}

@Override
public Map<String, String> getProvisionProperties() {
return ImmutableMap.of(CLUSTER_PHASE_PROPERTY, CLUSTER_PHASE_INITIAL_INSTALL);
}
},

/**
* This special step is used for START_ONLY services/components, because state
* transition cannot skip INSTALLED in the INIT -> INSTALLED -> STARTED sequence.
*/
SKIP_INSTALL {
@Override
public State getDesiredStateToSet() {
return State.INSTALLED;
}

@Override
public Map<String, String> getProvisionProperties() {
return ImmutableMap.of(
SKIP_INSTALL_FOR_COMPONENTS, FOR_ALL_COMPONENTS,
DO_NOT_SKIP_INSTALL_FOR_COMPONENTS, FOR_NO_COMPONENTS,
CLUSTER_PHASE_PROPERTY, CLUSTER_PHASE_INITIAL_INSTALL
);
}
},

START {
@Override
public State getDesiredStateToSet() {
return State.STARTED;
}

@Override
public Map<String, String> getProvisionProperties() {
return ImmutableMap.of(CLUSTER_PHASE_PROPERTY, CLUSTER_PHASE_INITIAL_START);
}
},
;

public abstract State getDesiredStateToSet();
public abstract Map<String, String> getProvisionProperties();

}
@@ -23,7 +23,6 @@
import java.util.Optional;
import java.util.Set;

import org.apache.ambari.server.controller.AddServiceRequest;
import org.apache.ambari.server.controller.internal.RequestStageContainer;
import org.apache.ambari.server.controller.internal.Stack;
import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
@@ -46,13 +45,24 @@ public final class AddServiceInfo {
public AddServiceInfo(
AddServiceRequest request,
String clusterName,
RequestStageContainer stages,
Stack stack,
Configuration config,
KerberosDescriptor kerberosDescriptor,
Map<String, Map<String, Set<String>>> newServices
) {
this(request, clusterName, stages, stack, config, newServices, null, null);
}

AddServiceInfo(
AddServiceRequest request,
String clusterName,
RequestStageContainer stages,
Map<String, Map<String,
Set<String>>> newServices,
LayoutRecommendationInfo recommendationInfo) {
Stack stack,
Configuration config,
Map<String, Map<String, Set<String>>> newServices,
KerberosDescriptor kerberosDescriptor,
LayoutRecommendationInfo recommendationInfo
) {
this.request = request;
this.clusterName = clusterName;
this.stack = stack;
@@ -65,11 +75,11 @@ public AddServiceInfo(

public AddServiceInfo withLayoutRecommendation(Map<String, Map<String, Set<String>>> services,
LayoutRecommendationInfo recommendation) {
return new AddServiceInfo(request, clusterName, stack, config, kerberosDescriptor, stages, services, recommendation);
return new AddServiceInfo(request, clusterName, stages, stack, config, services, kerberosDescriptor, recommendation);
}

public AddServiceInfo withConfig(Configuration newConfig) {
return new AddServiceInfo(request, clusterName, stack, newConfig, kerberosDescriptor, stages, newServices, recommendationInfo);
return new AddServiceInfo(request, clusterName, stages, stack, newConfig, newServices, kerberosDescriptor, recommendationInfo);
}

@Override

0 comments on commit 1431ab4

Please sign in to comment.