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

[WFMP-246] Ensure the serverConfig parameter sets the server configu… #489

Merged
merged 1 commit into from
Mar 15, 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 @@ -13,7 +13,9 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
Expand All @@ -22,6 +24,7 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.wildfly.plugin.common.PropertyNames;
import org.wildfly.plugin.core.Constants;

/**
* Build (and push) an application image containing the provisioned server and the deployment.
Expand Down Expand Up @@ -217,13 +220,27 @@ private void generateDockerfile(String runtimeImage, Path targetDir, String wild
}

String targetName = getDeploymentTargetName();
Files.writeString(targetDir.resolve("Dockerfile"),
"FROM " + runtimeImage + "\n" +
"COPY --chown=jboss:root " + jbossHome + " $JBOSS_HOME\n" +
"RUN chmod -R ug+rwX $JBOSS_HOME\n" +
"COPY --chown=jboss:root " + getDeploymentContent().getFileName()
+ " $JBOSS_HOME/standalone/deployments/" + targetName,
StandardCharsets.UTF_8);

// Create the Dockerfile content
final StringBuilder dockerfileContent = new StringBuilder();
dockerfileContent.append("FROM ").append(runtimeImage).append('\n')
.append("COPY --chown=jboss:root ").append(jbossHome).append(" $JBOSS_HOME\n")
.append("RUN chmod -R ug+rwX $JBOSS_HOME\n")
.append("COPY --chown=jboss:root ").append(getDeploymentContent().getFileName())
.append(" $JBOSS_HOME/standalone/deployments/").append(targetName);

final List<String> serverArgs = new ArrayList<>();
if (!layers.isEmpty() && !layersConfigurationFileName.equals(Constants.STANDALONE_XML)) {
serverArgs.add("-c=" + layersConfigurationFileName);
} else if (!serverConfig.equals(Constants.STANDALONE_XML)) {
serverArgs.add("-c=" + serverConfig);
}

if (!serverArgs.isEmpty()) {
dockerfileContent.append('\n').append("ENV SERVER_ARGS=\"").append(String.join(",", serverArgs)).append('"');
}

Files.writeString(targetDir.resolve("Dockerfile"), dockerfileContent, StandardCharsets.UTF_8);
}

private boolean isImageBinaryAvailable(String imageBinary) {
Expand Down
36 changes: 36 additions & 0 deletions plugin/src/main/java/org/wildfly/plugin/provision/ExecUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

import org.apache.maven.plugin.logging.Log;
import org.wildfly.plugin.tools.ConsoleConsumer;

public class ExecUtil {

Expand Down Expand Up @@ -58,6 +60,18 @@ public static boolean exec(Log log, String command, String... args) {
return exec(log, new File("."), command, args);
}

/**
* Execute the specified command from within the current directory.
*
* @param out the output stream used to consume the console output
* @param command The command
* @param args The command arguments
* @return true if commands where executed successfully
*/
public static boolean exec(final OutputStream out, String command, String... args) {
return exec(out, new File("."), command, args);
}

/**
* Execute silently the specified command until the given timeout from within the current directory.
*
Expand Down Expand Up @@ -91,6 +105,28 @@ public static boolean exec(Log log, File directory, String command,
}
}

/**
* Execute the specified command from within the specified directory.
* The method allows specifying an output filter that processes the command output.
*
* @param out the output stream used to consume the console output
* @param directory The directory
* @param command The command
* @param args The command arguments
* @return true if commands where executed successfully
*/
public static boolean exec(final OutputStream out, final File directory, final String command,
final String... args) {
try {
Process process = startProcess(directory, command, args);
ConsoleConsumer.start(process.getInputStream(), out);
process.waitFor();
return process.exitValue() == 0;
} catch (InterruptedException e) {
return false;
}
}

/**
* Execute the specified command until the given timeout from within the specified directory.
* The method allows specifying an output filter that processes the command output.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,12 @@ public class PackageServerMojo extends AbstractProvisionServerMojo {
* deployment. Defaults to 'standalone.xml'. If {@code layers-configuration-file-name} has been set,
* this property is ignored and the deployment is deployed inside the configuration referenced from
* {@code layers-configuration-file-name}.
* <p>
* The value of this parameter is also ignored if any layers are defined.
* </p>
*/
@Parameter(property = PropertyNames.SERVER_CONFIG, alias = "server-config", defaultValue = STANDALONE_XML)
private String serverConfig;
String serverConfig;

/**
* Specifies the name used for the deployment.
Expand Down
16 changes: 16 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
<version.junit.junit>4.13.2</version.junit.junit>
<version.org.mockito.mockito>5.10.0</version.org.mockito.mockito>

<!-- Test only dependencies -->
<version.jakarta.json-api>2.1.3</version.jakarta.json-api>
<version.org.eclipse.parsson>1.1.5</version.org.eclipse.parsson>

<!-- Require at least Java 11 to compile -->
<jdk.min.version>11</jdk.min.version>
<maven.compiler.target>11</maven.compiler.target>
Expand Down Expand Up @@ -427,6 +431,18 @@
<version>${version.org.wildfly.glow}</version>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>${version.jakarta.json-api}</version>
<scope>test</scope>
</dependency>
<dependency> <!-- json-p ri -->
<groupId>org.eclipse.parsson</groupId>
<artifactId>parsson</artifactId>
<version>${version.org.eclipse.parsson}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.galleon</groupId>
<artifactId>galleon-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,33 +125,37 @@ protected MavenSession newMavenSession(MavenProject project) {
}

protected Mojo lookupConfiguredMojo(File pom, String goal) throws Exception {
return lookupConfiguredMojo(pom.toPath(), goal);
}

protected Mojo lookupConfiguredMojo(final Path pom, final String goal) throws Exception {
assertNotNull(pom);
assertTrue(pom.exists());
assertTrue(Files.exists(pom));
patchPomFile(pom);
ProjectBuildingRequest buildingRequest = newMavenSession().getProjectBuildingRequest();
// Need to resolve artifacts for tests that upgrade server components
buildingRequest.setResolveDependencies(true);
ProjectBuilder projectBuilder = lookup(ProjectBuilder.class);
MavenProject project = projectBuilder.build(pom, buildingRequest).getProject();
MavenProject project = projectBuilder.build(pom.toFile(), buildingRequest).getProject();

Mojo mojo = lookupConfiguredMojo(project, goal);

// For some reasons, the configuration item gets ignored in lookupConfiguredMojo
// explicitly configure it
configureMojo(mojo, artifactId, pom);
configureMojo(mojo, artifactId, pom.toFile());

return mojo;
}

private void patchPomFile(File pom) throws IOException {
private void patchPomFile(final Path pom) throws IOException {
StringBuilder content = new StringBuilder();
for (String s : Files.readAllLines(pom.toPath())) {
for (String s : Files.readAllLines(pom)) {
if (s.contains(TEST_REPLACE_WF_VERSION)) {
s = s.replace(TEST_REPLACE_WF_VERSION, System.getProperty(WILDFLY_VERSION));
}
content.append(s).append(System.lineSeparator());
}
Files.write(pom.toPath(), content.toString().getBytes());
Files.write(pom, content.toString().getBytes());
}

@Before
Expand Down
22 changes: 22 additions & 0 deletions tests/standalone-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@
<artifactId>maven-resolver-util</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<scope>test</scope>
</dependency>
<dependency> <!-- json-p ri -->
<groupId>org.eclipse.parsson</groupId>
<artifactId>parsson</artifactId>
<scope>test</scope>
</dependency>

<!-- to fix slf4j warning when provisioning -->
<dependency>
Expand All @@ -96,6 +106,18 @@
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Some tests cannot run more than one MOJO invocation in the same JVM. Some of the configuration
settings, for some reason, do not get reset. For example, in the image tests, the provisioningDir
property is always set to the first one that is executed. For this reason, we need to launch
each test in a new JVM. -->
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/
package org.wildfly.plugin.provision;

import static org.junit.Assume.assumeNotNull;
import static org.wildfly.plugin.tests.AbstractWildFlyMojoTest.getPomFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonString;
import jakarta.json.JsonStructure;
import jakarta.json.JsonValue;
import jakarta.json.JsonWriter;
import jakarta.json.JsonWriterFactory;
import jakarta.json.stream.JsonGenerator;

import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.logging.Log;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.wildfly.plugin.tests.AbstractProvisionConfiguredMojoTestCase;
import org.wildfly.plugin.tests.AbstractWildFlyMojoTest;

abstract class AbstractImageTest extends AbstractProvisionConfiguredMojoTestCase {

public AbstractImageTest() {
super("wildfly-maven-plugin");
}

@BeforeClass
public static void checkDockerInstallation() {
assumeNotNull("Docker is not present in the installation, skipping the tests",
ExecUtil.resolveImageBinary());
}

protected void assertConfigFileName(final String prefix, final String expectedEnvVar) throws Exception {
final String imageName = "wildfly-" + prefix + "-maven-plugin/testing";
final String binary = ExecUtil.resolveImageBinary();
try {
final Mojo imageMojo = lookupConfiguredMojo(getPomFile(prefix + "-pom.xml"), "image");
imageMojo.execute();
final Path jbossHome = AbstractWildFlyMojoTest.getBaseDir().resolve("target").resolve(prefix);
assertTrue(Files.exists(jbossHome));

final ByteArrayOutputStream stdout = new ByteArrayOutputStream();
assertTrue(ExecUtil.exec(stdout, binary, "inspect", imageName));
assertEnvironmentSet(stdout, expectedEnvVar);

} finally {
exec(binary, "rmi", imageName);
}
}

protected static boolean exec(String command, String... args) {
return ExecUtil.exec((Log) null, new File("."), command, args);
}

protected static String formatJson(final JsonStructure json) throws IOException {
try (StringWriter writer = new StringWriter()) {
JsonWriterFactory factory = Json.createWriterFactory(Map.of(JsonGenerator.PRETTY_PRINTING, true));
try (JsonWriter jsonWriter = factory.createWriter(writer)) {
jsonWriter.write(json);
return writer.toString();
}
}
}

protected static void assertEnvironmentSet(final ByteArrayOutputStream stdout, final String expectedEnvVar) {
assertEnvironment(stdout, expectedEnvVar, true);
}

protected static void assertEnvironmentUnset(final ByteArrayOutputStream stdout, final String expectedEnvVar) {
assertEnvironment(stdout, expectedEnvVar, false);
}

private static void assertEnvironment(final ByteArrayOutputStream stdout, final String expectedEnvVar,
final boolean isSet) {

try (JsonReader reader = Json.createReader(new ByteArrayInputStream(stdout.toByteArray()))) {
final JsonArray array = reader.readArray();
Assert.assertFalse("Array was not expected to be empty: " + array, array.isEmpty());
final JsonObject json = array.getJsonObject(0);
final JsonObject config = json.getJsonObject("Config");
final JsonArray env = config.getJsonArray("Env");
boolean found = false;
for (JsonValue value : env) {
Assert.assertEquals(String.format("JSON value %s is not a string type: %s", value, value.getValueType()),
JsonValue.ValueType.STRING, value.getValueType());
if (((JsonString) value).getString().contains(expectedEnvVar)) {
found = true;
break;
}
}
if (isSet && !found) {
Assert.fail(
String.format("Failed to find %s in environment.%n%s", expectedEnvVar, formatJson(env)));
}
if (!isSet && found) {
Assert.fail(
String.format("Found %s in environment and it should not exist.%n%s", expectedEnvVar, formatJson(env)));
}
} catch (Exception e) {
Assert.fail(String.format("Output from inspect is not valid JSON: %s%nOutput:%n%s", e.getMessage(), stdout));
}
}
}
Loading