Search in sources :

Example 16 with HostGroup

use of com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup in project cloudbreak by hortonworks.

the class RecipeTemplateService method isGeneratedRecipesInDbStale.

/**
 * Compare generated recipes from the database against on-the-fly generated recipes for every host groups
 * If any of those will differ from the source (in database) or no recipe relation found for generated recipe, the result will be false.
 */
public boolean isGeneratedRecipesInDbStale(Set<HostGroup> hostGroups, Map<HostGroup, List<RecipeModel>> generatedModels) {
    for (HostGroup hostGroup : hostGroups) {
        Set<GeneratedRecipe> generatedRecipes = hostGroup.getGeneratedRecipes();
        boolean hasRecipes = CollectionUtils.isNotEmpty(hostGroup.getRecipes());
        boolean hasGeneratedRecipes = CollectionUtils.isNotEmpty(generatedRecipes);
        boolean recipeModelsContainsHostGroup = MapUtils.isNotEmpty(generatedModels) && generatedModels.containsKey(hostGroup);
        if (hasRecipes && !hasGeneratedRecipes) {
            LOGGER.debug("No generated recipes found for host group '{}', but it has recipes. Recipes should be uploaded and regenerated.", hostGroup.getName());
            return false;
        } else if (!hasGeneratedRecipes) {
            LOGGER.debug("No source and generated recipes found for host group '{}', skip comparing source and generated recipes.", hostGroup.getName());
            continue;
        } else if (!recipeModelsContainsHostGroup) {
            LOGGER.debug("Generated recipe models do not contain host group {}. Recipes should be regenerated.", hostGroup.getName());
            return false;
        }
        boolean anyWithoutRecipeSource = generatedRecipes.stream().anyMatch(g -> g.getRecipe() == null);
        if (anyWithoutRecipeSource) {
            LOGGER.debug("Not found recipe source for generated recipe. Recipes should be uploaded and regenerated.");
            return false;
        }
        Map<String, GeneratedRecipe> generatedRecipeNameMap = generatedRecipes.stream().collect(Collectors.toMap(g -> g.getRecipe().getName(), g -> g, (g1, g2) -> g1));
        List<RecipeModel> recipeModelList = generatedModels.get(hostGroup);
        if (generatedRecipes.size() != recipeModelList.size()) {
            LOGGER.debug("Source and generated recipe counts are not matching for host group '{}'. Recipes should be uploaded and regenerated.", hostGroup.getName());
            return false;
        }
        if (isRecipeUpToDateInHostGroup(hostGroup, generatedRecipeNameMap, recipeModelList)) {
            LOGGER.debug("Recipes matches for host group '{}'", hostGroup.getName());
        } else {
            return false;
        }
    }
    return true;
}
Also used : MapUtils(org.apache.commons.collections4.MapUtils) Stack(com.sequenceiq.cloudbreak.domain.stack.Stack) Logger(org.slf4j.Logger) GeneratedRecipe(com.sequenceiq.cloudbreak.domain.stack.cluster.host.GeneratedRecipe) Benchmark.measure(com.sequenceiq.cloudbreak.util.Benchmark.measure) LoggerFactory(org.slf4j.LoggerFactory) GeneratedRecipeService(com.sequenceiq.cloudbreak.service.recipe.GeneratedRecipeService) Set(java.util.Set) Collectors(java.util.stream.Collectors) TemplatePreparationObject(com.sequenceiq.cloudbreak.template.TemplatePreparationObject) Base64(org.apache.commons.codec.binary.Base64) CollectionUtils(org.apache.commons.collections4.CollectionUtils) Workspace(com.sequenceiq.cloudbreak.workspace.model.Workspace) Recipe(com.sequenceiq.cloudbreak.domain.Recipe) RecipeModel(com.sequenceiq.cloudbreak.orchestrator.model.RecipeModel) List(java.util.List) TransactionService(com.sequenceiq.cloudbreak.common.service.TransactionService) HostGroup(com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup) CentralRecipeUpdater(com.sequenceiq.cloudbreak.recipe.CentralRecipeUpdater) Service(org.springframework.stereotype.Service) Map(java.util.Map) StackToTemplatePreparationObjectConverter(com.sequenceiq.cloudbreak.converter.StackToTemplatePreparationObjectConverter) StringUtils(io.micrometer.core.instrument.util.StringUtils) GeneratedRecipe(com.sequenceiq.cloudbreak.domain.stack.cluster.host.GeneratedRecipe) HostGroup(com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup) RecipeModel(com.sequenceiq.cloudbreak.orchestrator.model.RecipeModel)

Example 17 with HostGroup

use of com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup in project cloudbreak by hortonworks.

the class UpdateRecipeService method refreshRecipesForCluster.

/**
 * Updating recipes for an existing cluster. The input should contain host group - recipes mapping
 * If a host group key from the mappings is missing from the input, that is not going to be updated.
 * (or both - that is the default). Output is the newly attached/detached recipes in db.
 */
public UpdateRecipesV4Response refreshRecipesForCluster(Long workspaceId, Stack stack, List<UpdateHostGroupRecipes> recipesPerHostGroup) {
    Set<String> recipesToFind = recipesPerHostGroup.stream().flatMap(rphg -> rphg.getRecipeNames().stream()).collect(Collectors.toSet());
    Map<String, Set<String>> recipesToUpdate = recipesPerHostGroup.stream().collect(Collectors.toMap(UpdateHostGroupRecipes::getHostGroupName, UpdateHostGroupRecipes::getRecipeNames, (n1, n2) -> n1));
    LOGGER.debug("Update recipes {}", recipesToUpdate);
    Set<Recipe> recipes = recipeService.getByNamesForWorkspaceId(recipesToFind, workspaceId);
    validate(recipesToFind, recipes);
    Set<HostGroup> hostGroups = hostGroupService.getByClusterWithRecipes(stack.getCluster().getId());
    UpdateRecipesV4Response result = updateRecipesForHostGroups(recipesToUpdate, recipes, hostGroups);
    LOGGER.debug("Update recipes result: {}", result);
    return result;
}
Also used : Stack(com.sequenceiq.cloudbreak.domain.stack.Stack) BadRequestException(com.sequenceiq.cloudbreak.common.exception.BadRequestException) Logger(org.slf4j.Logger) GeneratedRecipe(com.sequenceiq.cloudbreak.domain.stack.cluster.host.GeneratedRecipe) AttachRecipeV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recipe.AttachRecipeV4Response) UpdateRecipesV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recipe.UpdateRecipesV4Response) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) HostGroupService(com.sequenceiq.cloudbreak.service.hostgroup.HostGroupService) UpdateHostGroupRecipes(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.base.UpdateHostGroupRecipes) Collectors(java.util.stream.Collectors) DetachRecipeV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recipe.DetachRecipeV4Response) Recipe(com.sequenceiq.cloudbreak.domain.Recipe) HashSet(java.util.HashSet) List(java.util.List) HostGroup(com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup) Service(org.springframework.stereotype.Service) Map(java.util.Map) Optional(java.util.Optional) NotFoundException(com.sequenceiq.cloudbreak.common.exception.NotFoundException) Joiner(com.google.common.base.Joiner) Set(java.util.Set) HashSet(java.util.HashSet) UpdateRecipesV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recipe.UpdateRecipesV4Response) GeneratedRecipe(com.sequenceiq.cloudbreak.domain.stack.cluster.host.GeneratedRecipe) Recipe(com.sequenceiq.cloudbreak.domain.Recipe) HostGroup(com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup)

Example 18 with HostGroup

use of com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup in project cloudbreak by hortonworks.

the class UpdateRecipeService method updateRecipeForCluster.

private void updateRecipeForCluster(Long workspaceId, Stack stack, String recipeName, String hostGroupName, boolean detach) {
    Recipe recipe = recipeService.getByNameForWorkspaceId(recipeName, workspaceId);
    HostGroup hostGroup = hostGroupService.getByClusterIdAndNameWithRecipes(stack.getCluster().getId(), hostGroupName);
    if (hostGroup == null) {
        throw new NotFoundException(String.format("Host group '%s' not found for workspace", hostGroupName));
    }
    Set<Recipe> existingRecipes = hostGroup.getRecipes();
    Set<String> existingRecipeNames = existingRecipes.stream().map(Recipe::getName).collect(Collectors.toSet());
    if (detach) {
        detachRecipeFromHostGroup(recipe, hostGroup, existingRecipeNames);
    } else {
        attachRecipeToHostGroup(recipe, hostGroup, existingRecipeNames);
    }
}
Also used : GeneratedRecipe(com.sequenceiq.cloudbreak.domain.stack.cluster.host.GeneratedRecipe) Recipe(com.sequenceiq.cloudbreak.domain.Recipe) HostGroup(com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup) NotFoundException(com.sequenceiq.cloudbreak.common.exception.NotFoundException)

Example 19 with HostGroup

use of com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup in project cloudbreak by hortonworks.

the class UpdateRecipeService method updateRecipesForHostGroups.

private UpdateRecipesV4Response updateRecipesForHostGroups(Map<String, Set<String>> recipesToUpdate, Set<Recipe> recipes, Set<HostGroup> hostGroups) {
    UpdateRecipesV4Response result = new UpdateRecipesV4Response();
    for (HostGroup hostGroup : hostGroups) {
        UpdateHostGroupRecipesPair updatePairs = doHostGroupRecipeUpdate(recipesToUpdate, recipes, hostGroup);
        updatePairs.getRecipesToAttach().ifPresent(a -> result.getRecipesAttached().add(a));
        updatePairs.getRecipesToDetach().ifPresent(d -> result.getRecipesDetached().add(d));
    }
    return result;
}
Also used : UpdateRecipesV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recipe.UpdateRecipesV4Response) HostGroup(com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup)

Example 20 with HostGroup

use of com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup in project cloudbreak by hortonworks.

the class ClouderaManagerDecomissioner method collectHostsToRemove.

public Map<String, InstanceMetaData> collectHostsToRemove(Stack stack, HostGroup hostGroup, Set<String> hostNames, ApiClient client) {
    Set<InstanceMetaData> hostsInHostGroup = hostGroup.getInstanceGroup().getNotTerminatedInstanceMetaDataSet();
    Map<String, InstanceMetaData> hostsToRemove = hostsInHostGroup.stream().filter(hostMetadata -> hostNames.contains(hostMetadata.getDiscoveryFQDN())).collect(Collectors.toMap(InstanceMetaData::getDiscoveryFQDN, hostMetadata -> hostMetadata));
    if (hostsToRemove.size() != hostNames.size()) {
        List<String> missingHosts = hostNames.stream().filter(h -> !hostsToRemove.containsKey(h)).collect(Collectors.toList());
        LOGGER.debug("Not all requested hosts found in CB for host group: {}. MissingCount={}, missingHosts=[{}]. Requested hosts: [{}]", hostGroup.getName(), missingHosts.size(), missingHosts, hostNames);
    }
    HostsResourceApi hostsResourceApi = clouderaManagerApiFactory.getHostsResourceApi(client);
    try {
        ApiHostList hostRefList = hostsResourceApi.readHosts(null, null, SUMMARY_REQUEST_VIEW);
        List<String> runningHosts = hostRefList.getItems().stream().map(ApiHost::getHostname).collect(Collectors.toList());
        // TODO: what if i remove a node from CM manually?
        List<String> matchingCmHosts = hostsToRemove.keySet().stream().filter(hostName -> runningHosts.contains(hostName)).collect(Collectors.toList());
        Set<String> matchingCmHostSet = new HashSet<>(matchingCmHosts);
        if (matchingCmHosts.size() != hostsToRemove.size()) {
            List<String> missingHostsInCm = hostsToRemove.keySet().stream().filter(h -> !matchingCmHostSet.contains(h)).collect(Collectors.toList());
            LOGGER.debug("Not all requested hosts found in CM. MissingCount={}, missingHosts=[{}]. Requested hosts: [{}]", missingHostsInCm.size(), missingHostsInCm, hostsToRemove.keySet());
        }
        Sets.newHashSet(hostsToRemove.keySet()).stream().filter(hostName -> !matchingCmHostSet.contains(hostName)).forEach(hostsToRemove::remove);
        LOGGER.debug("Collected hosts to remove: [{}]", hostsToRemove);
        return hostsToRemove;
    } catch (ApiException e) {
        LOGGER.error("Failed to get host list for cluster: {}", stack.getName(), e);
        throw new CloudbreakServiceException(e.getMessage(), e);
    }
}
Also used : LoggerFactory(org.slf4j.LoggerFactory) ApiService(com.cloudera.api.swagger.model.ApiService) ApiRole(com.cloudera.api.swagger.model.ApiRole) ApiException(com.cloudera.api.swagger.client.ApiException) ClustersResourceApi(com.cloudera.api.swagger.ClustersResourceApi) ApiRoleState(com.cloudera.api.swagger.model.ApiRoleState) FlowMessageService(com.sequenceiq.cloudbreak.message.FlowMessageService) Map(java.util.Map) ApiHostTemplate(com.cloudera.api.swagger.model.ApiHostTemplate) ClouderaManagerResourceApi(com.cloudera.api.swagger.ClouderaManagerResourceApi) HostTemplatesResourceApi(com.cloudera.api.swagger.HostTemplatesResourceApi) ApiHostTemplateList(com.cloudera.api.swagger.model.ApiHostTemplateList) NotEnoughNodeException(com.sequenceiq.cloudbreak.cluster.service.NotEnoughNodeException) ApiConfig(com.cloudera.api.swagger.model.ApiConfig) ApiHostsToRemoveArgs(com.cloudera.api.swagger.model.ApiHostsToRemoveArgs) ResourceAttributeUtil(com.sequenceiq.cloudbreak.cluster.util.ResourceAttributeUtil) Collection(java.util.Collection) HostsResourceApi(com.cloudera.api.swagger.HostsResourceApi) Set(java.util.Set) Status(com.sequenceiq.cloudbreak.api.endpoint.v4.common.Status) ExtendedPollingResult(com.sequenceiq.cloudbreak.polling.ExtendedPollingResult) ApiHostNameList(com.cloudera.api.swagger.model.ApiHostNameList) VolumeSetAttributes(com.sequenceiq.cloudbreak.cloud.model.VolumeSetAttributes) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) List(java.util.List) ApiServiceConfig(com.cloudera.api.swagger.model.ApiServiceConfig) Stream(java.util.stream.Stream) ApiHealthSummary(com.cloudera.api.swagger.model.ApiHealthSummary) Optional(java.util.Optional) CancellationException(com.sequenceiq.cloudbreak.cloud.scheduler.CancellationException) Joiner(com.google.common.base.Joiner) Stack(com.sequenceiq.cloudbreak.domain.stack.Stack) ApiCommand(com.cloudera.api.swagger.model.ApiCommand) HostServiceStatuses(com.sequenceiq.cloudbreak.cluster.status.HostServiceStatuses) HostServiceStatus(com.sequenceiq.cloudbreak.cluster.status.HostServiceStatus) ApiClient(com.cloudera.api.swagger.client.ApiClient) ApiHostList(com.cloudera.api.swagger.model.ApiHostList) Function(java.util.function.Function) ServicesResourceApi(com.cloudera.api.swagger.ServicesResourceApi) ClouderaManagerPollingServiceProvider(com.sequenceiq.cloudbreak.cm.polling.ClouderaManagerPollingServiceProvider) HashSet(java.util.HashSet) Inject(javax.inject.Inject) ApiHost(com.cloudera.api.swagger.model.ApiHost) RolesResourceApi(com.cloudera.api.swagger.RolesResourceApi) NodeIsBusyException(com.sequenceiq.cloudbreak.cluster.service.NodeIsBusyException) Logger(org.slf4j.Logger) ResourceEvent(com.sequenceiq.cloudbreak.event.ResourceEvent) Consumer(java.util.function.Consumer) HostName.hostName(com.sequenceiq.cloudbreak.cloud.model.HostName.hostName) Component(org.springframework.stereotype.Component) HostGroup(com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup) InstanceMetaData(com.sequenceiq.cloudbreak.domain.stack.instance.InstanceMetaData) CommandsResourceApi(com.cloudera.api.swagger.CommandsResourceApi) HostName(com.sequenceiq.cloudbreak.cloud.model.HostName) CloudbreakServiceException(com.sequenceiq.cloudbreak.common.exception.CloudbreakServiceException) MgmtServiceResourceApi(com.cloudera.api.swagger.MgmtServiceResourceApi) Comparator(java.util.Comparator) ApiRoleRef(com.cloudera.api.swagger.model.ApiRoleRef) ApiServiceList(com.cloudera.api.swagger.model.ApiServiceList) ClouderaManagerApiFactory(com.sequenceiq.cloudbreak.cm.client.retry.ClouderaManagerApiFactory) StringUtils(org.springframework.util.StringUtils) CloudbreakServiceException(com.sequenceiq.cloudbreak.common.exception.CloudbreakServiceException) InstanceMetaData(com.sequenceiq.cloudbreak.domain.stack.instance.InstanceMetaData) ApiHostList(com.cloudera.api.swagger.model.ApiHostList) HostsResourceApi(com.cloudera.api.swagger.HostsResourceApi) HashSet(java.util.HashSet) ApiException(com.cloudera.api.swagger.client.ApiException)

Aggregations

HostGroup (com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup)132 InstanceMetaData (com.sequenceiq.cloudbreak.domain.stack.instance.InstanceMetaData)66 Stack (com.sequenceiq.cloudbreak.domain.stack.Stack)60 HashSet (java.util.HashSet)55 Test (org.junit.jupiter.api.Test)52 List (java.util.List)50 InstanceGroup (com.sequenceiq.cloudbreak.domain.stack.instance.InstanceGroup)43 Cluster (com.sequenceiq.cloudbreak.domain.stack.cluster.Cluster)37 Map (java.util.Map)37 Set (java.util.Set)37 Collectors (java.util.stream.Collectors)35 HostGroupService (com.sequenceiq.cloudbreak.service.hostgroup.HostGroupService)25 Optional (java.util.Optional)25 ArrayList (java.util.ArrayList)24 StackService (com.sequenceiq.cloudbreak.service.stack.StackService)22 InstanceStatus (com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.base.InstanceStatus)21 ClusterApiConnectors (com.sequenceiq.cloudbreak.service.cluster.ClusterApiConnectors)21 HashMap (java.util.HashMap)19 Logger (org.slf4j.Logger)19 LoggerFactory (org.slf4j.LoggerFactory)19