Skip to content

Commit

Permalink
[WFCORE-6503]:Add support for unmanaged deployments with YAML extension.
Browse files Browse the repository at this point in the history
* checking that the YAML deployment is unmanaged.
* adding the unmanaged deployment to the list of operations
* adding some light esting on this

Jira: https://issues.redhat.com/browse/WFCORE-6503
Proposal: wildfly/wildfly-proposals#554

Signed-off-by: Emmanuel Hugonnet <[email protected]>
  • Loading branch information
ehsavoie committed Feb 14, 2024
1 parent 0f80581 commit 9991522
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3752,4 +3752,7 @@ OperationFailedRuntimeException capabilityAlreadyRegisteredInContext(String capa

@Message(id = 504, value = "The operation %s is not defined for resource %s.")
UnsupportedOperationException missingOperationForResource(String op, String address);

@Message(id = 505, value = "Unsuported deployment yaml file %s with attributes %s")
IllegalArgumentException unsupportedDeployment(String deployment, Set<String> attribues);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@

import static org.jboss.as.controller.client.impl.AdditionalBootCliScriptInvoker.CLI_SCRIPT_PROPERTY;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.BYTES;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DEPLOYMENT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.EMPTY;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HASH;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INPUT_STREAM_INDEX;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.UNDEFINE_ATTRIBUTE_OPERATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.URL;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.WRITE_ATTRIBUTE_OPERATION;
import static org.jboss.as.controller.logging.ControllerLogger.MGMT_OP_LOGGER;
Expand All @@ -27,6 +33,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
Expand Down Expand Up @@ -74,7 +81,9 @@ public class YamlConfigurationExtension implements ConfigurationExtension {
private boolean needReload;
private Path[] files;
private final List<Map<String, Object>> configs = new ArrayList<>();
private static final String[] EXCLUDED_ELEMENTS = {" deployment", "extension", "deployment-overlay"};
private final Map<String, Object> deployments = new LinkedHashMap<>();
private static final String[] EXCLUDED_ELEMENTS = {"deployment", "extension", "deployment-overlay"};
public static final Set<String> MANAGED_CONTENT_ATTRIBUTES = Set.of(INPUT_STREAM_INDEX, HASH, BYTES, URL, EMPTY);

@SuppressWarnings("unchecked")
public YamlConfigurationExtension() {
Expand Down Expand Up @@ -103,7 +112,10 @@ private void load() {
if (yamlConfig.containsKey(CONFIGURATION_ROOT_KEY)) {
Map<String, Object> config = (Map<String, Object>) yamlConfig.get(CONFIGURATION_ROOT_KEY);
for (String excluded : EXCLUDED_ELEMENTS) {
config.remove(excluded);
Object value = config.remove(excluded);
if(value != null && value instanceof Map && DEPLOYMENT.equals(excluded)) {
deployments.putAll((Map<String, Object>) value);
}
}
parsedFiles.add(file.toAbsolutePath().toString());
this.configs.add(config);
Expand Down Expand Up @@ -142,6 +154,9 @@ public void processOperations(ImmutableManagementResourceRegistration rootRegist
for (Map<String, Object> config : configs) {
processResource(PathAddress.EMPTY_ADDRESS, new HashMap<>(config), rootRegistration, rootRegistration, xmlOperations, postExtensionOps, false);
}
for(Map.Entry<String, Object> deployment : deployments.entrySet()) {
processUnmanagedDeployments(rootRegistration, deployment, xmlOperations, postExtensionOps);
}
this.configs.clear();
needReload = true;
}
Expand Down Expand Up @@ -468,6 +483,22 @@ public String getCommandLineInstructions() {
return MGMT_OP_LOGGER.argYaml();
}

private void processUnmanagedDeployments(ImmutableManagementResourceRegistration rootRegistration, Map.Entry<String, Object> deployment, Map<PathAddress, ParsedBootOp> xmlOperations, List<ParsedBootOp> postExtensionOps) {
String name = deployment.getKey();
OperationEntry operationEntry = rootRegistration.getOperationEntry(PathAddress.pathAddress("deployment", name), ADD);
if (deployment.getValue() != null && deployment.getValue() instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> attributes = (Map<String, Object>) deployment.getValue();
Map<String, Object> content = (Map<String, Object>) (((Iterable<? extends Object>)attributes.get("content")).iterator().next());
Set<String> result = content.keySet().stream().distinct().filter(MANAGED_CONTENT_ATTRIBUTES::contains).collect(Collectors.toSet());
if (!result.isEmpty()) {
throw MGMT_OP_LOGGER.unsupportedDeployment(name, result);
}
PathAddress address = PathAddress.pathAddress(DEPLOYMENT, name);
processAttributes(address, rootRegistration, operationEntry, attributes, postExtensionOps);
}
}

private interface Operation {
void processOperation(ImmutableManagementResourceRegistration rootRegistration, Map<PathAddress, ParsedBootOp> xmlOperations, List<ParsedBootOp> postExtensionOps, PathAddress address, String name);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@
package org.jboss.as.test.manualmode.management.persistence;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ARCHIVE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CONTENT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PATH;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RELATIVE_TO;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RUNNING_MODE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RUNTIME_NAME;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import jakarta.inject.Inject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardOpenOption;
import java.util.Iterator;
import java.util.regex.Pattern;
import org.jboss.as.controller.PathAddress;
Expand All @@ -23,6 +33,10 @@
import org.jboss.as.test.integration.management.util.CLIWrapper;
import org.jboss.as.test.shared.TimeoutUtil;
import org.jboss.dmr.ModelNode;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
Expand Down Expand Up @@ -51,8 +65,11 @@ public class YamlExtensionTestCase {
@Inject
private ServerController container;

private static final Path basedir = new File(WildFlySecurityManager.getPropertyPrivileged("jboss.home", "toto")).toPath().resolve("standalone");
private static Path markerDirectory;
private static Path testYaml;
private static Path testDeploymentYaml;
private static Path testManagedDeploymentYaml;
private static Path cliScript;
private static String expectedXml;
private static String expectedBootCLiXml;
Expand All @@ -61,7 +78,7 @@ public class YamlExtensionTestCase {
@BeforeClass
public static void setup() throws Exception {
Assume.assumeTrue("Layer testing provides a different XML file than the standard one which results in failures", System.getProperty("ts.layers") == null);
Path configurationDir = new File(WildFlySecurityManager.getPropertyPrivileged("jboss.home", "toto")).toPath().resolve("standalone").resolve("configuration");
Path configurationDir = basedir.resolve("configuration");
Path referenceConfiguration = configurationDir.resolve("reference-standalone.xml");
Files.copy(configurationDir.resolve("standalone.xml"), referenceConfiguration, REPLACE_EXISTING);
try (CLIWrapper cli = new CLIWrapper(false)) {
Expand All @@ -74,8 +91,8 @@ public static void setup() throws Exception {
}
Path referenceCliConfiguration = configurationDir.resolve("reference-cli-standalone.xml");
Files.copy(configurationDir.resolve("standalone.xml"), referenceCliConfiguration, REPLACE_EXISTING);
Files.copy(new File(YamlExtensionTestCase.class.getResource("bootable-groups.properties").toURI()).toPath(),configurationDir.resolve("bootable-groups.properties"), REPLACE_EXISTING);
Files.copy(new File(YamlExtensionTestCase.class.getResource("bootable-users.properties").toURI()).toPath(),configurationDir.resolve("bootable-users.properties"), REPLACE_EXISTING);
Files.copy(new File(YamlExtensionTestCase.class.getResource("bootable-groups.properties").toURI()).toPath(), configurationDir.resolve("bootable-groups.properties"), REPLACE_EXISTING);
Files.copy(new File(YamlExtensionTestCase.class.getResource("bootable-users.properties").toURI()).toPath(), configurationDir.resolve("bootable-users.properties"), REPLACE_EXISTING);
try (CLIWrapper cli = new CLIWrapper(false)) {
cli.sendLine("embed-server --admin-only --server-config=reference-cli-standalone.xml");
cli.sendLine("/system-property=foo:add(value=bar)");
Expand All @@ -88,6 +105,9 @@ public static void setup() throws Exception {
cli.quit();
}
testYaml = new File(YamlExtensionTestCase.class.getResource("test.yml").toURI()).toPath().toAbsolutePath();
testDeploymentYaml = new File(YamlExtensionTestCase.class.getResource("test-deployment.yml").toURI()).toPath().toAbsolutePath();
testManagedDeploymentYaml = new File(YamlExtensionTestCase.class.getResource("test-managed-deployment.yml").toURI()).toPath().toAbsolutePath();
createDeployment(configurationDir.getParent().resolve("test.jar"));
cliScript = new File(YamlExtensionTestCase.class.getResource("test.cli").toURI()).toPath().toAbsolutePath();
expectedXml = loadFile(referenceConfiguration).replace("\"", "'");
expectedBootCLiXml = loadFile(referenceCliConfiguration).replace("\"", "'");
Expand Down Expand Up @@ -138,6 +158,60 @@ public void testSimpleYaml() throws URISyntaxException, Exception {
}
}

@Test
public void testDeploymentYaml() throws URISyntaxException, Exception {
try {
container.startYamlExtension(new Path[]{testDeploymentYaml});
try (ModelControllerClient client = container.getClient().getControllerClient()) {
ModelNode deployment = readDeployment(client, "test.jar");
Assert.assertEquals("test.jar", deployment.get(NAME).asString());
Assert.assertEquals("test.jar", deployment.get(RUNTIME_NAME).asString());
ModelNode contentItemNode = deployment.get(CONTENT).get(0);
Assert.assertEquals("test.jar", contentItemNode.get(PATH).asString());
Assert.assertEquals("jboss.server.base.dir", contentItemNode.get(RELATIVE_TO).asString());
Assert.assertEquals(true, contentItemNode.get(ARCHIVE).asBoolean());
deployment = readDeployment(client, "hello.jar");
Assert.assertEquals("hello.jar", deployment.get(NAME).asString());
Assert.assertEquals("hello.jar", deployment.get(RUNTIME_NAME).asString());
contentItemNode = deployment.get(CONTENT).get(0);
Assert.assertEquals("test.jar", contentItemNode.get(PATH).asString());
Assert.assertEquals("jboss.server.base.dir", contentItemNode.get(RELATIVE_TO).asString());
Assert.assertEquals(true, contentItemNode.get(ARCHIVE).asBoolean());
}
} finally {
container.stop();
}
}

/**
* Managed deployments are not supported. We should fail
*
* @throws URISyntaxException
* @throws Exception
*/
@Test
public void testFailedDeploymentYaml() throws URISyntaxException, Exception {
try {
container.startYamlExtension(new Path[]{testManagedDeploymentYaml});
Assert.assertFalse(container.isStarted());
} catch (RuntimeException ex) {
Assert.assertFalse(container.isStarted());
try (final BufferedReader reader = Files.newBufferedReader(basedir.resolve("log").resolve("server.log"), StandardCharsets.UTF_8)) {
Assert.assertTrue(reader.lines().anyMatch(line -> line.contains("WFLYCTL0505: Unsuported deployment yaml file hello.jar with attributes [empty]")));
}
} finally {
container.stop();
}
}

private static void createDeployment(Path deployment) throws IOException {
final JavaArchive archive = ShrinkWrap.create(JavaArchive.class);
archive.add(new StringAsset("Dependencies: =org.jboss.modules"), "META-INF/MANIFEST.MF");
try (OutputStream out = Files.newOutputStream(deployment, StandardOpenOption.CREATE_NEW)) {
archive.as(ZipExporter.class).exportTo(out);
}
}

@Test
public void testSimpleYamlWithReload() throws URISyntaxException, Exception {
try {
Expand Down Expand Up @@ -206,7 +280,10 @@ private void compareXML(String expected, String result) {
Assert.fail("Missing line " + expectedLines[i] + " in " + System.lineSeparator() + result);
}
}
}

private ModelNode readDeployment(ModelControllerClient client, String deploymentName) throws IOException {
return Operations.readResult(client.execute(Operations.createReadResourceOperation(PathAddress.pathAddress("deployment", deploymentName).toModelNode())));
}

private String readXmlConfig() throws IOException {
Expand All @@ -218,4 +295,5 @@ private String readXmlConfig() throws IOException {
private static String removeWhiteSpaces(String line) {
return Pattern.compile("(^\\s*$\\r?\\n)+", Pattern.MULTILINE).matcher(line.stripTrailing()).replaceAll("");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
wildfly-configuration:
deployment:
test.jar:
content:
-
path: test.jar
relative-to: jboss.server.base.dir
archive: true
hello.jar:
content:
-
path: test.jar
relative-to: jboss.server.base.dir
archive: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
wildfly-configuration:
deployment:
test.jar:
content:
-
path: test.jar
relative-to: jboss.server.base.dir
archive: true
hello.jar:
content:
-
empty: true

0 comments on commit 9991522

Please sign in to comment.