Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for WFGP-264, WFGP-265 and WFGP-272, stability handling #280

Merged
merged 3 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public abstract class BaseConfigGenerator {
protected String jbossHome;
protected boolean forkEmbedded;
protected String resetSysProps;
protected String stabilityLevel;

protected Path script;
protected PrintWriter scriptWriter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@ public static Set<String> computeResettableSysProps(String resetSysProps) {
return Collections.unmodifiableSet(result);
}

public void generate(ProvisioningRuntime runtime, boolean forkEmbedded, String resetSystemProperties) throws ProvisioningException {
public void generate(ProvisioningRuntime runtime, boolean forkEmbedded, String resetSystemProperties, String stabilityLevel) throws ProvisioningException {
this.messageWriter = runtime.getMessageWriter();
this.forkEmbedded = forkEmbedded;
this.resetSysProps = resetSystemProperties;
this.jbossHome = runtime.getStagedDir().toString();
this.stabilityLevel = stabilityLevel;
final Map<Object, Object> originalProps = new HashMap<>(System.getProperties());
final Map<Object, Object> resetProps = new HashMap<>();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,9 @@ private String[] getEmbeddedArgs(ProvisionedConfig config) throws ProvisioningEx
embeddedArgs.add(configNameProp);
embeddedArgs.add(config.getName());
}
if (configGen.stabilityLevel != null && !configGen.stabilityLevel.isEmpty()) {
embeddedArgs.add("--stability=" + configGen.stabilityLevel);
}
return embeddedArgs.toArray(new String[embeddedArgs.size()]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public class FeatureSpecGenerator implements ForkCallback {
private Path systemProps;
private Path standaloneSpecsFile;
private Path domainSpecsFile;
private String mimimumStability;

String getBranchId(String spec, int dots) {
int i = 0;
Expand Down Expand Up @@ -138,12 +139,14 @@ void increaseSpecCount() {
public FeatureSpecGenerator() {
}

public FeatureSpecGenerator(String installation, Path outputDir, Map<String, Path> inheritedSpecs, boolean fork, boolean debug) {
public FeatureSpecGenerator(String installation, Path outputDir, Map<String, Path> inheritedSpecs,
String mimimumStability, boolean fork, boolean debug) {
this.installation = installation;
this.outputDir = outputDir;
this.fork = fork;
this.debug = debug;
this.inheritedSpecs = inheritedSpecs;
this.mimimumStability = mimimumStability;
}

public int generateSpecs() throws ProvisioningException {
Expand Down Expand Up @@ -180,20 +183,21 @@ private void doGenerate() throws ProvisioningException {
final ModelNode standaloneFeatures;
ModelNode domainRoots = null;
if(fork) {
ForkedEmbeddedUtil.fork(this, getStoredSystemProps(), installation, getStandaloneSpecsFile().toString(), getDomainSpecsFile().toString());
String minStab = mimimumStability == null ? "" : mimimumStability;
ForkedEmbeddedUtil.fork(this, getStoredSystemProps(), installation, getStandaloneSpecsFile().toString(), getDomainSpecsFile().toString(), minStab);
standaloneFeatures = readSpecsFile(getStandaloneSpecsFile());
if(Files.exists(Paths.get(installation).resolve(WfConstants.DOMAIN).resolve(WfConstants.CONFIGURATION))) {
domainRoots = readSpecsFile(getDomainSpecsFile());
}
} else {
final Path home = Paths.get(installation);
if(Files.exists(home.resolve(WfConstants.STANDALONE).resolve(WfConstants.CONFIGURATION))) {
standaloneFeatures = readFeatureSpecs(createStandaloneServer(installation));
standaloneFeatures = readFeatureSpecs(createStandaloneServer(installation, mimimumStability));
} else {
throw new ProvisioningException("The installation does not include standalone configuration");
}
if(Files.exists(home.resolve(WfConstants.DOMAIN).resolve(WfConstants.CONFIGURATION))) {
domainRoots = readFeatureSpecs(createEmbeddedHc(installation));
domainRoots = readFeatureSpecs(createEmbeddedHc(installation, mimimumStability));
}
}

Expand Down Expand Up @@ -226,16 +230,17 @@ private void doGenerate() throws ProvisioningException {

@Override
public void forkedForEmbedded(String... args) throws ConfigGeneratorException {
if(args.length != 3) {
if(args.length != 3 && args.length != 4) {
final StringBuilder buf = new StringBuilder();
StringUtils.append(buf, Arrays.asList(args));
throw new IllegalArgumentException("Expected 3 arguments but got " + Arrays.asList(args));
throw new IllegalArgumentException("Expected 3-4 arguments but got " + Arrays.asList(args));
}
try {
ModelNode result = readFeatureSpecs(createStandaloneServer(args[0]));
String mimimumStability = args.length == 4 ? args[3] : null;
ModelNode result = readFeatureSpecs(createStandaloneServer(args[0], mimimumStability));
writeSpecsFile(Paths.get(args[1]), result);
if (Files.exists(Paths.get(args[0]).resolve(WfConstants.DOMAIN).resolve(WfConstants.CONFIGURATION))) {
result = readFeatureSpecs(createEmbeddedHc(args[0]));
result = readFeatureSpecs(createEmbeddedHc(args[0], mimimumStability));
writeSpecsFile(Paths.get(args[2]), result);
}
} catch (ProvisioningException e) {
Expand Down Expand Up @@ -297,12 +302,21 @@ protected FeatureSpec getInheritedSpec(String name) throws ProvisioningException
return spec;
}

private static EmbeddedManagedProcess createStandaloneServer(String jbossHome) {
return EmbeddedProcessFactory.createStandaloneServer(jbossHome, null, null, new String[] {"--admin-only"});
private static EmbeddedManagedProcess createStandaloneServer(String jbossHome, String minimumStability) {
String[] cmdArgs = getCmdArgs(minimumStability);
return EmbeddedProcessFactory.createStandaloneServer(jbossHome, null, null, cmdArgs);
}

private static EmbeddedManagedProcess createEmbeddedHc(String jbossHome) {
return EmbeddedProcessFactory.createHostController(jbossHome, null, null, new String[] {"--admin-only"});
private static EmbeddedManagedProcess createEmbeddedHc(String jbossHome, String minimumStability) {
String[] cmdArgs = getCmdArgs(minimumStability);
return EmbeddedProcessFactory.createHostController(jbossHome, null, null, cmdArgs);
}

private static String[] getCmdArgs(String mimimumStability) {
if (mimimumStability != null && !mimimumStability.isEmpty()) {
return new String[] {"--admin-only", "--stability=" + mimimumStability};
}
return new String[] {"--admin-only"};
}

private static ModelNode readFeatureSpecs(final EmbeddedManagedProcess server) throws ProvisioningException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 Red Hat, Inc. and/or its affiliates
* Copyright 2016-2024 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -377,7 +377,10 @@ private void persistSpec(String name, ModelNode descr, int model) throws Provisi
if(branchId != null) {
builder.addAnnotation(FeatureAnnotation.featureBranch(branchId));
}

if(descr.hasDefined("stability")) {
String stability = descr.get("stability").asString();
builder.setStability(stability);
}
if (descr.hasDefined("requires")) {
for (ModelNode capability : descr.require("requires").asList()) {
builder.requiresCapability(capability.get("name").asString(), capability.hasDefined("optional") && capability.get("optional").asBoolean());
Expand Down Expand Up @@ -451,6 +454,9 @@ private void persistSpec(String name, ModelNode descr, int model) throws Provisi
if (param.hasDefined("type")) {
featureParamSpecBuilder.setType(param.get("type").asString());
}
if (param.hasDefined("stability")) {
featureParamSpecBuilder.setStability(param.get("stability").asString());
}
builder.addParam(featureParamSpecBuilder.build());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ private String isResetEmbeddedSystemProperties() throws ProvisioningException {
return value == null ? "" : value;
}

private String getStabilityLevel() throws ProvisioningException {
final String value = runtime.getLowestStability();
return value == null ? "" : value;
}

private boolean getBooleanOption(ProvisioningOption option) throws ProvisioningException {
if (!runtime.isOptionSet(option)) {
return false;
Expand Down Expand Up @@ -775,11 +780,11 @@ private void generateConfigs(ProvisioningRuntime runtime) throws ProvisioningExc
try {
final Class<?> configHandlerCls = configGenCl.loadClass(CONFIG_GEN_CLASS);
final Constructor<?> ctor = configHandlerCls.getConstructor();
final Method m = configHandlerCls.getMethod(CONFIG_GEN_METHOD, ProvisioningRuntime.class, boolean.class, String.class);
final Object generator = ctor.newInstance();
final boolean forkEmbedded = isForkEmbedded(runtime);
final String resetEmbeddedSystemProperties = isResetEmbeddedSystemProperties();
m.invoke(generator, runtime, forkEmbedded, resetEmbeddedSystemProperties);
final String stabilityLevel = getStabilityLevel();
invokeConfigGenerator(configHandlerCls, generator, forkEmbedded, resetEmbeddedSystemProperties, stabilityLevel);
if(startTime > 0) {
log.print(Errors.tookTime("WildFly configuration generation", startTime));
}
Expand Down Expand Up @@ -1201,4 +1206,19 @@ void resolveMaven(MavenArtifact artifact) throws ProvisioningException {
boolean isOverriddenArtifact(MavenArtifact artifact) throws ProvisioningException {
return Utils.containsArtifact(overriddenArtifactVersions, artifact);
}

private void invokeConfigGenerator(Class<?> configHandlerCls, Object generator, boolean forkEmbedded,
String resetEmbeddedSystemProperties, String stabilityLevel)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
try {
final Method m = configHandlerCls.getMethod(CONFIG_GEN_METHOD, ProvisioningRuntime.class, boolean.class, String.class, String.class);
m.invoke(generator, runtime, forkEmbedded, resetEmbeddedSystemProperties, stabilityLevel);
} catch (NoSuchMethodException e) {
if (stabilityLevel != null && !stabilityLevel.isEmpty()) {
throw e;
}
final Method m = configHandlerCls.getMethod(CONFIG_GEN_METHOD, ProvisioningRuntime.class, boolean.class, String.class);
m.invoke(generator, runtime, forkEmbedded, resetEmbeddedSystemProperties);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
import org.jboss.galleon.Errors;
import org.jboss.galleon.ProvisioningDescriptionException;
import org.jboss.galleon.ProvisioningException;
import org.jboss.galleon.Stability;
import org.jboss.galleon.config.ConfigModel;
import org.jboss.galleon.config.FeaturePackConfig;
import org.jboss.galleon.layout.FeaturePackDescriber;
Expand Down Expand Up @@ -203,6 +204,14 @@ static boolean isProvided(String module) {
@Component
private MavenProjectHelper projectHelper;

/**
* The minimum stability level of the WildFly processes used to generate feature specs.
* Set this if you need to generate feature specs for features with a lower stability level
* than the default level of the WildFly process being used for feature-spec generation.
*/
@Parameter(alias = "minimum-stability", required = false)
protected String minimumStability;

private MavenProjectArtifactVersions artifactVersions;

private Map<String, FeaturePackDescription> fpDependencies = Collections.emptyMap();
Expand All @@ -213,10 +222,12 @@ static boolean isProvided(String module) {
private Path resourcesWildFly;
private Path fpResourcesDir;
private Path resourcesDir;
private Stability stability;

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
try {
stability = minimumStability == null ? null : Stability.fromString(minimumStability);
artifactVersions = MavenProjectArtifactVersions.getInstance(project);
doExecute();
} catch (RuntimeException | Error | MojoExecutionException | MojoFailureException e) {
Expand Down Expand Up @@ -367,6 +378,7 @@ protected void buildFeaturePack(FeaturePackDescription.Builder fpBuilder, WildFl

final FeaturePackDescription fpLayout;
try {
fpBuilder.getSpecBuilder().setMinStability(stability);
fpLayout = fpBuilder.build();
FeaturePackXmlWriter.getInstance().write(fpLayout.getSpec(), getFpDir().resolve(Constants.FEATURE_PACK_XML));
} catch (XMLStreamException | IOException | ProvisioningDescriptionException e) {
Expand Down Expand Up @@ -705,16 +717,26 @@ private void packageModules(FeaturePackDescription.Builder fpBuilder,
for (Map.Entry<String, Path> module : moduleXmlByPkgName.entrySet()) {
final String packageName = module.getKey();
final Path moduleXml = module.getValue();

final Path packageDir = getPackagesDir().resolve(packageName);
final Path targetXml = packageDir.resolve(WfConstants.PM).resolve(WfConstants.WILDFLY).resolve(WfConstants.MODULE).resolve(resourcesDir.relativize(moduleXml));
mkdirs(targetXml.getParent());
IoUtils.copy(moduleXml.getParent(), targetXml.getParent());

final PackageSpec.Builder pkgSpecBuilder = PackageSpec.builder(packageName);
final ModuleParseResult parsedModule;
try {
parsedModule = ModuleXmlParser.parse(targetXml, WfConstants.UTF8, targetToAlias);
parsedModule = ModuleXmlParser.parse(moduleXml, WfConstants.UTF8, targetToAlias);
String packageStability = parsedModule.getProperty("org.jboss.stability");
if (packageStability != null) {
Stability stab = Stability.fromString(packageStability);
if (stability != null && !stability.enables(stab)) {
getLog().warn("JBoss Modules module " + parsedModule.getIdentifier() + " is not included in the feature-pack. "
+ "Package stability '" +
packageStability + "' is not enabled by the '" + stability +
"' stability level that is the feature-pack minimum stability level.");
continue;
}
pkgSpecBuilder.setStability(stab);
}
final Path targetXml = packageDir.resolve(WfConstants.PM).resolve(WfConstants.WILDFLY).resolve(WfConstants.MODULE).resolve(resourcesDir.relativize(moduleXml));
mkdirs(targetXml.getParent());
IoUtils.copy(moduleXml.getParent(), targetXml.getParent());
if (!parsedModule.dependencies.isEmpty()) {
for (ModuleParseResult.ModuleDependency moduleDep : parsedModule.dependencies) {
final ModuleIdentifier moduleId = moduleDep.getModuleId();
Expand Down Expand Up @@ -763,7 +785,7 @@ private void packageModules(FeaturePackDescription.Builder fpBuilder,
}
}
} catch (ParsingException e) {
throw new IOException(Errors.parseXml(targetXml), e);
throw new IOException(Errors.parseXml(moduleXml), e);
}

final PackageSpec pkgSpec = pkgSpecBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ public class FeatureSpecGeneratorInvoker {
private Set<String> domainExtensions = Collections.emptySet();
private Set<String> hostExtensions = Collections.emptySet();
private List<Path> layersConfs = Collections.emptyList();
private String minimumStability;

private WildFlyPackageTasksParser tasksParser;
private ProvisioningLayoutFactory layoutFactory;
Expand All @@ -138,6 +139,7 @@ public class FeatureSpecGeneratorInvoker {
this.forkEmbedded = mojo.forkEmbedded;
this.wildflyHome = mojo.wildflyHome.toPath();
this.moduleTemplatesDir = mojo.moduleTemplatesDir.toPath();
this.minimumStability = mojo.minimumStability;
this.log = mojo.getLog();
}

Expand Down Expand Up @@ -252,8 +254,7 @@ private int doExecute() throws MojoExecutionException, MojoFailureException, Mav
}
final Class<?> specGenCls = (newCl == null ? originalCl : newCl).loadClass("org.wildfly.galleon.plugin.featurespec.generator.FeatureSpecGenerator");
final Method specGenMethod = specGenCls.getMethod("generateSpecs");
return (int) specGenMethod.invoke(specGenCls.getConstructor(String.class, Path.class, Map.class, boolean.class, boolean.class)
.newInstance(wildflyHome.toString(), featureSpecsOutput.toPath(), inheritedFeatureSpecs, forkEmbedded, log.isDebugEnabled()));
return (int) specGenMethod.invoke(getFeaturePackGenerator(specGenCls));
} catch(InvocationTargetException e) {
throw new MojoExecutionException("Feature spec generator failed", e.getCause());
} catch (Throwable e) {
Expand Down Expand Up @@ -719,4 +720,20 @@ private void debug(String format, Object... args) {
log.debug(String.format(format, args));
}
}

private Object getFeaturePackGenerator(Class<?> specGenCls) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
debug("Creating a feature spec generator for stability %s using %s", minimumStability, specGenCls);
try {
return specGenCls.getConstructor(String.class, Path.class, Map.class, String.class, boolean.class, boolean.class)
.newInstance(wildflyHome.toString(), featureSpecsOutput.toPath(), inheritedFeatureSpecs, minimumStability, forkEmbedded, log.isDebugEnabled());
} catch (NoSuchMethodException e) {
if (minimumStability != null && !minimumStability.isEmpty()) {
return specGenCls.getConstructor(String.class, Path.class, Map.class, boolean.class, boolean.class)
.newInstance(wildflyHome.toString(), featureSpecsOutput.toPath(), inheritedFeatureSpecs, forkEmbedded, log.isDebugEnabled());
} else {
// We've been configured to use a stability but the generator class does not support it
throw e;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.wildfly.galleon.maven;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand All @@ -33,11 +34,28 @@ class ModuleParseResult {
final Document document;
ModuleIdentifier identifier;
ArtifactName versionArtifactName;
private final Map<String, String> props = new HashMap<>();

ModuleParseResult(final Document document) {
this.document = document;
}

boolean hasProperties() {
return !props.isEmpty();
}

boolean hasProperty(String name) {
return props.containsKey(name);
}

String getProperty(String name) {
return props.get(name);
}

Map<String, String> getProperties() {
return props;
}

List<ModuleDependency> getDependencies() {
return dependencies;
}
Expand Down
Loading
Loading