Skip to content

Commit

Permalink
Merge pull request #509 from spyrkob/issue_411
Browse files Browse the repository at this point in the history
[#411] When displaying the update candidates, display the name of the channel the update was found in
  • Loading branch information
spyrkob authored Dec 8, 2023
2 parents 679700c + d4f19a7 commit 68730f9
Show file tree
Hide file tree
Showing 15 changed files with 495 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.wildfly.channel.ChannelMapper;
import org.wildfly.channel.Repository;
import org.wildfly.channel.Stream;
import org.wildfly.prospero.actions.ApplyCandidateAction;
import org.wildfly.prospero.api.exceptions.MetadataException;
import org.wildfly.prospero.metadata.ManifestVersionRecord;
import org.wildfly.prospero.actions.UpdateAction;
Expand All @@ -44,6 +45,8 @@
import org.wildfly.prospero.metadata.ProsperoMetadataUtils;
import org.wildfly.prospero.model.ManifestYamlSupport;
import org.wildfly.prospero.test.MetadataTestUtils;
import org.wildfly.prospero.updates.CandidateProperties;
import org.wildfly.prospero.updates.CandidatePropertiesParser;
import org.wildfly.prospero.wfchannel.MavenSessionManager;

import java.io.File;
Expand Down Expand Up @@ -176,6 +179,12 @@ public void prepareUpdateCreatesMarkerFile() throws Exception {
assertThat(record.get().getMavenManifests())
.map(ManifestVersionRecord.MavenManifest::getVersion)
.containsExactly("1.0.1");

final Path channelNamesFile = preparedUpdatePath.resolve(ProsperoMetadataUtils.METADATA_DIR).resolve(ApplyCandidateAction.CANDIDATE_CHANNEL_NAME_LIST);
assertTrue(Files.exists(channelNamesFile));

final CandidateProperties candidateProperties = CandidatePropertiesParser.read(channelNamesFile);
assertEquals("test", candidateProperties.getUpdateChannel("org.wildfly.core:wildfly-cli"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,11 @@ public void updatesFound(List<ArtifactChange> artifactUpdates) {
final Optional<String> newVersion = artifactUpdate.getNewVersion();
final Optional<String> oldVersion = artifactUpdate.getOldVersion();
final String artifactName = artifactUpdate.getArtifactName();
final String channelName = artifactUpdate.getChannelName().map(name -> "[" + name + "]")
.orElse("");

getStdOut().printf(" %s%-50s %-20s ==> %-20s%n", artifactUpdate.isDowngrade()?"[*]":"", artifactName, oldVersion.orElse("[]"),
newVersion.orElse("[]"));
getStdOut().printf(" %s%-50s %-20s ==> %-20s %-20s%n", artifactUpdate.isDowngrade()?"[*]":"", artifactName, oldVersion.orElse("[]"),
newVersion.orElse("[]"), channelName);
}

if (artifactUpdates.stream().anyMatch(ArtifactChange::isDowngrade)) {
Expand All @@ -180,9 +182,11 @@ public void changesFound(List<ArtifactChange> artifactUpdates) {
final Optional<String> newVersion = artifactUpdate.getNewVersion();
final Optional<String> oldVersion = artifactUpdate.getOldVersion();
final String artifactName = artifactUpdate.getArtifactName();
final String channelName = artifactUpdate.getChannelName().map(name -> "[" + name + "]")
.orElse("");

getStdOut().printf(" %-50s %-20s ==> %-20s%n", artifactName, oldVersion.orElse("[]"),
newVersion.orElse("[]"));
getStdOut().printf(" %-50s %-20s ==> %-20s %-20s%n", artifactName, oldVersion.orElse("[]"),
newVersion.orElse("[]"),channelName);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2023 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.prospero.cli;

import org.eclipse.aether.artifact.DefaultArtifact;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.wildfly.prospero.api.ArtifactChange;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class CliConsoleTest extends AbstractConsoleTest {
private CliConsole cliConsole;

private ByteArrayOutputStream outputStream;
private PrintStream originalOut;

@Before
public void setUp() {
cliConsole = new CliConsole();
outputStream = new ByteArrayOutputStream();
originalOut = System.out;
System.setOut(new PrintStream(outputStream));
}

@Test
public void testUpdatesFoundWithUpdates_ArtifactChange_update() {
final List<ArtifactChange> artifactChanges = new ArrayList<>();
final ArtifactChange artifactChange = ArtifactChange.updated(new DefaultArtifact("test.group", "test-artifact2", "jar", "2.0.0"), new DefaultArtifact("test.group", "test-artifact2", "jar", "2.1.0"), "channel-1");

artifactChanges.add(artifactChange);
cliConsole.updatesFound(artifactChanges);
final String capturedOutput = outputStream.toString();

assertThat(capturedOutput)
.contains("test.group:test-artifact2")
.contains("[channel-1]");
}
@Test
public void testUpdatesFoundWithUpdates_ArtifactChange_add() {
final List<ArtifactChange> artifactChanges = new ArrayList<>();
final ArtifactChange artifactChange = ArtifactChange.added(new DefaultArtifact("test.group", "test-artifact2", "jar", "2.0.0"), "channel-1");

artifactChanges.add(artifactChange);
cliConsole.updatesFound(artifactChanges);
final String capturedOutput = outputStream.toString();

assertThat(capturedOutput)
.contains("test.group:test-artifact2")
.contains("[channel-1]");
}

@After
public void destory() throws IOException {
outputStream.close();
cliConsole = null;
System.setOut(originalOut);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,16 @@ public interface ProsperoLogger extends BasicLogger {

@Message(id = 260, value = "The selected folder %s cannot be created.")
IllegalArgumentException dirMustBeWritable(Path directory);

@Message(id = 261, value = "Channel map data has been written to %s.")
@LogMessage(level = Logger.Level.DEBUG)
void channelNamesWrittenToFile(String fileName);

@Message(id = 262, value = "Unable to create a candidate properties file %s.")
@LogMessage(level = Logger.Level.ERROR)
void unableToWriteChannelNamesToFile(String fileName, @Cause Exception e);

@Message(id = 263, value = "Unable to read the candidate properties file %s.")
@LogMessage(level = Logger.Level.ERROR)
void unableToReadChannelNames(String fileName, @Cause Exception e);
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.jboss.galleon.Errors;

import org.jboss.galleon.ProvisioningManager;
import org.jboss.logging.Logger;
import org.wildfly.prospero.ProsperoLogger;
import org.wildfly.prospero.api.ArtifactChange;
import org.wildfly.prospero.api.FileConflict;
Expand Down Expand Up @@ -70,6 +71,8 @@
import org.wildfly.prospero.galleon.GalleonEnvironment;
import org.wildfly.prospero.installation.git.GitStorage;
import org.wildfly.prospero.metadata.ProsperoMetadataUtils;
import org.wildfly.prospero.updates.CandidateProperties;
import org.wildfly.prospero.updates.CandidatePropertiesParser;
import org.wildfly.prospero.updates.MarkerFile;
import org.wildfly.prospero.updates.UpdateSet;
import org.wildfly.prospero.wfchannel.MavenSessionManager;
Expand All @@ -81,10 +84,13 @@
public class ApplyCandidateAction {
public static final Path STANDALONE_STARTUP_MARKER = Path.of("standalone", "tmp", "startup-marker");
public static final Path DOMAIN_STARTUP_MARKER = Path.of("domain", "tmp", "startup-marker");
public static final String CANDIDATE_CHANNEL_NAME_LIST = "candidate_properties.yaml";
private final Path updateDir;
private final Path installationDir;
private final SystemPaths systemPaths;

private static final Logger log = Logger.getLogger(ApplyCandidateAction.class);

public enum Type {
UPDATE("UPDATE"), REVERT("REVERT"), FEATURE_ADD("FEATURE_ADD");

Expand Down Expand Up @@ -280,10 +286,14 @@ public UpdateSet findUpdates() throws OperationException {
candidateMap.put(artifact.getGroupId() + ":" + artifact.getArtifactId(), artifact);
}
List<ArtifactChange> changes = new ArrayList<>();

final CandidateProperties candidateProperties = readCandidateProperties();

for (String key : baseMap.keySet()) {
if (candidateMap.containsKey(key)) {
if (!baseMap.get(key).getVersion().equals(candidateMap.get(key).getVersion())) {
changes.add(ArtifactChange.updated(baseMap.get(key), candidateMap.get(key)));
final String updateChannelName = candidateProperties.getUpdateChannel(key);
changes.add(ArtifactChange.updated(baseMap.get(key), candidateMap.get(key), updateChannelName));
}
} else {
changes.add(ArtifactChange.removed(baseMap.get(key)));
Expand All @@ -299,6 +309,21 @@ public UpdateSet findUpdates() throws OperationException {
return new UpdateSet(changes);
}

private CandidateProperties readCandidateProperties() {
final Path candidatePropertiesPath = updateDir
.resolve(ProsperoMetadataUtils.METADATA_DIR).resolve(CANDIDATE_CHANNEL_NAME_LIST);
if (Files.exists(candidatePropertiesPath)) {
try {
return CandidatePropertiesParser.read(candidatePropertiesPath);
} catch (IOException | MetadataException e) {
ProsperoLogger.ROOT_LOGGER.unableToReadChannelNames(candidatePropertiesPath.toString(), e);
}
}

// return default properties if not able to read the file
return new CandidateProperties(Collections.emptyList());
}

/**
* returns the revision of the candidate server
* @return {@code SavedState}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.wildfly.channel.ChannelManifest;
import org.wildfly.channel.UnresolvedMavenArtifactException;
import org.wildfly.prospero.ProsperoLogger;
import org.wildfly.prospero.api.ArtifactChange;
import org.wildfly.prospero.api.InstallationMetadata;
import org.wildfly.prospero.api.SavedState;
import org.wildfly.prospero.api.exceptions.ArtifactResolutionException;
Expand All @@ -35,12 +36,18 @@
import org.wildfly.prospero.galleon.GalleonUtils;
import org.wildfly.prospero.metadata.ManifestVersionRecord;
import org.wildfly.prospero.metadata.ManifestVersionResolver;
import org.wildfly.prospero.metadata.ProsperoMetadataUtils;
import org.wildfly.prospero.model.ProsperoConfig;
import org.wildfly.prospero.updates.CandidateProperties;
import org.wildfly.prospero.updates.CandidatePropertiesParser;
import org.wildfly.prospero.updates.MarkerFile;
import org.wildfly.prospero.updates.UpdateSet;
import org.wildfly.prospero.wfchannel.MavenSessionManager;

import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

Expand All @@ -59,11 +66,29 @@ class PrepareCandidateAction implements AutoCloseable{

boolean buildCandidate(Path targetDir, GalleonEnvironment galleonEnv, ApplyCandidateAction.Type operation,
ProvisioningConfig config) throws ProvisioningException, OperationException {
return this.buildCandidate(targetDir, galleonEnv, operation, config, new UpdateSet(Collections.emptyList()));
}

/**
* Builds an update/revert candidate server in {@code targetDir}.
*
* @param targetDir
* @param galleonEnv
* @param operation
* @param config
* @param updateSet
* @return
* @throws ProvisioningException
* @throws OperationException
*/
boolean buildCandidate(Path targetDir, GalleonEnvironment galleonEnv, ApplyCandidateAction.Type operation,
ProvisioningConfig config, UpdateSet updateSet) throws ProvisioningException, OperationException {
doBuildUpdate(targetDir, galleonEnv, config);

try {
final SavedState savedState = metadata.getRevisions().get(0);
new MarkerFile(savedState.getName(), operation).write(targetDir);
writeCandidateProperties(updateSet, targetDir);
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -115,4 +140,24 @@ private void writeProsperoMetadata(Path home, ChannelManifest manifest, List<Cha
installationMetadata.recordProvision(true, false);
}
}

private void writeCandidateProperties(UpdateSet updateSet, Path installationDir) {
final List<CandidateProperties.ComponentUpdate> updates = new ArrayList<>();

for (ArtifactChange artifactChange : updateSet.getArtifactUpdates()) {
final String[] gaSplit = artifactChange.getArtifactName().split(":");
if (artifactChange.getChannelName().isPresent()) {
updates.add(new CandidateProperties.ComponentUpdate(gaSplit[0], gaSplit[1], artifactChange.getChannelName().get()));
}
}

final Path candidateFile = installationDir.resolve(ProsperoMetadataUtils.METADATA_DIR).resolve(ApplyCandidateAction.CANDIDATE_CHANNEL_NAME_LIST);
try {
CandidatePropertiesParser.write(new CandidateProperties(updates), candidateFile);
ProsperoLogger.ROOT_LOGGER.channelNamesWrittenToFile(candidateFile.toFile().getAbsolutePath());
} catch (IOException e) {
ProsperoLogger.ROOT_LOGGER.unableToWriteChannelNamesToFile(candidateFile.toFile().getAbsolutePath(),e);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ public boolean buildUpdate(Path targetDir) throws ProvisioningException, Operati
InstallFolderUtils.verifyIsWritable(targetDir);
}

if (findUpdates().isEmpty()) {
final UpdateSet updateSet = findUpdates();
if (updateSet.isEmpty()) {
ProsperoLogger.ROOT_LOGGER.noUpdatesFound(installDir);
return false;
}
Expand All @@ -122,7 +123,7 @@ public boolean buildUpdate(Path targetDir) throws ProvisioningException, Operati
final ProvisioningConfig provisioningConfig = ProvisioningXmlParser.parse(PathsUtils.getProvisioningXml(installDir));

final boolean result = prepareCandidateAction.buildCandidate(targetDir, galleonEnv,
ApplyCandidateAction.Type.UPDATE, provisioningConfig);
ApplyCandidateAction.Type.UPDATE, provisioningConfig, updateSet);
ProsperoLogger.ROOT_LOGGER.updateCandidateCompleted(targetDir);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@
import java.util.Optional;

public class ArtifactChange extends Diff {
private final String channelName;

public static ArtifactChange added(Artifact newVersion) {
Objects.requireNonNull(newVersion);
return new ArtifactChange(toGav(newVersion), null, newVersion.getVersion());
}
public static ArtifactChange added(Artifact newVersion, String channelName) {
Objects.requireNonNull(newVersion);
return new ArtifactChange(toGav(newVersion), null, newVersion.getVersion(), channelName);
}

public static ArtifactChange removed(Artifact oldVersion) {
Objects.requireNonNull(oldVersion);
Expand All @@ -39,9 +45,19 @@ public static ArtifactChange updated(Artifact oldVersion, Artifact newVersion) {
Objects.requireNonNull(newVersion);
return new ArtifactChange(toGav(oldVersion), oldVersion.getVersion(), newVersion.getVersion());
}
public static ArtifactChange updated(Artifact oldVersion, Artifact newVersion, String channelName) {
Objects.requireNonNull(oldVersion);
Objects.requireNonNull(newVersion);
return new ArtifactChange(toGav(oldVersion), oldVersion.getVersion(), newVersion.getVersion(), channelName);
}

private ArtifactChange(String gav, String oldVersion, String newVersion) {
this(gav, oldVersion, newVersion, null);
}

private ArtifactChange(String gav, String oldVersion, String newVersion, String channelName) {
super(gav, oldVersion, newVersion);
this.channelName = channelName;
}

@SuppressWarnings("OptionalGetWithoutIsPresent")
Expand All @@ -54,6 +70,10 @@ public Optional<String> getOldVersion() {
return getOldValue();
}

public Optional<String> getChannelName() {
return Optional.ofNullable(channelName);
}

public Optional<String> getNewVersion() {
return getNewValue();
}
Expand Down Expand Up @@ -89,6 +109,7 @@ public boolean isUpdated() {
}

public String prettyPrint() {
return String.format("[%s] %s %s ==> %s", getStatus(), getName().orElse(""), getOldValue().orElse("[]"), getNewValue().orElse("[]"));
return String.format("[%s] %s %s ==> %s @ %s", getStatus(), getName().orElse(""), getOldValue().orElse("[]"),
getNewValue().orElse("[]"), getChannelName().orElse("Unknown"));
}
}
Loading

0 comments on commit 68730f9

Please sign in to comment.