From 5d227dd1882ca7533f2b167ba162e19fbc14f87c Mon Sep 17 00:00:00 2001 From: Bartosz Spyrko-Smietanko Date: Wed, 1 May 2024 15:09:49 +0100 Subject: [PATCH] [#648] Extend channels versions operation to identify active and inactive channels --- .../org/wildfly/prospero/cli/CliMain.java | 1 + .../prospero/cli/commands/ChannelCommand.java | 42 ++++++++ .../prospero/actions/ChannelStatusAction.java | 101 ++++++++++++++++++ .../wildfly/prospero/api/ChannelVersions.java | 43 ++++++++ .../actions/ChannelStatusActionTest.java | 21 ++++ 5 files changed, 208 insertions(+) create mode 100644 prospero-common/src/main/java/org/wildfly/prospero/actions/ChannelStatusAction.java create mode 100644 prospero-common/src/main/java/org/wildfly/prospero/api/ChannelVersions.java create mode 100644 prospero-common/src/test/java/org/wildfly/prospero/actions/ChannelStatusActionTest.java diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java index 7b07049d5..0764d8f48 100644 --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java @@ -91,6 +91,7 @@ public static CommandLine createCommandLine(CliConsole console, String[] args, A channelCmd.addSubcommand(new ChannelRemoveCommand(console, actionFactory)); channelCmd.addSubcommand(new ChannelCommand.ChannelListCommand(console, actionFactory)); channelCmd.addSubcommand(new ChannelCommand.ChannelVersionCommand(console, actionFactory)); + channelCmd.addSubcommand(new ChannelCommand.ChannelStatusCommand(console, actionFactory)); channelCmd.addSubcommand(new ChannelInitializeCommand(console, actionFactory)); channelCmd.addSubcommand(new ChannelPromoteCommand(console, actionFactory)); diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/ChannelCommand.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/ChannelCommand.java index 6d2a00c11..a29f382ef 100644 --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/ChannelCommand.java +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/ChannelCommand.java @@ -22,7 +22,9 @@ import java.util.Optional; import org.wildfly.channel.Channel; +import org.wildfly.prospero.actions.ChannelStatusAction; import org.wildfly.prospero.actions.MetadataAction; +import org.wildfly.prospero.api.ChannelVersions; import org.wildfly.prospero.cli.ActionFactory; import org.wildfly.prospero.cli.CliConsole; import org.wildfly.prospero.cli.CliMessages; @@ -120,5 +122,45 @@ private static String buildManifestGav(ManifestVersionRecord.MavenManifest maven } } + @CommandLine.Command(name = "status") + public static class ChannelStatusCommand extends AbstractCommand { + + @CommandLine.Option(names = CliConstants.DIR) + private Optional directory; + + public ChannelStatusCommand(CliConsole console, ActionFactory actionFactory) { + super(console, actionFactory); + } + + @Override + public Integer call() throws Exception { + final Path installationDir = determineInstallationDirectory(directory); + final ChannelStatusAction channelStatusAction = new ChannelStatusAction(installationDir); + + final List channelsStatus = channelStatusAction.getChannelsStatus(); + + console.println(CliMessages.MESSAGES.serverVersionsHeader()); + + for (ChannelVersions status : channelsStatus) { + final String statusText; + switch (status.getStatus()) { + case FULL: + statusText = "ACTIVE (FULL)"; + break; + case PARTIAL: + statusText = "ACTIVE (PARTIAL)"; + break; + case NONE: + statusText = "INACTIVE"; + break; + default: + statusText = "UNKNOWN"; + break; + } + System.out.printf(" * %-20s %-50s %-25s %-15s%n", status.getName(), status.getMavenCoord(), status.getVersion(), statusText); + } + return ReturnCodes.SUCCESS; + } + } } diff --git a/prospero-common/src/main/java/org/wildfly/prospero/actions/ChannelStatusAction.java b/prospero-common/src/main/java/org/wildfly/prospero/actions/ChannelStatusAction.java new file mode 100644 index 000000000..ef7c63622 --- /dev/null +++ b/prospero-common/src/main/java/org/wildfly/prospero/actions/ChannelStatusAction.java @@ -0,0 +1,101 @@ +package org.wildfly.prospero.actions; + +import org.jboss.galleon.ProvisioningException; +import org.wildfly.channel.Channel; +import org.wildfly.channel.ChannelManifest; +import org.wildfly.channel.ChannelManifestMapper; +import org.wildfly.channel.ChannelSession; +import org.wildfly.channel.MavenArtifact; +import org.wildfly.channel.MavenCoordinate; +import org.wildfly.channel.Stream; +import org.wildfly.prospero.api.ChannelVersions; +import org.wildfly.prospero.api.InstallationMetadata; +import org.wildfly.prospero.api.MavenOptions; +import org.wildfly.prospero.api.exceptions.OperationException; +import org.wildfly.prospero.galleon.GalleonEnvironment; +import org.wildfly.prospero.metadata.ManifestVersionRecord; +import org.wildfly.prospero.wfchannel.MavenSessionManager; + +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public class ChannelStatusAction { + + + private final InstallationMetadata installationMetadata; + private final ChannelSession channelSession; + + public ChannelStatusAction(Path installation) throws OperationException, ProvisioningException { + this.installationMetadata = InstallationMetadata.loadInstallation(installation); + final List channels = installationMetadata.getProsperoConfig().getChannels(); + final MavenSessionManager msm = new MavenSessionManager(MavenOptions.DEFAULT_OPTIONS); + final GalleonEnvironment env = GalleonEnvironment.builder(installation, channels, msm, true).build(); + this.channelSession = env.getChannelSession(); + } + + public List getChannelsStatus() throws MalformedURLException { + final ChannelManifest installedManifest = this.installationMetadata.getManifest(); + + final Optional manifestVersions = this.installationMetadata.getManifestVersions(); + if (manifestVersions.isEmpty()) { + return Collections.emptyList(); + } + + final List channels = this.installationMetadata.getProsperoConfig().getChannels(); + + + final List channelVersions = new ArrayList<>(); + for (ManifestVersionRecord.MavenManifest mavenManifest : manifestVersions.get().getMavenManifests()) { + Channel channel = mapToChannel(mavenManifest, channels); + + // resolve this manifest + final MavenArtifact artifact = channelSession.resolveDirectMavenArtifact(mavenManifest.getGroupId(), mavenManifest.getArtifactId(), "yaml", "manifest", mavenManifest.getVersion()); + + final ChannelManifest manifest = ChannelManifestMapper.from(artifact.getFile().toURI().toURL()); + + ChannelVersions.Status status = ChannelVersions.Status.NONE; + boolean found = false; + for (Stream stream : manifest.getStreams()) { + final Optional installedArtifact = installedManifest.findStreamFor(stream.getGroupId(), stream.getArtifactId()); + if (installedArtifact.isEmpty()) { + continue; + } + + if (!installedArtifact.get().getVersion().equals(stream.getVersion())) { + if (status != ChannelVersions.Status.NONE) { + status = ChannelVersions.Status.PARTIAL; + } + found = true; + } else { + if (status != ChannelVersions.Status.PARTIAL) { + status = ChannelVersions.Status.FULL; + } + } + } + if (status == ChannelVersions.Status.FULL && found) { + status = ChannelVersions.Status.PARTIAL; + } + channelVersions.add(new ChannelVersions(channel==null?"":channel.getName(), mavenManifest.getGroupId() + ":" + mavenManifest.getArtifactId(), mavenManifest.getVersion(), status)); + } + + return channelVersions; + } + + private Channel mapToChannel(ManifestVersionRecord.MavenManifest mavenManifest, List channels) { + for (Channel channel : channels) { + if (channel.getManifestCoordinate() == null || channel.getManifestCoordinate().getMaven() == null) { + return null; + } + + final MavenCoordinate mavenCoord = channel.getManifestCoordinate().getMaven(); + if (mavenCoord.getGroupId().equals(mavenManifest.getGroupId()) && mavenCoord.getArtifactId().equals(mavenManifest.getArtifactId())) { + return channel; + } + } + return null; + } +} diff --git a/prospero-common/src/main/java/org/wildfly/prospero/api/ChannelVersions.java b/prospero-common/src/main/java/org/wildfly/prospero/api/ChannelVersions.java new file mode 100644 index 000000000..fe2286773 --- /dev/null +++ b/prospero-common/src/main/java/org/wildfly/prospero/api/ChannelVersions.java @@ -0,0 +1,43 @@ +package org.wildfly.prospero.api; + +public class ChannelVersions { + + private final String mavenCoord; + + public enum Status {FULL, PARTIAL, NONE, UNKNOWN} + private String name; + private String version; + private Status status; + + public ChannelVersions(String name, String mavenCoord, String version, Status status) { + this.name = name; + this.version = version; + this.status = status; + this.mavenCoord = mavenCoord; + } + + public String getName() { + return name; + } + + public String getVersion() { + return version; + } + + public Status getStatus() { + return status; + } + + public String getMavenCoord() { + return mavenCoord; + } + + @Override + public String toString() { + return "ChannelVersions{" + + "name='" + name + '\'' + + ", version='" + version + '\'' + + ", status=" + status + + '}'; + } +} diff --git a/prospero-common/src/test/java/org/wildfly/prospero/actions/ChannelStatusActionTest.java b/prospero-common/src/test/java/org/wildfly/prospero/actions/ChannelStatusActionTest.java new file mode 100644 index 000000000..0af68e69d --- /dev/null +++ b/prospero-common/src/test/java/org/wildfly/prospero/actions/ChannelStatusActionTest.java @@ -0,0 +1,21 @@ +package org.wildfly.prospero.actions; + +import org.junit.Test; +import org.wildfly.prospero.api.ChannelVersions; + +import java.nio.file.Path; +import java.util.List; + + +public class ChannelStatusActionTest { + + @Test + public void testMe() throws Exception { + final ChannelStatusAction channelStatusAction = new ChannelStatusAction(Path.of("/Users/spyrkob/workspaces/set/prospero/tmp/JBEAP-26936/server")); + + final List channelsStatus = channelStatusAction.getChannelsStatus(); + + channelsStatus.forEach(System.out::println); + } + +} \ No newline at end of file