diff --git a/docs/guide/intro/index.adoc b/docs/guide/intro/index.adoc index 4591ca52..2258bd1f 100644 --- a/docs/guide/intro/index.adoc +++ b/docs/guide/intro/index.adoc @@ -506,7 +506,16 @@ Each artifact version is the one that would get installed when building the Boot The Maven artifacts to upgrade must be added to the `` of your Maven project (with a `provided` scope to avoid the dependency to be added to your application). In addition, the plugin configuration element -`` must contain the artifacts. For example, the version 3.0.0 of `io.undertow:undertow-core` will +`` must contain the artifacts. + +In order to narrow artifact upgrade inside a Galleon feature-pack, the `` configuration element is evolved +with an `` set that contains the artifacts (JBoss Modules module +artifacts only) that are in use for the upgrade. These artifacts are upgraded only in the feature-pack that define them. +A `` element can be added to the pom.xml as a dependency only. A dependency feature-pack +is used to override artifacts present in a dependency feature-pack. +Use the `true` element to create a dependency feature-pack . + +For example, the version 3.0.0 of `io.undertow:undertow-core` will replace the version referenced in the WildFly Galleon feature-pack used to build the bootable JAR: [source,xml] @@ -541,15 +550,21 @@ Some notes: ** The JBoss module runtime jar (jboss-modules.jar file). ** All jar artifacts referenced from JBoss Modules modules. -* If an overridden artifact is no present in the dependencies, then a failure occurs during build. +* If an overridden artifact is not present in the dependencies, then a failure occurs during build. * An artifact upgraded to the same version as the one referenced in the Galleon feature-pack is not upgraded. In this case a warning is displayed during build. * It is possible to downgrade an artifact to an older version. In this case a warning is displayed during build. -* An artifact is referenced in the `overridden-artifacts` by GroupId, Artifactid and optionally Classifier. Version is being retrieved from the Maven dependencies. +* An artifact is referenced in the `overridden-server-artifacts` by GroupId, Artifactid and optionally Classifier. Version is being retrieved from the Maven dependencies. + +* An artifact presents in the `overridden-server-artifacts` list must be unique. Any duplicate will make the packaging to fail. + +* An artifact is referenced in the `` `overridden-artifacts` by GroupId, ArtifactId, optionally Classifier and optionally Version. +Version is being retrieved from the Maven dependencies if not set. Being able to set the version allows to have +multiple artifacts with the same GA to be upgraded to different versions according to the feature-pack that contain them. -* An artifact presents in the `overridden-artifacts` list must be unique. Any duplicate will make the packaging to fail. +* An overridden artifact presents in the `` `overridden-artifacts` must be unique. Any duplicate will make the packaging to fail. * Adding an overridden artifact that is not part of the provisioned server artifacts will lead to a failure during build. diff --git a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/common/FeaturePack.java b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/common/FeaturePack.java index 5211d5a9..80944c51 100644 --- a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/common/FeaturePack.java +++ b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/common/FeaturePack.java @@ -44,12 +44,23 @@ public class FeaturePack implements DependableCoordinate, ArtifactCoordinate { private String includedDefaultConfig; + private boolean dependency; + private Boolean inheritPackages = false; private List excludedPackages = Collections.emptyList(); private List includedPackages = Collections.emptyList(); + private List overriddenArtifacts = Collections.emptyList(); private Path path; + public boolean isDependency() { + return dependency; + } + + public void setDependency(boolean dependency) { + this.dependency = dependency; + } + @Override public String getGroupId() { return groupId; @@ -151,6 +162,14 @@ public void setIncludedPackages(List includedPackages) { this.includedPackages = includedPackages; } + public List getOverridenArtifacts() { + return overriddenArtifacts; + } + + public void setOverridenArtifacts(List overriddenArtifacts) { + this.overriddenArtifacts = overriddenArtifacts; + } + public void setPath(File path) { assertPathLocation(); this.path = path.toPath().normalize(); @@ -204,6 +223,10 @@ public String toString() { buf.append(" included-default-config="); buf.append(includedDefaultConfig); } + if (dependency) { + buf.append(" dependency="); + buf.append(dependency); + } return buf.append('}').toString(); } diff --git a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractBuildBootableJarMojo.java b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractBuildBootableJarMojo.java index 7510a6fa..c661f42d 100644 --- a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractBuildBootableJarMojo.java +++ b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractBuildBootableJarMojo.java @@ -41,6 +41,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -389,6 +390,9 @@ public class AbstractBuildBootableJarMojo extends AbstractMojo { private boolean forkCli; + // Exposed to MavenUpgrade + Map resolvedLocations = new IdentityHashMap<>(); + // EE-9 specific private Path provisioningMavenRepo; private String jakartaTransformSuffix; @@ -854,7 +858,15 @@ private GalleonConfig buildFeaturePacksConfig(ProvisioningManager pm, boolean ha } else { fpl = FeaturePackLocation.fromString(fp.getLocation()); } - + // They will be used when computing the overridden artifacts per feature-pack. + if (!fp.getOverridenArtifacts().isEmpty()) { + resolvedLocations.put(fp, fpl); + } + // We are using dependencies only to convey overriden artifacts. + // Dependencies are upgraded as overridden artifacts not as dependency. + if (fp.isDependency()) { + continue; + } final FeaturePackConfig.Builder fpConfig = FeaturePackConfig.builder(fpl); fpConfig.setInheritConfigs(false); if (fp.isInheritPackages() != null) { diff --git a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/MavenUpgrade.java b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/MavenUpgrade.java index 20a90d13..e4115973 100644 --- a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/MavenUpgrade.java +++ b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/MavenUpgrade.java @@ -49,6 +49,7 @@ final class MavenUpgrade { private final AbstractBuildBootableJarMojo mojo; private final ProvisioningConfig config; private final Map producerToGAC = new HashMap<>(); + private final Map gACToProducer = new HashMap<>(); private final ProvisioningManager pm; private ScannedModules modules; @@ -58,23 +59,41 @@ final class MavenUpgrade { this.config = config; this.pm = pm; for (FeaturePackConfig cfg : config.getFeaturePackDeps()) { - FeaturePack fp = toFeaturePack(cfg, pm); + FeaturePack fp = toFeaturePack(cfg.getLocation(), pm); if (fp == null) { throw new ProvisioningException("Invalid location " + cfg.getLocation()); } topLevels.put(fp.getGAC(), fp); } + Map explicitDependencies = new HashMap<>(); + for (Entry entry : mojo.resolvedLocations.entrySet()) { + FeaturePackLocation location = entry.getValue(); + FeaturePack original = entry.getKey(); + if (original.isDependency()) { + FeaturePack fp = toFeaturePack(location, pm); + if (fp == null) { + throw new ProvisioningException("Invalid location " + location); + } + explicitDependencies.put(fp.getGAC(), fp); + } + } + // Resolve the FP to retrieve dependencies as expressed in fp spec. Map resolvedFeaturePacks = new HashMap<>(); for (FeaturePack fp : topLevels.values()) { resolvedFeaturePacks.put(fp.getGAC(), mojo.resolveMaven(fp)); } + for (FeaturePack fp : explicitDependencies.values()) { + resolvedFeaturePacks.put(fp.getGAC(), mojo.resolveMaven(fp)); + } mojo.debug("Top level feature-packs: %s", topLevels); + mojo.debug("Explicit dependencies feature-packs: %s", explicitDependencies); mojo.debug("Resolved feature-packs: %s", resolvedFeaturePacks); for (Entry entry : resolvedFeaturePacks.entrySet()) { FeaturePackSpec spec = FeaturePackDescriber.readSpec(entry.getValue()); producerToGAC.put(spec.getFPID().getProducer(), entry.getKey()); + gACToProducer.put(entry.getKey(), spec.getFPID()); List allDeps = new ArrayList<>(); for (FeaturePackConfig cfg : spec.getFeaturePackDeps()) { allDeps.add(cfg); @@ -83,7 +102,7 @@ final class MavenUpgrade { allDeps.add(cfg); } for (FeaturePackConfig cfg : allDeps) { - FeaturePack fp = toFeaturePack(cfg, pm); + FeaturePack fp = toFeaturePack(cfg.getLocation(), pm); if (fp != null) { String gac = fp.getGAC(); // Only add the dep if not already seen. The first installed FP dep wins. @@ -104,6 +123,10 @@ private Map getOriginalVersions() throws ProvisioningException, return getScannedModules().getProvisionedArtifacts(); } + private Map getOriginalVersions(String producer) throws ProvisioningException, MojoExecutionException { + return getScannedModules().getProvisionedArtifacts(producer); + } + private ScannedModules getScannedModules() throws ProvisioningException, MojoExecutionException { if (modules == null) { modules = ScannedModules.scanProvisionedArtifacts(pm, config); @@ -112,7 +135,7 @@ private ScannedModules getScannedModules() throws ProvisioningException, MojoExe } void dumpArtifacts(Path file) throws ProvisioningException, MojoExecutionException, IOException { - Map> perModules = getScannedModules().getPerModuleArtifacts(); + Map>> perFeaturePack = getScannedModules().getPerFeaturePackArtifacts(); StringBuilder builder = new StringBuilder(); builder.append("").append(System.lineSeparator()); @@ -140,24 +163,30 @@ void dumpArtifacts(Path file) throws ProvisioningException, MojoExecutionExcepti builder.append(" ").append(jbossModules.getVersion()).append("").append(System.lineSeparator()); builder.append(" ").append(jbossModules.getType()).append("").append(System.lineSeparator()); builder.append(" ").append(System.lineSeparator()); - builder.append(" ").append(System.lineSeparator()); - for (Entry> module : perModules.entrySet()) { - builder.append(" ").append(System.lineSeparator()); - for (String s : module.getValue().values()) { - Artifact a = AbstractBuildBootableJarMojo.getArtifact(s); - builder.append(" ").append(System.lineSeparator()); - builder.append(" ").append(a.getGroupId()).append("").append(System.lineSeparator()); - builder.append(" ").append(a.getArtifactId()).append("").append(System.lineSeparator()); - if (a.getClassifier() != null && !a.getClassifier().isEmpty()) { - builder.append(" ").append(a.getClassifier()).append("").append(System.lineSeparator()); + builder.append(" ").append(System.lineSeparator()); + for (Entry>> fp : perFeaturePack.entrySet()) { + builder.append(" ").append(System.lineSeparator()); + builder.append(" ").append(System.lineSeparator()); + for (Entry> module : fp.getValue().entrySet()) { + builder.append(" ").append(System.lineSeparator()); + for (String s : module.getValue().values()) { + Artifact a = AbstractBuildBootableJarMojo.getArtifact(s); + builder.append(" ").append(System.lineSeparator()); + builder.append(" ").append(a.getGroupId()).append("").append(System.lineSeparator()); + builder.append(" ").append(a.getArtifactId()).append("").append(System.lineSeparator()); + if (a.getClassifier() != null && !a.getClassifier().isEmpty()) { + builder.append(" ").append(a.getClassifier()).append("").append(System.lineSeparator()); + } + builder.append(" ").append(a.getVersion()).append("").append(System.lineSeparator()); + builder.append(" ").append(a.getType()).append("").append(System.lineSeparator()); + builder.append(" ").append(System.lineSeparator()); } - builder.append(" ").append(a.getVersion()).append("").append(System.lineSeparator()); - builder.append(" ").append(a.getType()).append("").append(System.lineSeparator()); - builder.append(" ").append(System.lineSeparator()); + builder.append(" ").append(System.lineSeparator()); } - builder.append(" ").append(System.lineSeparator()); + builder.append(" ").append(System.lineSeparator()); + builder.append(" ").append(System.lineSeparator()); } - builder.append(" ").append(System.lineSeparator()); + builder.append(" ").append(System.lineSeparator()); builder.append("").append(System.lineSeparator()); Files.write(file, builder.toString().getBytes("UTF-8")); } @@ -178,7 +207,7 @@ private static String getOriginalArtifactVersion(OverriddenArtifact a, Map originalVersions = getOriginalVersions(); @@ -191,7 +220,7 @@ ProvisioningConfig upgrade() throws MojoExecutionException, ProvisioningDescript } String key = a.getGAC(); if (allArtifacts.containsKey(key)) { - throw new MojoExecutionException("Artifact " + key + " is present more than once in the overridden artifacts. Must be unique."); + throw new MojoExecutionException("Artifact " + key + " is present more than once in the global overridden artifacts. Must be unique."); } else { allArtifacts.put(key, a); } @@ -236,36 +265,46 @@ ProvisioningConfig upgrade() throws MojoExecutionException, ProvisioningDescript } throw new MojoExecutionException("No version for artifact " + a.getGAC()); } else { - checkScope(mavenArtifact); - if (a.getVersion() == null) { - a.setVersion(mavenArtifact.getVersion()); - } - if (a.getType() == null) { - a.setType(mavenArtifact.getType()); - } - String originalVersion = getOriginalArtifactVersion(a, originalVersions); - if (originalVersion == null) { - throw new MojoExecutionException("Overridden artifact " + a.getGAC() + " not know in provisioned feature-packs"); - } - DefaultArtifactVersion orig = new DefaultArtifactVersion(originalVersion); - DefaultArtifactVersion overriddenVersion = new DefaultArtifactVersion(a.getVersion()); - int compared = orig.compareTo(overriddenVersion); - if (compared > 0) { - if (mojo.warnArtifactDowngrade) { - mojo.getLog().warn("[UPDATE] Downgrading artifact " + a.getGAC() + " from " + originalVersion + " to " + a.getVersion()); - } - } else { - if (compared == 0) { - mojo.getLog().warn("[UPDATE] Artifact " + a.getGAC() + " is already at version " + a.getVersion() + ", will be not upgraded."); - } - } - if (compared != 0) { - artifactDependencies.add(a); - } + addArtifact(a, mavenArtifact, originalVersions, artifactDependencies, null); + } + } + } + Map> perFeaturePack = new HashMap<>(); + for (Entry entry : mojo.resolvedLocations.entrySet()) { + FeaturePack fp = entry.getKey(); + String gac = fp.getGAC(); + FeaturePackLocation.FPID fpid = gACToProducer.get(gac); + // A universe base FPL. + if (fpid == null) { + fpid = entry.getValue().getFPID(); + } + String producerName = fpid.getProducer().getName(); + Map originalversionsForProducer = getOriginalVersions(producerName); + Map seenArtifacts = new HashMap<>(); + for (OverriddenArtifact o : fp.getOverridenArtifacts()) { + String key = o.getGAC(); + if (seenArtifacts.containsKey(key)) { + throw new MojoExecutionException("Artifact " + key + " is present more than once in the overridden artifacts of " + gac + ". Must be unique."); + } else { + seenArtifacts.put(key, o); + } + if (o.getGroupId() == null || o.getArtifactId() == null) { + throw new MojoExecutionException("Invalid Artifact , groupId and artifactId are required"); + } + Artifact mavenArtifact = mojo.artifactVersions.getArtifact(o); + if (mavenArtifact == null) { + throw new MojoExecutionException("No version for artifact " + o.getGAC()); } + List lst = perFeaturePack.get(producerName); + if (lst == null) { + lst = new ArrayList<>(); + perFeaturePack.put(producerName, lst); + } + addArtifact(o, mavenArtifact, originalversionsForProducer, lst, producerName); } } - if (!artifactDependencies.isEmpty() || !featurePackDependencies.isEmpty()) { + + if (!artifactDependencies.isEmpty() || !featurePackDependencies.isEmpty() || !perFeaturePack.isEmpty()) { ProvisioningConfig.Builder c = ProvisioningConfig.builder(config); if (!featurePackDependencies.isEmpty()) { mojo.getLog().info("[UPDATE] Overriding Galleon feature-pack dependency with: "); @@ -277,16 +316,31 @@ ProvisioningConfig upgrade() throws MojoExecutionException, ProvisioningDescript c.addTransitiveDep(fpl); } } - if (!artifactDependencies.isEmpty()) { - mojo.getLog().info("[UPDATE] Overriding server artifacts with:"); - if (!mojo.pluginOptions.containsKey("jboss-overridden-artifacts")) { + StringBuilder artifactsOption = new StringBuilder(); + if (mojo.pluginOptions.containsKey("jboss-overridden-artifacts")) { + mojo.getLog().warn("[UPDATE] jboss-overridden-artifacts plugin option already set, any " + + "specified artifact upgrade will be not applied."); + } else { + // Global upgrade + if (!artifactDependencies.isEmpty()) { + mojo.getLog().info("[UPDATE] Overriding server artifacts globally with:"); String updates = toOptionValue(artifactDependencies); - for (OverriddenArtifact update : artifactDependencies) { - mojo.getLog().info("[UPDATE] " + update.getGroupId() + ":" + update.getArtifactId() + ":" - + (update.getClassifier() == null ? "" : update.getClassifier() + ":") - + update.getVersion() + (update.getType() == null ? "" : ":" + update.getType())); + advertiseArtifactsUpgrade(artifactDependencies); + artifactsOption.append(updates); + } + // per feature-pack + if (!perFeaturePack.isEmpty()) { + for (Entry> entry : perFeaturePack.entrySet()) { + List artifacts = entry.getValue(); + String producer = entry.getKey(); + mojo.getLog().info("[UPDATE] Overriding server artifacts from " + producer + " with:"); + String updates = toOptionValue(artifacts); + advertiseArtifactsUpgrade(artifacts); + artifactsOption.append("@").append(producer).append("=").append(updates); } - c.addOption("jboss-overridden-artifacts", updates); + } + if (artifactsOption.length() != 0) { + c.addOption("jboss-overridden-artifacts", artifactsOption.toString()); } } return c.build(); @@ -295,6 +349,45 @@ ProvisioningConfig upgrade() throws MojoExecutionException, ProvisioningDescript } } + private void advertiseArtifactsUpgrade(List artifactDependencies) { + for (OverriddenArtifact update : artifactDependencies) { + mojo.getLog().info("[UPDATE] " + update.getGroupId() + ":" + update.getArtifactId() + ":" + + (update.getClassifier() == null ? "" : update.getClassifier() + ":") + + update.getVersion() + (update.getType() == null ? "" : ":" + update.getType())); + } + } + + private void addArtifact(OverriddenArtifact a, Artifact mavenArtifact, + Map originalVersions, List artifactDependencies, String producer) throws MojoExecutionException { + checkScope(mavenArtifact); + if (a.getVersion() == null) { + a.setVersion(mavenArtifact.getVersion()); + } + if (a.getType() == null) { + a.setType(mavenArtifact.getType()); + } + String originalVersion = getOriginalArtifactVersion(a, originalVersions); + if (originalVersion == null) { + throw new MojoExecutionException("Overridden artifact " + a.getGAC() + " not known in " + + (producer == null ? "provisioned feature-packs" : producer)); + } + DefaultArtifactVersion orig = new DefaultArtifactVersion(originalVersion); + DefaultArtifactVersion overriddenVersion = new DefaultArtifactVersion(a.getVersion()); + int compared = orig.compareTo(overriddenVersion); + if (compared > 0) { + if (mojo.warnArtifactDowngrade) { + mojo.getLog().warn("[UPDATE] Downgrading artifact " + a.getGAC() + " from " + originalVersion + " to " + a.getVersion()); + } + } else { + if (compared == 0) { + mojo.getLog().warn("[UPDATE] Artifact " + a.getGAC() + " is already at version " + a.getVersion() + ", will be not upgraded."); + } + } + if (compared != 0) { + artifactDependencies.add(a); + } + } + void checkScope(Artifact a) { if (!"provided".equals(a.getScope())) { mojo.getLog().warn("[UPDATE] Overridden artifact " + a.getGroupId() +":"+ a.getArtifactId()+ @@ -318,13 +411,13 @@ static String locationWithVersion(String featurePackLocation, MavenProjectArtifa return featurePackLocation; } - private FeaturePack toFeaturePack(FeaturePackConfig cfg, ProvisioningManager pm) throws MojoExecutionException { + private FeaturePack toFeaturePack(FeaturePackLocation location, ProvisioningManager pm) throws MojoExecutionException { FeaturePack fp; - validateFPL(cfg.getLocation()); - if (cfg.getLocation().isMavenCoordinates()) { - fp = getFeaturePack(cfg.getLocation().toString()); + validateFPL(location); + if (location.isMavenCoordinates()) { + fp = getFeaturePack(location.toString()); } else { - fp = getFeaturePack(cfg, pm); + fp = getFeaturePack(location, pm); } return fp; } @@ -344,24 +437,24 @@ String getMavenFeaturePack(FeaturePackLocation.FPID location) { } } - private FeaturePack getFeaturePack(FeaturePackConfig cfg, ProvisioningManager pm) { + private FeaturePack getFeaturePack(FeaturePackLocation location, ProvisioningManager pm) { try { - Channel channel = pm.getLayoutFactory().getUniverseResolver().getChannel(cfg.getLocation()); + Channel channel = pm.getLayoutFactory().getUniverseResolver().getChannel(location); if (channel instanceof MavenChannel) { MavenChannel mavenChannel = (MavenChannel) channel; FeaturePack fp = new FeaturePack(); fp.setGroupId(mavenChannel.getFeaturePackGroupId()); fp.setArtifactId(mavenChannel.getFeaturePackArtifactId()); - String build = cfg.getLocation().getBuild(); + String build = location.getBuild(); if (build == null) { - build = mavenChannel.getLatestBuild(cfg.getLocation()); + build = mavenChannel.getLatestBuild(location); } fp.setVersion(build); return fp; } } catch (ProvisioningException ex) { // OK, invalid channel, can occurs for non registered FP that are referenced from GAV. - mojo.debug("Invalid channel for %s, the feature-pack is not known in the universe, skipping it.", cfg.getLocation()); + mojo.debug("Invalid channel for %s, the feature-pack is not known in the universe, skipping it.", location); } return null; } diff --git a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ScannedModules.java b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ScannedModules.java index 55253f26..ccbc738c 100644 --- a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ScannedModules.java +++ b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ScannedModules.java @@ -50,18 +50,18 @@ final class ScannedModules { private static final String MODULE = "module"; private static final String MODULE_RUNTIME_KEY = "org.jboss.modules:jboss-modules"; - private final Map> perModule; + private final Map>> perFeaturePacks; private final String moduleRuntimeKey; private final String moduleRuntimeValue; - ScannedModules(Map> perModule, String moduleRuntimeKey, String moduleRuntimeValue) { - this.perModule = perModule; + ScannedModules(Map>> perFeaturePacks, String moduleRuntimeKey, String moduleRuntimeValue) { + this.perFeaturePacks = perFeaturePacks; this.moduleRuntimeKey = moduleRuntimeKey; this.moduleRuntimeValue = moduleRuntimeValue; } - Map> getPerModuleArtifacts() { - return perModule; + Map>> getPerFeaturePackArtifacts() { + return perFeaturePacks; } String getModuleRuntime() { @@ -70,17 +70,31 @@ String getModuleRuntime() { Map getProvisionedArtifacts() { Map all = new HashMap<>(); - for (Map artifacts : perModule.values()) { - all.putAll(artifacts); + for (String producer : perFeaturePacks.keySet()) { + Map> perModule = perFeaturePacks.get(producer); + for (Map artifacts : perModule.values()) { + all.putAll(artifacts); + } } all.put(moduleRuntimeKey, moduleRuntimeValue); return all; } + Map getProvisionedArtifacts(String producer) { + Map all = new HashMap<>(); + Map> perModule = perFeaturePacks.get(producer); + if (perModule != null) { + for (Map artifacts : perModule.values()) { + all.putAll(artifacts); + } + } + return all; + } + static ScannedModules scanProvisionedArtifacts(ProvisioningManager pm, ProvisioningConfig config) throws ProvisioningException, MojoExecutionException { Map propsMap = new HashMap<>(); - Map> perModule = new TreeMap<>(); + Map>> perFeaturePack = new TreeMap<>(); try (ProvisioningRuntime rt = pm.getRuntime(config)) { for (FeaturePackRuntime fprt : rt.getFeaturePacks()) { Path artifactProps = fprt.getResource(AbstractBuildBootableJarMojo.WILDFLY_ARTIFACT_VERSIONS_RESOURCE_PATH); @@ -91,6 +105,8 @@ static ScannedModules scanProvisionedArtifacts(ProvisioningManager pm, Provision } } for (FeaturePackRuntime fprt : rt.getFeaturePacks()) { + Map> perModule = new TreeMap<>(); + perFeaturePack.put(fprt.getFPID().getProducer().getName(), perModule); processPackages(fprt, perModule, propsMap); } } @@ -99,7 +115,7 @@ static ScannedModules scanProvisionedArtifacts(ProvisioningManager pm, Provision if (moduleRuntimeValue == null) { throw new ProvisioningException("No JBoss Modules runtime found"); } - return new ScannedModules(perModule, MODULE_RUNTIME_KEY, moduleRuntimeValue); + return new ScannedModules(perFeaturePack, MODULE_RUNTIME_KEY, moduleRuntimeValue); } private static void processPackages(final FeaturePackRuntime fp, diff --git a/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactProducerFPLTestCase.java b/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactProducerFPLTestCase.java new file mode 100644 index 00000000..df2a6f3d --- /dev/null +++ b/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactProducerFPLTestCase.java @@ -0,0 +1,132 @@ +/* + * Copyright 2021 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"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wildfly.plugins.bootablejar.maven.goals; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.wildfly.plugins.bootablejar.maven.common.OverriddenArtifact; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * @author jdenise + */ +// Need WF 23.x that supports per feature-pack upgrade. +@Ignore +public class UpgradeArtifactProducerFPLTestCase extends AbstractBootableJarMojoTestCase { + + public UpgradeArtifactProducerFPLTestCase() { + super("upgrade-artifact-producer-fpl-pom.xml", true, null); + } + + @Test + public void testUpgrade() throws Exception { + BuildBootableJarMojo mojo = lookupMojo("package"); + MavenProjectArtifactVersions artifacts = MavenProjectArtifactVersions.getInstance(mojo.project); + // Upgrade wildfly-ee-galleon-pack and undertow-core. GLoba undertow-core is hidden by specific upgrade + // on wildfly-ee-galleon-pack. + Assert.assertEquals(2, mojo.overriddenServerArtifacts.size()); + String hiddenUndertowVersion = null; + String wildflyeeVersion = null; + boolean seenArtifact = false; + boolean seenFeaturePack = false; + for (OverriddenArtifact oa : mojo.overriddenServerArtifacts) { + Artifact a = null; + if ("io.undertow".equals(oa.getGroupId())) { + a = artifacts.getArtifact(oa); + Assert.assertNotNull(oa.getGroupId() + ":" + oa.getArtifactId(), a); + seenArtifact = true; + hiddenUndertowVersion = a.getVersion(); + } else { + a = artifacts.getFeaturePackArtifact(oa.getGroupId(), oa.getArtifactId(), oa.getClassifier()); + Assert.assertNotNull(oa.getGroupId() + ":" + oa.getArtifactId(), a); + seenFeaturePack = true; + wildflyeeVersion = a.getVersion(); + } + Assert.assertNotNull(a); + Assert.assertNotNull(a.getVersion()); + Assert.assertEquals(oa.getGroupId(), a.getGroupId()); + Assert.assertEquals(oa.getArtifactId(), a.getArtifactId()); + } + Assert.assertTrue(seenArtifact && seenFeaturePack); + + // We have an older release of undertow-core in wildfly-ee-galleon-pack in the pom.xml + Assert.assertEquals(1, mojo.featurePacks.get(0).getOverridenArtifacts().size()); + + OverriddenArtifact oartifact = mojo.featurePacks.get(0).getOverridenArtifacts().get(0); + Artifact a = artifacts.getArtifact(oartifact); + Assert.assertNotNull(oartifact.getGroupId() + ":" + oartifact.getArtifactId(), a); + // Version is present directly in overridden artifact, it hides the global one. + String undertowVersion = oartifact.getVersion(); + mojo.recordState = true; + mojo.execute(); + final Path dir = getTestDir(); + String[] layers = {"jaxrs-server"}; + Path unzippedJar = checkAndGetWildFlyHome(dir, true, true, layers, null); + try { + Path modulesDir = unzippedJar.resolve("modules").resolve("system").resolve("layers").resolve("base"); + Path undertow = modulesDir.resolve("io").resolve("undertow").resolve("core").resolve("main").resolve("undertow-core-" + undertowVersion + ".jar"); + Assert.assertTrue(undertow.toString(), Files.exists(undertow)); + Path ee = modulesDir.resolve("org").resolve("jboss").resolve("as").resolve("ee").resolve("main").resolve("wildfly-ee-" + wildflyeeVersion + ".jar"); + Assert.assertTrue(ee.toString(), Files.exists(ee)); + } finally { + BuildBootableJarMojo.deleteDir(unzippedJar); + } + checkJar(dir, true, true, layers, null); + checkDeployment(dir, true); + } + + @Test + public void testInvalidUpgrades() throws Exception { + BuildBootableJarMojo mojo = lookupMojo("package"); + Assert.assertEquals(1, mojo.featurePacks.get(0).getOverridenArtifacts().size()); + List orig = new ArrayList<>(); + orig.addAll(mojo.featurePacks.get(0).getOverridenArtifacts()); + mojo.featurePacks.get(0).getOverridenArtifacts().addAll(mojo.featurePacks.get(0).getOverridenArtifacts()); + try { + mojo.execute(); + throw new Exception("Should have failed"); + } catch (MojoExecutionException ex) { + // XXX Expected + } + mojo.featurePacks.get(0).setOverridenArtifacts(orig); + String grpId = orig.get(0).getGroupId(); + try { + orig.get(0).getGroupId(); + orig.get(0).setGroupId(null); + mojo.execute(); + throw new Exception("Should have failed"); + } catch (MojoExecutionException ex) { + // XXX Expected + } + orig.get(0).setGroupId(grpId); + try { + orig.get(0).setArtifactId(null); + mojo.execute(); + throw new Exception("Should have failed"); + } catch (MojoExecutionException ex) { + // XXX Expected + } + + } +} diff --git a/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactProducerTestCase.java b/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactProducerTestCase.java new file mode 100644 index 00000000..10066799 --- /dev/null +++ b/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactProducerTestCase.java @@ -0,0 +1,133 @@ +/* + * Copyright 2021 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"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wildfly.plugins.bootablejar.maven.goals; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.wildfly.plugins.bootablejar.maven.common.OverriddenArtifact; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * @author jdenise + */ + +// Need WF 23.x that supports per feature-pack upgrade. +@Ignore +public class UpgradeArtifactProducerTestCase extends AbstractBootableJarMojoTestCase { + + public UpgradeArtifactProducerTestCase() { + super("upgrade-artifact-producer-pom.xml", true, null); + } + + @Test + public void testUpgrade() throws Exception { + BuildBootableJarMojo mojo = lookupMojo("package"); + MavenProjectArtifactVersions artifacts = MavenProjectArtifactVersions.getInstance(mojo.project); + // Upgrade wildfly-ee-galleon-pack and undertow-core. GLoba undertow-core is hidden by specific upgrade + // on wildfly-ee-galleon-pack. + Assert.assertEquals(2, mojo.overriddenServerArtifacts.size()); + String hiddenUndertowVersion = null; + String wildflyeeVersion = null; + boolean seenArtifact = false; + boolean seenFeaturePack = false; + for (OverriddenArtifact oa : mojo.overriddenServerArtifacts) { + Artifact a = null; + if ("io.undertow".equals(oa.getGroupId())) { + a = artifacts.getArtifact(oa); + Assert.assertNotNull(oa.getGroupId() + ":" + oa.getArtifactId(), a); + seenArtifact = true; + hiddenUndertowVersion = a.getVersion(); + } else { + a = artifacts.getFeaturePackArtifact(oa.getGroupId(), oa.getArtifactId(), oa.getClassifier()); + Assert.assertNotNull(oa.getGroupId() + ":" + oa.getArtifactId(), a); + seenFeaturePack = true; + wildflyeeVersion = a.getVersion(); + } + Assert.assertNotNull(a); + Assert.assertNotNull(a.getVersion()); + Assert.assertEquals(oa.getGroupId(), a.getGroupId()); + Assert.assertEquals(oa.getArtifactId(), a.getArtifactId()); + } + Assert.assertTrue(seenArtifact && seenFeaturePack); + + // We have an older release of undertow-core in wildfly-ee-galleon-pack in the pom.xml + Assert.assertEquals(1, mojo.featurePacks.get(0).getOverridenArtifacts().size()); + + OverriddenArtifact oartifact = mojo.featurePacks.get(0).getOverridenArtifacts().get(0); + Artifact a = artifacts.getArtifact(oartifact); + Assert.assertNotNull(oartifact.getGroupId() + ":" + oartifact.getArtifactId(), a); + // Version is present directly in overridden artifact, it hides the global one. + String undertowVersion = oartifact.getVersion(); + mojo.recordState = true; + mojo.execute(); + final Path dir = getTestDir(); + String[] layers = {"jaxrs-server"}; + Path unzippedJar = checkAndGetWildFlyHome(dir, true, true, layers, null); + try { + Path modulesDir = unzippedJar.resolve("modules").resolve("system").resolve("layers").resolve("base"); + Path undertow = modulesDir.resolve("io").resolve("undertow").resolve("core").resolve("main").resolve("undertow-core-" + undertowVersion + ".jar"); + Assert.assertTrue(undertow.toString(), Files.exists(undertow)); + Path ee = modulesDir.resolve("org").resolve("jboss").resolve("as").resolve("ee").resolve("main").resolve("wildfly-ee-" + wildflyeeVersion + ".jar"); + Assert.assertTrue(ee.toString(), Files.exists(ee)); + } finally { + BuildBootableJarMojo.deleteDir(unzippedJar); + } + checkJar(dir, true, true, layers, null); + checkDeployment(dir, true); + } + + @Test + public void testInvalidUpgrades() throws Exception { + BuildBootableJarMojo mojo = lookupMojo("package"); + Assert.assertEquals(1, mojo.featurePacks.get(0).getOverridenArtifacts().size()); + List orig = new ArrayList<>(); + orig.addAll(mojo.featurePacks.get(0).getOverridenArtifacts()); + mojo.featurePacks.get(0).getOverridenArtifacts().addAll(mojo.featurePacks.get(0).getOverridenArtifacts()); + try { + mojo.execute(); + throw new Exception("Should have failed"); + } catch (MojoExecutionException ex) { + // XXX Expected + } + mojo.featurePacks.get(0).setOverridenArtifacts(orig); + String grpId = orig.get(0).getGroupId(); + try { + orig.get(0).getGroupId(); + orig.get(0).setGroupId(null); + mojo.execute(); + throw new Exception("Should have failed"); + } catch (MojoExecutionException ex) { + // XXX Expected + } + orig.get(0).setGroupId(grpId); + try { + orig.get(0).setArtifactId(null); + mojo.execute(); + throw new Exception("Should have failed"); + } catch (MojoExecutionException ex) { + // XXX Expected + } + + } +} diff --git a/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactUnknownArtifactTestCase.java b/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactUnknownArtifactTestCase.java index 46a58e7a..c56c1b93 100644 --- a/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactUnknownArtifactTestCase.java +++ b/tests/src/test/java/org/wildfly/plugins/bootablejar/maven/goals/UpgradeArtifactUnknownArtifactTestCase.java @@ -37,7 +37,7 @@ public void testUpgrade() throws Exception { mojo.execute(); throw new Exception("Should have failed"); } catch (MojoExecutionException ex) { - Assert.assertTrue(ex.toString().contains("Overridden artifact jakarta.platform:jakarta.jakartaee-api not know in provisioned feature-packs")); + Assert.assertTrue(ex.toString().contains("Overridden artifact jakarta.platform:jakarta.jakartaee-api not known in provisioned feature-packs")); // XXX OK, expected } } diff --git a/tests/src/test/resources/poms/upgrade-artifact-producer-fpl-pom.xml b/tests/src/test/resources/poms/upgrade-artifact-producer-fpl-pom.xml new file mode 100644 index 00000000..8769d329 --- /dev/null +++ b/tests/src/test/resources/poms/upgrade-artifact-producer-fpl-pom.xml @@ -0,0 +1,76 @@ + + + + 4.0.0 + org.wildfly.plugins.tests + 1.0.0.Final-SNAPSHOT + test2 + war + + WildFly bootable jar Example for tests + + + + io.undertow + undertow-core + 2.2.2.Final + provided + + + org.wildfly + wildfly-galleon-pack + WF_VERSION + provided + zip + + + org.wildfly + wildfly-ee-galleon-pack + WF_EE_VERSION + provided + zip + + + + test + + + wildfly-jar-maven-plugin + + + + wildfly-ee@maven(org.jboss.universe:community-universe)#WF_EE_VERSION + true + + + + io.undertow + undertow-core + 2.2.1.Final + + + + + TEST_REPLACE + + + + jaxrs-server + + + + + io.undertow + undertow-core + + + org.wildfly + wildfly-ee-galleon-pack + + + + + + + diff --git a/tests/src/test/resources/poms/upgrade-artifact-producer-pom.xml b/tests/src/test/resources/poms/upgrade-artifact-producer-pom.xml new file mode 100644 index 00000000..a11c72ec --- /dev/null +++ b/tests/src/test/resources/poms/upgrade-artifact-producer-pom.xml @@ -0,0 +1,78 @@ + + + + 4.0.0 + org.wildfly.plugins.tests + 1.0.0.Final-SNAPSHOT + test2 + war + + WildFly bootable jar Example for tests + + + + io.undertow + undertow-core + 2.2.2.Final + provided + + + org.wildfly + wildfly-galleon-pack + WF_VERSION + provided + zip + + + org.wildfly + wildfly-ee-galleon-pack + WF_EE_VERSION + provided + zip + + + + test + + + wildfly-jar-maven-plugin + + + + org.wildfly + wildfly-ee-galleon-pack + true + + + + io.undertow + undertow-core + 2.2.1.Final + + + + + org.wildfly + wildfly-galleon-pack + + + + jaxrs-server + + + + + io.undertow + undertow-core + + + org.wildfly + wildfly-ee-galleon-pack + + + + + + +