Skip to content

Commit

Permalink
Merge pull request #12673 from hortonworks/merge-256
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'origin/CB-2.56.0' into master
  • Loading branch information
oleewere committed Apr 25, 2022
2 parents 9435f24 + e3a793d commit 96233da
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.sequenceiq.cloudbreak.service.recipe;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -19,6 +20,7 @@
import com.sequenceiq.cloudbreak.common.exception.NotFoundException;
import com.sequenceiq.cloudbreak.domain.Recipe;
import com.sequenceiq.cloudbreak.domain.stack.Stack;
import com.sequenceiq.cloudbreak.domain.stack.cluster.host.GeneratedRecipe;
import com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup;
import com.sequenceiq.cloudbreak.service.hostgroup.HostGroupService;

Expand All @@ -31,9 +33,12 @@ public class UpdateRecipeService {

private final HostGroupService hostGroupService;

public UpdateRecipeService(RecipeService recipeService, HostGroupService hostGroupService) {
private final GeneratedRecipeService generatedRecipeService;

public UpdateRecipeService(RecipeService recipeService, HostGroupService hostGroupService, GeneratedRecipeService generatedRecipeService) {
this.recipeService = recipeService;
this.hostGroupService = hostGroupService;
this.generatedRecipeService = generatedRecipeService;
}

/**
Expand Down Expand Up @@ -86,8 +91,19 @@ private UpdateHostGroupRecipesPair doHostGroupRecipeUpdate(Map<String, Set<Strin
.collect(Collectors.toSet());
attachHostGroupRecipesOpt = collectAttachHostGroupRecipes(hostGroupName, existingRecipeNames, updateRecipes);
detachHostGroupRecipesOpt = collectDetachHostGroupRecipes(hostGroupName, recipesForHostGroup, existingRecipes);
Set<GeneratedRecipe> generatedRecipeToDeleteSet = new HashSet<>();
if (detachHostGroupRecipesOpt.isPresent()) {
UpdateHostGroupRecipes detachHostGroupRecipes = detachHostGroupRecipesOpt.get();
generatedRecipeToDeleteSet = hostGroup.getGeneratedRecipes().stream()
.filter(gr -> recipeNamesMatchForGeneratedRecipe(gr, detachHostGroupRecipes.getRecipeNames()))
.collect(Collectors.toSet());
hostGroup.getGeneratedRecipes().removeAll(generatedRecipeToDeleteSet);
}
hostGroup.setRecipes(updateRecipes);
hostGroupService.save(hostGroup);
if (detachHostGroupRecipesOpt.isPresent() && !generatedRecipeToDeleteSet.isEmpty()) {
generatedRecipeService.deleteAll(generatedRecipeToDeleteSet);
}
}
}
return new UpdateHostGroupRecipesPair(attachHostGroupRecipesOpt.orElse(null), detachHostGroupRecipesOpt.orElse(null));
Expand Down Expand Up @@ -176,12 +192,22 @@ private void detachRecipeFromHostGroup(Recipe recipe, HostGroup hostGroup, Set<S
.filter(r -> !r.getName().equals(recipeName))
.collect(Collectors.toSet())
);
Optional<GeneratedRecipe> generatedRecipeToDelete =
hostGroup.getGeneratedRecipes().stream()
.filter(gr -> recipeNamesMatchForGeneratedRecipe(gr, Set.of(recipeName)))
.findFirst();
generatedRecipeToDelete.ifPresent(generatedRecipe -> hostGroup.getGeneratedRecipes().remove(generatedRecipe));
hostGroupService.save(hostGroup);
generatedRecipeToDelete.ifPresent(generatedRecipe -> generatedRecipeService.deleteAll(Set.of(generatedRecipe)));
} else {
LOGGER.debug("Recipe {} already detached from host group {}. ", recipeName, hostGroupName);
}
}

private boolean recipeNamesMatchForGeneratedRecipe(GeneratedRecipe gr, Set<String> recipeNames) {
return gr.getRecipe() != null && recipeNames != null && recipeNames.contains(gr.getRecipe().getName());
}

private void validate(Set<String> recipesToFind, Set<Recipe> recipes) {
Set<String> existingRecipesNames = recipes
.stream().map(Recipe::getName).collect(Collectors.toSet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
Expand All @@ -27,6 +33,7 @@
import com.sequenceiq.cloudbreak.domain.Recipe;
import com.sequenceiq.cloudbreak.domain.stack.Stack;
import com.sequenceiq.cloudbreak.domain.stack.cluster.Cluster;
import com.sequenceiq.cloudbreak.domain.stack.cluster.host.GeneratedRecipe;
import com.sequenceiq.cloudbreak.domain.stack.cluster.host.HostGroup;
import com.sequenceiq.cloudbreak.service.hostgroup.HostGroupService;

Expand All @@ -52,9 +59,12 @@ public class UpdateRecipeServiceTest {
@Mock
private HostGroupService hostGroupService;

@Mock
private GeneratedRecipeService generatedRecipeService;

@BeforeEach
public void setUp() {
underTest = new UpdateRecipeService(recipeService, hostGroupService);
underTest = new UpdateRecipeService(recipeService, hostGroupService, generatedRecipeService);
}

@Test
Expand All @@ -64,14 +74,16 @@ public void testRefreshRecipesForCluster() {
sampleMap.put(MASTER_HOST_GROUP_NAME, Set.of(PRE_CLDR_START_RECIPE));
Map<String, Set<String>> hostGroupsSample = new HashMap<>();
hostGroupsSample.put(MASTER_HOST_GROUP_NAME, Set.of(POST_CLDR_START_RECIPE));
when(recipeService.getByNamesForWorkspaceId(any(Set.class), anyLong()))
when(recipeService.getByNamesForWorkspaceId(anySet(), anyLong()))
.thenReturn(createRecipes(Set.of(PRE_CLDR_START_RECIPE, POST_CLDR_START_RECIPE)));
when(hostGroupService.getByClusterWithRecipes(anyLong()))
.thenReturn(createHostGroupWithRecipes(hostGroupsSample));
doNothing().when(generatedRecipeService).deleteAll(anySet());
// WHEN
UpdateRecipesV4Response response = underTest.refreshRecipesForCluster(DUMMY_ID, createStack(), createUpdateHostGroupRecipes(sampleMap));
// THEN
assertTrue(response.getRecipesAttached().get(0).getRecipeNames().contains(PRE_CLDR_START_RECIPE));
verify(generatedRecipeService, times(1)).deleteAll(anySet());
}

@Test
Expand All @@ -81,7 +93,7 @@ public void testRefreshRecipesForClusterNoUpdate() {
sampleMap.put(MASTER_HOST_GROUP_NAME, Set.of(PRE_CLDR_START_RECIPE));
Map<String, Set<String>> hostGroupsSample = new HashMap<>();
hostGroupsSample.put(MASTER_HOST_GROUP_NAME, Set.of(PRE_CLDR_START_RECIPE));
when(recipeService.getByNamesForWorkspaceId(any(Set.class), anyLong()))
when(recipeService.getByNamesForWorkspaceId(anySet(), anyLong()))
.thenReturn(createRecipes(Set.of(PRE_CLDR_START_RECIPE)));
when(hostGroupService.getByClusterWithRecipes(anyLong()))
.thenReturn(createHostGroupWithRecipes(hostGroupsSample));
Expand All @@ -97,9 +109,7 @@ public void testRefreshRecipesForClusterRecipeDoesNotExist() {
// GIVEN
Map<String, Set<String>> sampleMap = new HashMap<>();
sampleMap.put(MASTER_HOST_GROUP_NAME, Set.of(PRE_CLDR_START_RECIPE));
Map<String, Set<String>> hostGroupsSample = new HashMap<>();
hostGroupsSample.put(MASTER_HOST_GROUP_NAME, Set.of(POST_CLDR_START_RECIPE));
when(recipeService.getByNamesForWorkspaceId(any(Set.class), anyLong()))
when(recipeService.getByNamesForWorkspaceId(anySet(), anyLong()))
.thenReturn(createRecipes(Set.of(POST_CLDR_START_RECIPE)));
// WHEN
BadRequestException exception = assertThrows(BadRequestException.class, () -> underTest.refreshRecipesForCluster(DUMMY_ID, createStack(),
Expand All @@ -117,7 +127,7 @@ public void testRefreshRecipesForClusterAttachAndDetach() {
Map<String, Set<String>> hostGroupsSample = new HashMap<>();
hostGroupsSample.put(MASTER_HOST_GROUP_NAME, Set.of(POST_CLDR_START_RECIPE));
hostGroupsSample.put(GATEWAY_HOST_GROUP_NAME, new HashSet<>());
when(recipeService.getByNamesForWorkspaceId(any(Set.class), anyLong()))
when(recipeService.getByNamesForWorkspaceId(anySet(), anyLong()))
.thenReturn(createRecipes(Set.of(PRE_CLDR_START_RECIPE, POST_CLDR_START_RECIPE)));
when(hostGroupService.getByClusterWithRecipes(anyLong()))
.thenReturn(createHostGroupWithRecipes(hostGroupsSample));
Expand All @@ -136,7 +146,7 @@ public void testRefreshRecipesForClusterOnlyDbUpdate() {
sampleMap.put(MASTER_HOST_GROUP_NAME, Set.of(PRE_CLDR_START_RECIPE));
Map<String, Set<String>> hostGroupsSample = new HashMap<>();
hostGroupsSample.put(MASTER_HOST_GROUP_NAME, Set.of(POST_CLDR_START_RECIPE));
when(recipeService.getByNamesForWorkspaceId(any(Set.class), anyLong()))
when(recipeService.getByNamesForWorkspaceId(anySet(), anyLong()))
.thenReturn(createRecipes(Set.of(PRE_CLDR_START_RECIPE, POST_CLDR_START_RECIPE)));
when(hostGroupService.getByClusterWithRecipes(anyLong()))
.thenReturn(createHostGroupWithRecipes(hostGroupsSample));
Expand All @@ -147,6 +157,29 @@ public void testRefreshRecipesForClusterOnlyDbUpdate() {
assertTrue(response.getRecipesAttached().get(0).getRecipeNames().contains(PRE_CLDR_START_RECIPE));
}

@Test
public void testDetachRecipeFromCluster() {
// GIVEN
Set<Recipe> recipes = createRecipes(Set.of(POST_CLDR_START_RECIPE));
Map<String, Set<String>> hostGroupsSample = new HashMap<>();
hostGroupsSample.put(MASTER_HOST_GROUP_NAME, Set.of(POST_CLDR_START_RECIPE));
Set<HostGroup> hostGroups = createHostGroupWithRecipes(hostGroupsSample);
Recipe sampleRecipe = recipes.stream().findFirst().orElse(null);
HostGroup sampleHostGroup = hostGroups.stream().findFirst().orElse(null);
given(hostGroupService.getByClusterIdAndNameWithRecipes(anyLong(), anyString()))
.willReturn(sampleHostGroup);
given(recipeService.getByNameForWorkspaceId(anyString(), anyLong()))
.willReturn(sampleRecipe);
given(hostGroupService.save(any())).willReturn(sampleHostGroup);
doNothing().when(generatedRecipeService).deleteAll(anySet());
// WHEN
underTest.detachRecipeFromCluster(DUMMY_ID, createStack(), POST_CLDR_START_RECIPE, MASTER_HOST_GROUP_NAME);
// THEN
verify(hostGroupService, times(1)).save(any());
verify(hostGroupService, times(1)).getByClusterIdAndNameWithRecipes(anyLong(), anyString());
verify(generatedRecipeService, times(1)).deleteAll(anySet());
}

private List<UpdateHostGroupRecipes> createUpdateHostGroupRecipes(Map<String, Set<String>> hostGroupRecipesMap) {
List<UpdateHostGroupRecipes> result = new ArrayList<>();
for (Map.Entry<String, Set<String>> entry : hostGroupRecipesMap.entrySet()) {
Expand All @@ -164,12 +197,18 @@ private Set<HostGroup> createHostGroupWithRecipes(Map<String, Set<String>> hostG
HostGroup hostGroup = new HostGroup();
hostGroup.setName(entry.getKey());
Set<Recipe> recipeSet = new HashSet<>();
Set<GeneratedRecipe> generatedRecipeSet = new HashSet<>();
for (String recipeName : entry.getValue()) {
Recipe recipe = new Recipe();
GeneratedRecipe generatedRecipe = new GeneratedRecipe();
generatedRecipe.setRecipe(recipe);
recipe.setName(recipeName);
recipe.setGeneratedRecipes(Set.of(generatedRecipe));
recipeSet.add(recipe);
generatedRecipeSet.add(generatedRecipe);
}
hostGroup.setRecipes(recipeSet);
hostGroup.setGeneratedRecipes(generatedRecipeSet);
result.add(hostGroup);
}
return result;
Expand Down

0 comments on commit 96233da

Please sign in to comment.