package com.sequenceiq.cloudbreak.shell.commands.common;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
import com.google.common.base.Splitter;
import com.sequenceiq.cloudbreak.api.model.RecipeResponse;
import com.sequenceiq.cloudbreak.api.model.RecoveryMode;
import com.sequenceiq.cloudbreak.shell.completion.HostGroup;
import com.sequenceiq.cloudbreak.shell.model.Hints;
import com.sequenceiq.cloudbreak.shell.model.HostgroupEntry;
import com.sequenceiq.cloudbreak.shell.model.ShellContext;
public class HostGroupCommands implements CommandMarker {
private ShellContext shellContext;
public HostGroupCommands(ShellContext shellContext) {
this.shellContext = shellContext;
}
@CliAvailabilityIndicator(value = "hostgroup configure")
public boolean isCreateHostGroupAvailable() {
return (shellContext.isBlueprintAvailable() && shellContext.isCredentialAvailable() || shellContext.isStackAvailable())
&& !shellContext.isMarathonMode()
&& !shellContext.isYarnMode();
}
@CliAvailabilityIndicator(value = "hostgroup show")
public boolean isShowHostGroupAvailable() {
return !shellContext.isMarathonMode() && !shellContext.isYarnMode();
}
@CliCommand(value = "hostgroup configure", help = "Configure host groups")
public String createHostGroup(
@CliOption(key = "hostgroup", mandatory = true, help = "Name of the hostgroup") HostGroup hostgroup,
@CliOption(key = "recipeIds", help = "A comma separated list of recipe ids") String recipeIds,
@CliOption(key = "recipeNames", help = "A comma separated list of recipe names") String recipeNames,
@CliOption(key = "recoveryMode", help = "The recovery mode: AUTO or MANUAL", unspecifiedDefaultValue = "MANUAL") RecoveryMode recoverMode) {
try {
Set<Long> recipeIdSet = new HashSet<>();
if (recipeIds != null) {
recipeIdSet.addAll(getRecipeIds(recipeIds, RecipeParameterType.ID));
}
if (recipeNames != null) {
recipeIdSet.addAll(getRecipeIds(recipeNames, RecipeParameterType.NAME));
}
if (shellContext.getInstanceGroups().get(hostgroup.getName()) == null) {
throw shellContext.exceptionTransformer().transformToRuntimeException(String.format("Instancegroup named %s is missing", hostgroup.getName()));
}
shellContext.putHostGroup(hostgroup.getName(),
new HostgroupEntry(shellContext.getInstanceGroups().get(hostgroup.getName()).getNodeCount(), recipeIdSet, recoverMode));
if (shellContext.getHostGroups().entrySet().size() == shellContext.getInstanceGroups().entrySet().size()) {
shellContext.setHint(Hints.CREATE_CLUSTER);
} else {
shellContext.setHint(Hints.CONFIGURE_HOSTGROUP);
}
return shellContext.outputTransformer().render(shellContext.getHostGroups(), "hostgroup");
} catch (Exception ex) {
throw shellContext.exceptionTransformer().transformToRuntimeException(ex);
}
}
@CliCommand(value = "hostgroup show", help = "Show the currently available host groups")
public String showHostGroup() throws Exception {
return shellContext.outputTransformer().render(shellContext.getHostGroups(), "hostgroup");
}
private enum RecipeParameterType {
ID, NAME
}
private Set<Long> getRecipeIds(String inputs, final RecipeParameterType type) {
return StreamSupport.stream(Splitter.on(",").omitEmptyStrings().trimResults().split(inputs).spliterator(), false).map(input -> {
try {
RecipeResponse resp = null;
switch (type) {
case ID:
resp = shellContext.cloudbreakClient().recipeEndpoint().get(Long.valueOf(input));
break;
case NAME:
resp = shellContext.cloudbreakClient().recipeEndpoint().getPublic(input);
break;
default:
throw new UnsupportedOperationException();
}
return resp.getId();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}).collect(Collectors.toSet());
}
}