From 5d5d8d5aa91d329d368c3a3d98e49b4a7d5cec02 Mon Sep 17 00:00:00 2001 From: "James R. Perkins" Date: Tue, 19 Dec 2023 08:46:05 -0800 Subject: [PATCH] [WFMP-231] Migrate to using the wildfly-plugin-tools. Remove the utilities migrated to the new project. https://issues.redhat.com/browse/WFMP-231 Signed-off-by: James R. Perkins --- core/README.adoc | 106 +- core/pom.xml | 139 +-- .../org/wildfly/plugin/core/Assertions.java | 49 - .../wildfly/plugin/core/ConsoleConsumer.java | 79 -- .../org/wildfly/plugin/core/Constants.java | 12 +- .../plugin/core/ContainerDescription.java | 53 - .../core/DefaultContainerDescription.java | 119 -- .../plugin/core/DefaultDeploymentManager.java | 532 -------- .../org/wildfly/plugin/core/Deployment.java | 305 ----- .../plugin/core/DeploymentContent.java | 206 ---- .../plugin/core/DeploymentDescription.java | 31 - .../plugin/core/DeploymentException.java | 43 - .../plugin/core/DeploymentManager.java | 315 ----- .../plugin/core/DeploymentOperations.java | 449 ------- .../wildfly/plugin/core/DeploymentResult.java | 111 -- .../org/wildfly/plugin/core/GalleonUtils.java | 251 ---- .../plugin/core}/MavenJBossLogger.java | 2 +- .../core/OperationExecutionException.java | 84 -- .../plugin/core/PluginProgressTracker.java | 80 -- .../org/wildfly/plugin/core/ServerHelper.java | 477 -------- .../core/SimpleDeploymentDescription.java | 136 --- .../plugin/core/UndeployDescription.java | 196 --- .../java/org/wildfly/plugin/core/Utils.java | 47 - .../bootablejar/BootLoggingConfiguration.java | 1071 ----------------- .../core/bootablejar/BootableJarSupport.java | 219 ---- .../plugins/core/bootablejar/Expression.java | 221 ---- .../core/bootablejar/ScannedArtifacts.java | 48 - .../cli/CLIForkedBootConfigGenerator.java | 43 - .../wildfly/plugins/core/cli/CLIWrapper.java | 137 --- .../plugins/core/cli/ForkedCLIUtil.java | 140 --- core/src/main/resources/META-INF/LICENSE.txt | 202 ---- .../core/AbstractDeploymentManagerTest.java | 750 ------------ .../plugin/core/DeploymentResultTestCase.java | 98 -- .../plugin/core/DeploymentTestCase.java | 84 -- .../core/DomainDeploymentManagerIT.java | 196 --- .../org/wildfly/plugin/core/Environment.java | 126 -- .../core/StandaloneDeploymentManagerIT.java | 95 -- .../wildfly/plugin/core/common/Simple.java | 12 - .../BootLoggingConfigurationIT.java | 874 -------------- .../plugins/core/bootablejar/TestFilter.java | 86 -- .../plugins/core/bootablejar/main/module.xml | 14 - plugin/pom.xml | 6 +- .../plugin/cli/BaseCommandConfiguration.java | 26 +- .../wildfly/plugin/cli/CommandExecutor.java | 2 +- .../plugin/cli/ExecuteCommandsMojo.java | 2 +- .../wildfly/plugin/cli/LocalCLIExecutor.java | 2 +- .../plugin/cli/OfflineCommandExecutor.java | 2 +- ...venModelControllerClientConfiguration.java | 2 +- .../wildfly/plugin/common/StandardOutput.java | 2 +- .../java/org/wildfly/plugin/common/Utils.java | 2 +- .../plugin/deployment/AbstractDeployment.java | 8 +- .../plugin/deployment/DeployArtifactMojo.java | 6 +- .../wildfly/plugin/deployment/DeployMojo.java | 6 +- .../plugin/deployment/DeployOnlyMojo.java | 2 +- .../plugin/deployment/RedeployMojo.java | 6 +- .../plugin/deployment/RedeployOnlyMojo.java | 2 +- .../deployment/UndeployArtifactMojo.java | 6 +- .../plugin/deployment/UndeployMojo.java | 8 +- .../deployment/resource/AddResourceMojo.java | 2 +- .../java/org/wildfly/plugin/dev/DevMojo.java | 29 +- .../AbstractProvisionServerMojo.java | 7 +- .../plugin/provision/PackageServerMojo.java | 5 +- .../server/AbstractServerStartMojo.java | 4 +- .../org/wildfly/plugin/server/RunMojo.java | 4 +- .../wildfly/plugin/server/ShutdownMojo.java | 2 +- .../plugin/server/VersionComparator.java | 232 ---- .../plugin/server/VersionTestCase.java | 67 -- pom.xml | 8 +- .../wildfly/plugin/deployment/DeployTest.java | 6 +- .../deployment/UndeploymentMatchTest.java | 8 +- .../plugin/server/DomainTestServer.java | 6 +- .../org/wildfly/plugin/server/TestServer.java | 2 +- ...stractProvisionConfiguredMojoTestCase.java | 4 +- .../plugin/tests/AbstractWildFlyMojoTest.java | 2 +- .../tests/runner/WildFlyTestRunner.java | 2 +- .../plugin/server/ServerFunctionMojoTest.java | 2 +- .../wildfly/plugin/cli/FailOnErrorTest.java | 7 +- .../deployment/ArtifactDeploymentTest.java | 6 +- .../plugin/deployment/DeployOnlyTest.java | 4 +- .../wildfly/plugin/deployment/DeployTest.java | 4 +- .../deployment/UndeploymentMatchTest.java | 4 +- .../plugin/server/StandaloneTestServer.java | 6 +- 82 files changed, 119 insertions(+), 8632 deletions(-) delete mode 100644 core/src/main/java/org/wildfly/plugin/core/Assertions.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/ConsoleConsumer.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/ContainerDescription.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DefaultContainerDescription.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DefaultDeploymentManager.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/Deployment.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DeploymentContent.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DeploymentDescription.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DeploymentException.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DeploymentManager.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DeploymentOperations.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/DeploymentResult.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/GalleonUtils.java rename {plugin/src/main/java/org/wildfly/plugin/common => core/src/main/java/org/wildfly/plugin/core}/MavenJBossLogger.java (98%) delete mode 100644 core/src/main/java/org/wildfly/plugin/core/OperationExecutionException.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/PluginProgressTracker.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/ServerHelper.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/SimpleDeploymentDescription.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/UndeployDescription.java delete mode 100644 core/src/main/java/org/wildfly/plugin/core/Utils.java delete mode 100644 core/src/main/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfiguration.java delete mode 100644 core/src/main/java/org/wildfly/plugins/core/bootablejar/BootableJarSupport.java delete mode 100644 core/src/main/java/org/wildfly/plugins/core/bootablejar/Expression.java delete mode 100644 core/src/main/java/org/wildfly/plugins/core/bootablejar/ScannedArtifacts.java delete mode 100644 core/src/main/java/org/wildfly/plugins/core/cli/CLIForkedBootConfigGenerator.java delete mode 100644 core/src/main/java/org/wildfly/plugins/core/cli/CLIWrapper.java delete mode 100644 core/src/main/java/org/wildfly/plugins/core/cli/ForkedCLIUtil.java delete mode 100644 core/src/main/resources/META-INF/LICENSE.txt delete mode 100644 core/src/test/java/org/wildfly/plugin/core/AbstractDeploymentManagerTest.java delete mode 100644 core/src/test/java/org/wildfly/plugin/core/DeploymentResultTestCase.java delete mode 100644 core/src/test/java/org/wildfly/plugin/core/DeploymentTestCase.java delete mode 100644 core/src/test/java/org/wildfly/plugin/core/DomainDeploymentManagerIT.java delete mode 100644 core/src/test/java/org/wildfly/plugin/core/Environment.java delete mode 100644 core/src/test/java/org/wildfly/plugin/core/StandaloneDeploymentManagerIT.java delete mode 100644 core/src/test/java/org/wildfly/plugin/core/common/Simple.java delete mode 100644 core/src/test/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfigurationIT.java delete mode 100644 core/src/test/java/org/wildfly/plugins/core/bootablejar/TestFilter.java delete mode 100644 core/src/test/modules/org/wildfly/plugins/core/bootablejar/main/module.xml delete mode 100644 plugin/src/main/java/org/wildfly/plugin/server/VersionComparator.java delete mode 100644 plugin/src/test/java/org/wildfly/plugin/server/VersionTestCase.java diff --git a/core/README.adoc b/core/README.adoc index aaed82fa..2fad7517 100644 --- a/core/README.adoc +++ b/core/README.adoc @@ -1,107 +1,3 @@ = WildFly Plugins Core API -The WildFly Plugins Core API offers some simple API's for deploying applications to http://wildfly.org[WildFly] or https://www.redhat.com/en/technologies/jboss-middleware/application-platform[JBoss EAP]. - -== Deployment Manager - -The deployment manager can be used to deploy or redeploy content to a running server as well as undeploy content. It works with both standalone servers and managed domains. - -A simple example is deploying a WAR from the file system. -[source,java] ----- -final Path deploymentPath = Paths.get(System.getProperty("user.home"), "projects", "myapp", "target", "myapp.war"); -try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) { - final DeploymentManager deploymentManager = DeploymentManager.Factory.create(client); - final Deployment deployment = Deployment.of(deploymentPath); - deploymentManager.forceDeploy(deployment).assertSuccess(); -} ----- - -You can also deploy an input stream. -[source,java] ----- -final String deploymentName = "example.war"; -final WebArchive archive = ShrinkWrap.create(WebArchive.class, deploymentName); -archive.add(EmptyAsset.INSTANCE, "META-INF/beans.xml"); -archive.addPackage("org.jboss.example"); -try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) { - final DeploymentManager deploymentManager = DeploymentManager.Factory.create(client); - final Deployment deployment = Deployment.of(archive.as(ZipExporter.class).exportAsInputStream(), deploymentName); - deploymentManager.forceDeploy(deployment).assertSuccess(); -} ----- - -[source,java] -.Managed Domain Example ----- -final Path deploymentPath = Paths.get(System.getProperty("user.home"), "projects", "myapp", "target", "myapp.war"); -try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) { - final DeploymentManager deploymentManager = DeploymentManager.Factory.create(client); - final Deployment deployment = Deployment.of(deploymentPath) - .addServerGroups("main-server-group", "other-server-group"); - deploymentManager.deploy(deployment).assertSuccess(); -} ----- - -[source,java] -.Redeploy Example ----- -final Path deploymentPath = Paths.get(System.getProperty("user.home"), "projects", "myapp", "target", "myapp.war"); -try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) { - final DeploymentManager deploymentManager = DeploymentManager.Factory.create(client); - if (deploymentManager.hasDeployment(deploymentPath.getFileName().toString())) { - deploymentManager.redeploy(Deployment.of(deploymentPath)).assertSuccess(); - } -} ----- - -[source,java] -.Undeploy Example ----- -try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) { - final DeploymentManager deploymentManager = DeploymentManager.Factory.create(client); - final DeploymentResult result = deploymentManager.undeploy(UndeployDescription.of("example.war").setFailOnMissing(true)); - if (!result.successful()) { - logger.errorf("Failed to undeploy example.war. %s", result.getFailureMessage()); - } -} ----- - -== Deployment Operation Helper - -There is a helper if you'd rather execute operations on your own as well using the `org.wildfly.plugin.core.DeploymentOperations`. - -[source,java] ----- -final Path deploymentPath = Paths.get(System.getProperty("user.home"), "projects", "myapp", "target", "myapp.war"); -try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) { - final Operation op = DeploymentOperations.createDeployOperation(Deployment.of(deploymentPath)); - final ModelNode outcome = client.execute(op); - if (!Operations.isSuccessfulOutcome(outcome)) { - throw new DeploymentException(Operations.getFailureDescription(outcome).asString()); - } -} ----- - -== Server Helper - -You can also use the `org.wildfly.plugin.core.ServerHelper` to interact with a running server. - -[source,java] ----- -final Path wildflyHome = Paths.get(System.getProperty("user.home"), "servers", "wildfly-10.0.0.Final"); -final Process process = Launcher.of(StandaloneCommandBuilder.of(wildflyHome)).launch(); -try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) { - // Wait at the maximum 30 seconds for the server to start - ServerHelper.waitForStandalone(client, 30); - final Path deploymentPath = Paths.get(System.getProperty("user.home"), "projects", "myapp", "target", "myapp.war"); - final DeploymentManager deploymentManager = DeploymentManager.Factory.create(client); - final Deployment deployment = Deployment.of(deploymentPath); - deploymentManager.forceDeploy(deployment).assertSuccess(); - - // Shutdown the standalone server - ServerHelper.shutdownStandalone(client); -} finally { - process.destroy(); -} ----- \ No newline at end of file +The WildFly Plugins Core API offers some simple API's for deploying applications to http://wildfly.org[WildFly] or https://www.redhat.com/en/technologies/jboss-middleware/application-platform[JBoss EAP]. \ No newline at end of file diff --git a/core/pom.xml b/core/pom.xml index 5885adbb..a60a55b2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -17,25 +17,9 @@ WildFly Plugin Core Utilities - Utilities a plugin can use to interact with WildFly container. + Utilities for Maven plugins to interact with WildFly. - - 1.2.6 - - ${project.build.directory}${file.separator}wildfly - ${project.build.testOutputDirectory} - -Dmaven.repo.local=${settings.localRepository} - - - - - Apache License Version 2.0 - https://repository.jboss.org/licenses/apache-2.0.txt - repo - - - org.apache.maven @@ -45,68 +29,13 @@ org.jboss.logging jboss-logging - - org.wildfly.common - wildfly-common - - - org.wildfly.core - wildfly-controller-client - - - - org.wildfly.core - wildfly-protocol - - - org.jboss.galleon - galleon-api - org.apache.maven.shared maven-artifact-transfer - - - org.wildfly.core - wildfly-launcher - test - - - junit - junit - test - - - - org.jboss.shrinkwrap - shrinkwrap-api - ${version.org.jboss.shrinkwrap.shrinkwrap} - test - - - - org.jboss.shrinkwrap - shrinkwrap-impl-base - ${version.org.jboss.shrinkwrap.shrinkwrap} - test - - - - - src/test/resources - ${project.build.testOutputDirectory} - - - - src/test/modules - true - ${jboss.home}/modules - - maven-jar-plugin @@ -118,72 +47,6 @@ - - org.jboss.galleon - galleon-maven-plugin - - - provision-wildfly - pre-integration-test - - provision - - - - - wildfly@maven(org.jboss.universe:community-universe)#${version.org.wildfly} - - - false - ${project.build.directory}/wildfly - - ${plugin.fork.embedded} - - - - - - - - maven-resources-plugin - - - copy-module - pre-integration-test - - testResources - - - - - - maven-surefire-plugin - - - ${project.build.testOutputDirectory} - - - - - maven-failsafe-plugin - - ${maven.test.redirectTestOutputToFile} - - ${jboss.home} - ${test.jvm.args} - - - - - - integration-test - verify - - - - diff --git a/core/src/main/java/org/wildfly/plugin/core/Assertions.java b/core/src/main/java/org/wildfly/plugin/core/Assertions.java deleted file mode 100644 index 71c5fd2a..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/Assertions.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.util.Collection; - -import org.wildfly.common.Assert; - -/** - * @author James R. Perkins - */ -class Assertions { - - /** - * Checks if the parameter is {@code null} or empty and throws an {@link IllegalArgumentException} if it is. - * - * @param name the name of the parameter - * @param value the value to check - * - * @return the parameter value - * - * @throws IllegalArgumentException if the object representing the parameter is {@code null} - */ - static String requiresNotNullOrNotEmptyParameter(final String name, final String value) throws IllegalArgumentException { - Assert.checkNotNullParam(name, value); - Assert.checkNotEmptyParam(name, value); - return value; - } - - /** - * Checks if the parameter is {@code null} or empty and throws an {@link IllegalArgumentException} if it is. - * - * @param name the name of the parameter - * @param value the value to check - * - * @return the parameter value - * - * @throws IllegalArgumentException if the object representing the parameter is {@code null} - */ - static > T requiresNotNullOrNotEmptyParameter(final String name, final T value) - throws IllegalArgumentException { - Assert.checkNotNullParam(name, value); - Assert.checkNotEmptyParam(name, value); - return value; - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/ConsoleConsumer.java b/core/src/main/java/org/wildfly/plugin/core/ConsoleConsumer.java deleted file mode 100644 index 304d7f44..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/ConsoleConsumer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A utility which will consume output from an {@link InputStream} and write it to an {@link OutputStream}. This is - * commonly used when a processes {@link Process#getInputStream() stdout} or {@link Process#getErrorStream() stderr} - * needs to be consumed and redirected somewhere. - * - * @author James R. Perkins - */ -public class ConsoleConsumer implements Runnable { - private final InputStream in; - private final OutputStream out; - - /** - * Creates a new console consumer which will pipe the {@link InputStream} to the {@link OutputStream}. - * - * @param in the input stream that should be pipped - * @param out the output stream where the data should be written - */ - @SuppressWarnings("WeakerAccess") - public ConsoleConsumer(final InputStream in, final OutputStream out) { - this.in = in; - this.out = out; - } - - /** - * Creates and starts a daemon thread which consumes a {@linkplain Process processes} - * {@link Process#getInputStream() stdout} stream and pipes the date to the output stream. - *

- * Note that when using this method the {@link ProcessBuilder#redirectErrorStream(boolean)} should likely be - * {@code true}. Otherwise another {@linkplain #start(InputStream, OutputStream) thread} should be created to - * consume {@link Process#getErrorStream() stderr}. - *

- * - * @param process the process - * @param out the output stream where the data should be written - * - * @return the thread that was started - */ - public static Thread start(final Process process, final OutputStream out) { - return start(process.getInputStream(), out); - } - - /** - * Creates and starts a daemon thread which pipes int {@link InputStream} to the {@link OutputStream}. - * - * @param in the input stream that should be pipped - * @param out the output stream where the data should be written - * - * @return the thread that was started - */ - public static Thread start(final InputStream in, final OutputStream out) { - final Thread thread = new Thread(new ConsoleConsumer(in, out), "WildFly-Console-Consumer"); - thread.setDaemon(true); - thread.start(); - return thread; - } - - @Override - public void run() { - final byte[] buffer = new byte[64]; - try { - int len; - while ((len = in.read(buffer)) != -1 && !Thread.interrupted()) { - out.write(buffer, 0, len); - } - } catch (IOException ignore) { - } - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/Constants.java b/core/src/main/java/org/wildfly/plugin/core/Constants.java index 7ffe5b3f..0d2eb890 100644 --- a/core/src/main/java/org/wildfly/plugin/core/Constants.java +++ b/core/src/main/java/org/wildfly/plugin/core/Constants.java @@ -9,10 +9,10 @@ */ public interface Constants { - public static final String CLI_RESOLVE_PARAMETERS_VALUES = "--resolve-parameter-values"; - public static final String CLI_ECHO_COMMAND_ARG = "--echo-command"; - public static final String PLUGIN_PROVISIONING_FILE = ".wildfly-maven-plugin-provisioning.xml"; - public static final String STANDALONE = "standalone"; - public static final String STANDALONE_XML = "standalone.xml"; - public static final String FORK_EMBEDDED_PROCESS_OPTION = "jboss-fork-embedded"; + String CLI_RESOLVE_PARAMETERS_VALUES = "--resolve-parameter-values"; + String CLI_ECHO_COMMAND_ARG = "--echo-command"; + String PLUGIN_PROVISIONING_FILE = ".wildfly-maven-plugin-provisioning.xml"; + String STANDALONE = "standalone"; + String STANDALONE_XML = "standalone.xml"; + String FORK_EMBEDDED_PROCESS_OPTION = "jboss-fork-embedded"; } diff --git a/core/src/main/java/org/wildfly/plugin/core/ContainerDescription.java b/core/src/main/java/org/wildfly/plugin/core/ContainerDescription.java deleted file mode 100644 index 33a8b72c..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/ContainerDescription.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -/** - * Information about the running container. - * - * @author James R. Perkins - */ -@SuppressWarnings({ "WeakerAccess", "unused" }) -public interface ContainerDescription { - - /** - * Returns the name of the product. - * - * @return the name of the product - */ - String getProductName(); - - /** - * Returns the product version, if defined, or {@code null} if the product version was not defined. - * - * @return the product version or {@code null} if not defined - */ - String getProductVersion(); - - /** - * Returns the release version, if defined, or {@code null} if the release version was not defined. - *

- * Note that in WildFly 9+ this is usually the version for WildFly Core. In WildFly 8 this is the full version. - *

- * - * @return the release version or {@code null} if not defined - */ - String getReleaseVersion(); - - /** - * Returns the type of the server that was launched. - * - * @return the type of the server that was launched or {@code null} if not defined - */ - String getLaunchType(); - - /** - * Checks if the server is a managed domain server. - * - * @return {@code true} if this is a managed domain, otherwise {@code false} - */ - boolean isDomain(); -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DefaultContainerDescription.java b/core/src/main/java/org/wildfly/plugin/core/DefaultContainerDescription.java deleted file mode 100644 index ffb4de12..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DefaultContainerDescription.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.IOException; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.helpers.ClientConstants; -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.dmr.ModelNode; - -/** - * A default implementation for the {@link ContainerDescription}. - * - * @author James R. Perkins - */ -class DefaultContainerDescription implements ContainerDescription { - - private final String productName; - private final String productVersion; - private final String releaseVersion; - private final String launchType; - private final boolean isDomain; - - private DefaultContainerDescription(final String productName, final String productVersion, - final String releaseVersion, final String launchType, final boolean isDomain) { - this.productName = productName; - this.productVersion = productVersion; - this.releaseVersion = releaseVersion; - this.launchType = launchType; - this.isDomain = isDomain; - } - - @Override - public String getProductName() { - return productName; - } - - @Override - public String getProductVersion() { - return productVersion; - } - - @Override - public String getReleaseVersion() { - return releaseVersion; - } - - @Override - public String getLaunchType() { - return launchType; - } - - @Override - public boolean isDomain() { - return isDomain; - } - - @Override - public String toString() { - final StringBuilder result = new StringBuilder(64); - result.append(productName); - if (productVersion != null) { - result.append(' ').append(productVersion); - if (releaseVersion != null) { - result.append(" (WildFly Core ").append(releaseVersion).append(')'); - } - } else { - if (releaseVersion != null) { - result.append(' ').append(releaseVersion); - } - } - if (launchType != null) { - result.append(" - launch-type: ").append(launchType); - } - return result.toString(); - } - - /** - * Queries the running container and attempts to lookup the information from the running container. - * - * @param client the client used to execute the management operation - * - * @return the container description - * - * @throws IOException if an error occurs while executing the management operation - * @throws OperationExecutionException if the operation used to query the container fails - */ - static DefaultContainerDescription lookup(final ModelControllerClient client) - throws IOException, OperationExecutionException { - final ModelNode op = Operations.createReadResourceOperation(new ModelNode().setEmptyList()); - op.get(ClientConstants.INCLUDE_RUNTIME).set(true); - final ModelNode result = client.execute(op); - if (Operations.isSuccessfulOutcome(result)) { - final ModelNode model = Operations.readResult(result); - final String productName = getValue(model, "product-name", "WildFly"); - final String productVersion = getValue(model, "product-version"); - final String releaseVersion = getValue(model, "release-version"); - final String launchType = getValue(model, "launch-type"); - return new DefaultContainerDescription(productName, productVersion, releaseVersion, launchType, - "DOMAIN".equalsIgnoreCase(launchType)); - } - throw new OperationExecutionException(op, result); - } - - private static String getValue(final ModelNode model, final String attributeName) { - return getValue(model, attributeName, null); - } - - private static String getValue(final ModelNode model, final String attributeName, final String defaultValue) { - if (model.hasDefined(attributeName)) { - return model.get(attributeName).asString(); - } - return defaultValue; - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DefaultDeploymentManager.java b/core/src/main/java/org/wildfly/plugin/core/DefaultDeploymentManager.java deleted file mode 100644 index e33a7aa7..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DefaultDeploymentManager.java +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import static org.jboss.as.controller.client.helpers.ClientConstants.CHILD_TYPE; -import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT; -import static org.jboss.as.controller.client.helpers.ClientConstants.READ_CHILDREN_NAMES_OPERATION; -import static org.jboss.as.controller.client.helpers.ClientConstants.SERVER_GROUP; -import static org.wildfly.plugin.core.DeploymentOperations.createAddress; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.Operation; -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.as.controller.client.helpers.Operations.CompositeOperationBuilder; -import org.jboss.dmr.ModelNode; -import org.jboss.dmr.Property; -import org.wildfly.common.Assert; - -/** - * The default deployment manager. - * - * @author James R. Perkins - */ -@SuppressWarnings("Duplicates") -class DefaultDeploymentManager implements DeploymentManager { - - private final ModelControllerClient client; - private final ContainerDescription containerDescription = new LazyContainerDescription(); - - DefaultDeploymentManager(final ModelControllerClient client) { - this.client = client; - } - - @Override - public DeploymentResult deploy(final Deployment deployment) throws IOException { - final DeploymentResult failedResult = validateDeployment(deployment); - if (failedResult != null) { - return failedResult; - } - return execute(DeploymentOperations.createAddDeploymentOperation(deployment)); - } - - @Override - public DeploymentResult deploy(final Set deployments) throws IOException { - final DeploymentResult failedResult = validateDeployment(deployments); - if (failedResult != null) { - return failedResult; - } - return execute(DeploymentOperations.createAddDeploymentOperation(deployments)); - } - - @Override - public DeploymentResult forceDeploy(final Deployment deployment) throws IOException { - final DeploymentResult failedResult = validateDeployment(deployment); - if (failedResult != null) { - return failedResult; - } - if (hasDeployment(deployment.getName())) { - // Special handling for domains if the deployment is already in the content repository - if (containerDescription.isDomain()) { - // Retrieve the currently deployment content description - final DeploymentDescription current = getServerGroupDeployment(deployment.getName()); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - // Add a full-replace-deployment as well as add the deployment to any missing server groups - DeploymentOperations.addReplaceOperationSteps(builder, deployment, current, true); - return execute(builder.build()); - } - return redeploy(deployment); - } - return deploy(deployment); - } - - @Override - public DeploymentResult forceDeploy(final Set deployments) throws IOException { - final DeploymentResult failedResult = validateDeployment(deployments); - if (failedResult != null) { - return failedResult; - } - @SuppressWarnings("TypeMayBeWeakened") - final Set toDeploy = new LinkedHashSet<>(); - final Map toRedeploy = new LinkedHashMap<>(); - final Set currentDeployments = getDeployments(); - for (Deployment deployment : deployments) { - // Find if the current deployment with the same name as the deployment to be deployed, if found it will - // be replaced. If not found it will be deployed - final DeploymentDescription currentDeployment = findDeployment(currentDeployments, deployment); - if (currentDeployment != null) { - toRedeploy.put(deployment, currentDeployment); - } else { - toDeploy.add(deployment); - } - } - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - // Add all the deploy steps - for (Deployment deployment : toDeploy) { - DeploymentOperations.addDeploymentOperationStep(builder, deployment); - } - // Add all the redeploy steps - for (Deployment deployment : toRedeploy.keySet()) { - if (containerDescription.isDomain()) { - // Adds the full-replace-deployment operation for domains as well as adds missing deployments on server - // groups - DeploymentOperations.addReplaceOperationSteps(builder, deployment, toRedeploy.get(deployment), true); - } else { - DeploymentOperations.addReplaceOperationSteps(builder, deployment); - } - } - - return execute(builder.build()); - } - - @Override - public DeploymentResult deployToRuntime(final DeploymentDescription deployment) throws IOException { - return execute(DeploymentOperations.createDeployOperation(Assert.checkNotNullParam("deployment", deployment))); - } - - @Override - public DeploymentResult deployToRuntime(final Set deployments) throws IOException { - return execute(DeploymentOperations - .createDeployOperation(Assertions.requiresNotNullOrNotEmptyParameter("deployments", deployments))); - } - - @Override - public DeploymentResult redeploy(final Deployment deployment) throws IOException { - final DeploymentResult failedResult = validateDeployment(deployment); - if (failedResult != null) { - return failedResult; - } - return execute(DeploymentOperations.createReplaceOperation(deployment)); - } - - @Override - public DeploymentResult redeploy(final Set deployments) throws IOException { - final DeploymentResult failedResult = validateDeployment(deployments); - if (failedResult != null) { - return failedResult; - } - return execute(DeploymentOperations.createReplaceOperation(deployments)); - } - - @Override - public DeploymentResult redeployToRuntime(final DeploymentDescription deployment) throws IOException { - return execute(DeploymentOperations.createRedeployOperation(Assert.checkNotNullParam("deployment", deployment))); - } - - @Override - public DeploymentResult redeployToRuntime(final Set deployments) throws IOException { - return execute(DeploymentOperations - .createRedeployOperation(Assertions.requiresNotNullOrNotEmptyParameter("deployments", deployments))); - } - - @Override - public DeploymentResult undeploy(final UndeployDescription undeployDescription) throws IOException { - final DeploymentResult failedResult = validateDeployment(undeployDescription); - if (failedResult != null) { - return failedResult; - } - if (undeployDescription.isFailOnMissing()) { - return execute(DeploymentOperations.createUndeployOperation(undeployDescription)); - } - final Set currentDeployments = getDeployments(); - final DeploymentDescription found = findDeployment(currentDeployments, undeployDescription); - if (currentDeployments.isEmpty() || found == null) { - return DeploymentResult.SUCCESSFUL; - } - return execute(DeploymentOperations.createUndeployOperation(copyIfRequired(undeployDescription, found))); - } - - @Override - public DeploymentResult undeploy(final Set undeployDescriptions) throws IOException { - final DeploymentResult failedResult = validateDeployment(undeployDescriptions); - if (failedResult != null) { - return failedResult; - } - final Set currentDeployments = getDeployments(); - final Set toRemove = new LinkedHashSet<>(undeployDescriptions.size()); - final Set skipped = new LinkedHashSet<>(undeployDescriptions.size()); - boolean failOnMissing = false; - for (UndeployDescription undeployDescription : undeployDescriptions) { - if (undeployDescription.isFailOnMissing()) { - failOnMissing = true; - } - if (failOnMissing) { - toRemove.add(undeployDescription); - } else { - final DeploymentDescription found = findDeployment(currentDeployments, undeployDescription); - if (found == null) { - skipped.add(undeployDescription); - } else { - toRemove.add(copyIfRequired(undeployDescription, found)); - } - } - } - if (toRemove.isEmpty()) { - if (failOnMissing) { - return new DeploymentResult("No deployments were found matching any of the following deployments: %s", - undeployDescriptions); - } - return DeploymentResult.SUCCESSFUL; - } - // If this is expecting to fail we need to add the skipped ones so execution will fail and the failure message - // will be accurate. - if (failOnMissing) { - toRemove.addAll(skipped); - } - return execute(DeploymentOperations.createUndeployOperation(toRemove)); - } - - @Override - public Set getDeployments() throws IOException { - final ModelNode readDeployments = Operations.createOperation(READ_CHILDREN_NAMES_OPERATION); - readDeployments.get(CHILD_TYPE).set(DEPLOYMENT); - if (containerDescription.isDomain()) { - // Represents the deployment and each server-group the deployment belongs to - final Map> serverGroupDeployments = new LinkedHashMap<>(); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - // Get all the deployments in the deployment repository - builder.addStep(readDeployments); - - final ModelNode address = createAddress(SERVER_GROUP, "*", DEPLOYMENT, "*"); - // Get all the deployments that are deployed to server groups - builder.addStep(Operations.createReadResourceOperation(address)); - - final ModelNode result = client.execute(builder.build()); - if (Operations.isSuccessfulOutcome(result)) { - final ModelNode results = Operations.readResult(result); - // Load all deployments from the content repository - for (ModelNode r : Operations.readResult(results.get("step-1")).asList()) { - serverGroupDeployments.put(r.asString(), new LinkedHashSet()); - } - // Add the server groups to the deployments which belong to server groups - for (ModelNode r : Operations.readResult(results.get("step-2")).asList()) { - final List resultAddress = Operations.getOperationAddress(r).asPropertyList(); - String serverGroup = null; - String deployment = null; - for (Property property : resultAddress) { - if (SERVER_GROUP.equals(property.getName())) { - serverGroup = property.getValue().asString(); - } else if (DEPLOYMENT.equals(property.getName())) { - deployment = property.getValue().asString(); - } - } - // Add the server-group to the map of deployments - final Set serverGroups = serverGroupDeployments.get(deployment); - serverGroups.add(serverGroup); - } - // Convert the server-group mapping to deployment descriptions - final Set deployments = new LinkedHashSet<>(); - for (Map.Entry> entry : serverGroupDeployments.entrySet()) { - final String name = entry.getKey(); - deployments.add(SimpleDeploymentDescription.of(name, entry.getValue())); - } - return deployments; - } - throw new RuntimeException( - "Failed to get listing of deployments. Reason: " + Operations.getFailureDescription(result).asString()); - } - // Handle servers other than managed domains - final Set deployments = new LinkedHashSet<>(); - final ModelNode result = client.execute(readDeployments); - if (Operations.isSuccessfulOutcome(result)) { - for (ModelNode deployment : Operations.readResult(result).asList()) { - final String deploymentName = deployment.asString(); - deployments.add(SimpleDeploymentDescription.of(deploymentName)); - } - return deployments; - } - throw new RuntimeException( - "Failed to get listing of deployments. Reason: " + Operations.getFailureDescription(result).asString()); - } - - @Override - public Set getDeployments(final String serverGroup) throws IOException { - Assertions.requiresNotNullOrNotEmptyParameter("serverGroup", serverGroup); - if (!containerDescription.isDomain()) { - throw new IllegalStateException("Server is not a managed domain. Running container: " + containerDescription); - } - // Get all the current deployments and filter them to only return deployments located on this server group - final Set deployments = new LinkedHashSet<>(); - for (DeploymentDescription deployment : getDeployments()) { - final Set serverGroups = Collections.unmodifiableSet(deployment.getServerGroups()); - if (serverGroups.contains(serverGroup)) { - deployments.add(deployment); - } - } - return deployments; - } - - @Override - public Set getDeploymentNames() throws IOException { - final ModelNode readDeployments = Operations.createOperation(READ_CHILDREN_NAMES_OPERATION); - readDeployments.get(CHILD_TYPE).set(DEPLOYMENT); - final Set deployments = new LinkedHashSet<>(); - final ModelNode result = client.execute(readDeployments); - if (Operations.isSuccessfulOutcome(result)) { - for (ModelNode deployment : Operations.readResult(result).asList()) { - final String deploymentName = deployment.asString(); - deployments.add(deploymentName); - } - return deployments; - } - throw new RuntimeException( - "Failed to get listing of deployments. Reason: " + Operations.getFailureDescription(result).asString()); - } - - @Override - public boolean hasDeployment(final String name) { - return hasDeployment(DeploymentOperations.EMPTY_ADDRESS, Assertions.requiresNotNullOrNotEmptyParameter("name", name)); - } - - @Override - public boolean hasDeployment(final String name, final String serverGroup) { - final ModelNode address = DeploymentOperations.createAddress(SERVER_GROUP, - Assertions.requiresNotNullOrNotEmptyParameter("serverGroup", serverGroup)); - return hasDeployment(address, Assertions.requiresNotNullOrNotEmptyParameter("name", name)); - } - - @Override - public boolean isEnabled(final String name) { - return isEnabled( - DeploymentOperations.createAddress(DEPLOYMENT, Assertions.requiresNotNullOrNotEmptyParameter("name", name))); - } - - @Override - public boolean isEnabled(final String name, final String serverGroup) { - return isEnabled(DeploymentOperations.createAddress( - SERVER_GROUP, - Assertions.requiresNotNullOrNotEmptyParameter("serverGroup", serverGroup), - DEPLOYMENT, - Assertions.requiresNotNullOrNotEmptyParameter("name", name))); - } - - private boolean hasDeployment(final ModelNode address, final String name) { - final ModelNode op = Operations.createOperation(READ_CHILDREN_NAMES_OPERATION, address); - op.get(CHILD_TYPE).set(DEPLOYMENT); - final ModelNode listDeploymentsResult; - try { - listDeploymentsResult = client.execute(op); - // Check to make sure there is an outcome - if (Operations.isSuccessfulOutcome(listDeploymentsResult)) { - final List deployments = Operations.readResult(listDeploymentsResult).asList(); - for (ModelNode deployment : deployments) { - if (name.equals(deployment.asString())) { - return true; - } - } - } else { - throw new IllegalStateException(Operations.getFailureDescription(listDeploymentsResult).asString()); - } - } catch (IOException e) { - throw new IllegalStateException(String.format("Could not execute operation '%s'", op), e); - } - return false; - } - - private boolean isEnabled(final ModelNode address) { - final ModelNode op = Operations.createReadAttributeOperation(address, DeploymentOperations.ENABLED); - try { - final ModelNode result = client.execute(op); - // Check to make sure there is an outcome - if (Operations.isSuccessfulOutcome(result)) { - return Operations.readResult(result).asBoolean(); - } else { - throw new IllegalStateException(Operations.getFailureDescription(result).asString()); - } - } catch (IOException e) { - throw new IllegalStateException(String.format("Could not execute operation '%s'", op), e); - } - } - - private DeploymentResult execute(final Operation op) throws IOException { - final ModelNode result = client.execute(op); - return new DeploymentResult(result); - } - - private DeploymentDescription getServerGroupDeployment(final String name) throws IOException { - final Set serverGroups = new LinkedHashSet<>(); - final ModelNode address = createAddress(SERVER_GROUP, "*", DEPLOYMENT, name); - - final ModelNode result = client.execute(Operations.createReadResourceOperation(address)); - if (Operations.isSuccessfulOutcome(result)) { - // Load the server groups - for (ModelNode r : Operations.readResult(result).asList()) { - final List resultAddress = Operations.getOperationAddress(r).asPropertyList(); - String foundServerGroup = null; - for (Property property : resultAddress) { - if (SERVER_GROUP.equals(property.getName())) { - foundServerGroup = property.getValue().asString(); - } - } - // Add the server-group to the map of deployments - serverGroups.add(foundServerGroup); - } - return SimpleDeploymentDescription.of(name, serverGroups); - } - throw new RuntimeException( - "Failed to get listing of deployments. Reason: " + Operations.getFailureDescription(result).asString()); - } - - private DeploymentResult validateDeployment(final DeploymentDescription deployment) { - Assert.checkNotNullParam("deployment", deployment); - final Set serverGroups = deployment.getServerGroups(); - if (containerDescription.isDomain() && serverGroups.isEmpty()) { - return new DeploymentResult("No server groups were defined for the deployment operation. Deployment: %s", - deployment); - } else if (!containerDescription.isDomain() && !serverGroups.isEmpty()) { - return new DeploymentResult("Server is not a managed domain, but server groups were defined. Deployment: %s", - deployment); - } - return null; - } - - private DeploymentResult validateDeployment(final Set deployments) { - Assertions.requiresNotNullOrNotEmptyParameter("deployments", deployments); - - final Collection missingServerGroups = new LinkedHashSet<>(); - final Collection standaloneWithServerGroups = new LinkedHashSet<>(); - boolean error = false; - for (DeploymentDescription deployment : deployments) { - final Set serverGroups = deployment.getServerGroups(); - if (containerDescription.isDomain() && serverGroups.isEmpty()) { - error = true; - missingServerGroups.add(deployment); - } else if (!containerDescription.isDomain() && !serverGroups.isEmpty()) { - error = true; - standaloneWithServerGroups.add(deployment); - } - } - if (error) { - final StringBuilder message = new StringBuilder(); - if (!missingServerGroups.isEmpty()) { - message.append("No server groups were defined on the following deployments: ") - .append(missingServerGroups); - } - if (!standaloneWithServerGroups.isEmpty()) { - message.append("Server is not a managed domain but the following deployments had server groups defined: ") - .append(standaloneWithServerGroups); - } - return new DeploymentResult(message); - } - return null; - } - - private static DeploymentDescription findDeployment(final Iterable deployments, - final DeploymentDescription deployment) { - for (DeploymentDescription deploymentDescription : deployments) { - if (deploymentDescription.getName().equals(deployment.getName())) { - return deploymentDescription; - } - } - return null; - } - - private static UndeployDescription copyIfRequired(final UndeployDescription undeployDescription, - final DeploymentDescription found) { - final Collection unmatched = new LinkedHashSet<>(undeployDescription.getServerGroups()); - unmatched.removeAll(found.getServerGroups()); - if (unmatched.isEmpty()) { - return undeployDescription; - } - final Collection toRemove = new LinkedHashSet<>(undeployDescription.getServerGroups()); - toRemove.removeAll(unmatched); - // The parameter has more server-groups than the deployment found, create a new UndeployDescription description - // using only the server-groups the deployment exists on - return UndeployDescription.of(undeployDescription.getName()) - .addServerGroups(toRemove) - .setFailOnMissing(undeployDescription.isFailOnMissing()) - .setRemoveContent(undeployDescription.isRemoveContent()); - } - - private class LazyContainerDescription implements ContainerDescription { - private volatile ContainerDescription containerDescription; - - @Override - public String getProductName() { - return get().getProductName(); - } - - @Override - public String getProductVersion() { - return get().getProductVersion(); - } - - @Override - public String getReleaseVersion() { - return get().getReleaseVersion(); - } - - @Override - public String getLaunchType() { - return get().getLaunchType(); - } - - @Override - public boolean isDomain() { - return get().isDomain(); - } - - @Override - public String toString() { - return get().toString(); - } - - private ContainerDescription get() { - if (containerDescription == null) { - synchronized (this) { - if (containerDescription == null) { - try { - containerDescription = ServerHelper.getContainerDescription(client); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - } - } - return containerDescription; - } - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/Deployment.java b/core/src/main/java/org/wildfly/plugin/core/Deployment.java deleted file mode 100644 index 3b8bb0b0..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/Deployment.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.File; -import java.io.InputStream; -import java.net.URL; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; - -import org.wildfly.common.Assert; - -/** - * Represents a deployment to be deployed or redeployed to a server. - *

- * Instances of this are not thread-safe. - *

- * - * @author James R. Perkins - */ -@SuppressWarnings({ "unused", "WeakerAccess" }) -public class Deployment implements DeploymentDescription, Comparable { - - private final DeploymentContent content; - private final Set serverGroups; - private String name; - private String runtimeName; - private boolean enabled = true; - - private Deployment(final DeploymentContent content, final String name) { - this.content = content; - this.name = Assertions.requiresNotNullOrNotEmptyParameter("name", (name == null ? this.content.resolvedName() : name)); - serverGroups = new LinkedHashSet<>(); - } - - /** - * Creates a new deployment for the file. If the file is a directory the content will be deployed exploded using - * the file system location. - * - * @param content the file containing the content - * - * @return the deployment - */ - public static Deployment of(final File content) { - final DeploymentContent deploymentContent = DeploymentContent.of(Assert.checkNotNullParam("content", content).toPath()); - return new Deployment(deploymentContent, null); - } - - /** - * Creates a new deployment for the path. If the path is a directory the content will be deployed exploded using - * the file system location. - * - * @param content the path containing the content - * - * @return the deployment - */ - public static Deployment of(final Path content) { - final DeploymentContent deploymentContent = DeploymentContent.of(Assert.checkNotNullParam("content", content)); - return new Deployment(deploymentContent, null); - } - - /** - * Creates a new deployment for the input stream. The name is required for the deployment and cannot be {@code null}. - * If {@link #setName(String)} with a {@code null} argument is invoked when using this static factory an - * {@link IllegalArgumentException} will be thrown. - *

- * The {@linkplain InputStream content} will be copied, stored in-memory and then closed. Large content should be - * written to a file and the {@link #of(Path)} or {@link #of(File)} static factory methods should be used. - *

- * - * @param content the input stream representing the content - * @param name the name for the deployment - * - * @return the deployment - */ - public static Deployment of(final InputStream content, final String name) { - final DeploymentContent deploymentContent = DeploymentContent.of(Assert.checkNotNullParam("content", content)); - return new Deployment(deploymentContent, Assertions.requiresNotNullOrNotEmptyParameter("name", name)); - } - - /** - * Creates a new deployment for the URL. The target server will require access to the URL. - * - * @param url the URL representing the content - * - * @return the deployment - */ - public static Deployment of(final URL url) { - final DeploymentContent deploymentContent = DeploymentContent.of(Assert.checkNotNullParam("url", url)); - return new Deployment(deploymentContent, null); - } - - /** - * Creates a new deployment for the path. If the path is a directory the content will be deployed exploded using - * the file system location. Otherwise, the content is deployed with the local path as an archive. - * - * @param content the path containing the content - * - * @return the deployment - */ - public static Deployment local(final Path content) { - final DeploymentContent deploymentContent = DeploymentContent.local(Assert.checkNotNullParam("content", content)); - return new Deployment(deploymentContent, null); - } - - /** - * Adds a server group for the deployment. - * - * @param serverGroup the server group to add - * - * @return this deployment - * - * @see #addServerGroups(Collection) - * @see #addServerGroups(String...) - */ - public Deployment addServerGroup(final String serverGroup) { - serverGroups.add(serverGroup); - return this; - } - - /** - * Adds the server groups for the deployment. - * - * @param serverGroups the server groups to add - * - * @return this deployment - * - * @see #addServerGroup(String) - * @see #addServerGroups(Collection) - */ - public Deployment addServerGroups(final String... serverGroups) { - return addServerGroups(Arrays.asList(serverGroups)); - } - - /** - * Adds the server groups for the deployment. - * - * @param serverGroups the server groups to add - * - * @return this deployment - * - * @see #addServerGroup(String) - * @see #addServerGroups(String...) - */ - public Deployment addServerGroups(final Collection serverGroups) { - this.serverGroups.addAll(serverGroups); - return this; - } - - @Override - public Set getServerGroups() { - return Collections.unmodifiableSet(serverGroups); - } - - /** - * Sets the server groups for the deployment. - * - * @param serverGroups the server groups to set - * - * @return this deployment - */ - public Deployment setServerGroups(final String... serverGroups) { - return setServerGroups(Arrays.asList(serverGroups)); - } - - /** - * Sets the server groups for the deployment. - * - * @param serverGroups the server groups to set - * - * @return this deployment - */ - public Deployment setServerGroups(final Collection serverGroups) { - this.serverGroups.clear(); - this.serverGroups.addAll(serverGroups); - return this; - } - - /** - * Indicates whether or not the deployment should be enabled by default. - *

- * If the value is set to {@code false} the content will only be added. An explicit {@code deploy} operation will - * be required to deploy the content to the runtime. - *

- * - * @return {@code true} if the deployment should be enabled, {@code false} if the deployment should not be enabled - */ - public boolean isEnabled() { - return enabled; - } - - /** - * Sets whether or not the deployment should be enabled. If set to {@code false} the deployment will not be enabled, - * but the content will be uploaded and added. This is set to {@code true} by default. - *

- * If the value is set to {@code false} the content will only be added. An explicit {@code deploy} operation will - * be required to deploy the content to the runtime. - *

- * - * @param enabled {@code false} to keep the content disabled - * - * @return this deployment - */ - public Deployment setEnabled(final boolean enabled) { - this.enabled = enabled; - return this; - } - - @Override - public String getName() { - return name; - } - - /** - * Sets the name for the deployment. This can be {@code null} for a deployment created based on a file system path. - * If the deployment was created using in input stream and the value is {@code null} an {@link IllegalArgumentException} - * will be thrown. - * - * @param name the name for the deployment - * - * @return this deployment - */ - public Deployment setName(final String name) { - if (name == null) { - this.name = content.resolvedName(); - if (this.name == null) { - throw new IllegalArgumentException("The name parameter is required and could not be resolved from the content: " - + content); - } - } else { - this.name = name; - } - return this; - } - - /** - * Returns the runtime name set for the deployment which may be {@code null}. - * - * @return the runtime name set or {@code null} if one was not set - */ - public String getRuntimeName() { - return runtimeName; - } - - /** - * Sets the runtime name for the deployment. - * - * @param runtimeName the runtime name, can be {@code null} - * - * @return this deployment - */ - public Deployment setRuntimeName(final String runtimeName) { - this.runtimeName = runtimeName; - return this; - } - - @Override - public int compareTo(@SuppressWarnings("NullableProblems") final Deployment o) { - return name.compareTo(o.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof Deployment)) { - return false; - } - final Deployment other = (Deployment) obj; - return Objects.equals(name, other.name); - } - - @Override - public String toString() { - final StringBuilder result = new StringBuilder(Deployment.class.getSimpleName()); - result.append('('); - result.append("name=").append(name); - if (runtimeName != null) { - result.append(", runtimeName=").append(runtimeName); - } - if (!serverGroups.isEmpty()) { - result.append(", serverGroups=").append(serverGroups); - } - result.append(", content=").append(content); - return result.append(')').toString(); - } - - DeploymentContent getContent() { - return content; - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DeploymentContent.java b/core/src/main/java/org/wildfly/plugin/core/DeploymentContent.java deleted file mode 100644 index b9e89933..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DeploymentContent.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import static org.jboss.as.controller.client.helpers.ClientConstants.CONTENT; -import static org.jboss.as.controller.client.helpers.ClientConstants.PATH; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.jboss.as.controller.client.OperationBuilder; -import org.jboss.as.controller.client.helpers.ClientConstants; -import org.jboss.dmr.ModelNode; - -/** - * Allows content to be added to an operation. The content will be attached to an {@link OperationBuilder} with either - * the {@link OperationBuilder#addInputStream(InputStream)} or {@link OperationBuilder#addFileAsAttachment(File)} - * depending on the type of content being used. - * - * @author James R. Perkins - */ -abstract class DeploymentContent { - - /** - * Adds the content to the operation. - * - * @param builder the builder used to attach the content to - * @param op the deployment operation to be modified with the information required to represent the content - * being deployed - */ - abstract void addContentToOperation(OperationBuilder builder, ModelNode op); - - /** - * If a name can be resolved from the content that name will be used, otherwise {@code null} will be returned. - * - * @return the name resolved from the content or {@code null} if no name could be resolved - */ - String resolvedName() { - return null; - } - - /** - * Creates new deployment content based on a file system path. - *

- * The {@link #resolvedName()} will return the name of the file. - *

- * - * @param content the path to the content - * - * @return the deployment content - */ - static DeploymentContent of(final Path content) { - return new DeploymentContent() { - - @Override - void addContentToOperation(final OperationBuilder builder, final ModelNode op) { - final ModelNode contentNode = op.get(CONTENT); - final ModelNode contentItem = contentNode.get(0); - // If the content points to a directory we are deploying exploded content - if (Files.isDirectory(content)) { - contentItem.get(PATH).set(content.toAbsolutePath().toString()); - contentItem.get("archive").set(false); - } else { - // The index is 0 based so use the input stream count before adding the input stream - contentItem.get(ClientConstants.INPUT_STREAM_INDEX).set(builder.getInputStreamCount()); - builder.addFileAsAttachment(content.toFile()); - } - } - - @Override - String resolvedName() { - return content.getFileName().toString(); - } - - @Override - public String toString() { - return String.format("%s(%s)", DeploymentContent.class.getName(), content); - } - }; - } - - /** - * Creates new deployment content based on the stream content. The stream content is copied, stored in-memory and - * closed. - * - * @param content the content to deploy - * - * @return the deployment content - */ - static DeploymentContent of(final InputStream content) { - final ByteArrayInputStream copiedContent = copy(content); - return new DeploymentContent() { - @Override - void addContentToOperation(final OperationBuilder builder, final ModelNode op) { - copiedContent.reset(); - final ModelNode contentNode = op.get(CONTENT); - final ModelNode contentItem = contentNode.get(0); - // The index is 0 based so use the input stream count before adding the input stream - contentItem.get(ClientConstants.INPUT_STREAM_INDEX).set(builder.getInputStreamCount()); - builder.addInputStream(copiedContent); - } - - @Override - public String toString() { - return String.format("%s(%s)", DeploymentContent.class.getName(), copiedContent); - } - }; - } - - /** - * Creates new deployment content based on the {@linkplain URL URL}. The server will require access to the URL. - * - * @param url the URL of the content to deploy - * - * @return the deployment content - */ - static DeploymentContent of(final URL url) { - return new DeploymentContent() { - @Override - void addContentToOperation(final OperationBuilder builder, final ModelNode op) { - final ModelNode contentNode = op.get(CONTENT); - final ModelNode contentItem = contentNode.get(0); - contentItem.get("url").set(url.toExternalForm()); - } - - @Override - String resolvedName() { - final String path = url.getPath(); - final int index = path.lastIndexOf('/'); - if (index >= 0) { - return path.substring(index + 1); - } - return path; - } - - @Override - public String toString() { - return String.format("%s(%s)", DeploymentContent.class.getName(), url.toExternalForm()); - } - }; - } - - /** - * Creates new deployment content based on a file system path. - *

- * The {@link #resolvedName()} will return the name of the file. - *

- * - * @param content the path to the content - * - * @return the deployment content - */ - static DeploymentContent local(final Path content) { - if (Files.notExists(content)) { - throw new IllegalArgumentException(String.format("File or directory %s does not exist.", content)); - } - return new DeploymentContent() { - - @Override - void addContentToOperation(final OperationBuilder builder, final ModelNode op) { - final ModelNode contentNode = op.get(CONTENT); - final ModelNode contentItem = contentNode.get(0); - contentItem.get(PATH).set(content.toAbsolutePath().toString()); - contentItem.get("archive").set(!Files.isDirectory(content)); - } - - @Override - String resolvedName() { - return content.getFileName().toString(); - } - - @Override - public String toString() { - return String.format("%s(%s)", DeploymentContent.class.getName(), content); - } - }; - } - - private static ByteArrayInputStream copy(final InputStream in) { - final ByteArrayOutputStream copy = new ByteArrayOutputStream(); - final byte[] buffer = new byte[64]; - int len; - try { - while ((len = in.read(buffer)) > 0) { - copy.write(buffer, 0, len); - } - return new ByteArrayInputStream(copy.toByteArray()); - } catch (IOException e) { - throw new RuntimeException("Failed to copy input stream.", e); - } finally { - try { - in.close(); - } catch (IOException ignore) { - } - } - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DeploymentDescription.java b/core/src/main/java/org/wildfly/plugin/core/DeploymentDescription.java deleted file mode 100644 index af675b0e..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DeploymentDescription.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.util.Set; - -/** - * Represents a default description for a deployment. - * - * @author James R. Perkins - */ -@SuppressWarnings("WeakerAccess") -public interface DeploymentDescription { - - /** - * Returns the name for this deployment. - * - * @return the name for this deployment - */ - String getName(); - - /** - * Returns the server groups for this deployment. - * - * @return a set of server groups for this deployment - */ - Set getServerGroups(); -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DeploymentException.java b/core/src/main/java/org/wildfly/plugin/core/DeploymentException.java deleted file mode 100644 index 1985251d..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DeploymentException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -/** - * An exception that represents a deployment error. - * - * @author James R. Perkins - */ -@SuppressWarnings({ "WeakerAccess", "unused" }) -public class DeploymentException extends RuntimeException { - - /** - * Creates a new deployment exception. - * - * @param message the message for the exception - */ - public DeploymentException(final String message) { - super(message); - } - - /** - * Creates a new deployment exception. - * - * @param cause the cause of the exception - */ - public DeploymentException(final Throwable cause) { - super(cause); - } - - /** - * Creates a new deployment exception. - * - * @param message the message for the exception - * @param cause the cause of the exception - */ - public DeploymentException(final String message, final Throwable cause) { - super(message, cause); - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DeploymentManager.java b/core/src/main/java/org/wildfly/plugin/core/DeploymentManager.java deleted file mode 100644 index b70e5a8e..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DeploymentManager.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.IOException; -import java.util.Set; - -import org.jboss.as.controller.client.ModelControllerClient; - -/** - * Allows deployment operations to be executed on a running server. This will work with both standalone servers and - * managed domain servers. - *

- * The {@linkplain DeploymentResult#asModelNode() server result} for each deployment operation will be the result of a - * composite operation. - *

- *

- * If the server is a managed domain {@linkplain DeploymentDescription#getServerGroups() server groups} are required. If - * the server is a standalone server no server groups are allowed to be define. A failed {@link DeploymentResult} - * will be returned if the server groups are empty for a managed domain or populated for a standalone server. - *

- * - * @author James R. Perkins - */ -@SuppressWarnings("unused") -public interface DeploymentManager { - - /** - * Deploys the content to the server. - *

- * If the deployment is not {@linkplain Deployment#setEnabled(boolean) enabled} a {@code deploy} operation will - * need to be invoked. This can also be achieved by invoking the {@link #deployToRuntime(DeploymentDescription)} - * method. - *

- * - * @param deployment the deployment to deploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - * @see #deployToRuntime(DeploymentDescription) - */ - DeploymentResult deploy(Deployment deployment) throws IOException; - - /** - * Deploys the content of each deployment to the server. - *

- * If the deployment is not {@linkplain Deployment#setEnabled(boolean) enabled} a {@code deploy} operation will - * need to be invoked. This can also be achieved by invoking the {@link #deployToRuntime(Set)} method. - *

- *

- * Also note that it is safe to trigger a {@code deploy} operation on already deployed deployments. - *

- * - * @param deployments a set of deployments to deploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - * @see #deployToRuntime(Set) - */ - DeploymentResult deploy(Set deployments) throws IOException; - - /** - * Deploys the content to the server if it does not already exist on the server. If the deployment already exist the - * deployment is replaced. - *

- * If the deployment is not {@linkplain Deployment#setEnabled(boolean) enabled} a {@code deploy} operation will - * need to be invoked. This can also be achieved by invoking the {@link #deployToRuntime(DeploymentDescription)} - * method. - *

- * - * @param deployment the deployment to deploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - * @see #deployToRuntime(DeploymentDescription) - */ - DeploymentResult forceDeploy(Deployment deployment) throws IOException; - - /** - * Deploys the content to the server if it does not already exist on the server. If the deployment already exist the - * deployment is replaced. - *

- * If the deployment is not {@linkplain Deployment#setEnabled(boolean) enabled} a {@code deploy} operation will - * need to be invoked. This can also be achieved by invoking the {@link #deployToRuntime(Set)} method. - *

- *

- * Also note that it is safe to trigger a {@code deploy} operation on already deployed deployments. - *

- * - * @param deployments a set of deployments to deploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - * @see #deployToRuntime(Set) - */ - DeploymentResult forceDeploy(Set deployments) throws IOException; - - /** - * Deploys existing deployment content to the runtime. - * - * @param deployment the deployment description to deploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - */ - DeploymentResult deployToRuntime(DeploymentDescription deployment) throws IOException; - - /** - * Deploys existing deployment content to the runtime for each deployment description. - * - * @param deployments the deployment descriptions to deploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - */ - DeploymentResult deployToRuntime(Set deployments) throws IOException; - - /** - * Redeploys the content to the server. Uses a {@code full-replace-deployment} operation to upload the new content, - * undeploy the old content, deploy the new content and then remove the old content. - *

- * If the deployment is not {@linkplain Deployment#setEnabled(boolean) enabled} a {@code deploy} or {@code redeploy} - * operation will need to be invoked. This can also be achieved by invoking the - * {@link #deployToRuntime(DeploymentDescription)} method or the {@link #redeployToRuntime(DeploymentDescription)} - * method. - *

- * - * @param deployment the deployment to redeploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - * @see #redeployToRuntime(DeploymentDescription) - */ - DeploymentResult redeploy(Deployment deployment) throws IOException; - - /** - * Redeploys the content to the server. Uses a {@code full-replace-deployment} operation to upload the new content, - * undeploy the old content, deploy the new content and then remove the old content. - *

- * If the deployment is not {@linkplain Deployment#setEnabled(boolean) enabled} a {@code deploy} or {@code redeploy} - * operation will need to be invoked. This can also be achieved by invoking the {@link #deployToRuntime(Set)} - * method or the {@link #redeployToRuntime(Set)} method. - *

- *

- * Also note that it is safe to trigger a {@code deploy} or operation on already deployed deployments. - *

- * - * @param deployments a set of deployments to redeploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - * @see #redeployToRuntime(Set) - */ - DeploymentResult redeploy(Set deployments) throws IOException; - - /** - * Redeploys existing deployment content to the runtime. - * - * @param deployment the deployment description to redeploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - */ - DeploymentResult redeployToRuntime(DeploymentDescription deployment) throws IOException; - - /** - * Redeploys existing deployment content to the runtime for each deployment description. - * - * @param deployments the deployment descriptions to redeploy - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - */ - DeploymentResult redeployToRuntime(Set deployments) throws IOException; - - /** - * Undeploys the deployment from the server. - * - * @param undeployDescription the description for undeploying the content - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - */ - DeploymentResult undeploy(UndeployDescription undeployDescription) throws IOException; - - /** - * Undeploys the deployment from the server. - * - * @param undeployDescriptions the descriptions for undeploying the content - * - * @return the result of the deployment - * - * @throws IOException if a failure occurs communicating with the server - */ - DeploymentResult undeploy(Set undeployDescriptions) throws IOException; - - /** - * Returns the available deployments. - * - * @return the deployments - * - * @throws IOException if a failure occurs communicating with the server - */ - Set getDeployments() throws IOException; - - /** - * Returns all the deployments on the specified server-group. These deployments may also belong to other server - * groups. - * - * @param serverGroup the server group to get the deployments for - * - * @return the deployments - * - * @throws IOException if a failure occurs communicating with the server - * @throws IllegalStateException if the running server is not a managed domain - */ - Set getDeployments(String serverGroup) throws IOException; - - /** - * Returns the names of deployed content. - * - * @return the names of deployed content - * - * @throws IOException if a failure occurs communicating with the server - */ - Set getDeploymentNames() throws IOException; - - /** - * Checks if the deployment content is on the server. - * - * @param name the name of the deployment - * - * @return {@code true} if the deployment content exists otherwise {@code false} - * - * @throws IOException if a failure occurs communicating with the server - */ - boolean hasDeployment(String name) throws IOException; - - /** - * Checks if the deployment content is on the server. - * - * @param name the name of the deployment - * @param serverGroup the server group to check for the deployment on - * - * @return {@code true} if the deployment content exists otherwise {@code false} - */ - boolean hasDeployment(String name, String serverGroup) throws IOException; - - /** - * Checks if the deployment has been deployed to the runtime. The deployment must already exist on the server. - *

- * If a deployment is enabled it has been deployed to the runtime. Otherwise the deployment has not been - * deployed to the runtime. - *

- * - * @param name the name of the deployment - * - * @return {@code true} if the deployment content exists and is enabled otherwise {@code false} - * - * @throws IOException if a failure occurs communicating with the server - * @see #isEnabled(String, String) for managed domain deployments - */ - boolean isEnabled(String name) throws IOException; - - /** - * Checks if the deployment has been deployed to the runtime. The deployment must already exist on the server. - *

- * If a deployment is enabled it has been deployed to the runtime. Otherwise the deployment has not been - * deployed to the runtime. - *

- * - * @param name the name of the deployment - * @param serverGroup the server group to check for the deployment on - * - * @return {@code true} if the deployment content exists and is enabled otherwise {@code false} - * - * @see #isEnabled(String) for standalone deployments - */ - boolean isEnabled(String name, String serverGroup) throws IOException; - - /** - * A factory to create a new deployment manager - */ - class Factory { - - /** - * Creates a new deployment manager. - *

- * The client will not be {@linkplain ModelControllerClient#close() closed} by the {@link DeploymentManager}. - * The user is responsible for {@linkplain ModelControllerClient#close() closing} the client. - *

- * - * @param client the client used to communicate with the server - * - * @return a new deployment manager - */ - public static DeploymentManager create(final ModelControllerClient client) { - return new DefaultDeploymentManager(client); - } - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DeploymentOperations.java b/core/src/main/java/org/wildfly/plugin/core/DeploymentOperations.java deleted file mode 100644 index 5578b578..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DeploymentOperations.java +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT; -import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT_DEPLOY_OPERATION; -import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT_FULL_REPLACE_OPERATION; -import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT_REDEPLOY_OPERATION; -import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT_UNDEPLOY_OPERATION; -import static org.jboss.as.controller.client.helpers.ClientConstants.NAME; -import static org.jboss.as.controller.client.helpers.ClientConstants.RUNTIME_NAME; -import static org.jboss.as.controller.client.helpers.ClientConstants.SERVER_GROUP; -import static org.jboss.as.controller.client.helpers.Operations.createAddOperation; -import static org.jboss.as.controller.client.helpers.Operations.createOperation; -import static org.jboss.as.controller.client.helpers.Operations.createRemoveOperation; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.jboss.as.controller.client.Operation; -import org.jboss.as.controller.client.helpers.Operations.CompositeOperationBuilder; -import org.jboss.dmr.ModelNode; -import org.jboss.dmr.ModelType; -import org.wildfly.common.Assert; - -/** - * A helper to create deployment operations. - *

- * Note that when creating operations deployment operations the - * {@linkplain Deployment#getServerGroups() deployments server-groups} are used to determine if the deployment is for a - * managed domain. If the server groups are {@linkplain Set#isEmpty() is empty} the standalone deployment operations - * will be created. Otherwise deployment operations for managed domains will be created. - *

- *

- * All operations create will be composite operations for consistency of parsing the result of executing the operation. - *

- * - * @author James R. Perkins - */ -@SuppressWarnings({ "unused", "StaticMethodOnlyUsedInOneClass", "WeakerAccess" }) -public class DeploymentOperations { - static final String ENABLED = "enabled"; - static final ModelNode EMPTY_ADDRESS = new ModelNode().setEmptyList(); - - static { - EMPTY_ADDRESS.protect(); - } - - /** - * Creates an {@linkplain ModelNode address} that can be used as the address for an operation. The address is - * simply a {@link ModelNode} of type {@link ModelType#LIST}. - *

- * The string is split into key/value pairs. If the final key does not have a value an {@code *} is used to - * indicate a wildcard for the address. - *

- * - * @param pairs the key/value pairs to use - * - * @return an address for the key/value pairs - */ - static ModelNode createAddress(final String... pairs) { - return createAddress(Arrays.asList(pairs)); - } - - /** - * Creates an {@linkplain ModelNode address} that can be used as the address for an operation. The address is - * simply a {@link ModelNode} of type {@link ModelType#LIST}. - *

- * The string is split into key/value pairs. If the final key does not have a value an {@code *} is used to - * indicate a wildcard for the address. - *

- * - * @param pairs the key/value pairs to use - * - * @return an address for the key/value pairs - */ - static ModelNode createAddress(final Iterable pairs) { - final ModelNode address = new ModelNode(); - final Iterator iterator = pairs.iterator(); - while (iterator.hasNext()) { - final String key = iterator.next(); - final String value = (iterator.hasNext() ? iterator.next() : "*"); - address.add(key, value); - } - return address; - } - - /** - * Creates an operation to add deployment content to a running server. If the deployment is set to be - * {@linkplain Deployment#isEnabled() enabled} the content will also be deployed. - * - * @param deployment the deployment to deploy - * - * @return the deploy operation - * - * @see #createDeployOperation(DeploymentDescription) - */ - public static Operation createAddDeploymentOperation(final Deployment deployment) { - Assert.checkNotNullParam("deployment", deployment); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - addDeploymentOperationStep(builder, deployment); - return builder.build(); - } - - /** - * Creates an operation to add deployment content to a running server for each deployment. If the deployment is set - * to be {@linkplain Deployment#isEnabled() enabled} the content will also be deployed. - * - * @param deployments a set of deployments to deploy - * - * @return the deploy operation - * - * @see #createDeployOperation(Set) - */ - public static Operation createAddDeploymentOperation(final Set deployments) { - Assertions.requiresNotNullOrNotEmptyParameter("deployments", deployments); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - for (Deployment deployment : deployments) { - addDeploymentOperationStep(builder, deployment); - } - return builder.build(); - } - - /** - * Creates an operation to deploy existing deployment content to the runtime. - * - * @param deployment the deployment to deploy - * - * @return the deploy operation - */ - public static Operation createDeployOperation(final DeploymentDescription deployment) { - Assert.checkNotNullParam("deployment", deployment); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - addDeployOperationStep(builder, deployment); - return builder.build(); - } - - /** - * Creates an option to deploy existing content to the runtime for each deployment - * - * @param deployments a set of deployments to deploy - * - * @return the deploy operation - */ - public static Operation createDeployOperation(final Set deployments) { - Assertions.requiresNotNullOrNotEmptyParameter("deployments", deployments); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - for (DeploymentDescription deployment : deployments) { - addDeployOperationStep(builder, deployment); - } - return builder.build(); - } - - /** - * Creates an operation to replace deployment content to a running server. The previous content is undeployed, then - * the new content is deployed, followed by the previous content being removed. - * - * @param deployment the deployment used to replace an existing deployment - * - * @return the deploy operation - */ - public static Operation createReplaceOperation(final Deployment deployment) { - Assert.checkNotNullParam("deployment", deployment); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - addReplaceOperationSteps(builder, deployment); - return builder.build(); - } - - /** - * Creates an operation to replace deployment content to a running server. The previous content is undeployed, then - * the new content is deployed, followed by the previous content being removed. - * - * @param deployments the set deployment used to replace existing deployments which match the same name - * - * @return the deploy operation - */ - public static Operation createReplaceOperation(final Set deployments) { - Assertions.requiresNotNullOrNotEmptyParameter("deployments", deployments); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - for (Deployment deployment : deployments) { - addReplaceOperationSteps(builder, deployment); - } - return builder.build(); - } - - /** - * Creates a redeploy operation for the deployment. - *

- * Note this does not upload new content. To add new content and deploy the new content see - * {@link #createReplaceOperation(Deployment)}. - *

- * - * @param deployment the deployment to redeploy - * - * @return the redeploy operation - */ - public static Operation createRedeployOperation(final DeploymentDescription deployment) { - Assert.checkNotNullParam("deployment", deployment); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - addRedeployOperationStep(builder, deployment); - return builder.build(); - } - - /** - * Creates a redeploy operation for the deployment. - *

- * Note this does not upload new content. To add new content and deploy the new content see - * {@link #createReplaceOperation(Set)}. - *

- * - * @param deployments the set of deployments to redeploy - * - * @return the redeploy operation - */ - public static Operation createRedeployOperation(final Set deployments) { - Assertions.requiresNotNullOrNotEmptyParameter("deployments", deployments); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - for (DeploymentDescription deployment : deployments) { - addRedeployOperationStep(builder, deployment); - } - return builder.build(); - } - - /** - * Creates an undeploy operation. - *

- * If the {@link UndeployDescription#isRemoveContent()} returns {@code true} the content will also be removed from - * the content repository. Otherwise the content will remain on the server and only the {@code undeploy} operation - * will be executed. - *

- *

- * Note that the {@link UndeployDescription#isFailOnMissing() failOnMissing} is ignored and the operation will fail - * if any deployments being undeployed are missing. - *

- * - * @param undeployDescription the description used to crate the operation - * - * @return the undeploy operation - */ - public static Operation createUndeployOperation(final UndeployDescription undeployDescription) { - Assert.checkNotNullParam("undeployDescription", undeployDescription); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - addUndeployOperationStep(builder, undeployDescription); - return builder.build(); - } - - /** - * Creates an undeploy operation for each deployment description. - *

- * If the {@link UndeployDescription#isRemoveContent()} returns {@code true} the content will also be removed from - * the content repository. Otherwise the content will remain on the server and only the {@code undeploy} operation - * will be executed. - *

- *

- * Note that the {@link UndeployDescription#isFailOnMissing() failOnMissing} is ignored and the operation will fail - * if any deployments being undeployed are missing. - *

- * - * @param undeployDescriptions the set of descriptions used to crate the operation - * - * @return the undeploy operation - */ - public static Operation createUndeployOperation(final Set undeployDescriptions) { - Assertions.requiresNotNullOrNotEmptyParameter("undeployDescriptions", undeployDescriptions); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(true); - for (UndeployDescription undeployDescription : undeployDescriptions) { - addUndeployOperationStep(builder, undeployDescription); - } - return builder.build(); - } - - /** - * Creates an add operation on the deployment resource to the composite operation. - *

- * If the {@link Deployment#isEnabled()} is {@code false} a step to - * {@linkplain #addDeployOperationStep(CompositeOperationBuilder, DeploymentDescription) deploy} the content may be - * required. - *

- * - * @param builder the builder to add the step to - * @param deployment the deployment to deploy - */ - static void addDeploymentOperationStep(final CompositeOperationBuilder builder, final Deployment deployment) { - final String name = deployment.getName(); - final ModelNode address = createAddress(DEPLOYMENT, name); - final String runtimeName = deployment.getRuntimeName(); - final ModelNode addOperation = createAddOperation(address); - if (runtimeName != null) { - addOperation.get(RUNTIME_NAME).set(runtimeName); - } - addOperation.get(ENABLED).set(deployment.isEnabled()); - addContent(builder, addOperation, deployment); - builder.addStep(addOperation); - - final Set serverGroups = deployment.getServerGroups(); - // If the server groups are empty this is a standalone deployment - if (!serverGroups.isEmpty()) { - for (String serverGroup : serverGroups) { - final ModelNode sgAddress = createAddress(SERVER_GROUP, serverGroup, DEPLOYMENT, name); - - final ModelNode op = createAddOperation(sgAddress); - op.get(ENABLED).set(deployment.isEnabled()); - if (runtimeName != null) { - op.get(RUNTIME_NAME).set(runtimeName); - } - builder.addStep(op); - } - } - } - - /** - * Adds the deploy operation as a step to the composite operation. - * - * @param builder the builder to add the step to - * @param deployment the deployment to deploy - */ - static void addDeployOperationStep(final CompositeOperationBuilder builder, final DeploymentDescription deployment) { - final String name = deployment.getName(); - - final Set serverGroups = deployment.getServerGroups(); - // If the server groups are empty this is a standalone deployment - if (serverGroups.isEmpty()) { - final ModelNode address = createAddress(DEPLOYMENT, name); - builder.addStep(createOperation(DEPLOYMENT_DEPLOY_OPERATION, address)); - } else { - for (String serverGroup : serverGroups) { - final ModelNode address = createAddress(SERVER_GROUP, serverGroup, DEPLOYMENT, name); - builder.addStep(createOperation(DEPLOYMENT_DEPLOY_OPERATION, address)); - } - } - } - - /** - * Adds a {@code full-replace-deployment} operation. If the {@code allowAddIfMissing} is set to {@code true} and - * the {@linkplain Deployment#getServerGroups() server-groups} are not empty the content will be first added to the - * server-group before the {@code full-replace-deployment} is executed. - * - * @param builder the composite builder to add steps to - * @param deployment the deployment used for the replacement - * @param currentDeployment the currently deployed application - * @param allowAddIfMissing {@code true} if this should add deployments to server groups which they do not already - * exist on, otherwise {@code false} - */ - static void addReplaceOperationSteps(final CompositeOperationBuilder builder, final Deployment deployment, - final DeploymentDescription currentDeployment, final boolean allowAddIfMissing) { - final String name = deployment.getName(); - final String runtimeName = deployment.getRuntimeName(); - // Adds need to happen first on server-groups otherwise the full-replace-deployment will fail currently - if (allowAddIfMissing) { - // If deployment is not on the server group, add it but don't yet enable it. The full-replace-deployment - // should handle that part. - @SuppressWarnings("TypeMayBeWeakened") - final Set serverGroups = new LinkedHashSet<>(deployment.getServerGroups()); - if (!serverGroups.isEmpty()) { - serverGroups.removeAll(currentDeployment.getServerGroups()); - for (String serverGroup : serverGroups) { - final ModelNode sgAddress = createAddress(SERVER_GROUP, serverGroup, DEPLOYMENT, name); - final ModelNode addOp = createAddOperation(sgAddress); - // Explicitly set to false here as the full-replace-deployment should take care of enabling this - addOp.get(ENABLED).set(false); - if (runtimeName != null) { - addOp.get(RUNTIME_NAME).set(runtimeName); - } - builder.addStep(addOp); - } - } - } - final ModelNode op = createOperation(DEPLOYMENT_FULL_REPLACE_OPERATION); - op.get(NAME).set(name); - if (runtimeName != null) { - op.get(RUNTIME_NAME).set(runtimeName); - } - addContent(builder, op, deployment); - op.get(ENABLED).set(deployment.isEnabled()); - builder.addStep(op); - } - - /** - * Adds a {@code full-replace-deployment} step for the deployment. - * - * @param builder the builder to add the step to - * @param deployment the deployment used to replace the existing deployment - */ - static void addReplaceOperationSteps(final CompositeOperationBuilder builder, final Deployment deployment) { - final String name = deployment.getName(); - final String runtimeName = deployment.getRuntimeName(); - final ModelNode op = createOperation(DEPLOYMENT_FULL_REPLACE_OPERATION); - op.get(NAME).set(name); - if (runtimeName != null) { - op.get(RUNTIME_NAME).set(runtimeName); - } - addContent(builder, op, deployment); - op.get(ENABLED).set(deployment.isEnabled()); - builder.addStep(op); - } - - /** - * Adds a redeploy step to the composite operation. - * - * @param builder the builder to add the step to - * @param deployment the deployment being redeployed - */ - private static void addRedeployOperationStep(final CompositeOperationBuilder builder, - final DeploymentDescription deployment) { - final String deploymentName = deployment.getName(); - final Set serverGroups = deployment.getServerGroups(); - if (serverGroups.isEmpty()) { - builder.addStep(createOperation(DEPLOYMENT_REDEPLOY_OPERATION, createAddress(DEPLOYMENT, deploymentName))); - } else { - for (String serverGroup : serverGroups) { - builder.addStep(createOperation(DEPLOYMENT_REDEPLOY_OPERATION, - createAddress(SERVER_GROUP, serverGroup, DEPLOYMENT, deploymentName))); - } - } - } - - private static void addUndeployOperationStep(final CompositeOperationBuilder builder, - @SuppressWarnings("TypeMayBeWeakened") final UndeployDescription undeployDescription) { - final String name = undeployDescription.getName(); - final Set serverGroups = undeployDescription.getServerGroups(); - if (serverGroups.isEmpty()) { - final ModelNode address = createAddress(DEPLOYMENT, name); - builder.addStep(createOperation(DEPLOYMENT_UNDEPLOY_OPERATION, address)); - if (undeployDescription.isRemoveContent()) { - builder.addStep(createRemoveOperation(address)); - } - } else { - for (String serverGroup : serverGroups) { - final ModelNode address = createAddress(SERVER_GROUP, serverGroup, DEPLOYMENT, name); - builder.addStep(createOperation(DEPLOYMENT_UNDEPLOY_OPERATION, address)); - if (undeployDescription.isRemoveContent()) { - builder.addStep(createRemoveOperation(address)); - } - } - if (undeployDescription.isRemoveContent()) { - builder.addStep(createRemoveOperation(createAddress(DEPLOYMENT, name))); - } - } - } - - private static void addContent(final CompositeOperationBuilder builder, final ModelNode op, final Deployment deployment) { - deployment.getContent().addContentToOperation(builder, op); - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/DeploymentResult.java b/core/src/main/java/org/wildfly/plugin/core/DeploymentResult.java deleted file mode 100644 index 7abb5d26..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/DeploymentResult.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.dmr.ModelNode; - -/** - * Represents the results of a deployment. - * - * @author James R. Perkins - */ -@SuppressWarnings("unused") -public class DeploymentResult { - - static final DeploymentResult SUCCESSFUL = new DeploymentResult(); - - private final boolean successful; - private final String failureMessage; - private final ModelNode result; - - private DeploymentResult() { - successful = true; - failureMessage = null; - result = new ModelNode(); - result.protect(); - } - - /** - * Creates a new deployment result based on the DMR result from the deployment operation. - * - * @param result the DMR result from the operation - */ - DeploymentResult(final ModelNode result) { - successful = Operations.isSuccessfulOutcome(result); - if (successful) { - failureMessage = null; - } else { - failureMessage = Operations.getFailureDescription(result).asString(); - } - this.result = result.clone(); - this.result.protect(); - } - - /** - * Creates an unsuccessful result with the failure description. - * - * @param failureMessage the failure description - */ - DeploymentResult(final CharSequence failureMessage) { - successful = false; - this.failureMessage = failureMessage.toString(); - result = new ModelNode(); - result.protect(); - } - - /** - * Creates an unsuccessful result with the failure description. - * - * @param format the format used for the failure description - * @param args the arguments for the format pattern - */ - DeploymentResult(final String format, final Object... args) { - this(String.format(format, args)); - } - - /** - * Determines if the deployment was successful or not. - * - * @return {@code true} if the deployment was successful, otherwise {@code false} - */ - public boolean successful() { - return successful; - } - - /** - * Checks to see if the deployment was successful and if not throws a {@link DeploymentException} with the failure - * message. - * - * @throws DeploymentException if the deployment was not successful - */ - public void assertSuccess() throws DeploymentException { - if (!successful) { - throw new DeploymentException(failureMessage); - } - } - - /** - * Returns the failure message if the deployment was not {@linkplain #successful() successful}. - * - * @return the failure description or {@code null} if the deployment was {@linkplain #successful() successful}. - */ - public String getFailureMessage() { - return failureMessage; - } - - /** - * The result from the deployment operation. - *

- * In some cases the result may be {@linkplain org.jboss.dmr.ModelType#UNDEFINED undefined}. - *

- * - * @return the result - */ - public ModelNode asModelNode() { - return result; - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/GalleonUtils.java b/core/src/main/java/org/wildfly/plugin/core/GalleonUtils.java deleted file mode 100644 index 5beec61b..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/GalleonUtils.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugin.core; - -import static org.wildfly.plugin.core.Constants.FORK_EMBEDDED_PROCESS_OPTION; -import static org.wildfly.plugin.core.Constants.STANDALONE; - -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import org.jboss.galleon.Constants; -import org.jboss.galleon.ProvisioningException; -import org.jboss.galleon.api.ConfigurationId; -import org.jboss.galleon.api.GalleonBuilder; -import org.jboss.galleon.api.GalleonFeaturePack; -import org.jboss.galleon.api.Provisioning; -import org.jboss.galleon.api.config.GalleonConfigurationWithLayersBuilder; -import org.jboss.galleon.api.config.GalleonFeaturePackConfig; -import org.jboss.galleon.api.config.GalleonProvisioningConfig; -import org.jboss.galleon.universe.FeaturePackLocation; -import org.jboss.galleon.universe.maven.repo.MavenRepoManager; - -/** - * @author jdenise - */ -public class GalleonUtils { - - private static final String WILDFLY_DEFAULT_FEATURE_PACK_LOCATION = "wildfly@maven(org.jboss.universe:community-universe)"; - - /** - * Galleon provisioning of a default server. - * - * @param jbossHome Server installation directory - * @param featurePackLocation the location of the feature pack - * @param version WildFly version, if null latest is used. - * @param artifactResolver Artifact resolver used by Galleon - * @throws ProvisioningException if there is an error provisioning the server - */ - public static void provision(Path jbossHome, String featurePackLocation, String version, MavenRepoManager artifactResolver) - throws ProvisioningException { - GalleonProvisioningConfig config = buildDefaultConfig(featurePackLocation, version); - try (Provisioning pm = new GalleonBuilder().addArtifactResolver(artifactResolver).newProvisioningBuilder(config) - .setInstallationHome(jbossHome) - .build()) { - pm.provision(config); - } - } - - /** - * Build a default WildFly provisioning config. - * - * @return - * @throws ProvisioningException - */ - public static GalleonProvisioningConfig buildDefaultConfig() throws ProvisioningException { - return buildDefaultConfig(WILDFLY_DEFAULT_FEATURE_PACK_LOCATION, null); - } - - /** - * Build a default WildFly provisioning config. - * - * @param version WildFly version, if null latest is used. - * @return - * @throws ProvisioningException - */ - public static GalleonProvisioningConfig buildDefaultConfig(String featurePackLocation, String version) - throws ProvisioningException { - String location = getWildFlyFeaturePackLocation(featurePackLocation, version); - GalleonProvisioningConfig.Builder state = GalleonProvisioningConfig.builder(); - GalleonFeaturePackConfig.Builder fp = GalleonFeaturePackConfig.builder(FeaturePackLocation.fromString(location)); - fp.setInheritConfigs(true); - fp.setInheritPackages(true); - state.addFeaturePackDep(fp.build()); - Map options = new HashMap<>(); - options.put(FORK_EMBEDDED_PROCESS_OPTION, "true"); - state.addOptions(options); - return state.build(); - } - - /** - * Build a Galleon provisioning configuration. - * - * @param pm The Galleon provisioning runtime. - * @param featurePacks The list of feature-packs. - * @param layers Layers to include. - * @param excludedLayers Layers to exclude. - * @param pluginOptions Galleon plugin options. - * @param layersConfigFileName The name of the configuration generated from layers - * @return The provisioning config. - * @throws ProvisioningException - */ - public static GalleonProvisioningConfig buildConfig(GalleonBuilder pm, - List featurePacks, - List layers, - List excludedLayers, - Map pluginOptions, String layersConfigFileName) - throws ProvisioningException, IllegalArgumentException { - final GalleonProvisioningConfig.Builder state = GalleonProvisioningConfig.builder(); - boolean hasLayers = !layers.isEmpty(); - boolean fpWithDefaults = true; - if (!hasLayers) { - // Check we have all feature-packs with default values only. - for (GalleonFeaturePack fp : featurePacks) { - if (fp.isInheritConfigs() != null || - fp.isInheritPackages() != null || - !fp.getIncludedConfigs().isEmpty() || - !fp.getExcludedConfigs().isEmpty() || - fp.isTransitive() || - !fp.getExcludedPackages().isEmpty() || - !fp.getIncludedPackages().isEmpty()) { - fpWithDefaults = false; - break; - } - } - } - - for (GalleonFeaturePack fp : featurePacks) { - if (fp.getLocation() == null && (fp.getGroupId() == null || fp.getArtifactId() == null) - && fp.getNormalizedPath() == null) { - throw new IllegalArgumentException("Feature-pack location, Maven GAV or feature pack path is missing"); - } - - final FeaturePackLocation fpl; - if (fp.getNormalizedPath() != null) { - fpl = pm.addLocal(fp.getNormalizedPath(), false); - } else if (fp.getGroupId() != null && fp.getArtifactId() != null) { - String coords = getMavenCoords(fp); - fpl = FeaturePackLocation.fromString(coords); - } else { - // Special case for G:A that conflicts with producer:channel that we can't have in the plugin. - String location = fp.getLocation(); - if (!FeaturePackLocation.fromString(location).hasUniverse()) { - long numSeparators = location.chars().filter(ch -> ch == ':').count(); - if (numSeparators <= 1) { - location += ":"; - } - } - fpl = FeaturePackLocation.fromString(location); - } - - final GalleonFeaturePackConfig.Builder fpConfig = fp.isTransitive() - ? GalleonFeaturePackConfig.transitiveBuilder(fpl) - : GalleonFeaturePackConfig.builder(fpl); - if (fp.isInheritConfigs() == null) { - if (hasLayers) { - fpConfig.setInheritConfigs(false); - } else { - if (fpWithDefaults) { - fpConfig.setInheritConfigs(true); - } - } - } else { - fpConfig.setInheritConfigs(fp.isInheritConfigs()); - } - - if (fp.isInheritPackages() == null) { - if (hasLayers) { - fpConfig.setInheritPackages(false); - } else { - if (fpWithDefaults) { - fpConfig.setInheritConfigs(true); - } - } - } else { - fpConfig.setInheritPackages(fp.isInheritPackages()); - } - - if (!fp.getExcludedConfigs().isEmpty()) { - for (ConfigurationId configId : fp.getExcludedConfigs()) { - if (configId.isModelOnly()) { - fpConfig.excludeConfigModel(configId.getId().getModel()); - } else { - fpConfig.excludeDefaultConfig(configId.getId()); - } - } - } - if (!fp.getIncludedConfigs().isEmpty()) { - for (ConfigurationId configId : fp.getIncludedConfigs()) { - if (configId.isModelOnly()) { - fpConfig.includeConfigModel(configId.getId().getModel()); - } else { - fpConfig.includeDefaultConfig(configId.getId()); - } - } - } - - if (!fp.getIncludedPackages().isEmpty()) { - for (String includedPackage : fp.getIncludedPackages()) { - fpConfig.includePackage(includedPackage); - } - } - if (!fp.getExcludedPackages().isEmpty()) { - for (String excludedPackage : fp.getExcludedPackages()) { - fpConfig.excludePackage(excludedPackage); - } - } - - state.addFeaturePackDep(fpConfig.build()); - } - - if (!layers.isEmpty()) { - GalleonConfigurationWithLayersBuilder config = GalleonConfigurationWithLayersBuilder.builder(STANDALONE, - layersConfigFileName); - for (String l : layers) { - config.includeLayer(l); - } - for (String l : excludedLayers) { - config.excludeLayer(l); - } - state.addConfig(config.build()); - if (pluginOptions.isEmpty()) { - pluginOptions = Collections.singletonMap(Constants.OPTIONAL_PACKAGES, Constants.PASSIVE_PLUS); - } else if (!pluginOptions.containsKey(Constants.OPTIONAL_PACKAGES)) { - pluginOptions.put(Constants.OPTIONAL_PACKAGES, Constants.PASSIVE_PLUS); - } - } - - state.addOptions(pluginOptions); - - return state.build(); - } - - private static String getMavenCoords(GalleonFeaturePack fp) { - StringBuilder builder = new StringBuilder(); - builder.append(fp.getGroupId()).append(":").append(fp.getArtifactId()); - String type = fp.getExtension() == null ? fp.getType() : fp.getExtension(); - if (fp.getClassifier() != null || type != null) { - builder.append(":").append(fp.getClassifier() == null ? "" : fp.getClassifier()).append(":") - .append(type == null ? "" : type); - } - if (fp.getVersion() != null) { - builder.append(":").append(fp.getVersion()); - } - return builder.toString(); - } - - private static String getWildFlyFeaturePackLocation(String featurePackLocation, String version) { - StringBuilder fplBuilder = new StringBuilder(); - fplBuilder.append(Objects.requireNonNull(featurePackLocation, "The feature pack location is required.")); - if (version != null) { - fplBuilder.append("#").append(version); - } - return fplBuilder.toString(); - } -} diff --git a/plugin/src/main/java/org/wildfly/plugin/common/MavenJBossLogger.java b/core/src/main/java/org/wildfly/plugin/core/MavenJBossLogger.java similarity index 98% rename from plugin/src/main/java/org/wildfly/plugin/common/MavenJBossLogger.java rename to core/src/main/java/org/wildfly/plugin/core/MavenJBossLogger.java index bbe7a2d4..269bb996 100644 --- a/plugin/src/main/java/org/wildfly/plugin/common/MavenJBossLogger.java +++ b/core/src/main/java/org/wildfly/plugin/core/MavenJBossLogger.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.wildfly.plugin.common; +package org.wildfly.plugin.core; import java.text.MessageFormat; diff --git a/core/src/main/java/org/wildfly/plugin/core/OperationExecutionException.java b/core/src/main/java/org/wildfly/plugin/core/OperationExecutionException.java deleted file mode 100644 index c35847b4..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/OperationExecutionException.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import org.jboss.as.controller.client.Operation; -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.dmr.ModelNode; - -/** - * An error indicating an operation has failed to execute. - * - * @author James R. Perkins - */ -@SuppressWarnings("WeakerAccess") -public class OperationExecutionException extends RuntimeException { - private final ModelNode result; - - /** - * Creates a new exception with the failure message from the result. - * - * @param operation the operation which failed - * @param result the result of the operation - */ - public OperationExecutionException(final Operation operation, final ModelNode result) { - this(null, operation, result); - } - - /** - * Creates a new exception with the failure message from the result. - * - * @param operation the operation which failed - * @param result the result of the operation - */ - public OperationExecutionException(final ModelNode operation, final ModelNode result) { - this(null, operation, result); - } - - /** - * Creates a new exception with the failure message from the result. - * - * @param message the message to prepend to the failure message - * @param operation the operation which failed - * @param result the result of the operation - */ - public OperationExecutionException(final String message, final Operation operation, final ModelNode result) { - this(message, operation.getOperation(), result); - } - - /** - * Creates a new exception with the failure message from the result. - * - * @param message the message to prepend to the failure message - * @param operation the operation which failed - * @param result the result of the operation - */ - public OperationExecutionException(final String message, final ModelNode operation, final ModelNode result) { - super(formatMessage(message, operation, result)); - this.result = result; - this.result.protect(); - } - - /** - * Returns the result from the operation executed. - * - * @return the result of the operation - */ - @SuppressWarnings("unused") - public ModelNode getExecutionResult() { - return result; - } - - private static String formatMessage(final String message, final ModelNode operation, final ModelNode result) { - if (message == null) { - return String.format("Failed to execute %s%nReason:%s", operation, - Operations.getFailureDescription(result).asString()); - } - final String msg = (message.endsWith(".") ? message : message + "."); - return String.format("%s Failed to execute %s%nReason:%s", msg, operation, - Operations.getFailureDescription(result).asString()); - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/PluginProgressTracker.java b/core/src/main/java/org/wildfly/plugin/core/PluginProgressTracker.java deleted file mode 100644 index 4fa04c0e..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/PluginProgressTracker.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugin.core; - -import org.apache.maven.plugin.logging.Log; -import org.jboss.galleon.api.Provisioning; -import org.jboss.galleon.progresstracking.ProgressCallback; -import org.jboss.galleon.progresstracking.ProgressTracker; - -/** - * - * @author jdenise@redhat.com - */ -public class PluginProgressTracker implements ProgressCallback { - - private static final String DELAYED_EXECUTION_MSG = "Delayed generation, waiting..."; - private final Log log; - private final String msgStart; - private long lastTime; - private final boolean delayed; - - private PluginProgressTracker(Log log, String msgStart, boolean delayed) { - this.log = log; - this.msgStart = msgStart; - this.delayed = delayed; - } - - @Override - public void starting(ProgressTracker tracker) { - log.info(msgStart); - lastTime = System.currentTimeMillis(); - } - - @Override - public void processing(ProgressTracker tracker) { - // The case of config generated in forked process. - if (delayed && tracker.getItem() == null) { - log.info(DELAYED_EXECUTION_MSG); - return; - } - // Print a message every 5 seconds - if (System.currentTimeMillis() - lastTime > 5000) { - if (tracker.getTotalVolume() > 0) { - log.info(String.format("%s of %s (%s%%)", - tracker.getProcessedVolume(), tracker.getTotalVolume(), - ((double) Math.round(tracker.getProgress() * 10)) / 10)); - } else { - log.info("In progress..."); - } - lastTime = System.currentTimeMillis(); - } - } - - @Override - public void processed(ProgressTracker tracker) { - } - - @Override - public void pulse(ProgressTracker tracker) { - } - - @Override - public void complete(ProgressTracker tracker) { - } - - public static void initTrackers(Provisioning pm, Log log) { - pm.setProgressCallback(org.jboss.galleon.Constants.TRACK_PACKAGES, - new PluginProgressTracker(log, "Installing packages", false)); - pm.setProgressCallback(org.jboss.galleon.Constants.TRACK_CONFIGS, - new PluginProgressTracker(log, "Generating configurations", true)); - pm.setProgressCallback(org.jboss.galleon.Constants.TRACK_LAYOUT_BUILD, - new PluginProgressTracker(log, "Resolving feature-packs", false)); - pm.setProgressCallback("JBMODULES", - new PluginProgressTracker(log, "Resolving artifacts", false)); - pm.setProgressCallback("JBEXTRACONFIGS", - new PluginProgressTracker(log, "Generating extra configurations", true)); - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/ServerHelper.java b/core/src/main/java/org/wildfly/plugin/core/ServerHelper.java deleted file mode 100644 index 89f005e7..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/ServerHelper.java +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import static org.jboss.as.controller.client.helpers.ClientConstants.CONTROLLER_PROCESS_STATE_STARTING; -import static org.jboss.as.controller.client.helpers.ClientConstants.CONTROLLER_PROCESS_STATE_STOPPING; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.as.controller.client.helpers.Operations.CompositeOperationBuilder; -import org.jboss.as.controller.client.helpers.domain.DomainClient; -import org.jboss.as.controller.client.helpers.domain.ServerIdentity; -import org.jboss.as.controller.client.helpers.domain.ServerStatus; -import org.jboss.dmr.ModelNode; -import org.jboss.logging.Logger; -import org.wildfly.common.Assert; - -/** - * @author James R. Perkins - */ -@SuppressWarnings({ "StaticMethodOnlyUsedInOneClass", "WeakerAccess", "unused", "MagicNumber" }) -public class ServerHelper { - private static final ModelNode EMPTY_ADDRESS = new ModelNode().setEmptyList(); - private static final Logger LOGGER = Logger.getLogger(ServerHelper.class); - - static { - EMPTY_ADDRESS.protect(); - } - - /** - * Checks whether or not the directory is a valid home directory for a server. - *

- * This validates the path is not {@code null}, exists, is a directory and contains a {@code jboss-modules.jar}. - *

- * - * @param path the path to validate - * - * @return {@code true} if the path is valid otherwise {@code false} - */ - public static boolean isValidHomeDirectory(final Path path) { - return Utils.isValidHomeDirectory(path); - } - - /** - * Checks whether or not the directory is a valid home directory for a server. - *

- * This validates the path is not {@code null}, exists, is a directory and contains a {@code jboss-modules.jar}. - *

- * - * @param path the path to validate - * - * @return {@code true} if the path is valid otherwise {@code false} - */ - public static boolean isValidHomeDirectory(final String path) { - return path != null && isValidHomeDirectory(Paths.get(path)); - } - - /** - * Returns the description of the running container. - * - * @param client the client used to query the server - * - * @return the description of the running container - * - * @throws IOException if an error occurs communicating with the server - * @throws OperationExecutionException if the operation used to query the container fails - */ - public static ContainerDescription getContainerDescription(final ModelControllerClient client) - throws IOException, OperationExecutionException { - return DefaultContainerDescription.lookup(Assert.checkNotNullParam("client", client)); - } - - /** - * Checks if the container status is "reload-required" and if it's the case executes reload and waits for completion. - * - * @param client the client used to execute the operation - */ - public static void reloadIfRequired(final ModelControllerClient client, final long timeout) { - final String launchType = launchType(client); - if ("STANDALONE".equalsIgnoreCase(launchType)) { - final String runningState = serverState(client); - if ("reload-required".equalsIgnoreCase(runningState)) { - executeReload(client, Operations.createOperation("reload")); - try { - waitForStandalone(client, timeout); - } catch (InterruptedException | TimeoutException e) { - throw new RuntimeException("Failed to reload the serve.", e); - } - } - } else { - LOGGER.warnf("Server type %s is not supported for a reload.", launchType); - } - } - - /** - * Reloads the server and returns immediately. - * - * @param client the client used to execute the reload operation - * @param reloadOp the reload operation to execute - */ - public static void executeReload(final ModelControllerClient client, final ModelNode reloadOp) { - try { - final ModelNode result = client.execute(reloadOp); - if (!Operations.isSuccessfulOutcome(result)) { - throw new RuntimeException(String.format("Failed to reload the server with %s: %s", reloadOp, - Operations.getFailureDescription(result))); - } - } catch (IOException e) { - final Throwable cause = e.getCause(); - if (!(cause instanceof ExecutionException) && !(cause instanceof CancellationException)) { - throw new RuntimeException(e); - } // else ignore, this might happen if the channel gets closed before we got the response - } - } - - /** - * Determines the servers "launch-type". - * - * @param client the client used to communicate with the server - * @return the servers launch-type or "unknown" if it could not be determined - */ - public static String launchType(final ModelControllerClient client) { - try { - final ModelNode response = client.execute(Operations.createReadAttributeOperation(EMPTY_ADDRESS, "launch-type")); - if (Operations.isSuccessfulOutcome(response)) { - return Operations.readResult(response).asString(); - } - } catch (RuntimeException | IOException e) { - LOGGER.trace("Interrupted determining the launch type", e); - } - return "unknown"; - } - - /** - * Gets the "server-state" for a standalone server. - * - * @param client the client used to communicate with the server - * @return the server-state or "failed" if an error occurred. A value of "unknown" is returned if the server is not a - * standalone server - */ - public static String serverState(final ModelControllerClient client) { - final String launchType = launchType(client); - if ("STANDALONE".equalsIgnoreCase(launchType)) { - try { - final ModelNode response = client - .execute(Operations.createReadAttributeOperation(EMPTY_ADDRESS, "server-state")); - return Operations.isSuccessfulOutcome(response) ? Operations.readResult(response).asString() : "failed"; - } catch (RuntimeException | IOException e) { - LOGGER.tracef("Interrupted determining the server state", e); - } - return "failed"; - } - return "unknown"; - } - - /** - * Waits the given amount of time in seconds for a managed domain to start. A domain is considered started when each - * of the servers in the domain are started unless the server is disabled. - * - * @param client the client used to communicate with the server - * @param startupTimeout the time, in seconds, to wait for the server start - * - * @throws InterruptedException if interrupted while waiting for the server to start - * @throws RuntimeException if the process has died - * @throws TimeoutException if the timeout has been reached and the server is still not started - */ - public static void waitForDomain(final ModelControllerClient client, final long startupTimeout) - throws InterruptedException, RuntimeException, TimeoutException { - waitForDomain(null, client, startupTimeout); - } - - /** - * Waits the given amount of time in seconds for a managed domain to start. A domain is considered started when each - * of the servers in the domain are started unless the server is disabled. - *

- * If the {@code process} is not {@code null} and a timeout occurs the process will be - * {@linkplain Process#destroy() destroyed}. - *

- * - * @param process the Java process can be {@code null} if no process is available - * @param client the client used to communicate with the server - * @param startupTimeout the time, in seconds, to wait for the server start - * - * @throws InterruptedException if interrupted while waiting for the server to start - * @throws RuntimeException if the process has died - * @throws TimeoutException if the timeout has been reached and the server is still not started - */ - public static void waitForDomain(final Process process, final ModelControllerClient client, final long startupTimeout) - throws InterruptedException, RuntimeException, TimeoutException { - Assert.checkNotNullParam("client", client); - long timeout = startupTimeout * 1000; - final long sleep = 100; - while (timeout > 0) { - long before = System.currentTimeMillis(); - if (isDomainRunning(client)) { - break; - } - timeout -= (System.currentTimeMillis() - before); - if (process != null && !process.isAlive()) { - throw new RuntimeException( - String.format("The process has unexpectedly exited with code %d", process.exitValue())); - } - TimeUnit.MILLISECONDS.sleep(sleep); - timeout -= sleep; - } - if (timeout <= 0) { - if (process != null) { - process.destroy(); - } - throw new TimeoutException(String.format("The server did not start within %s seconds.", startupTimeout)); - } - } - - /** - * Checks to see if the domain is running. If the server is not in admin only mode each servers running state is - * checked. If any server is not in a started state the domain is not considered to be running. - * - * @param client the client used to communicate with the server - * - * @return {@code true} if the server is in a running state, otherwise {@code false} - */ - public static boolean isDomainRunning(final ModelControllerClient client) { - return isDomainRunning(client, false); - } - - /** - * Shuts down a managed domain container. The servers are first stopped, then the host controller is shutdown. - * - * @param client the client used to communicate with the server - * - * @throws IOException if an error occurs communicating with the server - * @throws OperationExecutionException if the operation used to shutdown the managed domain failed - */ - public static void shutdownDomain(final ModelControllerClient client) throws IOException, OperationExecutionException { - shutdownDomain(client, 0); - } - - /** - * Shuts down a managed domain container. The servers are first stopped, then the host controller is shutdown. - * - * @param client the client used to communicate with the server - * @param timeout the graceful shutdown timeout, a value of {@code -1} will wait indefinitely and a value of - * {@code 0} will not attempt a graceful shutdown - * - * @throws IOException if an error occurs communicating with the server - * @throws OperationExecutionException if the operation used to shutdown the managed domain failed - */ - public static void shutdownDomain(final ModelControllerClient client, final int timeout) - throws IOException, OperationExecutionException { - // Note the following two operations used to shutdown a domain don't seem to work well in a composite operation. - // The operation occasionally sees a java.util.concurrent.CancellationException because the operation client - // is likely closed before the AsyncFuture.get() is complete. Using a non-composite operation doesn't seem to - // have this issue. - - // First shutdown the servers - final ModelNode stopServersOp = Operations.createOperation("stop-servers"); - stopServersOp.get("blocking").set(true); - stopServersOp.get("timeout").set(timeout); - ModelNode response = client.execute(stopServersOp); - if (!Operations.isSuccessfulOutcome(response)) { - throw new OperationExecutionException("Failed to stop servers.", stopServersOp, response); - } - - // Now shutdown the host - final ModelNode address = determineHostAddress(client); - final ModelNode shutdownOp = Operations.createOperation("shutdown", address); - response = client.execute(shutdownOp); - if (Operations.isSuccessfulOutcome(response)) { - // Wait until the process has died - while (true) { - if (isDomainRunning(client, true)) { - try { - TimeUnit.MILLISECONDS.sleep(20L); - } catch (InterruptedException e) { - LOGGER.trace("Interrupted during sleep", e); - } - } else { - break; - } - } - } else { - throw new OperationExecutionException("Failed to shutdown host.", shutdownOp, response); - } - } - - /** - * Determines the address for the host being used. - * - * @param client the client used to communicate with the server - * - * @return the address of the host - * - * @throws IOException if an error occurs communicating with the server - * @throws OperationExecutionException if the operation used to determine the host name fails - */ - public static ModelNode determineHostAddress(final ModelControllerClient client) - throws IOException, OperationExecutionException { - final ModelNode op = Operations.createReadAttributeOperation(EMPTY_ADDRESS, "local-host-name"); - ModelNode response = client.execute(op); - if (Operations.isSuccessfulOutcome(response)) { - return DeploymentOperations.createAddress("host", Operations.readResult(response).asString()); - } - throw new OperationExecutionException(op, response); - } - - /** - * Waits the given amount of time in seconds for a standalone server to start. - * - * @param client the client used to communicate with the server - * @param startupTimeout the time, in seconds, to wait for the server start - * - * @throws InterruptedException if interrupted while waiting for the server to start - * @throws RuntimeException if the process has died - * @throws TimeoutException if the timeout has been reached and the server is still not started - */ - public static void waitForStandalone(final ModelControllerClient client, final long startupTimeout) - throws InterruptedException, RuntimeException, TimeoutException { - waitForStandalone(null, client, startupTimeout); - } - - /** - * Waits the given amount of time in seconds for a standalone server to start. - *

- * If the {@code process} is not {@code null} and a timeout occurs the process will be - * {@linkplain Process#destroy() destroyed}. - *

- * - * @param process the Java process can be {@code null} if no process is available - * @param client the client used to communicate with the server - * @param startupTimeout the time, in seconds, to wait for the server start - * - * @throws InterruptedException if interrupted while waiting for the server to start - * @throws RuntimeException if the process has died - * @throws TimeoutException if the timeout has been reached and the server is still not started - */ - public static void waitForStandalone(final Process process, final ModelControllerClient client, final long startupTimeout) - throws InterruptedException, RuntimeException, TimeoutException { - Assert.checkNotNullParam("client", client); - long timeout = startupTimeout * 1000; - final long sleep = 100L; - while (timeout > 0) { - long before = System.currentTimeMillis(); - if (isStandaloneRunning(client)) - break; - timeout -= (System.currentTimeMillis() - before); - if (process != null && !process.isAlive()) { - throw new RuntimeException( - String.format("The process has unexpectedly exited with code %d", process.exitValue())); - } - TimeUnit.MILLISECONDS.sleep(sleep); - timeout -= sleep; - } - if (timeout <= 0) { - if (process != null) { - process.destroy(); - } - throw new TimeoutException(String.format("The server did not start within %s seconds.", startupTimeout)); - } - } - - /** - * Checks to see if a standalone server is running. - * - * @param client the client used to communicate with the server - * - * @return {@code true} if the server is running, otherwise {@code false} - */ - public static boolean isStandaloneRunning(final ModelControllerClient client) { - try { - final ModelNode response = client.execute(Operations.createReadAttributeOperation(EMPTY_ADDRESS, "server-state")); - if (Operations.isSuccessfulOutcome(response)) { - final String state = Operations.readResult(response).asString(); - return !CONTROLLER_PROCESS_STATE_STARTING.equals(state) - && !CONTROLLER_PROCESS_STATE_STOPPING.equals(state); - } - } catch (RuntimeException | IOException e) { - LOGGER.trace("Interrupted determining if standalone is running", e); - } - return false; - } - - /** - * Shuts down a standalone server. - * - * @param client the client used to communicate with the server - * - * @throws IOException if an error occurs communicating with the server - */ - public static void shutdownStandalone(final ModelControllerClient client) throws IOException { - shutdownStandalone(client, 0); - } - - /** - * Shuts down a standalone server. - * - * @param client the client used to communicate with the server - * @param timeout the graceful shutdown timeout, a value of {@code -1} will wait indefinitely and a value of - * {@code 0} will not attempt a graceful shutdown - * - * @throws IOException if an error occurs communicating with the server - */ - public static void shutdownStandalone(final ModelControllerClient client, final int timeout) throws IOException { - final ModelNode op = Operations.createOperation("shutdown"); - op.get("timeout").set(timeout); - final ModelNode response = client.execute(op); - if (Operations.isSuccessfulOutcome(response)) { - while (true) { - if (isStandaloneRunning(client)) { - try { - TimeUnit.MILLISECONDS.sleep(20L); - } catch (InterruptedException e) { - LOGGER.trace("Interrupted during sleep", e); - } - } else { - break; - } - } - } else { - throw new OperationExecutionException(op, response); - } - } - - private static boolean isDomainRunning(final ModelControllerClient client, boolean shutdown) { - final DomainClient domainClient = (client instanceof DomainClient ? (DomainClient) client - : DomainClient.Factory.create(client)); - try { - // Check for admin-only - final ModelNode hostAddress = determineHostAddress(domainClient); - final CompositeOperationBuilder builder = CompositeOperationBuilder.create() - .addStep(Operations.createReadAttributeOperation(hostAddress, "running-mode")) - .addStep(Operations.createReadAttributeOperation(hostAddress, "host-state")); - ModelNode response = domainClient.execute(builder.build()); - if (Operations.isSuccessfulOutcome(response)) { - response = Operations.readResult(response); - if ("ADMIN_ONLY".equals(Operations.readResult(response.get("step-1")).asString())) { - if (Operations.isSuccessfulOutcome(response.get("step-2"))) { - final String state = Operations.readResult(response).asString(); - return !CONTROLLER_PROCESS_STATE_STARTING.equals(state) - && !CONTROLLER_PROCESS_STATE_STOPPING.equals(state); - } - } - } - final Map servers = new HashMap<>(); - final Map statuses = domainClient.getServerStatuses(); - for (ServerIdentity id : statuses.keySet()) { - final ServerStatus status = statuses.get(id); - switch (status) { - case DISABLED: - case STARTED: { - servers.put(id, status); - break; - } - } - } - if (shutdown) { - return statuses.isEmpty(); - } - return statuses.size() == servers.size(); - } catch (Exception e) { - LOGGER.trace("Interrupted determining if domain is running", e); - } - return false; - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/SimpleDeploymentDescription.java b/core/src/main/java/org/wildfly/plugin/core/SimpleDeploymentDescription.java deleted file mode 100644 index eb26810c..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/SimpleDeploymentDescription.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; - -/** - * A simple deployment description. - * - * @author James R. Perkins - */ -@SuppressWarnings({ "WeakerAccess", "unused" }) -public class SimpleDeploymentDescription implements DeploymentDescription, Comparable { - - private final String name; - private final Set serverGroups; - - private SimpleDeploymentDescription(final String name) { - this.name = name; - serverGroups = new LinkedHashSet<>(); - } - - /** - * Creates a simple deployment description with an empty set of server groups. - * - * @param name the name for the deployment - * - * @return the deployment description - */ - public static SimpleDeploymentDescription of(final String name) { - return new SimpleDeploymentDescription(Assertions.requiresNotNullOrNotEmptyParameter("name", name)); - } - - /** - * Creates a simple deployment description. - * - * @param name the name for the deployment - * @param serverGroups the server groups - * - * @return the deployment description - */ - public static SimpleDeploymentDescription of(final String name, - @SuppressWarnings("TypeMayBeWeakened") final Set serverGroups) { - final SimpleDeploymentDescription result = of(name); - if (serverGroups != null) { - result.addServerGroups(serverGroups); - } - return result; - } - - /** - * Adds a server group for the deployment description. - * - * @param serverGroup the server group to add - * - * @return this deployment description - */ - public SimpleDeploymentDescription addServerGroup(final String serverGroup) { - serverGroups.add(serverGroup); - return this; - } - - /** - * Adds the server groups for the deployment description. - * - * @param serverGroups the server groups to add - * - * @return this deployment description - */ - public SimpleDeploymentDescription addServerGroups(final String... serverGroups) { - return addServerGroups(Arrays.asList(serverGroups)); - } - - /** - * Adds the server groups for the deployment description. - * - * @param serverGroups the server groups to add - * - * @return this deployment description - */ - public SimpleDeploymentDescription addServerGroups(final Collection serverGroups) { - this.serverGroups.addAll(serverGroups); - return this; - } - - @Override - public Set getServerGroups() { - return Collections.unmodifiableSet(serverGroups); - } - - @Override - public String getName() { - return name; - } - - @Override - public int compareTo(@SuppressWarnings("NullableProblems") final SimpleDeploymentDescription o) { - return name.compareTo(o.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof SimpleDeploymentDescription)) { - return false; - } - final SimpleDeploymentDescription other = (SimpleDeploymentDescription) obj; - return Objects.equals(name, other.name); - } - - @Override - public String toString() { - final StringBuilder result = new StringBuilder(SimpleDeploymentDescription.class.getSimpleName()); - result.append('('); - result.append("name=").append(name); - if (!serverGroups.isEmpty()) { - result.append(", serverGroups=").append(serverGroups); - } - return result.append(')').toString(); - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/UndeployDescription.java b/core/src/main/java/org/wildfly/plugin/core/UndeployDescription.java deleted file mode 100644 index 2fc51ccf..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/UndeployDescription.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; - -import org.wildfly.common.Assert; - -/** - * Represents the description for undeploying content from a running container. - *

- * Instances of this are not thread-safe. - *

- * - * @author James R. Perkins - */ -@SuppressWarnings({ "unused", "WeakerAccess" }) -public class UndeployDescription implements DeploymentDescription, Comparable { - - private final String name; - private final Set serverGroups; - private boolean failOnMissing; - private boolean removeContent; - - /** - * Creates a new undeploy description. - * - * @param name the name of the deployment - */ - private UndeployDescription(final String name) { - this.name = name; - serverGroups = new LinkedHashSet<>(); - failOnMissing = false; - removeContent = true; - } - - /** - * Creates a new undeploy description. - * - * @param name the name of the deployment - * - * @return the description - */ - public static UndeployDescription of(final String name) { - return new UndeployDescription(Assertions.requiresNotNullOrNotEmptyParameter("name", name)); - } - - /** - * Creates a new undeploy description. - * - * @param deploymentDescription the deployment description to copy - * - * @return the description - */ - public static UndeployDescription of(final DeploymentDescription deploymentDescription) { - Assert.checkNotNullParam("deploymentDescription", deploymentDescription); - return of(deploymentDescription.getName()).addServerGroups(deploymentDescription.getServerGroups()); - } - - /** - * Adds a server group for the deployment description. - * - * @param serverGroup the server group to add - * - * @return this deployment description - */ - public UndeployDescription addServerGroup(final String serverGroup) { - serverGroups.add(serverGroup); - return this; - } - - /** - * Adds the server groups for the deployment description. - * - * @param serverGroups the server groups to add - * - * @return this deployment description - */ - public UndeployDescription addServerGroups(final String... serverGroups) { - return addServerGroups(Arrays.asList(serverGroups)); - } - - /** - * Adds the server groups for the deployment description. - * - * @param serverGroups the server groups to add - * - * @return this deployment description - */ - public UndeployDescription addServerGroups(final Collection serverGroups) { - this.serverGroups.addAll(serverGroups); - return this; - } - - @Override - public Set getServerGroups() { - return Collections.unmodifiableSet(serverGroups); - } - - @Override - public String getName() { - return name; - } - - /** - * Indicates whether or not a failure should occur if the deployment does not exist on the container. A value of - * {@code true} indicates the deployment should fail. - * - * @return {@code true} if the undeploy should fail if not found on the container, otherwise {@code false} - */ - public boolean isFailOnMissing() { - return failOnMissing; - } - - /** - * Sets whether or not a failure should occur if the deployment does exist on the container. - * - * @param failOnMissing {@code true} if the undeploy should fail if the deployment was not found on the server, - * {@code false} if the deployment does not exist and the undeploy should be ignored - * - * @return the deployment description - */ - public UndeployDescription setFailOnMissing(final boolean failOnMissing) { - this.failOnMissing = failOnMissing; - return this; - } - - /** - * Indicates whether or not the content should be removed from the content repository. - * - * @return {@code true} if the content should also be removed from the repository, {@code false} it only an - * {@code undeploy} operation should be executed and the content should remain in the repository - */ - public boolean isRemoveContent() { - return removeContent; - } - - /** - * Sets whether or not the content should be removed after the {@code undeploy} operation. - *

- * The default value is {@code true}. - *

- * - * @param removeContent {@code true} if the content should be removed, {@code false} if the content should remain - * in the repository - * - * @return the deployment description - */ - public UndeployDescription setRemoveContent(final boolean removeContent) { - this.removeContent = removeContent; - return this; - } - - @Override - public int compareTo(@SuppressWarnings("NullableProblems") final UndeployDescription o) { - return name.compareTo(o.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof UndeployDescription)) { - return false; - } - final UndeployDescription other = (UndeployDescription) obj; - return Objects.equals(name, other.name); - } - - @Override - public String toString() { - final StringBuilder result = new StringBuilder(UndeployDescription.class.getSimpleName()); - result.append('('); - result.append("name=").append(name); - result.append(", failOnMissing=").append(failOnMissing); - result.append(", removeContent=").append(removeContent); - if (!serverGroups.isEmpty()) { - result.append(", serverGroups=").append(serverGroups); - } - return result.append(')').toString(); - } -} diff --git a/core/src/main/java/org/wildfly/plugin/core/Utils.java b/core/src/main/java/org/wildfly/plugin/core/Utils.java deleted file mode 100644 index 1fc7c8b3..00000000 --- a/core/src/main/java/org/wildfly/plugin/core/Utils.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugin.core; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * - * @author jdenise@redhat.com - */ -public class Utils { - private static final Pattern WHITESPACE_IF_NOT_QUOTED = Pattern.compile("(\\S+\"[^\"]+\")|\\S+"); - - public static boolean isValidHomeDirectory(final Path path) { - return path != null - && Files.exists(path) - && Files.isDirectory(path) - && Files.exists(path.resolve("jboss-modules.jar")); - } - - /** - * Splits the arguments into a list. The arguments are split based on - * whitespace while ignoring whitespace that is within quotes. - * - * @param arguments the arguments to split - * - * @return the list of the arguments - */ - public static List splitArguments(final CharSequence arguments) { - final List args = new ArrayList<>(); - final Matcher m = WHITESPACE_IF_NOT_QUOTED.matcher(arguments); - while (m.find()) { - final String value = m.group(); - if (!value.isEmpty()) { - args.add(value); - } - } - return args; - } -} diff --git a/core/src/main/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfiguration.java b/core/src/main/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfiguration.java deleted file mode 100644 index 28f3bda3..00000000 --- a/core/src/main/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfiguration.java +++ /dev/null @@ -1,1071 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugins.core.bootablejar; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.helpers.ClientConstants; -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.dmr.ModelNode; -import org.jboss.dmr.ModelType; -import org.jboss.dmr.Property; -import org.jboss.logging.Logger; - -/** - * Generates a new {@code logging.properties} file based on the logging subsystem model. - * - *

- * This should be considered a hack which generates a {@code logging.properties} file. The generated file will not - * necessarily be identical to that of which WildFly generates. Expressions will be written to the generated file. For - * this reason a new file will be generated which the entry point needs to load as system properties before the log - * manager is configured. - *

- * - *

- * Also handlers, formatters and filters considered explicit will not be configured at boot. As they are not used by - * another resource this should not be an issue. Once the logging subsystems runtime phase is executed these resources - * will be initialized. - *

- * - *

- * The generated file cannot support log4j appenders created as custom-handlers. Boot errors will - * occur if this happens. - *

- * - * @author James R. Perkins - */ -public class BootLoggingConfiguration { - - private static final Logger LOGGER = Logger.getLogger(BootLoggingConfiguration.class); - private static final Pattern SIZE_PATTERN = Pattern.compile("(\\d+)([kKmMgGbBtT])?"); - private static final String NEW_LINE = System.lineSeparator(); - - private static final Collection IGNORED_PROPERTIES = Arrays.asList( - "java.ext.dirs", - "java.home", - "jboss.home.dir", - "java.io.tmpdir", - "jboss.controller.temp.dir", - "jboss.server.base.dir", - "jboss.server.config.dir", - "jboss.server.data.dir", - "jboss.server.default.config", - "jboss.server.deploy.dir", - "jboss.server.log.dir", - "jboss.server.persist.config", - "jboss.server.management.uuid", - "jboss.server.temp.dir", - "modules.path", - "org.jboss.server.bootstrap.maxThreads", - "user.dir", - "user.home"); - private static final String KEY_OVERRIDES = "keyOverrides"; - private final Map properties; - private final Map usedProperties; - private final Map additionalPatternFormatters; - private ModelControllerClient client; - - public BootLoggingConfiguration() { - properties = new HashMap<>(); - usedProperties = new TreeMap<>(); - additionalPatternFormatters = new LinkedHashMap<>(); - } - - public void generate(final Path configDir, final ModelControllerClient client) throws Exception { - properties.clear(); - usedProperties.clear(); - additionalPatternFormatters.clear(); - // First we need to determine if there is a logging subsystem, if not we don't need to handle rewriting the - // configuration. - ModelNode op = Operations.createOperation("read-children-names"); - op.get(ClientConstants.CHILD_TYPE).set("subsystem"); - ModelNode result = client.execute(op); - if (!Operations.isSuccessfulOutcome(result)) { - throw new Exception("Could not determine if the logging subsystem was present: " - + Operations.getFailureDescription(result).asString()); - } else { - if (Operations.readResult(result) - .asList() - .stream() - .noneMatch((name) -> name.asString().equals("logging"))) { - return; - } - } - // Create the operations to read the resources required - final Operations.CompositeOperationBuilder builder = Operations.CompositeOperationBuilder.create() - .addStep(Operations.createReadResourceOperation(Operations.createAddress("subsystem", "logging"), true)); - op = Operations.createOperation("read-children-resources"); - op.get(ClientConstants.CHILD_TYPE).set("system-property"); - builder.addStep(op); - op = Operations.createOperation("read-children-resources"); - op.get(ClientConstants.CHILD_TYPE).set("path"); - builder.addStep(op); - - result = client.execute(builder.build()); - if (!Operations.isSuccessfulOutcome(result)) { - throw new Exception("Failed to determine the logging configuration: " - + Operations.getFailureDescription(result).asString()); - } - result = Operations.readResult(result); - // step-1 is the subsystem, step-2 is the system properties and step-3 is the paths - final ModelNode subsystem = Operations.readResult(result.get("step-1")); - final ModelNode systemProperties = Operations.readResult(result.get("step-2")); - final ModelNode paths = Operations.readResult(result.get("step-3")); - - // This shouldn't happen, but let's be safe - if (subsystem.isDefined()) { - // Sets the client to use - this.client = client; - parseProperties(systemProperties); - try (BufferedWriter writer = Files.newBufferedWriter(configDir.resolve("logging.properties"), - StandardCharsets.UTF_8)) { - writer.write("# Note this file has been generated and will be overwritten if a"); - writer.write(NEW_LINE); - writer.write("# logging subsystem has been defined in the XML configuration."); - writer.write(NEW_LINE); - writer.write(NEW_LINE); - - writeLoggers(writer, subsystem); - writeHandlers(writer, subsystem, paths); - // Note the formatters MUST be written after the handlers. Handlers have a legacy "formatter" attribute and - // additional pattern-formatters may need be written. - writeFormatters(writer, subsystem); - writeFilters(writer, subsystem); - } catch (IOException e) { - throw new Exception("Failed to write the logging configuration file to " + configDir.toAbsolutePath(), e); - } - - // Collect the properties we need at boot - final Properties requiredProperties = new Properties(); - final Iterator> iter = usedProperties.entrySet().iterator(); - while (iter.hasNext()) { - final Map.Entry entry = iter.next(); - final String key = entry.getKey(); - if (properties.containsKey(key)) { - requiredProperties.put(key, properties.get(key)); - } else { - LOGGER.warnf("The value for the expression \"%s\" could not be resolved " - + "and may not be set at boot if no default value is available.", entry.getValue()); - } - iter.remove(); - } - - if (!requiredProperties.isEmpty()) { - // Note the hard-coded "boot-config.properties", the bootable JAR entry point will look for this file - // and process it if it exists. - try (BufferedWriter writer = Files.newBufferedWriter(configDir.resolve("boot-config.properties"))) { - requiredProperties.store(writer, "Bootable JAR boot properties required by the log manager."); - } catch (IOException e) { - throw new Exception("Failed to write the system properties required by the logging configuration file to " - + configDir.toAbsolutePath(), e); - } - } - } - } - - private void writeFilters(final Writer writer, final ModelNode subsystem) throws IOException { - if (subsystem.hasDefined("filter")) { - for (Property property : subsystem.get("filter").asPropertyList()) { - final String name = property.getName(); - final ModelNode model = property.getValue(); - final String prefix = "filter." + name; - writeProperty(writer, prefix, null, resolveAsString(model.get("class"))); - writeProperty(writer, prefix, "module", resolveAsString(model.get("module"))); - - final ModelNode allProperties = new ModelNode(); - - if (model.hasDefined("constructor-properties")) { - final ModelNode properties = model.get("constructor-properties"); - final Collection constructorNames = properties.asPropertyList() - .stream() - .map(Property::getName) - .collect(Collectors.toList()); - writeProperty(writer, prefix, "constructorProperties", toCsvString(constructorNames)); - for (String n : constructorNames) { - allProperties.get(n).set(properties.get(n)); - } - } - if (model.hasDefined("properties")) { - final ModelNode properties = model.get("properties"); - final Collection propertyNames = properties.asPropertyList() - .stream() - .map(Property::getName) - .collect(Collectors.toList()); - for (String n : propertyNames) { - allProperties.get(n).set(properties.get(n)); - } - } - if (allProperties.isDefined()) { - writeProperty(writer, prefix, "properties", toCsvString(allProperties.asPropertyList() - .stream() - .map(Property::getName) - .collect(Collectors.toList()))); - writeProperties(writer, prefix, allProperties); - } - } - writer.write(NEW_LINE); - } - } - - private void writeFormatters(final Writer writer, final ModelNode subsystem) throws IOException { - // Formatters - if (subsystem.hasDefined("custom-formatter")) { - writeCustomFormatter(writer, subsystem.get("custom-formatter").asPropertyList()); - } - if (subsystem.hasDefined("json-formatter")) { - writeStructuredFormatter("org.jboss.logmanager.formatters.JsonFormatter", writer, - subsystem.get("json-formatter").asPropertyList()); - } - if (subsystem.hasDefined("pattern-formatter")) { - writePatternFormatter(writer, subsystem.get("pattern-formatter").asPropertyList()); - } - if (subsystem.hasDefined("xml-formatter")) { - writeStructuredFormatter("org.jboss.logmanager.formatters.XmlFormatter", writer, - subsystem.get("xml-formatter").asPropertyList()); - } - } - - private void writeCustomFormatter(final Writer writer, final List formatters) throws IOException { - for (Property property : formatters) { - final String name = property.getName(); - final ModelNode model = property.getValue().clone(); - final String prefix = "formatter." + name; - writeProperty(writer, prefix, null, resolveAsString(model.remove("class"))); - writeProperty(writer, prefix, "module", resolveAsString(model.remove("module"))); - if (model.hasDefined("properties")) { - final ModelNode properties = model.get("properties"); - // Next we need to write the properties - final Collection definedPropertyNames = properties.asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - writeProperty(writer, prefix, "properties", toCsvString(definedPropertyNames)); - // Write the property values - for (String attributeName : definedPropertyNames) { - writeProperty(writer, prefix, attributeName, properties.get(attributeName)); - } - } - writer.write(NEW_LINE); - } - } - - private void writePatternFormatter(final Writer writer, final List formatters) throws IOException { - for (Property property : formatters) { - final String name = property.getName(); - final ModelNode model = property.getValue().clone(); - final String prefix = "formatter." + name; - writeProperty(writer, prefix, null, "org.jboss.logmanager.formatters.PatternFormatter"); - - // Next we need to write the properties - final Collection definedPropertyNames = model.asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - writeProperty(writer, prefix, "properties", toCsvString(definedPropertyNames - .stream() - .map(BootLoggingConfiguration::resolvePropertyName) - .collect(Collectors.toList()))); - // Write the property values - for (String attributeName : definedPropertyNames) { - writeProperty(writer, prefix, resolvePropertyName(attributeName), model.get(attributeName)); - } - writer.write(NEW_LINE); - } - - // Write any additional pattern-formatters that were defined on a handlers "formatter" attribute - final Iterator> iter = additionalPatternFormatters.entrySet().iterator(); - while (iter.hasNext()) { - final Map.Entry entry = iter.next(); - final String prefix = "formatter." + entry.getKey(); - writeProperty(writer, prefix, null, "org.jboss.logmanager.formatters.PatternFormatter"); - writeProperty(writer, prefix, "constructorProperties", "pattern"); - writeProperty(writer, prefix, "properties", "pattern"); - writeProperty(writer, prefix, "pattern", entry.getValue()); - writer.write(NEW_LINE); - iter.remove(); - } - } - - private void writeStructuredFormatter(final String type, final Writer writer, - final List formatters) throws IOException { - for (Property property : formatters) { - final String name = property.getName(); - final ModelNode model = property.getValue().clone(); - final String prefix = "formatter." + name; - writeProperty(writer, prefix, null, type); - boolean needKeyOverrides = !model.hasDefined("key-overrides"); - // The key-overrides are used as constructor parameters - // This property is alwasy added. - writeProperty(writer, prefix, "constructorProperties", KEY_OVERRIDES); - // Next we need to write the properties - final Collection definedPropertyNames = model.asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - if (needKeyOverrides) { - definedPropertyNames.add(KEY_OVERRIDES); - } - writeProperty(writer, prefix, "properties", toCsvString(definedPropertyNames - .stream() - .map(BootLoggingConfiguration::resolvePropertyName) - .collect(Collectors.toList()))); - // Write the property values - for (String attributeName : definedPropertyNames) { - final ModelNode value = model.get(attributeName); - // Handle special cases - if ("exception-output-type".equals(attributeName)) { - writeProperty(writer, prefix, resolvePropertyName(attributeName), toEnumString(model.get(attributeName))); - } else { - if (needKeyOverrides && KEY_OVERRIDES.equals(attributeName)) { - // The value is empty if explicitely added. - writeProperty(writer, prefix, resolvePropertyName(attributeName), ""); - } else { - writeProperty(writer, prefix, resolvePropertyName(attributeName), value); - } - } - } - writer.write(NEW_LINE); - } - } - - private void writeHandlers(final Writer writer, final ModelNode subsystem, final ModelNode pathModel) throws IOException { - if (subsystem.hasDefined("async-handler")) { - writeAsyncHandlers(writer, subsystem.get("async-handler").asPropertyList()); - } - - if (subsystem.hasDefined("console-handler")) { - writeConsoleHandlers(writer, subsystem.get("console-handler").asPropertyList()); - } - if (subsystem.hasDefined("custom-handler")) { - writeCustomHandlers(writer, subsystem.get("custom-handler").asPropertyList()); - } - if (subsystem.hasDefined("file-handler")) { - writeFileHandlers(pathModel, "org.jboss.logmanager.handlers.FileHandler", writer, - subsystem.get("file-handler").asPropertyList()); - } - if (subsystem.hasDefined("periodic-rotating-file-handler")) { - writeFileHandlers(pathModel, "org.jboss.logmanager.handlers.PeriodicRotatingFileHandler", writer, - subsystem.get("periodic-rotating-file-handler").asPropertyList()); - } - if (subsystem.hasDefined("periodic-size-rotating-file-handler")) { - writeFileHandlers(pathModel, "org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler", writer, - subsystem.get("periodic-size-rotating-file-handler").asPropertyList()); - } - if (subsystem.hasDefined("size-rotating-file-handler")) { - writeFileHandlers(pathModel, "org.jboss.logmanager.handlers.SizeRotatingFileHandler", writer, - subsystem.get("size-rotating-file-handler").asPropertyList()); - } - if (subsystem.hasDefined("socket-handler")) { - writeSocketHandler(writer, subsystem.get("socket-handler").asPropertyList()); - } - if (subsystem.hasDefined("syslog-handler")) { - writeSyslogHandler(writer, subsystem.get("syslog-handler").asPropertyList()); - } - } - - private void writeAsyncHandlers(final Writer writer, final List handlers) throws IOException { - for (Property property : handlers) { - final String name = property.getName(); - final String prefix = "handler." + name; - final ModelNode model = property.getValue().clone(); - writeCommonHandler("org.jboss.logmanager.handlers.AsyncHandler", writer, name, prefix, model); - final ModelNode subhandlers = model.remove("subhandlers"); - if (isDefined(subhandlers)) { - writeProperty(writer, prefix, "handlers", subhandlers); - } - // Next we need to write the properties - final Collection definedPropertyNames = model.asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - definedPropertyNames.add("closeChildren"); - writeProperty(writer, prefix, "properties", toCsvString(definedPropertyNames - .stream() - .map(BootLoggingConfiguration::resolvePropertyName) - .collect(Collectors.toList()))); - // Write the constructor properties - writeProperty(writer, prefix, "constructorProperties", "queueLength"); - // Write the property values - for (String attributeName : definedPropertyNames) { - if ("closeChildren".equals(attributeName)) { - writeProperty(writer, prefix, attributeName, "false"); - } else { - writeProperty(writer, prefix, resolvePropertyName(attributeName), model.get(attributeName)); - } - } - writer.write(NEW_LINE); - } - } - - private void writeConsoleHandlers(final Writer writer, final List handlers) throws IOException { - for (Property property : handlers) { - final String name = property.getName(); - final String prefix = "handler." + name; - final ModelNode model = property.getValue().clone(); - writeCommonHandler("org.jboss.logmanager.handlers.ConsoleHandler", writer, name, prefix, model); - // Next we need to write the properties - final Collection definedPropertyNames = model.asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - writeProperty(writer, prefix, "properties", toCsvString(definedPropertyNames - .stream() - .map(BootLoggingConfiguration::resolvePropertyName) - .collect(Collectors.toList()))); - // Write the property values - for (String attributeName : definedPropertyNames) { - if ("target".equals(attributeName)) { - writeProperty(writer, prefix, resolvePropertyName(attributeName), toEnumString(model.get(attributeName))); - } else { - writeProperty(writer, prefix, resolvePropertyName(attributeName), model.get(attributeName)); - } - } - writer.write(NEW_LINE); - } - } - - private void writeCustomHandlers(final Writer writer, final List handlers) throws IOException { - for (Property property : handlers) { - final String name = property.getName(); - final String prefix = "handler." + name; - final ModelNode model = property.getValue().clone(); - writeCommonHandler(null, writer, name, prefix, model); - // Next we need to write the properties - if (model.hasDefined("properties")) { - final Collection definedPropertyNames = model.get("properties").asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - if (model.hasDefined("enabled")) { - definedPropertyNames.add("enabled"); - } - writeProperty(writer, prefix, "properties", toCsvString(definedPropertyNames)); - final ModelNode properties = model.get("properties"); - for (String attributeName : definedPropertyNames) { - if ("enabled".equals(attributeName)) { - if (model.hasDefined(attributeName)) { - writeProperty(writer, prefix, attributeName, model.get(attributeName)); - } - } else { - writeProperty(writer, prefix, attributeName, properties.get(attributeName)); - } - } - } else { - if (model.hasDefined("enabled")) { - writeProperty(writer, prefix, "properties", "enabled"); - writeProperty(writer, prefix, "enabled", model.get("enabled")); - } - } - writer.write(NEW_LINE); - } - } - - private void writeFileHandlers(final ModelNode pathModel, final String type, final Writer writer, - final List handlers) throws IOException { - for (Property property : handlers) { - final String name = property.getName(); - final String prefix = "handler." + name; - final ModelNode model = property.getValue().clone(); - - final ModelNode file = model.remove("file"); - // If the file is not defined, which shouldn't happen, we'll just skip this one - if (!isDefined(file)) { - continue; - } - - writeCommonHandler(type, writer, name, prefix, model); - - // Next we need to write the properties - final Collection definedPropertyNames = model.asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - final Collection propertyNames = definedPropertyNames - .stream() - .map(BootLoggingConfiguration::resolvePropertyName) - .collect(Collectors.toList()); - propertyNames.add("fileName"); - writeProperty(writer, prefix, "properties", toCsvString(propertyNames)); - - // Write the constructor properties - writeProperty(writer, prefix, "constructorProperties", "fileName,append"); - - // Write the remainder of the properties - for (String attributeName : definedPropertyNames) { - // The rotate-size requires special conversion - if ("rotate-size".equals(attributeName)) { - final String resolvedValue = String.valueOf(parseSize(model.get(attributeName))); - writeProperty(writer, prefix, resolvePropertyName(attributeName), resolvedValue); - } else { - writeProperty(writer, prefix, resolvePropertyName(attributeName), model.get(attributeName)); - } - } - - // Write the fileName - final StringBuilder result = new StringBuilder(); - if (file.hasDefined("relative-to")) { - final String relativeTo = file.get("relative-to").asString(); - resolveRelativeTo(pathModel, relativeTo, result); - } - if (file.hasDefined("path")) { - result.append(resolveAsString(file.get("path"))); - } - writeProperty(writer, prefix, "fileName", result.toString()); - writer.write(NEW_LINE); - } - } - - private void writeSocketHandler(final Writer writer, final List handlers) throws IOException { - // Socket handlers are actually configured late initialized defined as a DelayedHandler - for (Property property : handlers) { - final String name = property.getName(); - final String prefix = "handler." + name; - final ModelNode model = property.getValue().clone(); - writeCommonHandler("org.jboss.logmanager.handlers.DelayedHandler", writer, name, prefix, model); - if (model.hasDefined("enabled")) { - writeProperty(writer, prefix, "properties", "enabled"); - writeProperty(writer, prefix, "enabled", model.get("enabled")); - } - writer.write(NEW_LINE); - } - } - - private void writeSyslogHandler(final Writer writer, final List handlers) throws IOException { - // Socket handlers are actually configured late initialized defined as a DelayedHandler - for (Property property : handlers) { - final String name = property.getName(); - final String prefix = "handler." + name; - final ModelNode model = property.getValue().clone(); - writeCommonHandler("org.jboss.logmanager.handlers.SyslogHandler", writer, name, prefix, model); - - // Next we need to write the properties - final Collection definedPropertyNames = model.asPropertyList() - .stream() - .filter((p) -> p.getValue().isDefined()) - .map(Property::getName) - .collect(Collectors.toList()); - writeProperty(writer, prefix, "properties", toCsvString(definedPropertyNames - .stream() - .map(BootLoggingConfiguration::resolvePropertyName) - .collect(Collectors.toList()))); - for (String attributeName : definedPropertyNames) { - if ("facility".equals(attributeName)) { - writeProperty(writer, prefix, resolvePropertyName(attributeName), toEnumString(model.get(attributeName))); - } else { - writeProperty(writer, prefix, resolvePropertyName(attributeName), model.get(attributeName)); - } - } - writer.write(NEW_LINE); - } - } - - private void writeCommonHandler(final String type, final Writer writer, final String name, - final String prefix, final ModelNode model) throws IOException { - if (type == null) { - writeProperty(writer, prefix, null, resolveAsString(model.remove("class"))); - writeProperty(writer, prefix, "module", resolveAsString(model.remove("module"))); - } else { - writeProperty(writer, prefix, null, type); - } - - // Remove the legacy "name" attribute - model.remove("name"); - - // Write the level - final ModelNode level = model.remove("level"); - if (isDefined(level)) { - writeProperty(writer, prefix, "level", level); - } - final ModelNode encoding = model.remove("encoding"); - if (isDefined(encoding)) { - writeProperty(writer, prefix, "encoding", encoding); - } - - final ModelNode namedFormatter = model.remove("named-formatter"); - final ModelNode formatter = model.remove("formatter"); - if (isDefined(namedFormatter)) { - writeProperty(writer, prefix, "formatter", namedFormatter.asString()); - } else if (isDefined(formatter)) { - // We need to add a formatter with the known name used in WildFly - final String defaultFormatterName = name + "-wfcore-pattern-formatter"; - additionalPatternFormatters.put(defaultFormatterName, resolveAsString(formatter)); - writeProperty(writer, prefix, "formatter", defaultFormatterName); - } - // Write the filter spec and remove the filter attribute which we will not use - model.remove("filter"); - final ModelNode filter = model.remove("filter-spec"); - if (isDefined(filter)) { - writeProperty(writer, prefix, "filter", filter); - } - } - - private void writeLoggers(final Writer writer, final ModelNode model) throws IOException { - if (model.hasDefined("logger")) { - final List loggerModel = model.get("logger").asPropertyList(); - writer.write("# Additional loggers to configure (the root logger is always configured)"); - writer.write(NEW_LINE); - // First we need to list the loggers to define - writeProperty(writer, "loggers", null, toCsvString(loggerModel - .stream() - .map(Property::getName) - .collect(Collectors.toList()))); - writer.write(NEW_LINE); - // Next get the root logger - if (model.hasDefined("root-logger", "ROOT")) { - writeLogger(writer, null, model.get("root-logger", "ROOT")); - } - - for (Property property : loggerModel) { - writeLogger(writer, property.getName(), property.getValue()); - } - } - } - - private void writeLogger(final Writer writer, final String name, final ModelNode model) throws IOException { - final String prefix = name == null ? "logger" : "logger." + name; - if (model.hasDefined("filter-spec")) { - writeProperty(writer, prefix, "filter", model.get("filter-spec")); - } - if (model.hasDefined("handlers")) { - writeProperty(writer, prefix, "handlers", toCsvString(model.get("handlers").asList() - .stream() - .map(ModelNode::asString) - .collect(Collectors.toList()))); - } - if (model.hasDefined("level")) { - writeProperty(writer, prefix, "level", model.get("level")); - } - if (model.hasDefined("use-parent-filters")) { - writeProperty(writer, prefix, "useParentFilters", model.get("use-parent-filters")); - } - if (model.hasDefined("use-parent-handlers")) { - writeProperty(writer, prefix, "useParentHandlers", model.get("use-parent-handlers")); - } - writer.write(NEW_LINE); - } - - private void writeProperties(final Writer writer, final String prefix, final ModelNode model) throws IOException { - for (Property property : model.asPropertyList()) { - final String name = property.getName(); - final ModelNode value = property.getValue(); - if (value.isDefined()) { - writeProperty(writer, prefix, name, value); - } - } - } - - private void writeProperty(final Writer out, final String prefix, final String name, final ModelNode value) - throws IOException { - writeProperty(out, prefix, name, resolveAsString(value)); - } - - private String toEnumString(final ModelNode value) { - final StringBuilder result = new StringBuilder(); - if (value.getType() == ModelType.EXPRESSION) { - final Collection expressions = Expression.parse(value.asExpression()); - for (Expression expression : expressions) { - addUsedProperties(expression, value.asString()); - result.append("${"); - final Iterator iter = expression.getKeys().iterator(); - while (iter.hasNext()) { - result.append(iter.next()); - if (iter.hasNext()) { - result.append(','); - } - } - if (expression.hasDefault()) { - result.append(':'); - final String dft = expression.getDefaultValue(); - for (char c : dft.toCharArray()) { - if (c == '-' || c == '.') { - result.append('_'); - } else { - result.append(Character.toUpperCase(c)); - } - } - } - result.append('}'); - } - } else { - for (char c : value.asString().toCharArray()) { - if (c == '-' || c == '.') { - result.append('_'); - } else { - result.append(Character.toUpperCase(c)); - } - } - } - return result.toString(); - } - - private String resolveAsString(final ModelNode value) { - if (value.getType() == ModelType.LIST) { - return toCsvString(value.asList() - .stream() - .map(ModelNode::asString) - .collect(Collectors.toList())); - } else if (value.getType() == ModelType.OBJECT) { - return modelToMap(value); - } else { - if (value.getType() == ModelType.EXPRESSION) { - final Collection expressions = Expression.parse(value.asExpression()); - addUsedProperties(expressions, value.asString()); - } - return value.asString(); - } - } - - private long parseSize(final ModelNode value) throws IOException { - String stringValue; - // This requires some special handling as we need the resolved value. - if (value.getType() == ModelType.EXPRESSION) { - // We need update the usedProperties - final Collection expressions = Expression.parse(value.asExpression()); - addUsedProperties(expressions, value.asString()); - // Now we need to resolve the expression - final ModelNode op = Operations.createOperation("resolve-expression"); - op.get("expression").set(value.asString()); - final ModelNode result = client.execute(op); - if (!Operations.isSuccessfulOutcome(result)) { - throw new RuntimeException(String.format("Failed to resolve the expression %s: %s", value.asString(), - Operations.getFailureDescription(result).asString())); - } - stringValue = Operations.readResult(result).asString(); - } else { - stringValue = value.asString(); - } - final Matcher matcher = SIZE_PATTERN.matcher(stringValue); - // This shouldn't happen, but we shouldn't fail either - if (!matcher.matches()) { - // by default, rotate at 10MB - return 0xa0000L; - } - long qty = Long.parseLong(matcher.group(1), 10); - final String chr = matcher.group(2); - if (chr != null) { - switch (chr.charAt(0)) { - case 'b': - case 'B': - break; - case 'k': - case 'K': - qty <<= 10L; - break; - case 'm': - case 'M': - qty <<= 20L; - break; - case 'g': - case 'G': - qty <<= 30L; - break; - case 't': - case 'T': - qty <<= 40L; - break; - default: - // by default, rotate at 10MB - return 0xa0000L; - } - } - return qty; - } - - private void parseProperties(final ModelNode model) { - if (model.isDefined()) { - for (Property property : model.asPropertyList()) { - final String key = property.getName(); - if (IGNORED_PROPERTIES.contains(key)) { - continue; - } - final ModelNode value = property.getValue().get("value"); - if (value.isDefined()) { - properties.put(key, value.asString()); - } - } - } - } - - private void resolveRelativeTo(final ModelNode pathModel, final String relativeTo, final StringBuilder builder) { - if (pathModel.hasDefined(relativeTo)) { - final ModelNode path = pathModel.get(relativeTo); - if (path.hasDefined("relative-to")) { - resolveRelativeTo(pathModel, path.get("relative-to").asString(), builder); - } - if (path.hasDefined("path")) { - final ModelNode pathEntry = path.get("path"); - if (pathEntry.getType() == ModelType.EXPRESSION) { - final Collection expressions = Expression.parse(pathEntry.asExpression()); - for (Expression expression : expressions) { - for (String key : expression.getKeys()) { - if (!properties.containsKey(key)) { - LOGGER.warnf( - "The path %s is an undefined property. If not set at boot time unexpected results may occur.", - pathEntry.asString()); - } else { - // We use the property name and value directly rather than referencing the path - usedProperties.put(key, properties.get(key)); - expression.appendTo(builder); - } - } - } - } else { - if (!IGNORED_PROPERTIES.contains(relativeTo)) { - properties.put(relativeTo, pathEntry.asString()); - usedProperties.put(relativeTo, pathEntry.asString()); - } - builder.append("${") - .append(relativeTo) - .append("}"); - } - } - // Use a Linux style path separator as we can't use a Windows one on Linux, but we - // can use a Linux one on Windows. - builder.append('/'); - } - } - - private void addUsedProperties(final Collection expressions, final String value) { - for (Expression expression : expressions) { - addUsedProperties(expression, value); - } - } - - private void addUsedProperties(final Expression expression, final String value) { - for (String key : expression.getKeys()) { - usedProperties.put(key, value); - } - } - - private static void writeProperty(final Writer out, final String prefix, final String name, final String value) - throws IOException { - if (name == null) { - writeKey(out, prefix); - } else { - writeKey(out, String.format("%s.%s", prefix, name)); - } - writeValue(out, value); - out.write(NEW_LINE); - } - - private static void writeValue(final Appendable out, final String value) throws IOException { - writeSanitized(out, value, false); - } - - private static void writeKey(final Appendable out, final String key) throws IOException { - writeSanitized(out, key, true); - out.append('='); - } - - private static void writeSanitized(final Appendable out, final String string, final boolean escapeSpaces) - throws IOException { - for (int x = 0; x < string.length(); x++) { - final char c = string.charAt(x); - switch (c) { - case ' ': - if (x == 0 || escapeSpaces) - out.append('\\'); - out.append(c); - break; - case '\t': - out.append('\\').append('t'); - break; - case '\n': - out.append('\\').append('n'); - break; - case '\r': - out.append('\\').append('r'); - break; - case '\f': - out.append('\\').append('f'); - break; - case '\\': - case '=': - case ':': - case '#': - case '!': - out.append('\\').append(c); - break; - default: - out.append(c); - } - } - } - - private static String modelToMap(final ModelNode value) { - if (value.getType() != ModelType.OBJECT) { - return null; - } - final List properties = value.asPropertyList(); - final StringBuilder result = new StringBuilder(); - final Iterator iterator = properties.iterator(); - while (iterator.hasNext()) { - final Property property = iterator.next(); - escapeKey(result, property.getName()); - result.append('='); - final ModelNode v = property.getValue(); - if (v.isDefined()) { - escapeValue(result, v.asString()); - } - if (iterator.hasNext()) { - result.append(','); - } - } - return result.toString(); - } - - private static boolean isDefined(final ModelNode value) { - return value != null && value.isDefined(); - } - - private static String toCsvString(final Collection names) { - final StringBuilder result = new StringBuilder(1024); - Iterator iterator = names.iterator(); - while (iterator.hasNext()) { - final String name = iterator.next(); - // No need to write empty names - if (!name.isEmpty()) { - result.append(name); - if (iterator.hasNext()) { - result.append(","); - } - } - } - return result.toString(); - } - - private static String resolvePropertyName(final String modelName) { - if ("autoflush".equals(modelName)) { - return "autoFlush"; - } - if ("color-map".equals(modelName)) { - return "colors"; - } - if ("syslog-format".equals(modelName)) { - return "syslogType"; - } - if ("server-address".equals(modelName)) { - return "serverHostname"; - } - if (modelName.contains("-")) { - final StringBuilder builder = new StringBuilder(); - boolean cap = false; - for (char c : modelName.toCharArray()) { - if (c == '-') { - cap = true; - continue; - } - if (cap) { - builder.append(Character.toUpperCase(c)); - cap = false; - } else { - builder.append(c); - } - } - return builder.toString(); - } - return modelName; - } - - /** - * Escapes a maps key value for serialization to a string. If the key contains a {@code \} or an {@code =} it will - * be escaped by a preceding {@code \}. Example: {@code key\=} or {@code \\key}. - * - * @param sb the string builder to append the escaped key to - * @param key the key - */ - private static void escapeKey(final StringBuilder sb, final String key) { - final char[] chars = key.toCharArray(); - for (int i = 0; i < chars.length; i++) { - final char c = chars[i]; - // Ensure that \ and = are escaped - if (c == '\\') { - final int n = i + 1; - if (n >= chars.length) { - sb.append('\\').append('\\'); - } else { - final char next = chars[n]; - if (next == '\\' || next == '=') { - // Nothing to do, already properly escaped - sb.append(c); - sb.append(next); - i = n; - } else { - // Now we need to escape the \ - sb.append('\\').append('\\'); - } - } - } else if (c == '=') { - sb.append('\\').append(c); - } else { - sb.append(c); - } - } - } - - /** - * Escapes a maps value for serialization to a string. If a value contains a {@code \} or a {@code ,} it will be - * escaped by a preceding {@code \}. Example: {@code part1\,part2} or {@code value\\other}. - * - * @param sb the string builder to append the escaped value to - * @param value the value - */ - private static void escapeValue(final StringBuilder sb, final String value) { - if (value != null) { - final char[] chars = value.toCharArray(); - for (int i = 0; i < chars.length; i++) { - final char c = chars[i]; - // Ensure that \ and , are escaped - if (c == '\\') { - final int n = i + 1; - if (n >= chars.length) { - sb.append('\\').append('\\'); - } else { - final char next = chars[n]; - if (next == '\\' || next == ',') { - // Nothing to do, already properly escaped - sb.append(c); - sb.append(next); - i = n; - } else { - // Now we need to escape the \ - sb.append('\\').append('\\'); - } - } - } else if (c == ',') { - sb.append('\\').append(c); - } else { - sb.append(c); - } - } - } - } -} diff --git a/core/src/main/java/org/wildfly/plugins/core/bootablejar/BootableJarSupport.java b/core/src/main/java/org/wildfly/plugins/core/bootablejar/BootableJarSupport.java deleted file mode 100644 index e037ef43..00000000 --- a/core/src/main/java/org/wildfly/plugins/core/bootablejar/BootableJarSupport.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugins.core.bootablejar; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.jboss.galleon.MessageWriter; -import org.jboss.galleon.ProvisioningException; -import org.jboss.galleon.api.GalleonBuilder; -import org.jboss.galleon.api.GalleonFeaturePackRuntime; -import org.jboss.galleon.api.GalleonProvisioningRuntime; -import org.jboss.galleon.api.Provisioning; -import org.jboss.galleon.api.config.GalleonProvisioningConfig; -import org.jboss.galleon.universe.maven.MavenArtifact; -import org.jboss.galleon.universe.maven.MavenUniverseException; -import org.jboss.galleon.universe.maven.repo.MavenRepoManager; -import org.jboss.galleon.util.IoUtils; -import org.jboss.galleon.util.ZipUtils; -import org.jboss.logging.Logger; -import org.wildfly.plugins.core.cli.CLIForkedBootConfigGenerator; -import org.wildfly.plugins.core.cli.ForkedCLIUtil; - -/** - * - * @author jdenise - */ -public class BootableJarSupport { - - public static final String BOOTABLE_SUFFIX = "bootable"; - - public static final String JBOSS_MODULES_GROUP_ID = "org.jboss.modules"; - public static final String JBOSS_MODULES_ARTIFACT_ID = "jboss-modules"; - - private static final String MODULE_ID_JAR_RUNTIME = "org.wildfly.bootable-jar"; - - private static final String BOOT_ARTIFACT_ID = "wildfly-jar-boot"; - public static final String WILDFLY_ARTIFACT_VERSIONS_RESOURCE_PATH = "wildfly/artifact-versions.properties"; - - /** - * Package a wildfly server as a bootable JAR. - */ - public static void packageBootableJar(Path targetJarFile, Path target, - GalleonProvisioningConfig config, Path serverHome, MavenRepoManager resolver, - MessageWriter writer, Logger log) throws Exception { - Path contentRootDir = target.resolve("bootable-jar-build-artifacts"); - if (Files.exists(contentRootDir)) { - IoUtils.recursiveDelete(contentRootDir); - } - Files.createDirectories(contentRootDir); - try { - ScannedArtifacts bootable; - Path emptyHome = contentRootDir.resolve("tmp-home"); - Files.createDirectories(emptyHome); - try (Provisioning pm = new GalleonBuilder().addArtifactResolver(resolver).newProvisioningBuilder(config) - .setInstallationHome(emptyHome) - .setMessageWriter(writer) - .build()) { - bootable = scanArtifacts(pm, config, log); - pm.storeProvisioningConfig(config, contentRootDir.resolve("provisioning.xml")); - } - String[] paths = new String[bootable.getCliArtifacts().size()]; - int i = 0; - for (MavenArtifact a : bootable.getCliArtifacts()) { - resolver.resolve(a); - paths[i] = a.getPath().toAbsolutePath().toString(); - i += 1; - } - Path output = File.createTempFile("cli-script-output", null).toPath(); - Files.deleteIfExists(output); - output.toFile().deleteOnExit(); - IoUtils.recursiveDelete(emptyHome); - ForkedCLIUtil.fork(log, paths, CLIForkedBootConfigGenerator.class, serverHome, output); - zipServer(serverHome, contentRootDir); - buildJar(contentRootDir, targetJarFile, bootable, resolver); - } finally { - IoUtils.recursiveDelete(contentRootDir); - } - } - - public static void unzipCloudExtension(Path contentDir, String version, MavenRepoManager resolver) - throws MavenUniverseException, IOException { - MavenArtifact ma = new MavenArtifact(); - ma.setGroupId("org.wildfly.plugins"); - ma.setArtifactId("wildfly-jar-cloud-extension"); - ma.setExtension("jar"); - ma.setVersion(version); - resolver.resolve(ma); - ZipUtils.unzip(ma.getPath(), contentDir); - } - - public static void zipServer(Path home, Path contentDir) throws IOException { - cleanupServer(home); - Path target = contentDir.resolve("wildfly.zip"); - ZipUtils.zip(home, target); - } - - private static void cleanupServer(Path jbossHome) throws IOException { - Path history = jbossHome.resolve("standalone").resolve("configuration").resolve("standalone_xml_history"); - IoUtils.recursiveDelete(history); - Files.deleteIfExists(jbossHome.resolve("README.txt")); - } - - public static ScannedArtifacts scanArtifacts(Provisioning pm, GalleonProvisioningConfig config, Logger log) - throws Exception { - Set cliArtifacts = new HashSet<>(); - MavenArtifact jbossModules = null; - MavenArtifact bootArtifact = null; - try (GalleonProvisioningRuntime rt = pm.getProvisioningRuntime(config)) { - for (GalleonFeaturePackRuntime fprt : rt.getGalleonFeaturePacks()) { - if (fprt.getGalleonPackage(MODULE_ID_JAR_RUNTIME) != null) { - // We need to discover GAV of the associated boot. - Path artifactProps = fprt.getResource(WILDFLY_ARTIFACT_VERSIONS_RESOURCE_PATH); - final Map propsMap = new HashMap<>(); - try { - readProperties(artifactProps, propsMap); - } catch (Exception ex) { - throw new Exception("Error reading artifact versions", ex); - } - for (Map.Entry entry : propsMap.entrySet()) { - String value = entry.getValue(); - MavenArtifact a = getArtifact(value); - if (BOOT_ARTIFACT_ID.equals(a.getArtifactId())) { - // We got it. - log.debug("Found " + a + " in " + fprt.getFPID()); - bootArtifact = a; - break; - } - } - } - // Lookup artifacts to retrieve the required dependencies for isolated CLI execution - Path artifactProps = fprt.getResource(WILDFLY_ARTIFACT_VERSIONS_RESOURCE_PATH); - final Map propsMap = new HashMap<>(); - try { - readProperties(artifactProps, propsMap); - } catch (Exception ex) { - throw new Exception("Error reading artifact versions", ex); - } - for (Map.Entry entry : propsMap.entrySet()) { - String value = entry.getValue(); - MavenArtifact a = getArtifact(value); - if ("wildfly-cli".equals(a.getArtifactId()) - && "org.wildfly.core".equals(a.getGroupId())) { - // We got it. - a.setClassifier("client"); - log.debug("Found " + a + " in " + fprt.getFPID()); - cliArtifacts.add(a); - continue; - } - if (JBOSS_MODULES_ARTIFACT_ID.equals(a.getArtifactId()) - && JBOSS_MODULES_GROUP_ID.equals(a.getGroupId())) { - jbossModules = a; - } - } - } - } - if (bootArtifact == null) { - throw new ProvisioningException("Server doesn't support bootable jar packaging"); - } - if (jbossModules == null) { - throw new ProvisioningException("JBoss Modules not found in dependency, can't create a Bootable JAR"); - } - return new ScannedArtifacts(bootArtifact, jbossModules, cliArtifacts); - } - - public static void buildJar(Path contentDir, Path jarFile, ScannedArtifacts bootable, MavenRepoManager resolver) - throws Exception { - resolver.resolve(bootable.getBoot()); - Path rtJarFile = bootable.getBoot().getPath(); - resolver.resolve(bootable.getJbossModules()); - Path jbossModulesFile = bootable.getJbossModules().getPath(); - ZipUtils.unzip(jbossModulesFile, contentDir); - ZipUtils.unzip(rtJarFile, contentDir); - ZipUtils.zip(contentDir, jarFile); - } - - private static void readProperties(Path propsFile, Map propsMap) throws Exception { - try (BufferedReader reader = Files.newBufferedReader(propsFile)) { - String line = reader.readLine(); - while (line != null) { - line = line.trim(); - if (!line.isEmpty() && line.charAt(0) != '#') { - final int i = line.indexOf('='); - if (i < 0) { - throw new Exception("Failed to parse property " + line + " from " + propsFile); - } - propsMap.put(line.substring(0, i), line.substring(i + 1)); - } - line = reader.readLine(); - } - } - } - - static MavenArtifact getArtifact(String str) { - final String[] parts = str.split(":"); - final String groupId = parts[0]; - final String artifactId = parts[1]; - String version = parts[2]; - String classifier = parts[3]; - String extension = parts[4]; - - MavenArtifact ma = new MavenArtifact(); - ma.setGroupId(groupId); - ma.setArtifactId(artifactId); - ma.setVersion(version); - ma.setClassifier(classifier); - ma.setExtension(extension); - return ma; - } -} diff --git a/core/src/main/java/org/wildfly/plugins/core/bootablejar/Expression.java b/core/src/main/java/org/wildfly/plugins/core/bootablejar/Expression.java deleted file mode 100644 index 6acd5379..00000000 --- a/core/src/main/java/org/wildfly/plugins/core/bootablejar/Expression.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugins.core.bootablejar; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.jboss.dmr.ValueExpression; - -/** - * A simple expression parser which only parses the possible keys and default values. - * - * @author James R. Perkins - */ -class Expression { - - private static final int INITIAL = 0; - private static final int GOT_DOLLAR = 1; - private static final int GOT_OPEN_BRACE = 2; - private static final int RESOLVED = 3; - private static final int DEFAULT = 4; - - private final List keys; - private final String defaultValue; - - private Expression(final Collection keys, final String defaultValue) { - this.keys = new ArrayList<>(keys); - this.defaultValue = defaultValue; - } - - /** - * Creates a collection of expressions based on the value. - * - * @param value the expression value - * - * @return the expression keys and default value for each expression found within the value - */ - static Collection parse(final ValueExpression value) { - return parseExpression(value.getExpressionString()); - } - - /** - * Creates a collection of expressions based on the value. - * - * @param value the expression value - * - * @return the expression keys and default value for each expression found within the value - */ - static Collection parse(final String expression) { - return parseExpression(expression); - } - - /** - * All the keys associated with this expression. - * - * @return the keys - */ - List getKeys() { - return Collections.unmodifiableList(keys); - } - - /** - * Checks if there is a default value. - * - * @return {@code true} if the default value is not {@code null}, otherwise {@code false} - */ - boolean hasDefault() { - return defaultValue != null; - } - - /** - * Returns the default value which may be {@code null}. - * - * @return the default value - */ - String getDefaultValue() { - return defaultValue; - } - - void appendTo(final StringBuilder builder) { - builder.append("${"); - final Iterator iter = keys.iterator(); - while (iter.hasNext()) { - builder.append(iter.next()); - if (iter.hasNext()) { - builder.append(','); - } - } - if (hasDefault()) { - builder.append(':').append(defaultValue); - } - builder.append('}'); - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - appendTo(builder); - return builder.toString(); - } - - private static Collection parseExpression(final String expression) { - final Collection result = new ArrayList<>(); - final Collection keys = new ArrayList<>(); - final StringBuilder key = new StringBuilder(); - String defaultValue = null; - final char[] chars = expression.toCharArray(); - final int len = chars.length; - int state = 0; - int start = -1; - int nameStart = -1; - for (int i = 0; i < len; i++) { - char ch = chars[i]; - switch (state) { - case INITIAL: { - if (ch == '$') { - state = GOT_DOLLAR; - } - continue; - } - case GOT_DOLLAR: { - if (ch == '{') { - start = i + 1; - nameStart = start; - state = GOT_OPEN_BRACE; - } else { - // invalid; emit and resume - state = INITIAL; - } - continue; - } - case GOT_OPEN_BRACE: { - switch (ch) { - case ':': - case '}': - case ',': { - final String name = expression.substring(nameStart, i).trim(); - if ("/".equals(name)) { - state = ch == '}' ? INITIAL : RESOLVED; - continue; - } else if (":".equals(name)) { - state = ch == '}' ? INITIAL : RESOLVED; - continue; - } - key.append(name); - if (ch == '}') { - state = INITIAL; - if (key.length() > 0) { - keys.add(key.toString()); - key.setLength(0); - } - result.add(new Expression(keys, defaultValue)); - defaultValue = null; - keys.clear(); - continue; - } else if (ch == ',') { - if (key.length() > 0) { - keys.add(key.toString()); - key.setLength(0); - } - nameStart = i + 1; - continue; - } else { - start = i + 1; - state = DEFAULT; - if (key.length() > 0) { - keys.add(key.toString()); - key.setLength(0); - } - continue; - } - } - default: { - continue; - } - } - } - case RESOLVED: { - if (ch == '}') { - state = INITIAL; - if (keys.size() > 0) { - result.add(new Expression(keys, defaultValue)); - defaultValue = null; - keys.clear(); - } - } - continue; - } - case DEFAULT: { - if (ch == '}') { - state = INITIAL; - defaultValue = expression.substring(start, i); - if (key.length() > 0) { - keys.add(key.toString()); - key.setLength(0); - } - if (keys.size() > 0) { - result.add(new Expression(keys, defaultValue)); - defaultValue = null; - keys.clear(); - } - } - continue; - } - default: - throw new IllegalStateException(); - } - } - if (key.length() > 0) { - keys.add(key.toString()); - result.add(new Expression(keys, defaultValue)); - } - return result; - } -} diff --git a/core/src/main/java/org/wildfly/plugins/core/bootablejar/ScannedArtifacts.java b/core/src/main/java/org/wildfly/plugins/core/bootablejar/ScannedArtifacts.java deleted file mode 100644 index 8c9c048d..00000000 --- a/core/src/main/java/org/wildfly/plugins/core/bootablejar/ScannedArtifacts.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugins.core.bootablejar; - -import java.util.Set; - -import org.jboss.galleon.universe.maven.MavenArtifact; - -/** - * - * @author jdenise - */ -public class ScannedArtifacts { - - private final MavenArtifact jbossModules; - private final MavenArtifact boot; - private final Set cliArtifacts; - - public ScannedArtifacts(MavenArtifact bootArtifact, MavenArtifact jbossModules, Set cliArtifacts) { - this.boot = bootArtifact; - this.jbossModules = jbossModules; - this.cliArtifacts = cliArtifacts; - } - - /** - * @return the boot - */ - public MavenArtifact getBoot() { - return boot; - } - - /** - * @return the jbossModules - */ - public MavenArtifact getJbossModules() { - return jbossModules; - } - - /** - * @return the cliArtifacts - */ - public Set getCliArtifacts() { - return cliArtifacts; - } - -} diff --git a/core/src/main/java/org/wildfly/plugins/core/cli/CLIForkedBootConfigGenerator.java b/core/src/main/java/org/wildfly/plugins/core/cli/CLIForkedBootConfigGenerator.java deleted file mode 100644 index abcc7300..00000000 --- a/core/src/main/java/org/wildfly/plugins/core/cli/CLIForkedBootConfigGenerator.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugins.core.cli; - -import java.io.FileInputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Properties; - -import org.wildfly.plugins.core.bootablejar.BootLoggingConfiguration; - -/** - * Generate boot logging config forked process entry point. - * - * @author jdenise - */ -public class CLIForkedBootConfigGenerator { - - public static void main(String[] args) throws Exception { - Path jbossHome = Paths.get(args[0]); - Path cliOutput = Paths.get(args[1]); - Path systemProperties = Paths.get(args[2]); - Properties properties = new Properties(); - try (FileInputStream in = new FileInputStream(systemProperties.toFile())) { - properties.load(in); - for (String key : properties.stringPropertyNames()) { - System.setProperty(key, properties.getProperty(key)); - } - } - try (CLIWrapper executor = new CLIWrapper(jbossHome, false, CLIForkedBootConfigGenerator.class.getClassLoader(), - new BootLoggingConfiguration())) { - try { - executor.generateBootLoggingConfig(); - } finally { - Files.write(cliOutput, executor.getOutput().getBytes(StandardCharsets.UTF_8)); - } - } - } -} diff --git a/core/src/main/java/org/wildfly/plugins/core/cli/CLIWrapper.java b/core/src/main/java/org/wildfly/plugins/core/cli/CLIWrapper.java deleted file mode 100644 index 3112ea55..00000000 --- a/core/src/main/java/org/wildfly/plugins/core/cli/CLIWrapper.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugins.core.cli; - -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.wildfly.plugins.core.bootablejar.BootLoggingConfiguration; - -/** - * A CLI executor, resolving CLI classes from the provided Classloader. We can't - * have cli/embedded/jboss modules in plugin classpath, it causes issue because - * we are sharing the same jboss module classes between execution run inside the - * same JVM. - * - * CLI dependencies are retrieved from provisioned server artifacts list and - * resolved using maven. In addition jboss-modules.jar located in the - * provisioned server is added. - * - * @author jdenise - */ -public class CLIWrapper implements AutoCloseable { - - private final Object ctx; - private final Method handle; - private final Method handleSafe; - private final Method terminateSession; - private final Method getModelControllerClient; - private final Method bindClient; - private final ByteArrayOutputStream out = new ByteArrayOutputStream(); - private final String origConfig; - private final Path jbossHome; - private final BootLoggingConfiguration bootLoggingConfiguration; - - public CLIWrapper(Path jbossHome, boolean resolveExpression, ClassLoader loader) throws Exception { - this(jbossHome, resolveExpression, loader, null); - } - - public CLIWrapper(Path jbossHome, boolean resolveExpression, ClassLoader loader, - BootLoggingConfiguration bootLoggingConfiguration) throws Exception { - if (jbossHome != null) { - Path config = jbossHome.resolve("bin").resolve("jboss-cli.xml"); - origConfig = System.getProperty("jboss.cli.config"); - if (Files.exists(config)) { - System.setProperty("jboss.cli.config", config.toString()); - } - } else { - origConfig = null; - } - this.jbossHome = jbossHome; - final Object builder = loader.loadClass("org.jboss.as.cli.impl.CommandContextConfiguration$Builder").newInstance(); - final Method setEchoCommand = builder.getClass().getMethod("setEchoCommand", boolean.class); - setEchoCommand.invoke(builder, true); - final Method setResolve = builder.getClass().getMethod("setResolveParameterValues", boolean.class); - setResolve.invoke(builder, resolveExpression); - final Method setOutput = builder.getClass().getMethod("setConsoleOutput", OutputStream.class); - setOutput.invoke(builder, out); - Object ctxConfig = builder.getClass().getMethod("build").invoke(builder); - Object factory = loader.loadClass("org.jboss.as.cli.CommandContextFactory").getMethod("getInstance").invoke(null); - final Class configClass = loader.loadClass("org.jboss.as.cli.impl.CommandContextConfiguration"); - ctx = factory.getClass().getMethod("newCommandContext", configClass).invoke(factory, ctxConfig); - handle = ctx.getClass().getMethod("handle", String.class); - handleSafe = ctx.getClass().getMethod("handleSafe", String.class); - terminateSession = ctx.getClass().getMethod("terminateSession"); - getModelControllerClient = ctx.getClass().getMethod("getModelControllerClient"); - bindClient = ctx.getClass().getMethod("bindClient", ModelControllerClient.class); - this.bootLoggingConfiguration = bootLoggingConfiguration; - } - - public void handle(String command) throws Exception { - handle.invoke(ctx, command); - } - - public void handleSafe(String command) throws Exception { - handleSafe.invoke(ctx, command); - } - - public void bindClient(ModelControllerClient client) throws Exception { - bindClient.invoke(ctx, client); - } - - public String getOutput() { - return out.toString(); - } - - @Override - public void close() throws Exception { - try { - terminateSession.invoke(ctx); - } finally { - if (origConfig != null) { - System.setProperty("jboss.cli.config", origConfig); - } - } - } - - private ModelControllerClient getModelControllerClient() throws Exception { - return (ModelControllerClient) getModelControllerClient.invoke(ctx); - } - - public void generateBootLoggingConfig() throws Exception { - Objects.requireNonNull(bootLoggingConfiguration); - Exception toThrow = null; - try { - // Start the embedded server - handle("embed-server --jboss-home=" + jbossHome + " --std-out=discard"); - // Get the client used to execute the management operations - final ModelControllerClient client = getModelControllerClient(); - // Update the bootable logging config - final Path configDir = jbossHome.resolve("standalone").resolve("configuration"); - bootLoggingConfiguration.generate(configDir, client); - } catch (Exception e) { - toThrow = e; - } finally { - try { - // Always stop the embedded server - handle("stop-embedded-server"); - } catch (Exception e) { - if (toThrow != null) { - e.addSuppressed(toThrow); - } - toThrow = e; - } - } - // Check if an error has been thrown and throw it. - if (toThrow != null) { - throw toThrow; - } - } -} diff --git a/core/src/main/java/org/wildfly/plugins/core/cli/ForkedCLIUtil.java b/core/src/main/java/org/wildfly/plugins/core/cli/ForkedCLIUtil.java deleted file mode 100644 index b482d540..00000000 --- a/core/src/main/java/org/wildfly/plugins/core/cli/ForkedCLIUtil.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.plugins.core.cli; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -import org.jboss.galleon.BaseErrors; -import org.jboss.galleon.ProvisioningException; -import org.jboss.logging.Logger; - -/** - * - * @author jdenise - */ -public class ForkedCLIUtil { - - private static String javaHome; - private static String javaCmd; - - private static String getJavaHome() { - return javaHome == null ? javaHome = System.getProperty("java.home") : javaHome; - } - - private static String getJavaCmd() { - return javaCmd == null ? javaCmd = Paths.get(getJavaHome()).resolve("bin").resolve("java").toString() : javaCmd; - } - - public static void fork(Logger log, String[] artifacts, Class clazz, Path home, Path output, String... args) - throws Exception { - // prepare the classpath - final StringBuilder cp = new StringBuilder(); - for (String loc : artifacts) { - cp.append(loc).append(File.pathSeparator); - } - StringBuilder contextCP = new StringBuilder(); - collectCpUrls(getJavaHome(), Thread.currentThread().getContextClassLoader(), contextCP); - // This happens when running tests, use the process classpath to retrieve the CLIForkedExecutor main class - if (contextCP.length() == 0) { - log.debug("Re-using process classpath to retrieve Maven plugin classes to fork CLI process."); - cp.append(System.getProperty("java.class.path")); - } else { - cp.append(contextCP); - } - Path properties = storeSystemProps(); - - final List argsList = new ArrayList<>(); - argsList.add(getJavaCmd()); - argsList.add("-server"); - argsList.add("-cp"); - argsList.add(cp.toString()); - argsList.add(clazz.getName()); - argsList.add(home.toString()); - argsList.add(output.toString()); - argsList.add(properties.toString()); - for (String s : args) { - argsList.add(s); - } - log.debug("CLI process command line " + argsList); - try { - final Process p; - try { - p = new ProcessBuilder(argsList).redirectErrorStream(true).start(); - } catch (IOException e) { - throw new ProvisioningException("Failed to start forked process", e); - } - StringBuilder traces = new StringBuilder(); - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8))) { - String line = reader.readLine(); - while (line != null) { - traces.append(line).append(System.lineSeparator()); - line = reader.readLine(); - } - if (p.isAlive()) { - try { - p.waitFor(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - int exitCode = p.exitValue(); - if (exitCode != 0) { - log.error("Error executing CLI:" + traces); - throw new Exception("CLI execution failed:" + traces); - } - } finally { - Files.deleteIfExists(properties); - } - } - - private static Path storeSystemProps() throws ProvisioningException { - final Path props; - try { - props = Files.createTempFile("wfbootablejar", "sysprops"); - } catch (IOException e) { - throw new ProvisioningException("Failed to create a tmp file", e); - } - try (BufferedWriter writer = Files.newBufferedWriter(props)) { - System.getProperties().store(writer, ""); - } catch (IOException e) { - throw new ProvisioningException(BaseErrors.writeFile(props), e); - } - return props; - } - - private static void collectCpUrls(String javaHome, ClassLoader cl, StringBuilder buf) throws URISyntaxException { - final ClassLoader parentCl = cl.getParent(); - if (parentCl != null) { - collectCpUrls(javaHome, cl.getParent(), buf); - } - if (cl instanceof URLClassLoader) { - for (URL url : ((URLClassLoader) cl).getURLs()) { - final String file = new File(url.toURI()).getAbsolutePath(); - if (file.startsWith(javaHome)) { - continue; - } - if (buf.length() > 0) { - buf.append(File.pathSeparatorChar); - } - buf.append(file); - } - } - } -} diff --git a/core/src/main/resources/META-INF/LICENSE.txt b/core/src/main/resources/META-INF/LICENSE.txt deleted file mode 100644 index 7a4a3ea2..00000000 --- a/core/src/main/resources/META-INF/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. \ No newline at end of file diff --git a/core/src/test/java/org/wildfly/plugin/core/AbstractDeploymentManagerTest.java b/core/src/test/java/org/wildfly/plugin/core/AbstractDeploymentManagerTest.java deleted file mode 100644 index 8b421d1d..00000000 --- a/core/src/test/java/org/wildfly/plugin/core/AbstractDeploymentManagerTest.java +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.Closeable; -import java.io.IOException; -import java.net.UnknownHostException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.helpers.ClientConstants; -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.dmr.ModelNode; -import org.jboss.shrinkwrap.api.Archive; -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.EmptyAsset; -import org.jboss.shrinkwrap.api.exporter.ZipExporter; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.wildfly.plugin.core.common.Simple; - -/** - * @author James R. Perkins - */ -@SuppressWarnings("WeakerAccess") -abstract class AbstractDeploymentManagerTest { - - private static final char[] hexChars = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' - }; - - protected DeploymentManager deploymentManager; - - @Before - public void setup() throws UnknownHostException { - deploymentManager = DeploymentManager.Factory.create(getClient()); - } - - @After - public void undeployAll() throws IOException { - final Set deployments = new HashSet<>(); - for (DeploymentDescription deployment : deploymentManager.getDeployments()) { - deployments.add(UndeployDescription.of(deployment)); - } - if (!deployments.isEmpty()) { - deploymentManager.undeploy(deployments).assertSuccess(); - } - } - - @Test - public void testDeploy() throws Exception { - final String deploymentName = "test-deploy.war"; - final Deployment deployment = createDefaultDeployment(deploymentName); - deployForSuccess(deployment); - assertDeploymentEnabled(deployment); - - // Expect a failure when trying to deploy the same content - assertFailed(deploymentManager.deploy(deployment)); - } - - @Test - public void testDeployMulti() throws Exception { - final Deployment deployment1 = createDefaultDeployment("test-deploy-1.war"); - final Deployment deployment2 = createDefaultDeployment("test-deploy-2.war"); - final Set deployments = newSet(deployment1, deployment2); - deployForSuccess(deployments); - assertDeploymentEnabled(deployment1); - assertDeploymentEnabled(deployment2); - - // Expect a failure when trying to deploy the same content - assertFailed(deploymentManager.deploy(deployments)); - // Deployments should still exist and be enabled - assertDeploymentExists(deployment1, true); - assertDeploymentExists(deployment2, true); - } - - @Test - public void testDeployFile() throws Exception { - final Path tempPath = Files.createTempDirectory("deployment-content"); - try { - final Path content = tempPath.resolve("test-deploy-file.war"); - createDefaultArchive(content.getFileName().toString()).as(ZipExporter.class).exportTo(content.toFile(), true); - final Deployment deployment = configureDeployment(Deployment.of(content)); - deployForSuccess(deployment); - assertDeploymentEnabled(deployment); - } finally { - deletePath(tempPath); - } - } - - @Test - public void testDeployUrl() throws Exception { - final Path tempPath = Files.createTempDirectory("deployment-content"); - try { - final Path content = tempPath.resolve("test-deploy-file.war"); - createDefaultArchive(content.getFileName().toString()).as(ZipExporter.class).exportTo(content.toFile(), true); - final Deployment deployment = configureDeployment(Deployment.of(content.toUri().toURL())); - deployForSuccess(deployment); - assertDeploymentEnabled(deployment); - } finally { - deletePath(tempPath); - } - } - - @Test - public void testForceDeploy() throws Exception { - final String deploymentName = "test-deploy.war"; - final Deployment deployment = createDefaultDeployment(deploymentName); - DeployResult deployResult = deployForSuccess(deployment, true); - - // Get the current hash - final byte[] hash = deployResult.hash; - long lastEnabledTime = deployResult.enabledTime; - - // Force deploy the content and ensure the hash is the same - deployResult = deployForSuccess(deployment, true); - assertDeploymentEnabled(deployment); - - byte[] currentHash = deployResult.hash; - long currentLastEnabledTime = deployResult.enabledTime; - // Compare the original hash and the new hash, they should be equal as the content is exactly the same. However - // the timestamps should not be equal as the content should have been replaced and therefore undeployed, then - // redeployed. - Assert.assertArrayEquals( - String.format("Expected hash to be equal: %nExpected: %s%nFound: %s%n", bytesToHexString(hash), - bytesToHexString(currentHash)), - hash, currentHash); - Assert.assertNotEquals("Last enabled times should not match.", lastEnabledTime, currentLastEnabledTime); - - // Create a new deployment, add new content and force deploy it which should result in a new hash and timestamp - final WebArchive archive = createDefaultArchive(deploymentName) - .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); - final Deployment changedDeployment = createDeployment(archive); - deployResult = deployForSuccess(changedDeployment, true); - assertDeploymentEnabled(changedDeployment); - - currentHash = deployResult.hash; - lastEnabledTime = currentLastEnabledTime; - currentLastEnabledTime = deployResult.enabledTime; - - // In this case we've added some new content to the deployment. The hashes should not match and once again the - // timestamps should be different. - Assert.assertFalse( - String.format("Expected hash to be equal: %nExpected: %s%nFound: %s%n", bytesToHexString(hash), - bytesToHexString(currentHash)), - Arrays.equals(hash, currentHash)); - Assert.assertNotEquals("Last enabled times should not match.", lastEnabledTime, currentLastEnabledTime); - - } - - @Test - public void testForceDeployMulti() throws Exception { - final Deployment deployment1 = createDefaultDeployment("test-deploy-1.war"); - final Deployment deployment2 = createDefaultDeployment("test-deploy-2.war"); - final Set deployments = newSet(deployment1, deployment2); - final Map first = deployForSuccess(deployments, true); - - // Force deploy the content and ensure the hash is the same - final Set deployments2 = newSet(deployment1, deployment2); - final Map second = deployForSuccess(deployments2, true); - - Assert.assertEquals(first.size(), second.size()); - Assert.assertTrue(first.keySet().containsAll(second.keySet())); - - // Skip time checks on domain until WFCORE-1667 is fixed - final boolean checkTime = !ServerHelper.getContainerDescription(getClient()).isDomain(); - // Get the current hash - for (Deployment deployment : deployments) { - final byte[] hash = first.get(deployment).hash; - final long lastEnabledTime = first.get(deployment).enabledTime; - - final byte[] currentHash = second.get(deployment).hash; - final long currentLastEnabledTime = second.get(deployment).enabledTime; - // Compare the original hash and the new hash, they should be equal as the content is exactly the same. However - // the timestamps should not be equal as the content should have been replaced and therefore undeployed, then - // redeployed. - Assert.assertArrayEquals( - String.format("Expected hash to be equal: %nExpected: %s%nFound: %s%n", bytesToHexString(hash), - bytesToHexString(currentHash)), - hash, currentHash); - if (checkTime) { - Assert.assertNotEquals("Last enabled times should not match", lastEnabledTime, currentLastEnabledTime); - } - } - } - - @Test - public void testDeployToRuntime() throws Exception { - final String deploymentName = "test-runtime-deploy.war"; - final Deployment deployment = createDefaultDeployment(deploymentName) - .setEnabled(false); - - deployForSuccess(deployment); - // The content should be disable, i.e. not deployed to the runtime - assertDeploymentDisabled(deployment); - - // Deploy the content to the runtime, this should result in the enabled field resulting in true - assertSuccess(deploymentManager.deployToRuntime(deployment)); - // The content should now be enabled, i.e. deployed to runtime - assertDeploymentEnabled(deployment); - } - - @Test - public void testDeployToRuntimeMulti() throws Exception { - final Deployment deployment1 = createDefaultDeployment("test-runtime-deploy-1.war") - .setEnabled(false); - final Deployment deployment2 = createDefaultDeployment("test-runtime-deploy-2.war") - .setEnabled(false); - final Deployment deployment3 = createDefaultDeployment("test-runtime-deploy-3.war") - .setEnabled(true); - - deployForSuccess(newSet(deployment1, deployment2, deployment3)); - // The content should be disable, i.e. not deployed to the runtime - assertDeploymentDisabled(deployment1); - assertDeploymentDisabled(deployment2); - // This third deployment should be enabled - assertDeploymentEnabled(deployment3); - - // Deploy the content to the runtime, this should result in the enabled field resulting in true - assertSuccess(deploymentManager.deployToRuntime(newSet((DeploymentDescription) deployment1, deployment2, deployment3))); - // The content should now be enabled, i.e. deployed to runtime - assertDeploymentEnabled(deployment1); - assertDeploymentEnabled(deployment2); - assertDeploymentEnabled(deployment3); - } - - @Test - public void testRedeploy() throws Exception { - final String deploymentName = "test-redeploy.war"; - final Deployment deployment = createDefaultDeployment(deploymentName); - - // Redeploy should fail as the deployment should not exist - assertFailed(deploymentManager.redeploy(deployment)); - - // Deploy the content, the redeploy for a successful redeploy - final DeployResult deployResult = deployForSuccess(deployment); - final DeployResult currentDeployResult = redeployForSuccess(deployment); - // Compare the original hash and the new hash, they should be equal as the content is exactly the same. However - // the timestamps should not be equal as the content should have been replaced and therefore undeployed, then - // redeployed. - Assert.assertArrayEquals( - String.format("Expected hash to be equal: %nExpected: %s%nFound: %s%n", bytesToHexString(deployResult.hash), - bytesToHexString(currentDeployResult.hash)), - deployResult.hash, currentDeployResult.hash); - Assert.assertNotEquals("Last enabled times should not match.", deployResult.enabledTime, - currentDeployResult.enabledTime); - } - - @Test - public void testRedeployMulti() throws Exception { - final Deployment deployment1 = createDefaultDeployment("test-redeploy-1.war"); - final Deployment deployment2 = createDefaultDeployment("test-redeploy-2.war"); - final Deployment deployment3 = createDefaultDeployment("test-redeploy-3.war"); - final Set allDeployments = newSet(deployment1, deployment2, deployment3); - - // Redeploy should fail as the deployment should not exist - assertFailed(deploymentManager.redeploy(allDeployments)); - - // Deploy just two of the deployments, then attempt to redeploy all 3 which should fail since one of them could - // not be redeployed - final Map deployResults = deployForSuccess(newSet(deployment1, deployment2)); - assertFailed(deploymentManager.redeploy(allDeployments)); - - // Deploy the third deployment content, the redeploy all for a successful redeploy - deployResults.put(deployment3, deployForSuccess(deployment3)); - final Map currentDeployResults = redeployForSuccess(allDeployments); - - Assert.assertEquals("Expected the same size for the original deployment results and the redeploy results", - deployResults.size(), currentDeployResults.size()); - Assert.assertTrue(deployResults.keySet().containsAll(currentDeployResults.keySet())); - - // Skip time checks on domain until WFCORE-1667 is fixed - final boolean checkTime = !ServerHelper.getContainerDescription(getClient()).isDomain(); - - for (Deployment deployment : allDeployments) { - final DeployResult deployResult = deployResults.get(deployment); - final DeployResult currentDeployResult = currentDeployResults.get(deployment); - // Compare the original hash and the new hash, they should be equal as the content is exactly the same. However - // the timestamps should not be equal as the content should have been replaced and therefore undeployed, then - // redeployed. - Assert.assertArrayEquals( - String.format("Expected hash to be equal: %nExpected: %s%nFound: %s%n", bytesToHexString(deployResult.hash), - bytesToHexString(currentDeployResult.hash)), - deployResult.hash, currentDeployResult.hash); - if (checkTime) { - Assert.assertNotEquals("Last enabled times should not match.", deployResult.enabledTime, - currentDeployResult.enabledTime); - } - } - } - - @Test - public void testRedeployFile() throws Exception { - final Path tempPath = Files.createTempDirectory("deployment-content"); - try { - final Path content = tempPath.resolve("test-deploy-file.war"); - createDefaultArchive(content.getFileName().toString()).as(ZipExporter.class).exportTo(content.toFile(), true); - final Deployment deployment = configureDeployment(Deployment.of(content)); - // First deploy, then redeploy - deployForSuccess(deployment); - redeployForSuccess(deployment); - assertDeploymentEnabled(deployment); - } finally { - deletePath(tempPath); - } - } - - @Test - public void testRedeployUrl() throws Exception { - final Path tempPath = Files.createTempDirectory("deployment-content"); - try { - final Path content = tempPath.resolve("test-deploy-file.war"); - createDefaultArchive(content.getFileName().toString()).as(ZipExporter.class).exportTo(content.toFile(), true); - final Deployment deployment = configureDeployment(Deployment.of(content.toUri().toURL())); - // First deploy, then redeploy - deployForSuccess(deployment); - redeployForSuccess(deployment); - assertDeploymentEnabled(deployment); - } finally { - deletePath(tempPath); - } - } - - @Test - public void testRedeployToRuntime() throws Exception { - // There is a bug in WildFly, fixed in 10.1.0, using a full-replace-deployment operation when the enabled - // attribute is set to false. Do not test a redeploy with a disabled deployment here as it will remove all - // subsystems. See WFCORE-1577. - - final String deploymentName = "test-runtime-redeploy.war"; - final Deployment deployment = createDefaultDeployment(deploymentName); - - final DeployResult deployResult = deployForSuccess(deployment); - - // Deploy the content to the runtime, this should result in the enabled field resulting in true - final DeployResult currentDeployResult = createResult(deploymentManager.redeployToRuntime(deployment), deployment); - final DeploymentResult result = currentDeployResult.deploymentResult; - assertSuccess(result); - assertDeploymentExists(deployment, true); - Assert.assertArrayEquals( - String.format("Expected hash to be equal: %nExpected: %s%nFound: %s%n", bytesToHexString(deployResult.hash), - bytesToHexString(currentDeployResult.hash)), - deployResult.hash, currentDeployResult.hash); - // Timestamps should match as a redeploy only redploy's deploys the runtime not the content - Assert.assertEquals("Last enabled times should not match.", deployResult.enabledTime, currentDeployResult.enabledTime); - } - - @Test - public void testRedeployToRuntimeMulti() throws Exception { - // There is a bug in WildFly, fixed in 10.1.0, using a full-replace-deployment operation when the enabled - // attribute is set to false. Do not test a redeploy with a disabled deployment here as it will remove all - // subsystems. See WFCORE-1577. - - final Deployment deployment1 = createDefaultDeployment("test-runtime-redeploy-1.war"); - final Deployment deployment2 = createDefaultDeployment("test-runtime-redeploy-2.war"); - final Deployment deployment3 = createDefaultDeployment("test-runtime-redeploy-3.war"); - final Set allDeployments = newSet(deployment1, deployment2, deployment3); - final Map deployResults = deployForSuccess(allDeployments); - - // Deploy the content to the runtime, this should result in the enabled field resulting in true - final Map currentDeployResults = createResult( - deploymentManager.redeployToRuntime(newSet((DeploymentDescription) deployment1, deployment2, deployment3)), - allDeployments); - - Assert.assertEquals("Expected the same size for the original deployment results and the redeploy results", - deployResults.size(), currentDeployResults.size()); - Assert.assertTrue(deployResults.keySet().containsAll(currentDeployResults.keySet())); - - // Skip time checks on domain until WFCORE-1667 is fixed - final boolean checkTime = !ServerHelper.getContainerDescription(getClient()).isDomain(); - - for (Deployment deployment : allDeployments) { - final DeployResult deployResult = deployResults.get(deployment); - final DeployResult currentDeployResult = currentDeployResults.get(deployment); - Assert.assertArrayEquals( - String.format("Expected hash to be equal: %nExpected: %s%nFound: %s%n", bytesToHexString(deployResult.hash), - bytesToHexString(currentDeployResult.hash)), - deployResult.hash, currentDeployResult.hash); - if (checkTime) { - // Timestamps should match as a redeploy only redploy's deploys the runtime not the content - Assert.assertEquals("Last enabled times should not match.", deployResult.enabledTime, - currentDeployResult.enabledTime); - } - } - } - - @Test - public void testUndeploy() throws Exception { - final String deploymentName = "test-undeploy.war"; - final Deployment deployment = createDefaultDeployment(deploymentName); - - // First undeploy and don't fail on a missing deployment - undeployForSuccess(UndeployDescription.of(deployment) - .setFailOnMissing(false), - false); - - // Test an undeploy that should fail since it's missing - assertFailed(deploymentManager.undeploy( - UndeployDescription.of(deployment) - .setFailOnMissing(true))); - assertDeploymentDoesNotExist(deployment); - - // Deploy the content so it can be undeployed, but leave the content itself on the server. This should result in - // the enabled being false and the disabled-time being defined. - deployForSuccess(deployment); - - undeployForSuccess( - UndeployDescription.of(deployment) - .setRemoveContent(false), - true); - - // Deploy the content back to the runtime - assertSuccess(deploymentManager.deployToRuntime(deployment)); - - // Undeploy the content completely, the content should no longer be in the container - undeployForSuccess( - UndeployDescription.of(deployment) - .setRemoveContent(true), - false); - - } - - @Test - public void testUndeployMulti() throws Exception { - final Deployment deployment1 = createDefaultDeployment("test-undeploy-1.war"); - final Deployment deployment2 = createDefaultDeployment("test-undeploy-2.war"); - final Deployment deployment3 = createDefaultDeployment("test-undeploy-3.war"); - - // First undeploy and don't fail on a missing deployment - assertSuccess(deploymentManager.undeploy( - newSet(UndeployDescription.of(deployment1).setFailOnMissing(false), - UndeployDescription.of(deployment2).setFailOnMissing(false)))); - - // Test an undeploy that should fail since it's missing - assertFailed(deploymentManager.undeploy( - newSet(UndeployDescription.of(deployment1).setFailOnMissing(false), - UndeployDescription.of(deployment2).setFailOnMissing(true), - UndeployDescription.of(deployment3).setFailOnMissing(false)))); - - // Deploy the content so it can be undeployed, but leave the content itself on the server. This should result in - // the enabled being false and the disabled-time being defined. - deployForSuccess(newSet(deployment1, deployment2, deployment3)); - - // Remove all deployments, leaving deployment1 and deployment2 content, but removing deployment3's content - assertSuccess(deploymentManager.undeploy( - newSet(UndeployDescription.of(deployment1).setRemoveContent(false), - UndeployDescription.of(deployment2).setRemoveContent(false), - UndeployDescription.of(deployment3).setRemoveContent(true)))); - - assertDeploymentExists(deployment1, false); - assertDeploymentExists(deployment2, false); - assertDeploymentDoesNotExist(deployment3); - - // Deploy the content back to the runtime - assertSuccess(deploymentManager.deployToRuntime(newSet((DeploymentDescription) deployment1, deployment2))); - - // Undeploy remaining - assertSuccess(deploymentManager.undeploy( - newSet(UndeployDescription.of(deployment1).setRemoveContent(true), - UndeployDescription.of(deployment2).setRemoveContent(true)))); - assertDeploymentDoesNotExist(deployment1); - assertDeploymentDoesNotExist(deployment2); - } - - protected abstract ModelControllerClient getClient(); - - protected abstract ModelNode createDeploymentResourceAddress(String deploymentName) throws IOException; - - void assertSuccess(final DeploymentResult result) { - if (!result.successful()) { - Assert.fail(result.getFailureMessage()); - } - } - - void assertFailed(final DeploymentResult result) { - Assert.assertFalse("Deployment was expected to fail.", result.successful()); - } - - void assertDeploymentExists(final DeploymentDescription deployment) throws IOException { - Assert.assertTrue(String.format("Expected deployment %s to exist in the content repository.", deployment), - deploymentManager.hasDeployment(deployment.getName())); - for (String serverGroup : deployment.getServerGroups()) { - Assert.assertTrue(String.format("Expected deployment %s to exist in the content repository.", deployment), - deploymentManager.hasDeployment(deployment.getName(), serverGroup)); - } - } - - void assertDeploymentExists(final DeploymentDescription deployment, final boolean shouldBeEnabled) throws IOException { - Assert.assertTrue(String.format("Expected deployment %s to exist in the content repository.", deployment), - deploymentManager.hasDeployment(deployment.getName())); - final Set serverGroups = deployment.getServerGroups(); - if (serverGroups.isEmpty()) { - Assert.assertEquals( - String.format("Expected enabled attribute to be %s for deployment %s", shouldBeEnabled, deployment), - shouldBeEnabled, deploymentManager.isEnabled(deployment.getName())); - } else { - for (String serverGroup : serverGroups) { - Assert.assertTrue(String.format("Expected deployment %s to exist on %s.", deployment, serverGroup), - deploymentManager.hasDeployment(deployment.getName(), serverGroup)); - Assert.assertEquals(String.format("Expected enabled attribute to be %s for deployment %s on server group %s", - shouldBeEnabled, deployment, serverGroup), - shouldBeEnabled, deploymentManager.isEnabled(deployment.getName(), serverGroup)); - } - } - } - - void assertDeploymentDoesNotExist(final DeploymentDescription deployment) throws IOException { - Assert.assertFalse(String.format("Expected deployment %s to not exist.", deployment), - deploymentManager.hasDeployment(deployment.getName())); - } - - void assertDeploymentEnabled(final DeploymentDescription deployment) throws IOException { - final Set serverGroups = deployment.getServerGroups(); - if (serverGroups.isEmpty()) { - Assert.assertTrue(String.format("Expected deployment %s to be enabled", deployment), - deploymentManager.isEnabled(deployment.getName())); - } else { - for (String serverGroup : serverGroups) { - Assert.assertTrue(String.format("Expected deployment %s to be enabled on %s", deployment, serverGroup), - deploymentManager.isEnabled(deployment.getName(), serverGroup)); - } - } - } - - void assertDeploymentDisabled(final DeploymentDescription deployment) throws IOException { - final Set serverGroups = deployment.getServerGroups(); - if (serverGroups.isEmpty()) { - Assert.assertFalse(String.format("Expected deployment %s to be disabled", deployment), - deploymentManager.isEnabled(deployment.getName())); - } else { - for (String serverGroup : serverGroups) { - Assert.assertFalse(String.format("Expected deployment %s to be disabled on %s", deployment, serverGroup), - deploymentManager.isEnabled(deployment.getName(), serverGroup)); - } - } - } - - DeployResult deployForSuccess(final Deployment deployment) throws IOException { - return deployForSuccess(deployment, false); - } - - DeployResult deployForSuccess(final Deployment deployment, final boolean force) throws IOException { - final DeploymentResult result; - if (force) { - result = deploymentManager.forceDeploy(deployment); - } else { - result = deploymentManager.deploy(deployment); - } - assertSuccess(result); - assertDeploymentExists(deployment); - return createResult(result, deployment); - } - - Map deployForSuccess(final Set deployments) throws IOException, InterruptedException { - return deployForSuccess(deployments, false); - } - - Map deployForSuccess(final Set deployments, final boolean force) - throws IOException, InterruptedException { - final DeploymentResult result; - if (force) { - result = deploymentManager.forceDeploy(deployments); - } else { - result = deploymentManager.deploy(deployments); - } - assertSuccess(result); - final Map results = new LinkedHashMap<>(); - for (Deployment deployment : deployments) { - assertDeploymentExists(deployment); - results.put(deployment, createResult(result, deployment)); - } - return results; - } - - DeployResult redeployForSuccess(final Deployment deployment) throws IOException { - final DeploymentResult result = deploymentManager.redeploy(deployment); - assertSuccess(result); - assertDeploymentExists(deployment); - return createResult(result, deployment); - } - - Map redeployForSuccess(final Set deployments) throws IOException { - final DeploymentResult result = deploymentManager.redeploy(deployments); - assertSuccess(result); - final Map results = new LinkedHashMap<>(); - for (Deployment deployment : deployments) { - assertDeploymentExists(deployment); - results.put(deployment, createResult(result, deployment)); - } - return results; - } - - DeploymentResult undeployForSuccess(final UndeployDescription deployment, final boolean contentShouldExist) - throws IOException { - return undeployForSuccess(deployment, deployment.getServerGroups(), contentShouldExist); - } - - DeploymentResult undeployForSuccess(final UndeployDescription deployment, final Set expectedServerGroups, - final boolean contentShouldExist) throws IOException { - final DeploymentResult result = deploymentManager.undeploy(deployment); - assertSuccess(result); - if (contentShouldExist) { - final DeploymentDescription copy = SimpleDeploymentDescription.of(deployment.getName(), expectedServerGroups); - assertDeploymentExists(copy, false); - } else { - // There's no need to check the server-groups, if the content is no longer in the repository it can't be on - // the server groups. - assertDeploymentDoesNotExist(deployment); - } - return result; - } - - ModelNode executeOp(final ModelNode op) throws IOException { - final ModelNode result = getClient().execute(op); - if (Operations.isSuccessfulOutcome(result)) { - return Operations.readResult(result); - } - Assert.fail(String.format("Operation %s failed: %s", op, Operations.getFailureDescription(result))); - // Should never be reached - return new ModelNode(); - } - - Deployment createDefaultDeployment(final String name) { - return createDeployment(createDefaultArchive(name)); - } - - Deployment createDeployment(final Archive archive) { - return configureDeployment(Deployment.of(archive.as(ZipExporter.class).exportAsInputStream(), archive.getName())); - } - - Deployment configureDeployment(final Deployment deployment) { - return deployment; - } - - private byte[] readDeploymentHash(final String deploymentName) throws IOException { - final ModelNode op = Operations.createReadAttributeOperation( - DeploymentOperations.createAddress(ClientConstants.DEPLOYMENT, deploymentName), ClientConstants.CONTENT); - // Response should be a list, we only need the first entry - final ModelNode response = executeOp(op).get(0); - if (response.hasDefined("hash")) { - return response.get("hash").asBytes(); - } - return new byte[0]; - } - - private long readLastEnabledTime(final ModelNode address) throws IOException { - final ModelNode op = Operations.createReadAttributeOperation(address, "enabled-time"); - final ModelNode response = executeOp(op); - return response.isDefined() ? response.asLong() : 0L; - } - - private DeployResult createResult(final DeploymentResult result, final Deployment deployment) throws IOException { - return new DeployResult(result, deployment, readDeploymentHash(deployment.getName()), - readLastEnabledTime(createDeploymentResourceAddress(deployment.getName()))); - } - - private Map createResult(final DeploymentResult result, final Collection deployments) - throws IOException { - final Map results = new LinkedHashMap<>(deployments.size()); - for (Deployment deployment : deployments) { - results.put(deployment, createResult(result, deployment)); - } - return results; - } - - static WebArchive createDefaultArchive(final String name) { - return ShrinkWrap.create(WebArchive.class, name) - .addClass(Simple.class); - } - - static void safeClose(final Closeable closeable) { - if (closeable != null) - try { - closeable.close(); - } catch (Exception ignore) { - } - } - - @SuppressWarnings("unchecked") - static Set newSet(final E... entries) { - final Set result = new LinkedHashSet<>(); - Collections.addAll(result, entries); - return result; - } - - private static void deletePath(final Path path) throws IOException { - if (Files.isDirectory(path)) { - Files.walkFileTree(path, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { - Files.deleteIfExists(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException { - Files.deleteIfExists(dir); - return FileVisitResult.CONTINUE; - } - }); - } else { - Files.deleteIfExists(path); - } - } - - private static String bytesToHexString(final byte[] bytes) { - final StringBuilder builder = new StringBuilder(bytes.length * 2); - for (byte b : bytes) { - // noinspection MagicNumber - builder.append(hexChars[b >> 4 & 0x0f]).append(hexChars[b & 0x0f]); - } - return builder.toString(); - } - - @SuppressWarnings("unused") - static class DeployResult { - private final DeploymentResult deploymentResult; - private final Deployment deployment; - private final byte[] hash; - private final long enabledTime; - - DeployResult(final DeploymentResult deploymentResult, final Deployment deployment, final byte[] hash, - final long enabledTime) { - this.deploymentResult = deploymentResult; - this.deployment = deployment; - this.hash = hash; - this.enabledTime = enabledTime; - } - } - -} diff --git a/core/src/test/java/org/wildfly/plugin/core/DeploymentResultTestCase.java b/core/src/test/java/org/wildfly/plugin/core/DeploymentResultTestCase.java deleted file mode 100644 index 55980926..00000000 --- a/core/src/test/java/org/wildfly/plugin/core/DeploymentResultTestCase.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import org.jboss.dmr.ModelNode; -import org.junit.Assert; -import org.junit.Test; - -/** - * @author James R. Perkins - */ -public class DeploymentResultTestCase { - - @Test - public void testSuccessful() { - Assert.assertTrue(DeploymentResult.SUCCESSFUL.successful()); - Assert.assertNull(DeploymentResult.SUCCESSFUL.getFailureMessage()); - Assert.assertFalse(DeploymentResult.SUCCESSFUL.asModelNode().isDefined()); - - final DeploymentResult deploymentResult = new DeploymentResult(createCompositeOutcome()); - Assert.assertTrue(deploymentResult.successful()); - Assert.assertNull(deploymentResult.getFailureMessage()); - Assert.assertTrue(deploymentResult.asModelNode().isDefined()); - } - - @Test - public void testFailed() { - // Create a failure description - final ModelNode failureModel = createCompositeOutcome( - "WFLYCTL0212: Duplicate resource [(\"deployment\" => \"foo.war\")]"); - - DeploymentResult deploymentResult = new DeploymentResult(failureModel); - Assert.assertFalse(deploymentResult.successful()); - Assert.assertEquals("WFLYCTL0212: Duplicate resource [(\"deployment\" => \"foo.war\")]", - deploymentResult.getFailureMessage()); - Assert.assertTrue(deploymentResult.asModelNode().isDefined()); - - // Create a failure not based on model node - deploymentResult = new DeploymentResult("Test failed message"); - Assert.assertFalse(deploymentResult.successful()); - Assert.assertEquals("Test failed message", deploymentResult.getFailureMessage()); - Assert.assertFalse(deploymentResult.asModelNode().isDefined()); - - // Create a failure not based on model node - deploymentResult = new DeploymentResult("Test failed message %d", 2); - Assert.assertFalse(deploymentResult.successful()); - Assert.assertEquals("Test failed message 2", deploymentResult.getFailureMessage()); - Assert.assertFalse(deploymentResult.asModelNode().isDefined()); - } - - @Test - public void testFailureAssertion() { - try { - new DeploymentResult("Test failure result").assertSuccess(); - Assert.fail("Expected the deployment result to be a failure result"); - } catch (DeploymentException ignore) { - } - try { - new DeploymentResult("Test failure result %d", 2).assertSuccess(); - Assert.fail("Expected the deployment result to be a failure result"); - } catch (DeploymentException ignore) { - } - - // Create a failure description - try { - new DeploymentResult(createCompositeOutcome("WFLYCTL0212: Duplicate resource [(\"deployment\" => \"foo.war\")]")) - .assertSuccess(); - Assert.fail("Expected the deployment result to be a failure result"); - } catch (DeploymentException ignore) { - } - } - - private static ModelNode createCompositeOutcome() { - return createCompositeOutcome(null); - } - - private static ModelNode createCompositeOutcome(final String failureMessage) { - final ModelNode response = createOutcome(failureMessage); - final ModelNode result = response.get("result"); - result.get("step-1").set(createOutcome(failureMessage)); - return response; - } - - private static ModelNode createOutcome(final String failureMessage) { - final ModelNode result = new ModelNode().setEmptyObject(); - if (failureMessage == null) { - result.get("outcome").set("success"); - } else { - result.get("outcome").set("failed"); - result.get("failure-description").set(failureMessage); - result.get("rolled-back").set(true); - } - return result; - } -} diff --git a/core/src/test/java/org/wildfly/plugin/core/DeploymentTestCase.java b/core/src/test/java/org/wildfly/plugin/core/DeploymentTestCase.java deleted file mode 100644 index ba85fa36..00000000 --- a/core/src/test/java/org/wildfly/plugin/core/DeploymentTestCase.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.jboss.shrinkwrap.api.Archive; -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.exporter.ZipExporter; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Assert; -import org.junit.Test; -import org.wildfly.plugin.core.common.Simple; - -/** - * @author James R. Perkins - */ -public class DeploymentTestCase { - private static final Path TEST_DEPLOYMENT_DIR = Paths.get(System.getProperty("test.deployment.dir", ".")).toAbsolutePath() - .normalize(); - private static final String TEST_DEPLOYMENT_FILE_NAME = TEST_DEPLOYMENT_DIR.getFileName().toString(); - - @Test - public void testPathDeploymentName() { - final Deployment deployment = Deployment.of(TEST_DEPLOYMENT_DIR); - Assert.assertEquals(TEST_DEPLOYMENT_FILE_NAME, deployment.getName()); - - // Set the file name and expect the new name - final String name = "changed.war"; - deployment.setName(name); - Assert.assertEquals(name, deployment.getName()); - - // Reset the name to null and expect the file name - deployment.setName(null); - Assert.assertEquals(TEST_DEPLOYMENT_FILE_NAME, deployment.getName()); - } - - @Test - public void testInputStreamDeploymentName() { - final String name = "test.war"; - final WebArchive war = ShrinkWrap.create(WebArchive.class, name) - .addClass(Simple.class); - final TestInputStream in = new TestInputStream(war); - final Deployment deployment = Deployment.of(in, name); - Assert.assertEquals(name, deployment.getName()); - Assert.assertTrue("Expected to the input stream to be closed", in.closed.get()); - - // Set the file name and expect the new name - final String changedName = "changed.war"; - deployment.setName(changedName); - Assert.assertEquals(changedName, deployment.getName()); - - // Reset the name to null and expect a failure - try { - deployment.setName(null); - Assert.fail("Expected setting the name to null for an input stream to fail."); - } catch (IllegalArgumentException ignore) { - } - } - - private static class TestInputStream extends FilterInputStream { - private final AtomicBoolean closed = new AtomicBoolean(false); - - private TestInputStream(final Archive archive) { - super(archive.as(ZipExporter.class).exportAsInputStream()); - } - - @Override - public void close() throws IOException { - try { - super.close(); - } finally { - closed.set(true); - } - } - } -} diff --git a/core/src/test/java/org/wildfly/plugin/core/DomainDeploymentManagerIT.java b/core/src/test/java/org/wildfly/plugin/core/DomainDeploymentManagerIT.java deleted file mode 100644 index 870ca677..00000000 --- a/core/src/test/java/org/wildfly/plugin/core/DomainDeploymentManagerIT.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.helpers.ClientConstants; -import org.jboss.as.controller.client.helpers.domain.DomainClient; -import org.jboss.dmr.ModelNode; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.wildfly.core.launcher.DomainCommandBuilder; -import org.wildfly.core.launcher.Launcher; -import org.wildfly.core.launcher.ProcessHelper; - -/** - * @author James R. Perkins - */ -@SuppressWarnings("StaticVariableMayNotBeInitialized") -public class DomainDeploymentManagerIT extends AbstractDeploymentManagerTest { - private static final String DEFAULT_SERVER_GROUP = "main-server-group"; - // Workaround for WFCORE-4121 - private static final String[] MODULAR_JDK_ARGUMENTS = { - "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED", - "--add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED", - "--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED", - "--add-modules=java.se", - }; - private static final boolean IS_MODULAR_JDK; - - static { - final String javaVersion = System.getProperty("java.specification.version"); - int vmVersion; - try { - final Matcher matcher = Pattern.compile("^(?:1\\.)?(\\d+)$").matcher(javaVersion); // match 1. or - if (matcher.find()) { - vmVersion = Integer.valueOf(matcher.group(1)); - } else { - throw new RuntimeException("Unknown version of jvm " + javaVersion); - } - } catch (Exception e) { - vmVersion = 8; - } - IS_MODULAR_JDK = vmVersion > 8; - } - - private static Process process; - private static DomainClient client; - private static Thread consoleConsomer; - - @BeforeClass - public static void startServer() throws Exception { - boolean ok = false; - try { - client = DomainClient.Factory.create(Environment.createClient()); - if (ServerHelper.isDomainRunning(client) || ServerHelper.isStandaloneRunning(client)) { - Assert.fail("A WildFly server is already running: " + ServerHelper.getContainerDescription(client)); - } - final DomainCommandBuilder commandBuilder = DomainCommandBuilder.of(Environment.WILDFLY_HOME); - if (IS_MODULAR_JDK) { - commandBuilder.addHostControllerJavaOptions(MODULAR_JDK_ARGUMENTS); - } - process = Launcher.of(commandBuilder).launch(); - consoleConsomer = ConsoleConsumer.start(process, System.out); - ServerHelper.waitForDomain(client, Environment.TIMEOUT); - ok = true; - } finally { - if (!ok) { - final Process p = process; - final ModelControllerClient c = client; - process = null; - client = null; - try { - ProcessHelper.destroyProcess(p); - } finally { - safeClose(c); - } - } - } - } - - @AfterClass - @SuppressWarnings("StaticVariableUsedBeforeInitialization") - public static void shutdown() throws Exception { - try { - if (client != null) { - ServerHelper.shutdownDomain(client); - safeClose(client); - } - } finally { - if (process != null) { - process.destroy(); - process.waitFor(); - } - if (consoleConsomer != null) { - consoleConsomer.interrupt(); - } - } - } - - @Test - public void testFailedDeploy() throws Exception { - // Expect a failure with no server groups defined - final Deployment failedDeployment = createDefaultDeployment("test-failed-deployment.war") - .setServerGroups(Collections. emptySet()); - assertFailed(deploymentManager.deploy(failedDeployment)); - assertDeploymentDoesNotExist(failedDeployment); - } - - @Test - public void testFailedDeployMulti() throws Exception { - // Expect a failure with no server groups defined - final Set failedDeployments = new HashSet<>(); - failedDeployments.add(createDefaultDeployment("test-failed-deployment-1.war")); - failedDeployments - .add(createDefaultDeployment("test-failed-deployment-2.war").setServerGroups(Collections. emptySet())); - assertFailed(deploymentManager.deploy(failedDeployments)); - for (Deployment failedDeployment : failedDeployments) { - assertDeploymentDoesNotExist(failedDeployment); - } - } - - @Test - public void testFailedForceDeploy() throws Exception { - // Expect a failure with no server groups defined - final Deployment failedDeployment = createDefaultDeployment("test-failed-deployment.war") - .setServerGroups(Collections. emptySet()); - assertFailed(deploymentManager.forceDeploy(failedDeployment)); - assertDeploymentDoesNotExist(failedDeployment); - - } - - @Test - public void testFailedRedeploy() throws Exception { - // Expect a failure with no server groups defined - assertFailed(deploymentManager - .redeploy(createDefaultDeployment("test-redeploy.war").setServerGroups(Collections. emptySet()))); - } - - @Test - public void testFailedUndeploy() throws Exception { - // Undeploy with an additional server-group where the deployment does not exist - undeployForSuccess( - UndeployDescription.of("test-undeploy-multi-server-groups.war") - .setFailOnMissing(false) - .setRemoveContent(false) - .addServerGroup("other-server-group"), - Collections.singleton(DEFAULT_SERVER_GROUP), false); - - // Undeploy with an additional server-group where the deployment does not exist - final Deployment deployment = createDefaultDeployment("test-undeploy-multi-server-groups-failed.war"); - deployForSuccess(deployment); - final DeploymentResult result = deploymentManager.undeploy( - UndeployDescription.of(deployment) - .setFailOnMissing(true) - .addServerGroup("other-server-group")); - assertFailed(result); - assertDeploymentExists(deployment, true); - } - - @Test - public void testDeploymentQueries() throws Exception { - Assert.assertTrue("No deployments should exist.", deploymentManager.getDeployments().isEmpty()); - Assert.assertTrue("No deployments should exist.", deploymentManager.getDeploymentNames().isEmpty()); - Assert.assertTrue(String.format("No deployments should exist on %s", DEFAULT_SERVER_GROUP), - deploymentManager.getDeployments(DEFAULT_SERVER_GROUP).isEmpty()); - } - - @Override - protected ModelControllerClient getClient() { - return client; - } - - @Override - protected ModelNode createDeploymentResourceAddress(final String deploymentName) throws IOException { - return ServerHelper.determineHostAddress(getClient()) - .add(ClientConstants.SERVER, "server-one") - .add(ClientConstants.DEPLOYMENT, deploymentName); - } - - @Override - Deployment configureDeployment(final Deployment deployment) { - return deployment.addServerGroups(DEFAULT_SERVER_GROUP); - } -} diff --git a/core/src/test/java/org/wildfly/plugin/core/Environment.java b/core/src/test/java/org/wildfly/plugin/core/Environment.java deleted file mode 100644 index b0d9fccf..00000000 --- a/core/src/test/java/org/wildfly/plugin/core/Environment.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.net.UnknownHostException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collection; -import java.util.Collections; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.logging.Logger; - -/** - * @author James R. Perkins - */ -@SuppressWarnings({ "WeakerAccess", "Duplicates" }) -public class Environment { - - /** - * The default WildFly home directory specified by the {@code jboss.home} system property. - */ - public static final Path WILDFLY_HOME; - /** - * The host name specified by the {@code wildfly.management.hostname} system property or {@code localhost} by - * default. - */ - public static final String HOSTNAME = System.getProperty("wildfly.management.hostname", "localhost"); - /** - * The port specified by the {@code wildfly.management.port} system property or {@code 9990} by default. - */ - public static final int PORT; - - /** - * The default server startup timeout specified by {@code wildfly.timeout}, default is 60 seconds. - */ - public static final long TIMEOUT; - - private static final String TMP_DIR = System.getProperty("java.io.tmpdir", "target"); - private static final int LOG_SERVER_PORT = getProperty("ts.log.server.port", 10514); - private static final Collection JVM_ARGS; - static { - final Logger logger = Logger.getLogger(Environment.class); - - // Get the WildFly home directory and copy to the temp directory - final String wildflyDist = System.getProperty("jboss.home"); - assert wildflyDist != null : "WildFly home property, jboss.home, was not set"; - Path wildflyHome = Paths.get(wildflyDist); - validateWildFlyHome(wildflyHome); - WILDFLY_HOME = wildflyHome; - - final String port = System.getProperty("wildfly.management.port", "9990"); - try { - PORT = Integer.parseInt(port); - } catch (NumberFormatException e) { - logger.debugf(e, "Invalid port: %s", port); - throw new RuntimeException("Invalid port: " + port, e); - } - - final String timeout = System.getProperty("wildfly.timeout", "60"); - try { - TIMEOUT = Long.parseLong(timeout); - } catch (NumberFormatException e) { - logger.debugf(e, "Invalid timeout: %s", timeout); - throw new RuntimeException("Invalid timeout: " + timeout, e); - } - final String jvmArgs = System.getProperty("test.jvm.args"); - if (jvmArgs == null) { - JVM_ARGS = Collections.emptyList(); - } else { - JVM_ARGS = Utils.splitArguments(jvmArgs); - } - } - - public static ModelControllerClient createClient() throws UnknownHostException { - return ModelControllerClient.Factory.create(HOSTNAME, PORT); - } - - private static void validateWildFlyHome(final Path wildflyHome) { - if (!ServerHelper.isValidHomeDirectory(wildflyHome)) { - throw new RuntimeException("Invalid WildFly home directory: " + wildflyHome); - } - } - - /** - * Creates a temporary path based on the {@code java.io.tmpdir} system - * property. - * - * @param paths the additional portions of the path - * - * @return the path - */ - public static Path createTempPath(final String... paths) { - return Paths.get(TMP_DIR, paths); - } - - /** - * Gets the log server port - *

- * The default is 10514 and can be overridden via the - * {@code ts.log.server.port} system property. - *

- * - * @return the log server port - */ - public static int getLogServerPort() { - return LOG_SERVER_PORT; - } - - /** - * Returns a collection of the JVM arguments to set for any server started during the test process. - * - * @return the JVM arguments - */ - public static Collection getJvmArgs() { - return JVM_ARGS; - } - - private static int getProperty(final String name, final int dft) { - final String value = System.getProperty(name); - return value == null ? dft : Integer.parseInt(value); - } -} diff --git a/core/src/test/java/org/wildfly/plugin/core/StandaloneDeploymentManagerIT.java b/core/src/test/java/org/wildfly/plugin/core/StandaloneDeploymentManagerIT.java deleted file mode 100644 index 8a728e4c..00000000 --- a/core/src/test/java/org/wildfly/plugin/core/StandaloneDeploymentManagerIT.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core; - -import java.io.IOException; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.helpers.ClientConstants; -import org.jboss.dmr.ModelNode; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.wildfly.core.launcher.Launcher; -import org.wildfly.core.launcher.ProcessHelper; -import org.wildfly.core.launcher.StandaloneCommandBuilder; - -/** - * @author James R. Perkins - */ -@SuppressWarnings("StaticVariableMayNotBeInitialized") -public class StandaloneDeploymentManagerIT extends AbstractDeploymentManagerTest { - - private static Process process; - private static ModelControllerClient client; - private static Thread consoleConsomer; - - @BeforeClass - public static void startServer() throws Exception { - boolean ok = false; - try { - client = Environment.createClient(); - if (ServerHelper.isDomainRunning(client) || ServerHelper.isStandaloneRunning(client)) { - Assert.fail("A WildFly server is already running: " + ServerHelper.getContainerDescription(client)); - } - final StandaloneCommandBuilder commandBuilder = StandaloneCommandBuilder.of(Environment.WILDFLY_HOME); - process = Launcher.of(commandBuilder).launch(); - consoleConsomer = ConsoleConsumer.start(process, System.out); - ServerHelper.waitForStandalone(client, Environment.TIMEOUT); - ok = true; - } finally { - if (!ok) { - final Process p = process; - final ModelControllerClient c = client; - process = null; - client = null; - try { - ProcessHelper.destroyProcess(p); - } finally { - safeClose(c); - } - } - } - } - - @AfterClass - @SuppressWarnings("StaticVariableUsedBeforeInitialization") - public static void shutdown() throws Exception { - try { - if (client != null) { - ServerHelper.shutdownStandalone(client); - safeClose(client); - } - } finally { - if (process != null) { - process.destroy(); - process.waitFor(); - } - } - } - - @Test - public void testDeploymentQueries() throws Exception { - Assert.assertTrue("No deployments should exist.", deploymentManager.getDeployments().isEmpty()); - Assert.assertTrue("No deployments should exist.", deploymentManager.getDeploymentNames().isEmpty()); - try { - deploymentManager.getDeployments("main-server-group"); - Assert.fail("This is not a domain server and DeploymentManager.getDeployments(serverGroup) should have failed."); - } catch (IllegalStateException ignore) { - } - } - - @Override - protected ModelControllerClient getClient() { - return client; - } - - @Override - protected ModelNode createDeploymentResourceAddress(final String deploymentName) throws IOException { - return DeploymentOperations.createAddress(ClientConstants.DEPLOYMENT, deploymentName); - } -} diff --git a/core/src/test/java/org/wildfly/plugin/core/common/Simple.java b/core/src/test/java/org/wildfly/plugin/core/common/Simple.java deleted file mode 100644 index 6646d8c7..00000000 --- a/core/src/test/java/org/wildfly/plugin/core/common/Simple.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.core.common; - -/** - * @author James R. Perkins - */ -public class Simple { -} diff --git a/core/src/test/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfigurationIT.java b/core/src/test/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfigurationIT.java deleted file mode 100644 index 23ba98cc..00000000 --- a/core/src/test/java/org/wildfly/plugins/core/bootablejar/BootLoggingConfigurationIT.java +++ /dev/null @@ -1,874 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * - * Copyright 2020 Red Hat, Inc., and individual 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.plugins.core.bootablejar; - -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.regex.Pattern; - -import org.jboss.as.controller.client.ModelControllerClient; -import org.jboss.as.controller.client.Operation; -import org.jboss.as.controller.client.helpers.ClientConstants; -import org.jboss.as.controller.client.helpers.Operations; -import org.jboss.as.controller.client.helpers.Operations.CompositeOperationBuilder; -import org.jboss.dmr.ModelNode; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; -import org.wildfly.core.launcher.Launcher; -import org.wildfly.core.launcher.StandaloneCommandBuilder; -import org.wildfly.plugin.core.Environment; -import org.wildfly.plugin.core.ServerHelper; - -/** - * @author James R. Perkins - */ -public class BootLoggingConfigurationIT { - - private static final Pattern EXPRESSION_PATTERN = Pattern.compile(".*\\$\\{.*}.*"); - private static Process currentProcess; - private static Path stdout; - private static ModelControllerClient client; - - @Rule - public TestName testName = new TestName(); - - private final Deque tearDownOps = new ArrayDeque<>(); - private Path tmpDir; - - @BeforeClass - public static void startWildFly() throws Exception { - stdout = Files.createTempFile("stdout-", ".log"); - final StandaloneCommandBuilder builder = StandaloneCommandBuilder.of(Environment.WILDFLY_HOME) - .addJavaOptions(Environment.getJvmArgs()); - currentProcess = Launcher.of(builder) - .setRedirectErrorStream(true) - .redirectOutput(stdout) - .launch(); - client = ModelControllerClient.Factory.create(Environment.HOSTNAME, Environment.PORT); - // Wait for standalone to start - ServerHelper.waitForStandalone(currentProcess, client, Environment.TIMEOUT); - Assert.assertTrue(String.format("Standalone server is not running:%n%s", getLog()), - ServerHelper.isStandaloneRunning(client)); - } - - @AfterClass - public static void shutdown() throws Exception { - if (client != null) { - ServerHelper.shutdownStandalone(client); - client.close(); - } - if (currentProcess != null) { - if (!currentProcess.waitFor(Environment.TIMEOUT, TimeUnit.SECONDS)) { - currentProcess.destroyForcibly(); - } - } - } - - @Before - public void setup() throws Exception { - tmpDir = Environment.createTempPath("test-config", testName.getMethodName()); - if (Files.notExists(tmpDir)) { - Files.createDirectories(tmpDir); - } - } - - @After - public void cleanUp() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - ModelNode op; - while ((op = tearDownOps.pollFirst()) != null) { - builder.addStep(op); - } - executeOperation(builder.build()); - } - - @Test - public void testDefault() throws Exception { - generateAndTest(); - } - - @Test - public void testAsyncHandler() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Add a file handler - final ModelNode fileHandler = createLoggingAddress("file-handler", "test-file"); - ModelNode op = Operations.createAddOperation(fileHandler); - op.get("named-formatter").set("PATTERN"); - op.get("append").set(true); - final ModelNode file = op.get("file"); - file.get("relative-to").set("jboss.server.log.dir"); - file.get("path").set("test-file.log"); - builder.addStep(op); - - // Add the async handler - final ModelNode asyncAddress = createLoggingAddress("async-handler", "async"); - op = Operations.createAddOperation(asyncAddress); - op.get("overflow-action").set("DISCARD"); - op.get("queue-length").set(5000); - final ModelNode subhandlers = op.get("subhandlers").setEmptyList(); - subhandlers.add("test-file"); - builder.addStep(op); - - // Add the handler to the root-logger - builder.addStep(createAddHandlerOp("async")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(asyncAddress)); - tearDownOps.add(Operations.createRemoveOperation(fileHandler)); - generateAndTest(); - } - - @Test - public void testDefaultConsole() throws Exception { - final ModelNode address = createLoggingAddress("console-handler", "new-handler"); - // Just do a raw add which will add the default formatter rather than a named-formatter - executeOperation(Operations.createAddOperation(address)); - tearDownOps.add(Operations.createRemoveOperation(address)); - generateAndTest(); - } - - @Test - public void testCustomHandler() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - final ModelNode formatterAddress = createLoggingAddress("custom-formatter", "json"); - ModelNode op = Operations.createAddOperation(formatterAddress); - op.get("class").set("org.jboss.logmanager.formatters.JsonFormatter"); - op.get("module").set("org.jboss.logmanager"); - ModelNode properties = op.get("properties"); - properties.get("prettyPrint").set("true"); - properties.get("recordDelimiter").set("|"); - builder.addStep(op); - - final ModelNode handlerAddress = createLoggingAddress("custom-handler", "custom-console"); - op = Operations.createAddOperation(handlerAddress); - op.get("class").set("org.jboss.logmanager.handlers.ConsoleHandler"); - op.get("module").set("org.jboss.logmanager"); - op.get("named-formatter").set("json"); - properties = op.get("properties"); - properties.get("target").set("SYSTEM_ERR"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("custom-console")); - - executeOperation(builder.build()); - // Create the tear down ops - tearDownOps.addLast(Operations.createRemoveOperation(handlerAddress)); - tearDownOps.addLast(Operations.createRemoveOperation(formatterAddress)); - - generateAndTest(); - } - - @Test - public void testCustomHandlerNoProperties() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - final ModelNode formatterAddress = createLoggingAddress("custom-formatter", "json"); - ModelNode op = Operations.createAddOperation(formatterAddress); - op.get("class").set("org.jboss.logmanager.formatters.JsonFormatter"); - op.get("module").set("org.jboss.logmanager"); - builder.addStep(op); - - final ModelNode handlerAddress = createLoggingAddress("custom-handler", "custom-console"); - op = Operations.createAddOperation(handlerAddress); - op.get("class").set("org.jboss.logmanager.handlers.ConsoleHandler"); - op.get("module").set("org.jboss.logmanager"); - op.get("named-formatter").set("json"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("custom-console")); - - executeOperation(builder.build()); - // Create the tear down ops - tearDownOps.addLast(Operations.createRemoveOperation(handlerAddress)); - tearDownOps.addLast(Operations.createRemoveOperation(formatterAddress)); - - generateAndTest(); - } - - @Test - public void testPeriodicRotatingFileHandler() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Create a handler to assign the formatter to - final ModelNode handlerAddress = createLoggingAddress("periodic-rotating-file-handler", "new-file"); - final ModelNode op = Operations.createAddOperation(handlerAddress); - op.get("named-formatter").set("PATTERN"); - op.get("suffix").set(".yyyy-MM-dd"); - final ModelNode file = op.get("file"); - file.get("relative-to").set("jboss.server.log.dir"); - file.get("path").set("test.log"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("new-file")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - - generateAndTest(); - } - - @Test - public void testPeriodicSizeRotatingFileHandler() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Create a handler to assign the formatter to - final ModelNode handlerAddress = createLoggingAddress("periodic-size-rotating-file-handler", "new-file"); - final ModelNode op = Operations.createAddOperation(handlerAddress); - op.get("named-formatter").set("PATTERN"); - op.get("suffix").set(".yyyy-MM-dd"); - op.get("rotate-on-boot").set(false); - op.get("rotate-size").set("${test.rotate.size:50M}"); - final ModelNode file = op.get("file"); - file.get("relative-to").set("jboss.server.log.dir"); - file.get("path").set("test.log"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("new-file")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - - generateAndTest(); - } - - @Test - public void testSizeRotatingFileHandler() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Create a handler to assign the formatter to - final ModelNode handlerAddress = createLoggingAddress("size-rotating-file-handler", "new-file"); - final ModelNode op = Operations.createAddOperation(handlerAddress); - op.get("named-formatter").set("PATTERN"); - op.get("rotate-on-boot").set(false); - op.get("rotate-size").set("50M"); - op.get("max-backup-index").set(100); - final ModelNode file = op.get("file"); - file.get("relative-to").set("jboss.server.log.dir"); - file.get("path").set("test.log"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("new-file")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - - generateAndTest(); - } - - @Test - @Ignore("This test is failing on CI. See WFCORE-5155.") - public void testSocketHandler() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Add the socket binding - final ModelNode socketBindingAddress = Operations.createAddress("socket-binding-group", "standard-sockets", - "remote-destination-outbound-socket-binding", "log-server"); - ModelNode op = Operations.createAddOperation(socketBindingAddress); - op.get("host").set(Environment.HOSTNAME); - op.get("port").set(Environment.getLogServerPort()); - builder.addStep(op); - - // Add a socket handler - final ModelNode address = createLoggingAddress("socket-handler", "socket"); - op = Operations.createAddOperation(address); - op.get("named-formatter").set("PATTERN"); - op.get("outbound-socket-binding-ref").set("log-server"); - builder.addStep(op); - - // Add the handler to the root-logger - builder.addStep(createAddHandlerOp("socket")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(address)); - tearDownOps.add(Operations.createRemoveOperation(socketBindingAddress)); - - generateAndTest(); - } - - @Test - public void testSyslogHandler() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Add a socket handler - final ModelNode address = createLoggingAddress("syslog-handler", "syslog"); - final ModelNode op = Operations.createAddOperation(address); - op.get("app-name").set("test-app"); - op.get("enabled").set(false); - op.get("facility").set("local-use-0"); - op.get("hostname").set(Environment.HOSTNAME); - op.get("level").set("WARN"); - op.get("named-formatter").set("PATTERN"); - op.get("port").set(Environment.getLogServerPort()); - builder.addStep(op); - - // Add the handler to the root-logger - builder.addStep(createAddHandlerOp("syslog")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(address)); - - generateAndTest(); - } - - @Test - public void testFilter() throws Exception { - final ModelNode filterAddress = createLoggingAddress("filter", "testFilter"); - ModelNode op = Operations.createAddOperation(filterAddress); - op.get("class").set(TestFilter.class.getName()); - op.get("module").set("org.wildfly.plugins.core.bootablejar"); - final ModelNode constructorProperties = op.get("constructor-properties"); - constructorProperties.get("constructorText").set(" | constructor property text"); - final ModelNode properties = op.get("properties"); - properties.get("propertyText").set(" | property text"); - executeOperation(op); - tearDownOps.add(Operations.createRemoveOperation(filterAddress)); - - generateAndTest(); - } - - @Test - public void testFilterNoProperties() throws Exception { - final ModelNode filterAddress = createLoggingAddress("filter", "testFilter"); - ModelNode op = Operations.createAddOperation(filterAddress); - op.get("class").set(TestFilter.class.getName()); - op.get("module").set("org.wildfly.plugins.core.bootablejar"); - executeOperation(op); - tearDownOps.add(Operations.createRemoveOperation(filterAddress)); - - generateAndTest(); - } - - @Test - public void testJsonFormatter() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - final ModelNode formatterAddress = createLoggingAddress("json-formatter", "json"); - ModelNode op = Operations.createAddOperation(formatterAddress); - op.get("pretty-print").set(false); - op.get("exception-output-type").set("${test.type:formatted}"); - op.get("date-format").set("yyyy-MM-dd'T'HH:mm:SSSZ"); - - final ModelNode keyOverrides = op.get("key-overrides").setEmptyObject(); - keyOverrides.get("message").set("msg"); - keyOverrides.get("stack-trace").set("cause"); - - final ModelNode metaData = op.get("meta-data").setEmptyObject(); - metaData.get("app-name").set("test"); - metaData.get("@version").set("1"); - - op.get("print-details").set(true); - op.get("record-delimiter").set("\n"); - op.get("zone-id").set("GMT"); - builder.addStep(op); - - // Create a handler to assign the formatter to - final ModelNode handlerAddress = createLoggingAddress("file-handler", "json-file"); - op = Operations.createAddOperation(handlerAddress); - op.get("append").set(false); - op.get("level").set("DEBUG"); - op.get("named-formatter").set("json"); - final ModelNode file = op.get("file"); - file.get("relative-to").set("jboss.server.log.dir"); - file.get("path").set("test-json.log"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("json-file")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - tearDownOps.add(Operations.createRemoveOperation(formatterAddress)); - - generateAndTest(); - } - - @Test - public void testPatternFormatter() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - final ModelNode formatterAddress = createLoggingAddress("pattern-formatter", "new-pattern"); - ModelNode op = Operations.createAddOperation(formatterAddress); - op.get("pattern").set("[test] %d{HH:mm:ss,SSS} %-5p [%c] %s%e%n"); - op.get("color-map").set("info:blue,warn:yellow,error:red,debug:cyan"); - builder.addStep(op); - - // Create a handler to assign the formatter to - final ModelNode handlerAddress = createLoggingAddress("file-handler", "new-file"); - op = Operations.createAddOperation(handlerAddress); - op.get("append").set(false); - op.get("encoding").set("ISO-8859-1"); - op.get("level").set("DEBUG"); - op.get("filter-spec").set("any(accept,match(\".*\"))"); - op.get("named-formatter").set("new-pattern"); - final ModelNode file = op.get("file"); - file.get("relative-to").set("jboss.server.log.dir"); - file.get("path").set("test.log"); - builder.addStep(op); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - tearDownOps.add(Operations.createRemoveOperation(formatterAddress)); - - generateAndTest(); - } - - @Test - public void testLogger() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Add a filter for the logger - final ModelNode filterAddress = createLoggingAddress("filter", "testFilter"); - ModelNode op = Operations.createAddOperation(filterAddress); - op.get("class").set(TestFilter.class.getName()); - op.get("module").set("org.wildfly.plugins.core.bootablejar"); - builder.addStep(op); - - // Add a formatter for the handler - final ModelNode formatterAddress = createLoggingAddress("pattern-formatter", "custom-formatter"); - op = Operations.createAddOperation(formatterAddress); - op.get("pattern").set("[%X{debug.token} %K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"); - builder.addStep(op); - - // Add a handler for the logger - final ModelNode handlerAddress = createLoggingAddress("console-handler", "custom-console"); - op = Operations.createAddOperation(handlerAddress); - op.get("named-formatter").set("custom-formatter"); - builder.addStep(op); - - // Create the logger - final ModelNode loggerAddress = createLoggingAddress("logger", "org.jboss.as"); - op = Operations.createAddOperation(loggerAddress); - op.get("level").set("${test.level:DEBUG}"); - op.get("use-parent-handlers").set(false); - op.get("filter-spec").set("all(testFilter)"); - final ModelNode handlers = op.get("handlers").setEmptyList(); - handlers.add("custom-console"); - builder.addStep(op); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(loggerAddress)); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - tearDownOps.add(Operations.createRemoveOperation(formatterAddress)); - tearDownOps.add(Operations.createRemoveOperation(filterAddress)); - - generateAndTest(); - } - - @Test - public void testWithProperties() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Create some expected properties - final Properties expectedProperties = new Properties(); - expectedProperties.setProperty("test.level", "TRACE"); - expectedProperties.setProperty("test.rotate-on-boot", "true"); - expectedProperties.setProperty("test.pretty.print", "true"); - expectedProperties.setProperty("test.exception-output-type", "formatted"); - expectedProperties.setProperty("test.zone.id", "UTC"); - expectedProperties.setProperty("test.dir", System.getProperty("java.io.tmpdir")); - - // Add the system properties - for (String key : expectedProperties.stringPropertyNames()) { - final ModelNode address = Operations.createAddress("system-property", key); - final ModelNode op = Operations.createAddOperation(address); - op.get("value").set(expectedProperties.getProperty(key)); - builder.addStep(op); - } - // Add a path and set this after - final ModelNode tmpPathAddress = Operations.createAddress("path", "custom.log.dir"); - ModelNode op = Operations.createAddOperation(tmpPathAddress); - op.get("path").set("${test.dir}"); - builder.addStep(op); - - final ModelNode logPathAddress = Operations.createAddress("path", "test.log.dir"); - op = Operations.createAddOperation(logPathAddress); - op.get("relative-to").set("custom.log.dir"); - op.get("path").set("logs"); - builder.addStep(op); - - // Add one property that won't be used so it shouldn't end up in the boot-config.properties - final ModelNode sysPropAddress = Operations.createAddress("system-property", "unused.property"); - op = Operations.createAddOperation(sysPropAddress); - op.get("value").set("not used"); - builder.addStep(op); - tearDownOps.add(Operations.createRemoveOperation(sysPropAddress)); - - // Create a formatter - final ModelNode formatterAddress = createLoggingAddress("json-formatter", "json"); - op = Operations.createAddOperation(formatterAddress); - op.get("pretty-print").set("${test.pretty.print:false}"); - op.get("exception-output-type").set("${test.exception-output-type:detailed}"); - op.get("zone-id").set("${test.zone.id:GMT}"); - // Always add a key-override. The reason is WFCORE-6344 causes the property to always be added. However, when - // testing with legacy servers, this might not be the case so the test will fail. Simply adding a key-overrides - // will get around the failure. - final ModelNode keyOverrides = op.get("key-overrides").setEmptyObject(); - keyOverrides.get("timestamp").set("@timestamp"); - builder.addStep(op); - - // Create a file handler - final ModelNode handlerAddress = createLoggingAddress("size-rotating-file-handler", "json-file"); - op = Operations.createAddOperation(handlerAddress); - op.get("named-formatter").set("json"); - op.get("rotate-on-boot").set("${test.rotate-on-boot:false}"); - op.get("rotate-size").set("50M"); - op.get("max-backup-index").set(100); - final ModelNode file = op.get("file"); - file.get("relative-to").set("test.log.dir"); - file.get("path").set("test.log"); - builder.addStep(op); - // We don't actually expect the custom.log.dir property here as it should be written to the file as - // ${test.dir}/${test.log.dir}/test.log - expectedProperties.setProperty("test.log.dir", "logs"); - - // Create a logger - final ModelNode loggerAddress = createLoggingAddress("logger", "org.wildfly.core"); - op = Operations.createAddOperation(loggerAddress); - op.get("level").set("${test.level:INFO}"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("json-file")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(loggerAddress)); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - tearDownOps.add(Operations.createRemoveOperation(formatterAddress)); - tearDownOps.add(Operations.createRemoveOperation(logPathAddress)); - tearDownOps.add(Operations.createRemoveOperation(tmpPathAddress)); - - // Remove all the properties last - for (String name : expectedProperties.stringPropertyNames()) { - // test.log.dir isn't an actual system property - if ("test.log.dir".equals(name)) - continue; - final ModelNode address = Operations.createAddress("system-property", name); - tearDownOps.addLast(Operations.createRemoveOperation(address)); - } - - generateAndTest(expectedProperties); - } - - @Test - public void testNestedPaths() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Create some expected properties - final Properties expectedProperties = new Properties(); - // Add a path and set this after - final ModelNode tmpPathAddress = Operations.createAddress("path", "custom.log.dir"); - ModelNode op = Operations.createAddOperation(tmpPathAddress); - op.get("path").set("custom-logs"); - op.get("relative-to").set("jboss.server.log.dir"); - builder.addStep(op); - - final ModelNode logPathAddress = Operations.createAddress("path", "test.log.dir"); - op = Operations.createAddOperation(logPathAddress); - op.get("relative-to").set("custom.log.dir"); - op.get("path").set("logs"); - builder.addStep(op); - expectedProperties.setProperty("custom.log.dir", "custom-logs"); - expectedProperties.setProperty("test.log.dir", "logs"); - - // Create a file handler - final ModelNode handlerAddress = createLoggingAddress("file-handler", "test-file"); - op = Operations.createAddOperation(handlerAddress); - op.get("named-formatter").set("PATTERN"); - final ModelNode file = op.get("file"); - file.get("relative-to").set("test.log.dir"); - file.get("path").set("test.log"); - builder.addStep(op); - - builder.addStep(createAddHandlerOp("test-file")); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(handlerAddress)); - tearDownOps.add(Operations.createRemoveOperation(logPathAddress)); - tearDownOps.add(Operations.createRemoveOperation(tmpPathAddress)); - - generateAndTest(expectedProperties); - } - - @Test - public void testMultiKeyExpression() throws Exception { - final CompositeOperationBuilder builder = CompositeOperationBuilder.create(); - - // Create some expected properties - final Properties expectedProperties = new Properties(); - expectedProperties.setProperty("test.prod.level", "INFO"); - expectedProperties.setProperty("test.min.level", "WARN"); - - // Add the system properties - for (String key : expectedProperties.stringPropertyNames()) { - final ModelNode address = Operations.createAddress("system-property", key); - final ModelNode op = Operations.createAddOperation(address); - op.get("value").set(expectedProperties.getProperty(key)); - builder.addStep(op); - tearDownOps.add(Operations.createRemoveOperation(address)); - } - - // Create a logger to set the level on - final ModelNode address = createLoggingAddress("logger", BootLoggingConfigurationIT.class.getName()); - final ModelNode op = Operations.createAddOperation(address); - op.get("level").set("${test.dev.level,test.prod.level,test.min.level:DEBUG}"); - builder.addStep(op); - - executeOperation(builder.build()); - tearDownOps.add(Operations.createRemoveOperation(address)); - - generateAndTest(expectedProperties); - } - - private void generateAndTest() throws Exception { - generateAndTest(null); - } - - private void generateAndTest(final Properties expectedBootConfig) throws Exception { - final BootLoggingConfiguration config = new BootLoggingConfiguration(); - // @TODO, we can't use AbstractLogEnabled, it is not in the maven plugin classloader. - // config.enableLogging(TestLogger.getLogger(BootLoggingConfigurationTestCase.class)); - config.generate(tmpDir, client); - compare(load(findLoggingConfig(), true, true), - load(tmpDir.resolve("logging.properties"), false, true), true); - final Path bootConfig = tmpDir.resolve("boot-config.properties"); - if (expectedBootConfig == null) { - // The file should not exist - Assert.assertTrue("Expected " + bootConfig + " not to exist", Files.notExists(bootConfig)); - } else { - compare(expectedBootConfig, load(bootConfig, false, false), false); - } - } - - private ModelNode createAddHandlerOp(final String handlerName) { - final ModelNode address = createLoggingAddress("root-logger", "ROOT"); - // Create the remove op first - ModelNode op = Operations.createOperation("remove-handler", address); - op.get("name").set(handlerName); - tearDownOps.addFirst(op); - - // Create the add op - op = Operations.createOperation("add-handler", address); - op.get("name").set(handlerName); - return op; - } - - private Path findLoggingConfig() throws IOException { - final Path serverLogConfig = Environment.WILDFLY_HOME.resolve("standalone").resolve("configuration") - .resolve("logging.properties"); - Assert.assertTrue("Could find config file " + serverLogConfig, Files.exists(serverLogConfig)); - return Files.copy(serverLogConfig, tmpDir.resolve("server-logging.properties"), StandardCopyOption.REPLACE_EXISTING); - } - - private static ModelNode createLoggingAddress(final String... parts) { - final Collection addresses = new ArrayList<>(); - addresses.add("subsystem"); - addresses.add("logging"); - Collections.addAll(addresses, parts); - return Operations.createAddress(addresses); - } - - private static ModelNode executeOperation(final ModelNode op) throws IOException { - return executeOperation(Operation.Factory.create(op)); - } - - private static ModelNode executeOperation(final Operation op) throws IOException { - final ModelNode result = client.execute(op); - if (!Operations.isSuccessfulOutcome(result)) { - Assert.fail(String.format("Operation %s failed: %s", op.getOperation(), - Operations.getFailureDescription(result).asString())); - } - // Reload if required - if (result.hasDefined(ClientConstants.RESPONSE_HEADERS)) { - final ModelNode responseHeaders = result.get(ClientConstants.RESPONSE_HEADERS); - if (responseHeaders.hasDefined("process-state")) { - if (ClientConstants.CONTROLLER_PROCESS_STATE_RELOAD_REQUIRED - .equals(responseHeaders.get("process-state").asString())) { - executeOperation(Operations.createOperation("reload")); - try { - ServerHelper.waitForStandalone(currentProcess, client, Environment.TIMEOUT); - } catch (InterruptedException | TimeoutException e) { - e.printStackTrace(); - Assert.fail("Reloading the server failed: " + e.getLocalizedMessage()); - } - } - } - } - return Operations.readResult(result); - } - - private static String getLog() throws IOException { - final StringBuilder result = new StringBuilder(); - Files.readAllLines(stdout, StandardCharsets.UTF_8).forEach(line -> result.append(line).append(System.lineSeparator())); - return result.toString(); - } - - private static void compare(final Properties expected, final Properties found, final boolean resolveExpressions) - throws IOException { - compareKeys(expected, found); - compareValues(expected, found, resolveExpressions); - } - - private static void compareKeys(final Properties expected, final Properties found) { - final Set expectedKeys = new TreeSet<>(expected.stringPropertyNames()); - final Set foundKeys = new TreeSet<>(found.stringPropertyNames()); - // Find the missing expected keys - final Set missing = new TreeSet<>(expectedKeys); - missing.removeAll(foundKeys); - Assert.assertTrue("Missing the following keys in the generated file: " + missing.toString(), - missing.isEmpty()); - - // Find additional keys - missing.addAll(foundKeys); - missing.removeAll(expectedKeys); - Assert.assertTrue("Found the following extra keys in the generated file: " + missing.toString(), - missing.isEmpty()); - } - - private static void compareValues(final Properties expected, final Properties found, final boolean resolveExpressions) - throws IOException { - final Set keys = new TreeSet<>(expected.stringPropertyNames()); - for (String key : keys) { - final String expectedValue = expected.getProperty(key); - final String foundValue = found.getProperty(key); - if (key.endsWith("fileName")) { - final Path foundFileName = resolvePath(foundValue); - Assert.assertEquals(Paths.get(expectedValue).normalize(), foundFileName); - } else { - if (expectedValue.contains(",")) { - // Assume the values are a list - final List expectedValues = stringToList(expectedValue); - final List foundValues = stringToList(foundValue); - Assert.assertEquals(String.format("Found %s expected %s", foundValues, expectedValues), expectedValues, - foundValues); - } else { - if (resolveExpressions && EXPRESSION_PATTERN.matcher(foundValue).matches()) { - String resolvedValue = resolveExpression(foundValue); - // Handle some special cases - if ("formatted".equals(resolvedValue)) { - resolvedValue = resolvedValue.toUpperCase(); - } - Assert.assertEquals(expectedValue, resolvedValue); - } else { - Assert.assertEquals(expectedValue, foundValue); - } - } - } - } - } - - private static List stringToList(final String value) { - final List result = new ArrayList<>(); - Collections.addAll(result, value.split(",")); - Collections.sort(result); - return result; - } - - private static Properties load(final Path path, final boolean expected, final boolean filter) throws IOException { - final Properties result = new Properties(); - try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { - result.load(reader); - } - if (filter) { - if (expected) { - result.remove("handlers"); - result.remove("formatters"); - result.remove("filters"); - } else { - // For some reason the default console-handler and periodic-rotating-file-handler don't persist the enabled - // attribute. - for (String key : result.stringPropertyNames()) { - if (key.equals("handler.CONSOLE.enabled") || key.equals("handler.FILE.enabled")) { - result.remove(key); - final String propertiesKey = resolvePrefix(key) + ".properties"; - final String value = result.getProperty(propertiesKey); - if (value != null) { - if ("enabled".equals(value)) { - result.remove(propertiesKey); - } else { - result.setProperty(propertiesKey, value.replace("enabled,", "").replace(",enabled", "")); - } - } - } - } - } - } - return result; - } - - private static String resolvePrefix(final String key) { - final int i = key.lastIndexOf('.'); - if (i > 0) { - return key.substring(0, i); - } - return key; - } - - private static Path resolvePath(final String path) throws IOException { - Path resolved = Paths.get(path); - if (EXPRESSION_PATTERN.matcher(path).matches()) { - // For testing purposes we're just going to use the last entry which should be a path entry - final LinkedList expressions = new LinkedList<>(Expression.parse(path)); - Assert.assertFalse("The path could not be resolved: " + path, expressions.isEmpty()); - final Expression expression = expressions.getLast(); - // We're assuming we only have one key entry which for testing purposes should be okay - final ModelNode op = Operations.createOperation("path-info", - Operations.createAddress("path", expression.getKeys().get(0))); - final ModelNode result = client.execute(op); - if (!Operations.isSuccessfulOutcome(result)) { - Assert.fail(Operations.getFailureDescription(result).asString()); - } - final ModelNode pathInfo = Operations.readResult(result); - final String resolvedPath = pathInfo.get("path", "resolved-path").asString(); - resolved = Paths.get(resolvedPath, resolved.getFileName().toString()); - } - return resolved.normalize(); - } - - private static String resolveExpression(final String value) throws IOException { - // Resolve the expression - ModelNode op = Operations.createOperation("resolve-expression"); - op.get("expression").set(value); - return executeOperation(op).asString(); - } -} diff --git a/core/src/test/java/org/wildfly/plugins/core/bootablejar/TestFilter.java b/core/src/test/java/org/wildfly/plugins/core/bootablejar/TestFilter.java deleted file mode 100644 index 333b4960..00000000 --- a/core/src/test/java/org/wildfly/plugins/core/bootablejar/TestFilter.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * - * Copyright 2019 Red Hat, Inc., and individual 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.plugins.core.bootablejar; - -import java.util.logging.Filter; -import java.util.logging.LogRecord; - -/** - * @author James R. Perkins - */ -@SuppressWarnings({ "WeakerAccess", "unused" }) -public class TestFilter implements Filter { - private final String constructorText; - private final boolean isLoggable; - private String propertyText; - - public TestFilter() { - this(null, true); - } - - public TestFilter(final boolean isLoggable) { - this(null, isLoggable); - } - - public TestFilter(final String constructorText) { - this(constructorText, true); - } - - public TestFilter(final String constructorText, final boolean isLoggable) { - this.constructorText = constructorText; - this.isLoggable = isLoggable; - } - - @Override - public boolean isLoggable(final LogRecord record) { - if (isLoggable) { - final StringBuilder newMsg = new StringBuilder(record.getMessage()); - if (constructorText != null) { - newMsg.append(constructorText); - } - if (propertyText != null) { - newMsg.append(propertyText); - } - record.setMessage(newMsg.toString()); - } - return isLoggable; - } - - public String getPropertyText() { - return propertyText; - } - - public void setPropertyText(final String propertyText) { - this.propertyText = propertyText; - } - - public String getConstructorText() { - return constructorText; - } - - @Override - public String toString() { - return TestFilter.class.getName() + - "[constructorText=" + constructorText + - ", isLoggable=" + isLoggable + - ", propertyText=" + propertyText + - "]"; - } -} diff --git a/core/src/test/modules/org/wildfly/plugins/core/bootablejar/main/module.xml b/core/src/test/modules/org/wildfly/plugins/core/bootablejar/main/module.xml deleted file mode 100644 index 1f4827bc..00000000 --- a/core/src/test/modules/org/wildfly/plugins/core/bootablejar/main/module.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/plugin/pom.xml b/plugin/pom.xml index b5a8394e..4d76ce9c 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -160,7 +160,7 @@ org.wildfly.core wildfly-protocol - + org.jboss.modules jboss-modules @@ -171,6 +171,10 @@ org.wildfly.plugins wildfly-plugin-core + + org.wildfly.plugins + wildfly-plugin-tools + org.wildfly.channel channel-core diff --git a/plugin/src/main/java/org/wildfly/plugin/cli/BaseCommandConfiguration.java b/plugin/src/main/java/org/wildfly/plugin/cli/BaseCommandConfiguration.java index 3f90e9b8..208296d2 100644 --- a/plugin/src/main/java/org/wildfly/plugin/cli/BaseCommandConfiguration.java +++ b/plugin/src/main/java/org/wildfly/plugin/cli/BaseCommandConfiguration.java @@ -108,8 +108,7 @@ public T setJBossHome(final Path jbossHome) { } /** - * Adds the JVM options used if {@link #isFork()} or - * {@link #isOffline()} is set to {@code true}. + * Adds the JVM options used if running in a forked process. * * @param jvmOptions the JVM options or {@code null} * @@ -123,8 +122,7 @@ public T addJvmOptions(final String... jvmOptions) { } /** - * Adds the CLI arguments used if {@link #isFork()} or - * {@link #isOffline()} is set to {@code true}. + * Adds the CLI arguments used if running in a forked process. * * @param arguments the CLI arguments or {@code null} * @@ -206,8 +204,7 @@ public T setFailOnError(final boolean failOnError) { } /** - * Sets how the standard output stream should be handled if - * {@link #isFork()} or {@link #isOffline()} is set to {@code true}. + * Sets how the standard output stream should be handled if running in a forked process. * * @param stdout the pattern for standard out * @@ -232,12 +229,13 @@ public T setTimeout(final int timeout) { } /** - * If true resolve expression prior to send the operation to the server + * Set to {@code true} to resolve expressions prior to sending the operation to the server. * - * @param resolveExpression - * @return this + * @param resolveExpression {@code true} if expressions should be resolved before the operation is sent to the + * server + * @return this configuration */ - public T setResolveExpression(boolean resolveExpression) { + public T setResolveExpression(final boolean resolveExpression) { this.resolveExpression = resolveExpression; return builderInstance(); } @@ -281,7 +279,7 @@ public boolean isAppend() { } /** - * Indicates whether or not the commands should be run in a batch or not. + * Indicates whether the commands should be run in a batch or not. * * @return {@code true} if the commands should be executed in a batch, * otherwise {@code false} @@ -300,8 +298,7 @@ public Path getJBossHome() { } /** - * Returns the JVM options used if {@link #isFork()} or {@link #isOffline()} - * is set to {@code true}. + * Returns the JVM options used if running in a forked process. * * @return the JVM options */ @@ -310,8 +307,7 @@ public Collection getJvmOptions() { } /** - * Returns the CLI arguments used if {@link #isFork()} or - * {@link #isOffline()} is set to {@code true}. + * Returns the CLI arguments used if running in a forked process. * * @return the CLI arguments */ diff --git a/plugin/src/main/java/org/wildfly/plugin/cli/CommandExecutor.java b/plugin/src/main/java/org/wildfly/plugin/cli/CommandExecutor.java index f2299824..8f3836fd 100644 --- a/plugin/src/main/java/org/wildfly/plugin/cli/CommandExecutor.java +++ b/plugin/src/main/java/org/wildfly/plugin/cli/CommandExecutor.java @@ -23,7 +23,7 @@ import org.wildfly.core.launcher.CliCommandBuilder; import org.wildfly.plugin.common.MavenModelControllerClientConfiguration; import org.wildfly.plugin.common.StandardOutput; -import org.wildfly.plugin.core.ServerHelper; +import org.wildfly.plugin.tools.ServerHelper; /** * A command executor for executing CLI commands. diff --git a/plugin/src/main/java/org/wildfly/plugin/cli/ExecuteCommandsMojo.java b/plugin/src/main/java/org/wildfly/plugin/cli/ExecuteCommandsMojo.java index 3b295366..45f749dd 100644 --- a/plugin/src/main/java/org/wildfly/plugin/cli/ExecuteCommandsMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/cli/ExecuteCommandsMojo.java @@ -35,7 +35,7 @@ import org.wildfly.plugin.common.PropertyNames; import org.wildfly.plugin.common.Utils; import org.wildfly.plugin.core.MavenRepositoriesEnricher; -import org.wildfly.plugin.core.ServerHelper; +import org.wildfly.plugin.tools.ServerHelper; /** * Execute commands to the running WildFly Application Server. diff --git a/plugin/src/main/java/org/wildfly/plugin/cli/LocalCLIExecutor.java b/plugin/src/main/java/org/wildfly/plugin/cli/LocalCLIExecutor.java index 331485e3..ca1d7844 100644 --- a/plugin/src/main/java/org/wildfly/plugin/cli/LocalCLIExecutor.java +++ b/plugin/src/main/java/org/wildfly/plugin/cli/LocalCLIExecutor.java @@ -31,7 +31,7 @@ import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.galleon.universe.maven.MavenArtifact; import org.jboss.galleon.universe.maven.repo.MavenRepoManager; -import org.wildfly.plugins.core.cli.CLIWrapper; +import org.wildfly.plugin.tools.cli.CLIWrapper; /** * A CLI executor, resolving CLI artifact from Maven. diff --git a/plugin/src/main/java/org/wildfly/plugin/cli/OfflineCommandExecutor.java b/plugin/src/main/java/org/wildfly/plugin/cli/OfflineCommandExecutor.java index 74196a08..fb968917 100644 --- a/plugin/src/main/java/org/wildfly/plugin/cli/OfflineCommandExecutor.java +++ b/plugin/src/main/java/org/wildfly/plugin/cli/OfflineCommandExecutor.java @@ -16,7 +16,7 @@ import org.jboss.galleon.universe.maven.repo.MavenRepoManager; import org.wildfly.core.launcher.CliCommandBuilder; import org.wildfly.plugin.common.StandardOutput; -import org.wildfly.plugin.core.Utils; +import org.wildfly.plugin.tools.util.Utils; /** * A command executor for executing offline CLI commands. diff --git a/plugin/src/main/java/org/wildfly/plugin/common/MavenModelControllerClientConfiguration.java b/plugin/src/main/java/org/wildfly/plugin/common/MavenModelControllerClientConfiguration.java index 3571e230..cc0d64fd 100644 --- a/plugin/src/main/java/org/wildfly/plugin/common/MavenModelControllerClientConfiguration.java +++ b/plugin/src/main/java/org/wildfly/plugin/common/MavenModelControllerClientConfiguration.java @@ -18,7 +18,7 @@ /** * A configuration used to connect a {@link org.jboss.as.controller.client.ModelControllerClient} or used to connect a - * CLI {@link org.jboss.as.cli.CommandContext}. + * CLI {@code CommandContext} * * @author James R. Perkins */ diff --git a/plugin/src/main/java/org/wildfly/plugin/common/StandardOutput.java b/plugin/src/main/java/org/wildfly/plugin/common/StandardOutput.java index babbad55..0f591eb8 100644 --- a/plugin/src/main/java/org/wildfly/plugin/common/StandardOutput.java +++ b/plugin/src/main/java/org/wildfly/plugin/common/StandardOutput.java @@ -14,7 +14,7 @@ import java.nio.file.Paths; import java.util.Optional; -import org.wildfly.plugin.core.ConsoleConsumer; +import org.wildfly.plugin.tools.ConsoleConsumer; /** * Information on how the {@code stdout} should be consumed. diff --git a/plugin/src/main/java/org/wildfly/plugin/common/Utils.java b/plugin/src/main/java/org/wildfly/plugin/common/Utils.java index dccaf92a..a41d0137 100644 --- a/plugin/src/main/java/org/wildfly/plugin/common/Utils.java +++ b/plugin/src/main/java/org/wildfly/plugin/common/Utils.java @@ -24,8 +24,8 @@ import org.wildfly.glow.Arguments; import org.wildfly.glow.GlowSession; import org.wildfly.glow.ScanResults; -import org.wildfly.plugin.core.GalleonUtils; import org.wildfly.plugin.provision.GlowConfig; +import org.wildfly.plugin.tools.GalleonUtils; /** * A simple utility class. diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/AbstractDeployment.java b/plugin/src/main/java/org/wildfly/plugin/deployment/AbstractDeployment.java index 36ac001b..03066441 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/AbstractDeployment.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/AbstractDeployment.java @@ -19,10 +19,10 @@ import org.wildfly.plugin.common.AbstractServerConnection; import org.wildfly.plugin.common.MavenModelControllerClientConfiguration; import org.wildfly.plugin.common.PropertyNames; -import org.wildfly.plugin.core.Deployment; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; -import org.wildfly.plugin.core.ServerHelper; +import org.wildfly.plugin.tools.Deployment; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; +import org.wildfly.plugin.tools.ServerHelper; /** * The default implementation for executing build plans on the server. diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/DeployArtifactMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/DeployArtifactMojo.java index 89edd7bf..ddf51470 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/DeployArtifactMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/DeployArtifactMojo.java @@ -15,9 +15,9 @@ 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.Deployment; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; +import org.wildfly.plugin.tools.Deployment; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; /** * Deploys an arbitrary artifact to the WildFly application server diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/DeployMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/DeployMojo.java index d963f33e..fa0109de 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/DeployMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/DeployMojo.java @@ -13,9 +13,9 @@ 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.Deployment; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; +import org.wildfly.plugin.tools.Deployment; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; /** * Deploys the application to the WildFly Application Server. diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/DeployOnlyMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/DeployOnlyMojo.java index e77649cb..e333350e 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/DeployOnlyMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/DeployOnlyMojo.java @@ -12,7 +12,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.wildfly.plugin.common.PropertyNames; -import org.wildfly.plugin.core.Deployment; +import org.wildfly.plugin.tools.Deployment; /** * Deploys only the application to the WildFly Application Server without first invoking the diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployMojo.java index 4b9ed76d..1fd9be69 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployMojo.java @@ -11,9 +11,9 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.wildfly.plugin.core.Deployment; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; +import org.wildfly.plugin.tools.Deployment; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; /** * Redeploys the application to the WildFly Application Server. diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployOnlyMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployOnlyMojo.java index af61e217..20ea1b24 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployOnlyMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/RedeployOnlyMojo.java @@ -12,7 +12,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.wildfly.plugin.common.PropertyNames; -import org.wildfly.plugin.core.Deployment; +import org.wildfly.plugin.tools.Deployment; /** * Redeploys only the application to the WildFly Application Server without first invoking the diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployArtifactMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployArtifactMojo.java index 8d2e4753..3cde9e13 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployArtifactMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployArtifactMojo.java @@ -23,9 +23,9 @@ import org.wildfly.plugin.common.AbstractServerConnection; import org.wildfly.plugin.common.MavenModelControllerClientConfiguration; import org.wildfly.plugin.common.PropertyNames; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; -import org.wildfly.plugin.core.UndeployDescription; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; +import org.wildfly.plugin.tools.UndeployDescription; /** * Undeploys (removes) an arbitrary artifact to the WildFly application server diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployMojo.java index 6333ae78..3fb09057 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/UndeployMojo.java @@ -22,10 +22,10 @@ import org.wildfly.plugin.common.AbstractServerConnection; import org.wildfly.plugin.common.MavenModelControllerClientConfiguration; import org.wildfly.plugin.common.PropertyNames; -import org.wildfly.plugin.core.DeploymentDescription; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; -import org.wildfly.plugin.core.UndeployDescription; +import org.wildfly.plugin.tools.DeploymentDescription; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; +import org.wildfly.plugin.tools.UndeployDescription; /** * Undeploys the application to the WildFly Application Server. diff --git a/plugin/src/main/java/org/wildfly/plugin/deployment/resource/AddResourceMojo.java b/plugin/src/main/java/org/wildfly/plugin/deployment/resource/AddResourceMojo.java index 4a99248d..c301e2fd 100644 --- a/plugin/src/main/java/org/wildfly/plugin/deployment/resource/AddResourceMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/deployment/resource/AddResourceMojo.java @@ -22,7 +22,7 @@ import org.wildfly.plugin.common.MavenModelControllerClientConfiguration; import org.wildfly.plugin.common.PropertyNames; import org.wildfly.plugin.common.ServerOperations; -import org.wildfly.plugin.core.ServerHelper; +import org.wildfly.plugin.tools.ServerHelper; /** * Adds a resource diff --git a/plugin/src/main/java/org/wildfly/plugin/dev/DevMojo.java b/plugin/src/main/java/org/wildfly/plugin/dev/DevMojo.java index ddff6b51..a598ea9c 100644 --- a/plugin/src/main/java/org/wildfly/plugin/dev/DevMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/dev/DevMojo.java @@ -69,6 +69,7 @@ import org.jboss.galleon.maven.plugin.util.MvnMessageWriter; import org.jboss.galleon.universe.maven.repo.MavenRepoManager; import org.jboss.galleon.util.IoUtils; +import org.jboss.logging.Logger; import org.twdata.maven.mojoexecutor.MojoExecutor; import org.wildfly.channel.UnresolvedMavenArtifactException; import org.wildfly.core.launcher.CommandBuilder; @@ -78,14 +79,7 @@ import org.wildfly.plugin.common.Environment; import org.wildfly.plugin.common.PropertyNames; import org.wildfly.plugin.common.Utils; -import org.wildfly.plugin.core.ContainerDescription; -import org.wildfly.plugin.core.Deployment; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; -import org.wildfly.plugin.core.GalleonUtils; -import org.wildfly.plugin.core.PluginProgressTracker; -import org.wildfly.plugin.core.ServerHelper; -import org.wildfly.plugin.core.UndeployDescription; +import org.wildfly.plugin.core.MavenJBossLogger; import org.wildfly.plugin.deployment.PackageType; import org.wildfly.plugin.provision.ChannelConfiguration; import org.wildfly.plugin.provision.ChannelMavenArtifactRepositoryManager; @@ -93,7 +87,15 @@ import org.wildfly.plugin.server.AbstractServerStartMojo; import org.wildfly.plugin.server.ServerContext; import org.wildfly.plugin.server.ServerType; -import org.wildfly.plugin.server.VersionComparator; +import org.wildfly.plugin.tools.ContainerDescription; +import org.wildfly.plugin.tools.Deployment; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; +import org.wildfly.plugin.tools.GalleonUtils; +import org.wildfly.plugin.tools.PluginProgressTracker; +import org.wildfly.plugin.tools.ServerHelper; +import org.wildfly.plugin.tools.UndeployDescription; +import org.wildfly.plugin.tools.VersionComparator; /** * Starts a standalone instance of WildFly and deploys the application to the server. The deployment type must be a WAR. @@ -401,6 +403,7 @@ public class DevMojo extends AbstractServerStartMojo { private ScanResults results; private Path installDir; private boolean requiresWarDeletion; + private Logger mavenJBossLogger; @Override public void execute() throws MojoExecutionException, MojoFailureException { @@ -408,6 +411,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { if (!"war".equalsIgnoreCase(packageType.getPackaging())) { throw new MojoExecutionException("The dev goal only works for WAR deployments"); } + mavenJBossLogger = new MavenJBossLogger(getLog()); serverConfig = serverConfig == null ? "standalone.xml" : serverConfig; ServerContext context = null; if (remote) { @@ -639,7 +643,7 @@ protected Path provisionIfRequired(final Path installDir) throws MojoFailureExce .setInstallationHome(installDir) .setMessageWriter(new MvnMessageWriter(getLog())) .build()) { - PluginProgressTracker.initTrackers(pm, getLog()); + PluginProgressTracker.initTrackers(pm, mavenJBossLogger); pm.provision(config); // Check that at least the standalone or domain directories have been generated. if (Files.notExists(installDir.resolve("standalone")) && Files.notExists(installDir.resolve("domain"))) { @@ -669,7 +673,7 @@ private ScanResults scanDeployment(GalleonBuilder pm) throws Exception { private void provisionServer(Provisioning pm, GalleonProvisioningConfig config) throws ProvisioningException, MojoExecutionException { getLog().info("Provisioning server in " + installDir); - PluginProgressTracker.initTrackers(pm, getLog()); + PluginProgressTracker.initTrackers(pm, mavenJBossLogger); pm.provision(config); // Check that at least the standalone or domain directories have been generated. if (Files.notExists(installDir.resolve("standalone")) && Files.notExists(installDir.resolve("domain"))) { @@ -963,10 +967,9 @@ private Xpp3Dom getWarPluginConfig(final Plugin plugin) { // Load the allowed configuration params if not yet loaded if (allowedWarPluginParams.isEmpty()) { final String pluginVersion = plugin.getVersion(); - final VersionComparator comparator = new VersionComparator(); final Map parameters = remote ? WAR_PARAMETERS : EXPLODED_WAR_PARAMETERS; allowedWarPluginParams.addAll(parameters.entrySet().stream() - .filter(e -> e.getValue().isEmpty() || comparator.compare(e.getValue(), pluginVersion) <= 0) + .filter(e -> e.getValue().isEmpty() || VersionComparator.compareVersion(e.getValue(), pluginVersion) <= 0) .map(Map.Entry::getKey) .collect(Collectors.toSet())); } diff --git a/plugin/src/main/java/org/wildfly/plugin/provision/AbstractProvisionServerMojo.java b/plugin/src/main/java/org/wildfly/plugin/provision/AbstractProvisionServerMojo.java index 867e9236..9bf41ac8 100644 --- a/plugin/src/main/java/org/wildfly/plugin/provision/AbstractProvisionServerMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/provision/AbstractProvisionServerMojo.java @@ -43,9 +43,10 @@ import org.wildfly.channel.UnresolvedMavenArtifactException; import org.wildfly.plugin.common.PropertyNames; import org.wildfly.plugin.common.Utils; -import org.wildfly.plugin.core.GalleonUtils; +import org.wildfly.plugin.core.MavenJBossLogger; import org.wildfly.plugin.core.MavenRepositoriesEnricher; -import org.wildfly.plugin.core.PluginProgressTracker; +import org.wildfly.plugin.tools.GalleonUtils; +import org.wildfly.plugin.tools.PluginProgressTracker; /** * Provision a server @@ -308,7 +309,7 @@ private void provisionServer(Path home) throws ProvisioningException, return; } getLog().info("Provisioning server in " + home); - PluginProgressTracker.initTrackers(pm, getLog()); + PluginProgressTracker.initTrackers(pm, new MavenJBossLogger(getLog())); pm.provision(config); // Check that at least the standalone or domain directories have been generated. if (!Files.exists(home.resolve("standalone")) && !Files.exists(home.resolve("domain"))) { diff --git a/plugin/src/main/java/org/wildfly/plugin/provision/PackageServerMojo.java b/plugin/src/main/java/org/wildfly/plugin/provision/PackageServerMojo.java index e7de269c..cbd6f98e 100644 --- a/plugin/src/main/java/org/wildfly/plugin/provision/PackageServerMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/provision/PackageServerMojo.java @@ -36,13 +36,12 @@ import org.wildfly.plugin.cli.BaseCommandConfiguration; import org.wildfly.plugin.cli.CliSession; import org.wildfly.plugin.cli.OfflineCommandExecutor; -import org.wildfly.plugin.common.MavenJBossLogger; import org.wildfly.plugin.common.PropertyNames; import org.wildfly.plugin.common.StandardOutput; import org.wildfly.plugin.common.Utils; import org.wildfly.plugin.deployment.MojoDeploymentException; import org.wildfly.plugin.deployment.PackageType; -import org.wildfly.plugins.core.bootablejar.BootableJarSupport; +import org.wildfly.plugin.tools.bootablejar.BootableJarSupport; /** * Provision a server, copy extra content and deploy primary artifact if it @@ -381,7 +380,7 @@ private void packageBootableJar(Path jbossHome, GalleonProvisioningConfig active BootableJarSupport.packageBootableJar(targetJarFile, targetPath, activeConfig, jbossHome, artifactResolver, - new MvnMessageWriter(getLog()), new MavenJBossLogger(getLog())); + new MvnMessageWriter(getLog())); attachJar(targetJarFile); getLog().info("Bootable JAR packaging DONE. To run the server: java -jar " + targetJarFile); diff --git a/plugin/src/main/java/org/wildfly/plugin/server/AbstractServerStartMojo.java b/plugin/src/main/java/org/wildfly/plugin/server/AbstractServerStartMojo.java index 4f8b845e..c8fd3771 100644 --- a/plugin/src/main/java/org/wildfly/plugin/server/AbstractServerStartMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/server/AbstractServerStartMojo.java @@ -41,9 +41,9 @@ import org.wildfly.plugin.common.PropertyNames; import org.wildfly.plugin.common.StandardOutput; import org.wildfly.plugin.common.Utils; -import org.wildfly.plugin.core.GalleonUtils; import org.wildfly.plugin.core.MavenRepositoriesEnricher; -import org.wildfly.plugin.core.ServerHelper; +import org.wildfly.plugin.tools.GalleonUtils; +import org.wildfly.plugin.tools.ServerHelper; /** * @author James R. Perkins diff --git a/plugin/src/main/java/org/wildfly/plugin/server/RunMojo.java b/plugin/src/main/java/org/wildfly/plugin/server/RunMojo.java index 95adbe01..04da1067 100644 --- a/plugin/src/main/java/org/wildfly/plugin/server/RunMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/server/RunMojo.java @@ -27,9 +27,9 @@ import org.wildfly.plugin.cli.CommandConfiguration; import org.wildfly.plugin.cli.CommandExecutor; import org.wildfly.plugin.common.PropertyNames; -import org.wildfly.plugin.core.Deployment; -import org.wildfly.plugin.core.DeploymentManager; import org.wildfly.plugin.deployment.PackageType; +import org.wildfly.plugin.tools.Deployment; +import org.wildfly.plugin.tools.DeploymentManager; /** * Starts a standalone instance of WildFly and deploys the application to the server. diff --git a/plugin/src/main/java/org/wildfly/plugin/server/ShutdownMojo.java b/plugin/src/main/java/org/wildfly/plugin/server/ShutdownMojo.java index 2e8ffb44..898df772 100644 --- a/plugin/src/main/java/org/wildfly/plugin/server/ShutdownMojo.java +++ b/plugin/src/main/java/org/wildfly/plugin/server/ShutdownMojo.java @@ -17,7 +17,7 @@ import org.wildfly.plugin.common.AbstractServerConnection; import org.wildfly.plugin.common.PropertyNames; import org.wildfly.plugin.common.ServerOperations; -import org.wildfly.plugin.core.ServerHelper; +import org.wildfly.plugin.tools.ServerHelper; /** * Shuts down a running WildFly Application Server. diff --git a/plugin/src/main/java/org/wildfly/plugin/server/VersionComparator.java b/plugin/src/main/java/org/wildfly/plugin/server/VersionComparator.java deleted file mode 100644 index 108e9b4f..00000000 --- a/plugin/src/main/java/org/wildfly/plugin/server/VersionComparator.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.server; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * @author James R. Perkins - */ -public class VersionComparator implements Comparator { - @Override - public int compare(final String o1, final String o2) { - final Version v1 = Version.parse(o1); - final Version v2 = Version.parse(o2); - return v1.compareTo(v2); - } - - private enum ReleaseType { - UNKNOWN(null), - SNAPSHOT("snapshot"), - ALPHA("alpha", "a"), - BETA("beta", "b"), - MILESTONE("milestone", "m"), - RELEASE_CANDIDATE("rc", "cr"), - FINAL("final", "", "ga"),; - - private static final Map ENTRIES; - - static { - final Map map = new HashMap<>(); - for (ReleaseType r : values()) { - if (r == UNKNOWN) - continue; - map.put(r.type, r); - map.put("-" + r.type, r); - for (String alias : r.aliases) { - map.put(alias, r); - } - } - ENTRIES = Collections.unmodifiableMap(map); - } - - private final String type; - private final List aliases; - - ReleaseType(final String type, final String... aliases) { - this.type = type; - this.aliases = Collections.unmodifiableList(Arrays.asList(aliases)); - } - - static ReleaseType find(final String s) { - if (ENTRIES.containsKey(s)) { - return ENTRIES.get(s); - } - return UNKNOWN; - } - } - - private static class Version implements Comparable { - private final List parts; - private final String original; - - private Version(final String original, final List parts) { - this.original = original; - this.parts = parts; - } - - public static Version parse(final String version) { - final List parts = new ArrayList<>(); - final StringBuilder sb = new StringBuilder(); - boolean isDigit = false; - for (char c : version.toCharArray()) { - switch (c) { - case '-': - case '.': { - if (isDigit) { - parts.add(new IntegerPart(Integer.parseInt(sb.toString()))); - } else { - parts.add(new StringPart(sb.toString())); - } - sb.setLength(0); - isDigit = false; - continue; - } - default: { - if (Character.isDigit(c)) { - if (!isDigit && sb.length() > 0) { - parts.add(new StringPart(sb.toString())); - sb.setLength(0); - } - isDigit = true; - } else { - if (isDigit && sb.length() > 0) { - parts.add(new IntegerPart(Integer.parseInt(sb.toString()))); - sb.setLength(0); - } - isDigit = false; - } - sb.append(c); - } - } - } - if (sb.length() > 0) { - if (isDigit) { - parts.add(new IntegerPart(Integer.parseInt(sb.toString()))); - } else { - parts.add(new StringPart(sb.toString())); - } - } - return new Version(version, parts); - } - - @Override - public int compareTo(final Version o) { - final Iterator left = parts.iterator(); - final Iterator right = o.parts.iterator(); - int result = 0; - while (left.hasNext() || right.hasNext()) { - if (left.hasNext() && right.hasNext()) { - result = left.next().compareTo(right.next()); - } else if (left.hasNext()) { - result = left.next().compareTo(NULL_PART); - } else if (right.hasNext()) { - // Need the inverse of the comparison - result = (-1 * right.next().compareTo(NULL_PART)); - } - if (result != 0) { - break; - } - } - return result; - } - - @Override - public int hashCode() { - return 33 * (17 + original.hashCode()); - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) - return true; - if (!(obj instanceof Version)) { - return false; - } - final Version other = (Version) obj; - return original.equals(other.original); - } - - @Override - public String toString() { - return original; - } - - private interface Part extends Comparable { - } - - private static final Part NULL_PART = new Part() { - @Override - public int compareTo(final Part o) { - throw new UnsupportedOperationException(); - } - }; - - private static class IntegerPart implements Part { - private static final Integer DEFAULT_INTEGER = 0; - private final Integer value; - - private IntegerPart(final Integer value) { - this.value = value; - } - - @Override - public int compareTo(final Part o) { - if (o == NULL_PART) { - return value.compareTo(DEFAULT_INTEGER); - } - if (o instanceof IntegerPart) { - return value.compareTo(((IntegerPart) o).value); - } - return 1; - } - - @Override - public String toString() { - return value.toString(); - } - } - - private static class StringPart implements Part { - private final String originalValue; - private final String value; - private final ReleaseType releaseType; - - private StringPart(final String value) { - originalValue = value; - this.value = value.toLowerCase(Locale.ROOT); - releaseType = ReleaseType.find(this.value); - } - - @Override - public int compareTo(final Part o) { - if (o == NULL_PART) { - return releaseType.compareTo(ReleaseType.FINAL); - } - if (o instanceof StringPart) { - if (releaseType == ReleaseType.UNKNOWN && ((StringPart) o).releaseType == ReleaseType.UNKNOWN) { - return value.compareTo(((StringPart) o).value); - } - return releaseType.compareTo(((StringPart) o).releaseType); - } - return -1; - } - - @Override - public String toString() { - return originalValue; - } - } - } -} diff --git a/plugin/src/test/java/org/wildfly/plugin/server/VersionTestCase.java b/plugin/src/test/java/org/wildfly/plugin/server/VersionTestCase.java deleted file mode 100644 index 9b266c49..00000000 --- a/plugin/src/test/java/org/wildfly/plugin/server/VersionTestCase.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.plugin.server; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author James R. Perkins - */ -public class VersionTestCase { - - @Test - public void testGetLatest() { - compareLatest("10.0.2.Final", "10.0.2.Final", "9.0.1.Final", "8.0.0.Final", "1.0.0.Final", "10.0.0.Final"); - compareLatest("20.0.4.Alpha4", "2.0.3.Final", "20.0.4.Alpha3", "20.0.4.Alpha4", "10.0.5.Final"); - compareLatest("7.5.Final", "7.1.1.Final", "7.1.3.Final", "7.5.Final", "7.4.Final", "7.5.Final-SNAPSHOT"); - } - - @Test - public void testSortOrder() { - // Define a list in the expected order - final List orderedVersions = Arrays.asList( - "1.0.0.a1-SNAPSHOT", - "1.0.0.Alpha1", - "1.0.0.Beta1", - "1.0.0.b2", - "1.0.0.Final", - "1.0.1.Alpha3", - "1.0.1.Alpha20", - "1.7.0_6", - "1.7.0_07-b06", - "1.7.0_07-b07", - "1.7.0_07", - "1.7.0_09-a06", - "10.1.0.Beta1", - "10.1.0.GA-SNAPSHOT", - "10.1.0", - "10.1.1.Final", - "11.0.0.Alpha5", - "11.0.0.GA"); - - final List versions = new ArrayList<>(orderedVersions); - Collections.shuffle(versions); - - // All entries should in the same order - Assert.assertTrue(orderedVersions.containsAll(versions)); - Collections.sort(versions, new VersionComparator()); - Assert.assertTrue(orderedVersions.equals(versions)); - } - - private void compareLatest(final String expected, final String... versions) { - final SortedSet set = new TreeSet<>(new VersionComparator()); - set.addAll(Arrays.asList(versions)); - Assert.assertEquals(expected, set.last()); - } -} diff --git a/pom.xml b/pom.xml index 4bc0557a..eb3068a6 100644 --- a/pom.xml +++ b/pom.xml @@ -75,6 +75,7 @@ 3.5.3.Final 1.0.8.Final 1.7.0.Final + 1.0.0.Beta1 22.0.2.Final 30.0.0.Final @@ -370,6 +371,11 @@ wildfly-plugin-core ${project.version} + + org.wildfly.plugins + wildfly-plugin-tools + ${version.org.wildfly.plugin.tools} + org.wildfly.channel channel-core @@ -451,7 +457,7 @@ mockito-core ${version.org.mockito.mockito} - + org.jboss.slf4j slf4j-jboss-logging ${version.org.jboss.logging.slf4j-jboss-logging} diff --git a/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java b/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java index 891f9156..ce29e302 100644 --- a/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java +++ b/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java @@ -24,10 +24,10 @@ import org.jboss.dmr.ModelNode; import org.junit.Test; import org.wildfly.plugin.common.ServerOperations; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.ServerHelper; -import org.wildfly.plugin.core.UndeployDescription; import org.wildfly.plugin.tests.AbstractWildFlyServerMojoTest; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.ServerHelper; +import org.wildfly.plugin.tools.UndeployDescription; /** * deploy mojo testcase. diff --git a/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java b/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java index 6835f033..d9d5e275 100644 --- a/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java +++ b/tests/domain-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java @@ -23,11 +23,11 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.wildfly.plugin.core.DeploymentDescription; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.DeploymentResult; -import org.wildfly.plugin.core.UndeployDescription; import org.wildfly.plugin.tests.AbstractWildFlyServerMojoTest; +import org.wildfly.plugin.tools.DeploymentDescription; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentResult; +import org.wildfly.plugin.tools.UndeployDescription; /** * Matcher Undeployment test case. diff --git a/tests/domain-tests/src/test/java/org/wildfly/plugin/server/DomainTestServer.java b/tests/domain-tests/src/test/java/org/wildfly/plugin/server/DomainTestServer.java index 40beca32..cc01cf80 100644 --- a/tests/domain-tests/src/test/java/org/wildfly/plugin/server/DomainTestServer.java +++ b/tests/domain-tests/src/test/java/org/wildfly/plugin/server/DomainTestServer.java @@ -13,10 +13,10 @@ import org.wildfly.core.launcher.DomainCommandBuilder; import org.wildfly.core.launcher.Launcher; import org.wildfly.core.launcher.ProcessHelper; -import org.wildfly.plugin.core.ConsoleConsumer; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.ServerHelper; import org.wildfly.plugin.tests.TestEnvironment; +import org.wildfly.plugin.tools.ConsoleConsumer; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.ServerHelper; /** * @author James R. Perkins diff --git a/tests/shared/src/main/java/org/wildfly/plugin/server/TestServer.java b/tests/shared/src/main/java/org/wildfly/plugin/server/TestServer.java index a78de28b..7bab64ea 100644 --- a/tests/shared/src/main/java/org/wildfly/plugin/server/TestServer.java +++ b/tests/shared/src/main/java/org/wildfly/plugin/server/TestServer.java @@ -6,7 +6,7 @@ package org.wildfly.plugin.server; import org.jboss.as.controller.client.ModelControllerClient; -import org.wildfly.plugin.core.DeploymentManager; +import org.wildfly.plugin.tools.DeploymentManager; /** * @author James R. Perkins diff --git a/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractProvisionConfiguredMojoTestCase.java b/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractProvisionConfiguredMojoTestCase.java index 856d86d9..e2f923a9 100644 --- a/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractProvisionConfiguredMojoTestCase.java +++ b/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractProvisionConfiguredMojoTestCase.java @@ -57,8 +57,8 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.wildfly.core.launcher.ProcessHelper; -import org.wildfly.plugin.core.ServerHelper; -import org.wildfly.plugins.core.bootablejar.BootableJarSupport; +import org.wildfly.plugin.tools.ServerHelper; +import org.wildfly.plugin.tools.bootablejar.BootableJarSupport; /** * A class to construct a properly configured MOJO. diff --git a/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractWildFlyMojoTest.java b/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractWildFlyMojoTest.java index 43bcaa43..688928f6 100644 --- a/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractWildFlyMojoTest.java +++ b/tests/shared/src/main/java/org/wildfly/plugin/tests/AbstractWildFlyMojoTest.java @@ -28,7 +28,7 @@ import org.jboss.galleon.util.PropertyUtils; import org.junit.Assert; import org.junit.Rule; -import org.wildfly.plugin.core.Deployment; +import org.wildfly.plugin.tools.Deployment; /** * @author James R. Perkins diff --git a/tests/shared/src/main/java/org/wildfly/plugin/tests/runner/WildFlyTestRunner.java b/tests/shared/src/main/java/org/wildfly/plugin/tests/runner/WildFlyTestRunner.java index 24ecebb5..8d98d17c 100644 --- a/tests/shared/src/main/java/org/wildfly/plugin/tests/runner/WildFlyTestRunner.java +++ b/tests/shared/src/main/java/org/wildfly/plugin/tests/runner/WildFlyTestRunner.java @@ -17,8 +17,8 @@ import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.InitializationError; -import org.wildfly.plugin.core.DeploymentManager; import org.wildfly.plugin.server.TestServer; +import org.wildfly.plugin.tools.DeploymentManager; /** * @author James R. Perkins diff --git a/tests/shared/src/test/java/org/wildfly/plugin/server/ServerFunctionMojoTest.java b/tests/shared/src/test/java/org/wildfly/plugin/server/ServerFunctionMojoTest.java index 48a848a3..6156b978 100644 --- a/tests/shared/src/test/java/org/wildfly/plugin/server/ServerFunctionMojoTest.java +++ b/tests/shared/src/test/java/org/wildfly/plugin/server/ServerFunctionMojoTest.java @@ -19,9 +19,9 @@ import org.junit.After; import org.junit.Assert; import org.junit.Test; -import org.wildfly.plugin.core.ServerHelper; import org.wildfly.plugin.tests.AbstractWildFlyMojoTest; import org.wildfly.plugin.tests.TestEnvironment; +import org.wildfly.plugin.tools.ServerHelper; /** * @author James R. Perkins diff --git a/tests/standalone-tests/src/test/java/org/wildfly/plugin/cli/FailOnErrorTest.java b/tests/standalone-tests/src/test/java/org/wildfly/plugin/cli/FailOnErrorTest.java index 7e776db5..ae4077f4 100644 --- a/tests/standalone-tests/src/test/java/org/wildfly/plugin/cli/FailOnErrorTest.java +++ b/tests/standalone-tests/src/test/java/org/wildfly/plugin/cli/FailOnErrorTest.java @@ -9,7 +9,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -36,8 +35,7 @@ public void testExecuteCommandsFailOnError() throws Exception { executeCommandsMojo.execute(); fail("MojoExecutionException expected."); } catch (MojoExecutionException e) { - InvocationTargetException ex = (InvocationTargetException) e.getCause(); - assertEquals("org.jboss.as.cli.CommandLineException", ex.getCause().getClass().getName()); + assertEquals("org.jboss.as.cli.CommandLineException", e.getCause().getClass().getName()); } final ModelNode address = ServerOperations.createAddress("system-property", "propertyFailOnError"); final ModelNode op = ServerOperations.createReadAttributeOperation(address, "value"); @@ -173,8 +171,7 @@ public void testExecuteCommandScriptFailOnError() throws Exception { executeCommandsMojo.execute(); fail("MojoExecutionException expected."); } catch (MojoExecutionException e) { - InvocationTargetException ex = (InvocationTargetException) e.getCause(); - assertEquals("org.jboss.as.cli.CommandLineException", ex.getCause().getClass().getName()); + assertEquals("org.jboss.as.cli.CommandLineException", e.getCause().getClass().getName()); } final ModelNode address = ServerOperations.createAddress("system-property", "scriptFailOnError"); final ModelNode op = ServerOperations.createReadAttributeOperation(address, "value"); diff --git a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/ArtifactDeploymentTest.java b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/ArtifactDeploymentTest.java index 6c89bc39..f7689f3c 100644 --- a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/ArtifactDeploymentTest.java +++ b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/ArtifactDeploymentTest.java @@ -22,10 +22,10 @@ import org.junit.After; import org.junit.Test; import org.wildfly.plugin.common.ServerOperations; -import org.wildfly.plugin.core.Deployment; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.UndeployDescription; import org.wildfly.plugin.tests.AbstractWildFlyServerMojoTest; +import org.wildfly.plugin.tools.Deployment; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.UndeployDescription; /** * @author James R. Perkins diff --git a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployOnlyTest.java b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployOnlyTest.java index cc4135e1..7ae2b5a4 100644 --- a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployOnlyTest.java +++ b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployOnlyTest.java @@ -18,9 +18,9 @@ import org.jboss.dmr.ModelNode; import org.junit.Test; import org.wildfly.plugin.common.ServerOperations; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.UndeployDescription; import org.wildfly.plugin.tests.AbstractWildFlyServerMojoTest; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.UndeployDescription; /** * deploy mojo testcase. diff --git a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java index 86e31024..87865ca7 100644 --- a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java +++ b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/DeployTest.java @@ -16,9 +16,9 @@ import org.jboss.dmr.ModelNode; import org.junit.Test; import org.wildfly.plugin.common.ServerOperations; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.UndeployDescription; import org.wildfly.plugin.tests.AbstractWildFlyServerMojoTest; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.UndeployDescription; /** * deploy mojo testcase. diff --git a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java index 079f6ca9..34ccff1e 100644 --- a/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java +++ b/tests/standalone-tests/src/test/java/org/wildfly/plugin/deployment/UndeploymentMatchTest.java @@ -14,9 +14,9 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.wildfly.plugin.core.DeploymentDescription; -import org.wildfly.plugin.core.DeploymentManager; import org.wildfly.plugin.tests.AbstractWildFlyServerMojoTest; +import org.wildfly.plugin.tools.DeploymentDescription; +import org.wildfly.plugin.tools.DeploymentManager; /** * Matcher Undeployment test case. diff --git a/tests/standalone-tests/src/test/java/org/wildfly/plugin/server/StandaloneTestServer.java b/tests/standalone-tests/src/test/java/org/wildfly/plugin/server/StandaloneTestServer.java index 8fd15165..648c0b1c 100644 --- a/tests/standalone-tests/src/test/java/org/wildfly/plugin/server/StandaloneTestServer.java +++ b/tests/standalone-tests/src/test/java/org/wildfly/plugin/server/StandaloneTestServer.java @@ -12,10 +12,10 @@ import org.wildfly.core.launcher.Launcher; import org.wildfly.core.launcher.ProcessHelper; import org.wildfly.core.launcher.StandaloneCommandBuilder; -import org.wildfly.plugin.core.ConsoleConsumer; -import org.wildfly.plugin.core.DeploymentManager; -import org.wildfly.plugin.core.ServerHelper; import org.wildfly.plugin.tests.TestEnvironment; +import org.wildfly.plugin.tools.ConsoleConsumer; +import org.wildfly.plugin.tools.DeploymentManager; +import org.wildfly.plugin.tools.ServerHelper; /** * @author James R. Perkins