Skip to content

Commit

Permalink
Verify chosen configuration is available in the provisioned server
Browse files Browse the repository at this point in the history
  • Loading branch information
spyrkob committed Aug 22, 2023
1 parent 5dbe310 commit 38e0887
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,11 @@ default String modelNotSupported(String fpl, String model, Set<String> supported
fpl, model, StringUtils.join(supportedModels, ", "));
}

default String galleonConfigNotSupported(String fpl, String model, String name) {
return format(bundle.getString("prospero.features.add.validation.configuration.not_supported"),
fpl, model, name);
}

default String featuresAddHeader(String fpl, Path dir) {
return format(bundle.getString("prospero.features.add.header"), fpl, dir);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ public Integer call() throws Exception {
} catch (FeaturesAddAction.ModelNotDefinedException e) {
console.error(CliMessages.MESSAGES.modelNotSupported(fpl, e.getModel(), e.getSupportedModels()));
return ReturnCodes.INVALID_ARGUMENTS;
} catch (FeaturesAddAction.ConfigurationNotFoundException e) {
console.error(CliMessages.MESSAGES.galleonConfigNotSupported(fpl, e.getModel(), e.getName()));
return ReturnCodes.INVALID_ARGUMENTS;
}

final float totalTime = (System.currentTimeMillis() - startTime) / 1000f;
Expand Down
1 change: 1 addition & 0 deletions prospero-cli/src/main/resources/UsageMessages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ prospero.features.add.validation.layer.no_layers=The feature pack `%s` does not
Try removing the --layers parameter.
prospero.features.add.validation.model.not_supported=The feature pack `%s` does not provide requested model `%s`.\n \
Supported models are [%s].
prospero.features.add.validation.configuration.not_supported=The feature pack `%s` does not provide requested configuration `%s/%s`.

prospero.changes.diff.manifest=manifest
prospero.changes.diff.repositories=repositories
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.wildfly.prospero.cli.commands;

import org.jboss.galleon.config.ConfigId;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -248,6 +249,20 @@ public void nonExistingModelShowsError() throws Exception {
.contains("Supported models are [model1, model2]");
}

@Test
public void nonExistingConfigurationShowsError() throws Exception {
doThrow(new FeaturesAddAction.ConfigurationNotFoundException("test", new ConfigId("test", "idontexist")))
.when(featuresAddAction).addFeaturePack("org.test:test", Collections.emptySet(), "test", "idontexist");
int exitCode = commandLine.execute(CliConstants.Commands.FEATURE_PACKS, CliConstants.Commands.ADD,
CliConstants.DIR, installationDir.toString(),
CliConstants.MODEL, "test",
CliConstants.CONFIG, "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`.");
}

@Override
protected ActionFactory createActionFactory() {
return actionFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,7 @@ public interface ProsperoLogger extends BasicLogger {
@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 = 259, value = "Requested configuration %s/%s is not available in the feature packs.")
String galleonConfigNotFound(String model, String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.jboss.galleon.layout.ProvisioningLayoutFactory;
import org.jboss.galleon.universe.FeaturePackLocation;
import org.jboss.galleon.universe.maven.repo.MavenRepoManager;
import org.jboss.galleon.util.LayoutUtils;
import org.wildfly.channel.ArtifactTransferException;
import org.wildfly.channel.Channel;
import org.wildfly.channel.ChannelSession;
Expand Down Expand Up @@ -60,9 +61,11 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Installs a feature pack onto an existing server.
Expand Down Expand Up @@ -170,6 +173,8 @@ public void addFeaturePack(String featurePackCoord, Set<String> layers, String m
throw ProsperoLogger.ROOT_LOGGER.unableToCreateTemporaryDirectory(e);
}

verifyConfigurationsAvailable(newConfig);

// make sure the previous provisioning_config is persisted
try (InstallationMetadata metadata = InstallationMetadata.loadInstallation(installDir)) {
metadata.updateProvisioningConfiguration();
Expand Down Expand Up @@ -333,6 +338,41 @@ private static void verifyLayerAvailable(Set<String> layers, String selectedMode
}
}

private void verifyConfigurationsAvailable(ProvisioningConfig config) throws ProvisioningException, OperationException {
try( GalleonEnvironment env = GalleonEnvironment
.builder(installDir, prosperoConfig.getChannels(), mavenSessionManager).build()) {
final MavenRepoManager repositoryManager = env
.getRepositoryManager();

final ProvisioningLayoutFactory layoutFactory = GalleonUtils.getProvisioningLayoutFactory(repositoryManager);

final ProvisioningLayout<FeaturePackLayout> layout = layoutFactory.newConfigLayout(config);

final Stream<ConfigId> configIds = Stream.concat(
config.getFeaturePackDeps().stream().flatMap(fd -> fd.getIncludedConfigs().stream()),
config.getDefinedConfigs().stream().map(ConfigModel::getId));

final Optional<ConfigId> missingConfig = configIds.filter(cfg -> {
boolean found = true;
for (FeaturePackLayout fp : layout.getOrderedFeaturePacks()) {
try {
LayoutUtils.getConfigXml(fp.getDir(), cfg, true);
found = true;
break;
} catch (ProvisioningDescriptionException e) {
found = false;
}
}
return !found;
}).findFirst();

if (missingConfig.isPresent()) {
final ConfigId cfg = missingConfig.get();
throw new ConfigurationNotFoundException(ProsperoLogger.ROOT_LOGGER.galleonConfigNotFound(cfg.getModel(), cfg.getName()), cfg);
}
}
}

private static String getSelectedModel(String model, Map<String, Set<String>> allLayers)
throws ModelNotDefinedException {
if (allLayers.isEmpty()) {
Expand Down Expand Up @@ -466,6 +506,25 @@ public FeaturePackAlreadyInstalledException(String msg) {
}
}

public static class ConfigurationNotFoundException extends OperationException {
private final String model;
private final String name;

public ConfigurationNotFoundException(String msg, ConfigId id) {
super(msg);
model = id.getModel();
name = id.getName();
}

public String getModel() {
return model;
}

public String getName() {
return name;
}
}

// used in testing to inject mocks
interface CandidateActionsFactory {
PrepareCandidateAction newPrepareCandidateActionInstance(MavenSessionManager mavenSessionManager, ProsperoConfig prosperoConfig) throws OperationException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,6 @@ private GalleonEnvironment galleonEnvWithFpMapper(Path tempInstallationPath, Lis
return galleonEnv;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ public void requestedLayerAddsItsConfig() throws Exception {
.addConfigLayer(ConfigLayerSpec.builder()
.setModel("model")
.setName("layer1")
.build())
.addConfig(ConfigModel.builder()
.setModel("model")
.setName("model.xml")
.build());

deployFeaturePacks(creator);
Expand Down Expand Up @@ -293,6 +297,10 @@ public void selectedConfigOverridesDefaultWithRequestedLayer() throws Exception
.getCreator()
.newFeaturePack(FeaturePackLocation.fromString("org.test:added-pack:1.0.0:zip").getFPID())
.addDependency(FeaturePackLocation.fromString("org.test:base-pack:1.0.0"))
.addConfig(ConfigModel.builder()
.setModel("model")
.setName("test.xml")
.build())
.addConfigLayer(ConfigLayerSpec.builder()
.setModel("model")
.setName("layer1")
Expand Down Expand Up @@ -324,6 +332,10 @@ public void addFeaturePackAlreadyInstalledAsDependency() throws Exception {
creator.newFeaturePack(FeaturePackLocation.fromString("org.test:base-pack:1.0.0:zip").getFPID())
.getCreator()
.newFeaturePack(FeaturePackLocation.fromString("org.test:added-pack:1.0.0:zip").getFPID())
.addConfig(ConfigModel.builder()
.setModel("model")
.setName("test.xml")
.build())
.addConfigLayer(ConfigLayerSpec.builder()
.setModel("model")
.setName("layer1")
Expand Down Expand Up @@ -370,6 +382,10 @@ public void installingLayerOverridesExcludesLayer() throws Exception {
// install base feature pack
final FeaturePackCreator creator = FeaturePackCreator.getInstance().addArtifactResolver(repo);
creator.newFeaturePack(FeaturePackLocation.fromString("org.test:base-pack:1.0.0:zip").getFPID())
.addConfig(ConfigModel.builder()
.setModel("model")
.setName("test.xml")
.build())
.addConfigLayer(ConfigLayerSpec.builder()
.setModel("model")
.setName("layer1")
Expand Down Expand Up @@ -474,6 +490,10 @@ public void selectedModelOverridesTheDefault() throws Exception {
creator.newFeaturePack(FeaturePackLocation.fromString("org.test:base-pack:1.0.0:zip").getFPID())
.getCreator()
.newFeaturePack(FeaturePackLocation.fromString("org.test:added-pack:1.0.0:zip").getFPID())
.addConfig(ConfigModel.builder()
.setModel("model2")
.setName("model2.xml")
.build())
.addConfigLayer(ConfigLayerSpec.builder()
.setModel("model1")
.setName("layer1")
Expand Down Expand Up @@ -615,6 +635,7 @@ public void installSelectedConfigsIfNoLayersAreSpecified() throws Exception {
.getFeaturePack()

.addConfig(ConfigModel.builder()
.setModel("model1")
.setName("config2")
.includeLayer("layer1")
.addPackageDep("p1")
Expand Down Expand Up @@ -664,6 +685,10 @@ public void installSelectedConfigsIfLayersAreSpecified() throws Exception {
.writeContent("p3.txt", "foobar")
.getFeaturePack()

.addConfig(ConfigModel.builder()
.setModel("model1")
.setName("model1.xml")
.build())
.addConfig(ConfigModel.builder()
.setName("config2")
.includeLayer("layer1")
Expand Down Expand Up @@ -699,6 +724,62 @@ public void installSelectedConfigsIfLayersAreSpecified() throws Exception {
.isEmpty();
}

@Test
public void nonExistingConfigNameThrowsException() throws Exception {
// install base feature pack
final FeaturePackCreator creator = FeaturePackCreator.getInstance().addArtifactResolver(repo);
creator.newFeaturePack(FeaturePackLocation.fromString("org.test:base-pack:1.0.0:zip").getFPID())

.getCreator()
.newFeaturePack(FeaturePackLocation.fromString("org.test:added-pack:1.0.0:zip").getFPID())
.addConfig(ConfigModel.builder()
.setModel("model1")
.setName("config3")
.build())
.addConfigLayer(ConfigLayerSpec.builder()
.setModel("model1")
.setName("layer1")
.build());
deployFeaturePacks(creator);
// install
installFeaturePack(installDir, "org.test:base-pack:1.0.0:zip");

assertThatThrownBy(()->getFeaturesAddAction().addFeaturePack(
"org.test:added-pack", Set.of("layer1"), "model1", "idontexist"))
.isInstanceOf(FeaturesAddAction.ConfigurationNotFoundException.class)
.hasFieldOrPropertyWithValue("model", "model1")
.hasFieldOrPropertyWithValue("name", "idontexist");

}

@Test
public void nonExistingConfigNameWithoutLayersThrowsException() throws Exception {
// install base feature pack
final FeaturePackCreator creator = FeaturePackCreator.getInstance().addArtifactResolver(repo);
creator.newFeaturePack(FeaturePackLocation.fromString("org.test:base-pack:1.0.0:zip").getFPID())

.getCreator()
.newFeaturePack(FeaturePackLocation.fromString("org.test:added-pack:1.0.0:zip").getFPID())
.addConfig(ConfigModel.builder()
.setModel("model1")
.setName("config3")
.build())
.addConfigLayer(ConfigLayerSpec.builder()
.setModel("model1")
.setName("layer1")
.build());
deployFeaturePacks(creator);
// install
installFeaturePack(installDir, "org.test:base-pack:1.0.0:zip");

assertThatThrownBy(()->getFeaturesAddAction().addFeaturePack(
"org.test:added-pack", Collections.emptySet(), new ConfigId("model1", "idontexist")))
.isInstanceOf(FeaturesAddAction.ConfigurationNotFoundException.class)
.hasFieldOrPropertyWithValue("model", "model1")
.hasFieldOrPropertyWithValue("name", "idontexist");

}

private static FeaturePackConfig getFeaturePackConfig(ProvisioningConfig config, String fpl) {
return config.getFeaturePackDeps().stream().filter(f -> f.getLocation().toString().equals(fpl)).findFirst().get();
}
Expand Down

0 comments on commit 38e0887

Please sign in to comment.