Skip to content

Commit

Permalink
[WFCORE-6503]: Add support for unmanaged deployments with YAML extens…
Browse files Browse the repository at this point in the history
…ion.

* checking that the YAML deployment is unmanaged.
* adding the unmanaged deployment to the list of operations
* adding some light testing on this
* fixing issue WFCORE-6857 where you couldn't enable an unmanaged
  deployment with yaml

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

Signed-off-by: Emmanuel Hugonnet <[email protected]>
  • Loading branch information
ehsavoie committed Jun 26, 2024
1 parent 98d3c35 commit b7b8cac
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@

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.REMOVE;
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 @@ -28,6 +34,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 @@ -77,7 +84,9 @@ public class YamlConfigurationExtension implements ConfigurationExtension {
private boolean needReload;
private Path[] files;
private final List<Map<String, Object>> configs = new ArrayList<>();
private final Map<String, Object> deployments = new LinkedHashMap<>();
private static final String[] EXCLUDED_ELEMENTS = {"deployment", "extension", "deployment-overlay", "path"};
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 @@ -114,11 +123,15 @@ private void load() {
boolean isPresent = config.containsKey(excluded);
if (isPresent) {
Object value = config.remove(excluded);
String message = MGMT_OP_LOGGER.ignoreYamlElement(excluded);
if (value != null) {
message = message + MGMT_OP_LOGGER.ignoreYamlSubElement(yaml.dump(value).trim());
if (value instanceof Map && DEPLOYMENT.equals(excluded)) {
deployments.putAll((Map<String, Object>) value);
} else {
String message = MGMT_OP_LOGGER.ignoreYamlElement(excluded);
if (value != null) {
message = message + MGMT_OP_LOGGER.ignoreYamlSubElement(yaml.dump(value).trim());
}
MGMT_OP_LOGGER.warn(message);
}
MGMT_OP_LOGGER.warn(message);
}
}
parsedFiles.add(file.toAbsolutePath().toString());
Expand Down Expand Up @@ -160,6 +173,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 @@ -395,16 +411,25 @@ private void processAttribute(PathAddress address, ImmutableManagementResourceRe
@SuppressWarnings("unchecked")
private void processAttributes(PathAddress address, ImmutableManagementResourceRegistration rootRegistration, OperationEntry operationEntry, Map<String, Object> map, List<ParsedBootOp> postExtensionOps, Map<PathAddress, ParsedBootOp> xmlOperations) {
Set<AttributeDefinition> attributes = new HashSet<>();
Set<String> attributeNames = new HashSet<>();
for (AttributeAccess attributeAccess : rootRegistration.getAttributes(address).values()) {
if (attributeAccess.getStorageType() == AttributeAccess.Storage.CONFIGURATION) {
AttributeDefinition def = attributeAccess.getAttributeDefinition();
if (def != null) {
if (!def.isResourceOnly()) {
attributes.add(def);
attributeNames.add(def.getName());
}
}
}
}
for (AttributeDefinition def : operationEntry.getOperationDefinition().getParameters()) {
if (def != null && ! attributeNames.contains(def.getName())) {
if (!def.isResourceOnly()) {
attributes.add(def);
}
}
}
attributes.addAll(Arrays.asList(operationEntry.getOperationDefinition().getParameters()));
ModelNode op = createOperation(address, operationEntry);
if (map != null) {
Expand Down Expand Up @@ -524,6 +549,23 @@ public String getCommandLineInstructions() {
return MGMT_OP_LOGGER.argYaml();
}

@SuppressWarnings("unchecked")
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);
assert deployment.getValue() instanceof Map;
Map<String, Object> attributes = (Map<String, Object>) deployment.getValue();
if (attributes.get("content") instanceof Iterable) {
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, xmlOperations);
}

private interface Operation {

String getOperationName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,6 @@ public ServerEnvironment(final String hostControllerName, final Properties props
javaExtDirs = getFilesFromProperty(JAVA_EXT_DIRS, props);

if (launchType.equals(LaunchType.SELF_CONTAINED)) {
Path[] supplementalConfigurationFiles = findSupplementalConfigurationFiles(null, supplementalConfiguration);
ConfigurationExtension configurationExtension = ConfigurationExtensionFactory.createConfigurationExtension(supplementalConfigurationFiles);
if (configurationExtension != null) {
configInteractionPolicy = configurationExtension.shouldProcessOperations(runningModeControl) ? ConfigurationFile.InteractionPolicy.READ_ONLY : configInteractionPolicy;
}
homeDir = new File(WildFlySecurityManager.getPropertyPrivileged("user.dir", "."));
serverBaseDir = new File(WildFlySecurityManager.getPropertyPrivileged("user.dir", "."));
serverLogDir = new File(WildFlySecurityManager.getPropertyPrivileged("user.dir", "."));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.hamcrest.MatcherAssert.assertThat;
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.ENABLED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME;
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.RESULT;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RUNNING_MODE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RUNTIME_NAME;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.UUID;

Expand Down Expand Up @@ -145,6 +152,8 @@ public static void setup() throws Exception {
testRemoveSocketYaml = getResourceFilePath("test-remove-socket.yml");
testAddingExtensionPathDeploymentOverlayIgnored = getResourceFilePath("test-adding-extension-path-deployment-overlay-ignored.yml");
testAddingEmptyExtensionFailYaml = getResourceFilePath("test-adding-empty-extension.yml");
testDeploymentYaml = getResourceFilePath("test-deployment.yml");
testManagedDeploymentYaml = getResourceFilePath("test-managed-deployment.yml");
testReplacingByEmptyResourceYaml = getResourceFilePath("test-replacing-by-empty-resource.yml");
testWrongIndentationYaml = getResourceFilePath("test-indentation-wrong.yml");
testNonExistentAttributeYaml = getResourceFilePath("test-setting-non-existent-attribute.yml");
Expand All @@ -154,6 +163,7 @@ public static void setup() throws Exception {
testRemoveNonExistentResource = getResourceFilePath("test-remove-non-existent-resource.yml");
testListAddOperationToStringFails = getResourceFilePath("test-list-add-operation-to-string-fails.yml");
testListAddOperationToNonExistentResourceFails = getResourceFilePath("test-list-add-operation-to-non-existent-resource.yml");
createDeployment(configurationDir.getParent().resolve("test.jar"));
cliScript = getResourceFilePath("test.cli");
defaultXml = loadFile(configurationDir.resolve("standalone.xml")).replace("\"", "'");
expectedXml = loadFile(referenceConfiguration).replace("\"", "'");
Expand Down Expand Up @@ -248,6 +258,41 @@ public void testEmptyExtensionInYamlLogsWarnings() throws Exception {
assertThat("Information that adding path is ignored is missing in log.", byteArrayOutputStream.toString(), CoreMatchers.containsString("WFLYCTL0508: The yaml element 'extension' and its sub-elements are ignored."));
}

@Test
public void testDeploymentYaml() throws Exception {
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());
Assert.assertEquals("true", deployment.get(ENABLED).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.assertTrue(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.assertTrue(contentItemNode.get(ARCHIVE).asBoolean());
}
}

/**
* Managed deployments are not supported. We should fail
*/
@Test
public void testServerStartFailedForManagedDeployment() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
container.startYamlExtension(new PrintStream(byteArrayOutputStream), new Path[]{testManagedDeploymentYaml});
Assert.assertFalse(container.isStarted());
} catch (RuntimeException ex) {
Assert.assertFalse(container.isStarted());
}
}

private static void createDeployment(Path deployment) throws IOException {
final JavaArchive archive = ShrinkWrap.create(JavaArchive.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
wildfly-configuration:
deployment:
test.jar:
content:
-
path: test.jar
relative-to: jboss.server.base.dir
archive: true
enabled: 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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ wildfly-configuration:
standard-sockets:
socket-binding:
management-https: !remove

subsystem:
elytron:
disallowed-providers: !undefine
Expand Down

0 comments on commit b7b8cac

Please sign in to comment.