Skip to content

Commit

Permalink
Split up default-config and layer config arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
spyrkob committed Sep 1, 2023
1 parent 7fb7e2f commit 866b242
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 80 deletions.
2 changes: 2 additions & 0 deletions dist/docs/guide/usage/add_feature_pack.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ $ prospero feature-pack add \
If the feature pack provides multiple configuration model, the configuration name can be prefixed with model name e.g. `--config standalone/standalone.xml`
Some feature packs provide a set of "default" configurations that will be included when installing the feature pack without `--layers` option. This list can be modified using `--default-config` parameter selecting which default configurations should be provisioned.
#### Offline installation
Similarly to other operations, `feature-pack add` can be executed in an offline mode. To do so, users should provide local repositories with all required artifacts (both for base server and the new feature) using `--repositories` parameter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,5 @@ private Commands() {

public static final String LAYERS = "--layers";
public static final String CONFIG = "--config";
public static final String DEFAULT_CONFIG = "--default-config";
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
import picocli.CommandLine;

import java.nio.file.Path;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static org.wildfly.prospero.cli.commands.CliConstants.Commands.FEATURE_PACKS_ALIAS;

Expand All @@ -47,11 +48,25 @@ public static class AddCommand extends AbstractMavenCommand {
required = true)
private String fpl;

@CommandLine.Option(names = CliConstants.LAYERS, split = ",")
private Set<String> layers;

@CommandLine.Option(names = CliConstants.CONFIG)
private String config;
private static class LayersOptions {
@CommandLine.Option(names = CliConstants.LAYERS, split = ",", required = true)
private Set<String> layers;

@CommandLine.Option(names = CliConstants.CONFIG)
private String config;
}

private static class ConfigOptions {

@CommandLine.ArgGroup(exclusive = false)
private LayersOptions layersOptions = new LayersOptions();
@CommandLine.Option(names = CliConstants.DEFAULT_CONFIG, split = ",")
private final Set<String> defaultConfig = new HashSet<>();
}

@CommandLine.ArgGroup
private final ConfigOptions configOptions = new ConfigOptions();

@CommandLine.Option(names = {CliConstants.Y, CliConstants.YES})
boolean skipConfirmation;
Expand Down Expand Up @@ -92,7 +107,12 @@ public Integer call() throws Exception {
}

try {
featuresAddAction.addFeaturePack(fpl, layers == null ? Collections.emptySet() : layers, parseConfigName());
if (configOptions.layersOptions.layers == null) {
final Set<ConfigId> configurations = configOptions.defaultConfig.stream().map(AddCommand::parseConfigName).collect(Collectors.toSet());
featuresAddAction.addFeaturePack(fpl, configurations);
} else {
featuresAddAction.addFeaturePackWithLayers(fpl, configOptions.layersOptions.layers, parseConfigName(configOptions.layersOptions.config));
}
} catch (FeaturesAddAction.LayerNotFoundException e) {
if (!e.getSupportedLayers().isEmpty()) {
console.error(CliMessages.MESSAGES.layerNotSupported(fpl, e.getLayers(), e.getSupportedLayers()));
Expand All @@ -114,7 +134,7 @@ public Integer call() throws Exception {
return ReturnCodes.SUCCESS;
}

private ConfigId parseConfigName() {
private static ConfigId parseConfigName(String config) {
if (config == null) {
return null;
}
Expand All @@ -123,15 +143,16 @@ private ConfigId parseConfigName() {
return new ConfigId(null, config.trim());
}

if (i == config.length() -1) {
if (i == config.length() - 1) {
return new ConfigId(config.substring(0, i).trim(), null);
} else {
return new ConfigId(config.substring(0, i).trim(), config.substring(i+1).trim());
return new ConfigId(config.substring(0, i).trim(), config.substring(i + 1).trim());
}
}
}



public FeaturesCommand(CliConsole console, ActionFactory actionFactory) {
super(console, actionFactory, CliConstants.Commands.FEATURE_PACKS, List.of(new AddCommand(console, actionFactory)));
}
Expand Down
3 changes: 3 additions & 0 deletions prospero-cli/src/main/resources/UsageMessages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ ${prospero.dist.name}.feature-pack.add.usage.header = Installs a new feature pac
${prospero.dist.name}.feature-pack.add.layers = Feature Pack layers selected for installation. Specify multiple layers separated by commas.
${prospero.dist.name}.feature-pack.add.config = Configuration file that the Feature Pack changes will be applied to. \
If not specified, defaults to the @|bold <model>.xml|@ (e.g. standalone.xml).
${prospero.dist.name}.feature-pack.add.default-config = Selects which pre-defined configurations will be installed. \
If not defined uses default configurations defined in the feature pack \
Cannot be combined with --layers option.
${prospero.dist.name}.feature-pack.add.model = Configuration model (standalone or domain) that the Feature Pack changes should be applied to. \
If not specified, defaults to the model selected by the chosen layer.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public class FeaturesCommandTest extends AbstractMavenCommandTest {

@Captor
private ArgumentCaptor<ConfigId> configNameCaptor;
@Captor
private ArgumentCaptor<Set<ConfigId>> defaultConfigNamesCaptor;

@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
Expand Down Expand Up @@ -106,13 +108,10 @@ public void passArgumentsToFeaturesAddAction_OnlyFpl() throws Exception {
assertEquals(ReturnCodes.SUCCESS, exitCode);

final ArgumentCaptor<String> fplCaptor = ArgumentCaptor.forClass(String.class);
final ArgumentCaptor<Set<String>> layersCaptor = ArgumentCaptor.forClass(Set.class);
verify(featuresAddAction).addFeaturePack(fplCaptor.capture(), layersCaptor.capture(),
configNameCaptor.capture());
verify(featuresAddAction).addFeaturePack(fplCaptor.capture(), defaultConfigNamesCaptor.capture());

assertEquals(fplCaptor.getValue(), "test:test");
assertEquals(Collections.emptySet(), layersCaptor.getValue());
assertEquals(configNameCaptor.getValue(), null);
assertEquals(defaultConfigNamesCaptor.getValue(), Collections.emptySet());
}

@Test
Expand All @@ -124,7 +123,7 @@ public void passArgumentsToFeaturesAddAction_LayersAreSplit() throws Exception {
assertEquals(ReturnCodes.SUCCESS, exitCode);

final ArgumentCaptor<Set<String>> layersCaptor = ArgumentCaptor.forClass(Set.class);
verify(featuresAddAction).addFeaturePack(any(), layersCaptor.capture(),
verify(featuresAddAction).addFeaturePackWithLayers(any(), layersCaptor.capture(),
any());

assertEquals(Set.of("layer1", "layer2"), layersCaptor.getValue());
Expand All @@ -135,27 +134,29 @@ public void passArgumentsToFeaturesAddAction_ModuleOnlyConfig() throws Exception
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.FPL, "test:test",
CliConstants.CONFIG, "test/");
CliConstants.DEFAULT_CONFIG, "test/");
assertEquals(ReturnCodes.SUCCESS, exitCode);

verify(featuresAddAction).addFeaturePack(any(), any(),
configNameCaptor.capture());
verify(featuresAddAction).addFeaturePack(any(),
defaultConfigNamesCaptor.capture());

assertEquals(new ConfigId("test", null), configNameCaptor.getValue());
assertThat(defaultConfigNamesCaptor.getValue())
.contains(new ConfigId("test", null));
}

@Test
public void passArgumentsToFeaturesAddAction_NameOnlyConfig() throws Exception {
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.FPL, "test:test",
CliConstants.CONFIG, "test");
CliConstants.DEFAULT_CONFIG, "test");
assertEquals(ReturnCodes.SUCCESS, exitCode);

verify(featuresAddAction).addFeaturePack(any(), any(),
configNameCaptor.capture());
verify(featuresAddAction).addFeaturePack(any(),
defaultConfigNamesCaptor.capture());

assertEquals(new ConfigId(null, "test"), configNameCaptor.getValue());
assertThat(defaultConfigNamesCaptor.getValue())
.contains(new ConfigId(null, "test"));
}

@Test
Expand All @@ -168,7 +169,7 @@ public void passArgumentsToFeaturesAddAction_AllParameters() throws Exception {
assertEquals(ReturnCodes.SUCCESS, exitCode);

final ArgumentCaptor<Set<String>> layersCaptor = ArgumentCaptor.forClass(Set.class);
verify(featuresAddAction).addFeaturePack(any(), layersCaptor.capture(), configNameCaptor.capture());
verify(featuresAddAction).addFeaturePackWithLayers(any(), layersCaptor.capture(), configNameCaptor.capture());

assertEquals(Set.of("layer1"), layersCaptor.getValue());
assertEquals(new ConfigId("model", "config"), configNameCaptor.getValue());
Expand Down Expand Up @@ -230,7 +231,7 @@ public void fplWithTreePartsFails() throws Exception {
@Test
public void nonExistingLayersShowsError() throws Exception {
doThrow(new FeaturesAddAction.LayerNotFoundException("foo", Set.of("idontexist"), Set.of("layer1", "layer2")))
.when(featuresAddAction).addFeaturePack("org.test:test", Set.of("idontexist"), null);
.when(featuresAddAction).addFeaturePackWithLayers("org.test:test", Set.of("idontexist"), null);
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.LAYERS, "idontexist",
Expand All @@ -244,7 +245,7 @@ public void nonExistingLayersShowsError() throws Exception {
@Test
public void nonExistingLayersShowsErrorNoAvailableLayers() throws Exception {
doThrow(new FeaturesAddAction.LayerNotFoundException("foo", Set.of("idontexist"), Collections.emptySet()))
.when(featuresAddAction).addFeaturePack("org.test:test", Set.of("idontexist"), null);
.when(featuresAddAction).addFeaturePackWithLayers("org.test:test", Set.of("idontexist"), null);
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.LAYERS, "idontexist",
Expand All @@ -259,11 +260,11 @@ public void nonExistingLayersShowsErrorNoAvailableLayers() throws Exception {
@Test
public void nonExistingModelShowsError() throws Exception {
doThrow(new FeaturesAddAction.ModelNotDefinedException("test", "idontexist", Set.of("model1", "model2")))
.when(featuresAddAction).addFeaturePack("org.test:test", Collections.emptySet(),
new ConfigId("idontexist", "test"));
.when(featuresAddAction).addFeaturePack("org.test:test",
Set.of(new ConfigId("idontexist", "test")));
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.CONFIG, "idontexist/test",
CliConstants.DEFAULT_CONFIG, "idontexist/test",
CliConstants.FPL, "org.test:test");
assertEquals(ReturnCodes.INVALID_ARGUMENTS, exitCode);
assertThat(getErrorOutput())
Expand All @@ -274,17 +275,40 @@ public void nonExistingModelShowsError() throws Exception {
@Test
public void nonExistingConfigurationShowsError() throws Exception {
doThrow(new FeaturesAddAction.ConfigurationNotFoundException("test", new ConfigId("test", "idontexist")))
.when(featuresAddAction).addFeaturePack("org.test:test", Collections.emptySet(),
new ConfigId("test", "idontexist"));
.when(featuresAddAction).addFeaturePack("org.test:test",
Set.of(new ConfigId("test", "idontexist")));
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.CONFIG, "test/idontexist",
CliConstants.DEFAULT_CONFIG, "test/idontexist",
CliConstants.FPL, "org.test:test");
assertEquals(ReturnCodes.INVALID_ARGUMENTS, exitCode);
assertThat(getErrorOutput())
.contains("The feature pack `org.test:test` does not provide requested configuration `test/idontexist`.");
}

@Test
public void configRequiresLayer() throws Exception {
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.CONFIG, "test/idontexist",
CliConstants.FPL, "org.test:test");
assertEquals(ReturnCodes.INVALID_ARGUMENTS, exitCode);
assertThat(getErrorOutput())
.contains("Missing required argument(s): --layers");
}

@Test
public void layersExcludeDefaultConfig() throws Exception {
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.DEFAULT_CONFIG, "test/idontexist",
CliConstants.LAYERS, "layer1",
CliConstants.FPL, "org.test:test");
assertEquals(ReturnCodes.INVALID_ARGUMENTS, exitCode);
assertThat(getErrorOutput())
.contains("are mutually exclusive (specify only one)");
}

@Override
protected ActionFactory createActionFactory() {
return actionFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ public interface ProsperoLogger extends BasicLogger {
FeaturesAddAction.FeaturePackAlreadyInstalledException featurePackAlreadyInstalled(FeaturePackLocation fpl);

@LogMessage(level = Logger.Level.DEBUG)
@Message(id = 258, value = "Adding a feature pack [%s] with configId [%s:%s] and layers [%s]")
void addingFeaturePack(FeaturePackLocation fpl, String selectedConfig, String selectedModel, String layers);
@Message(id = 258, value = "Adding a feature pack [%s] with configuration %s and layers [%s]")
void addingFeaturePack(FeaturePackLocation fpl, String configuration, String layers);

@Message(id = 259, value = "Requested configuration %s/%s is not available in the feature packs.")
String galleonConfigNotFound(String model, String name);
Expand Down
Loading

0 comments on commit 866b242

Please sign in to comment.