Skip to content

Commit

Permalink
Remove dependency on WildFly Maven Plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
jfdenise committed Dec 17, 2024
1 parent 6a58293 commit fd68da1
Show file tree
Hide file tree
Showing 11 changed files with 551 additions and 47 deletions.
8 changes: 0 additions & 8 deletions plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,6 @@
<groupId>org.wildfly.launcher</groupId>
<artifactId>wildfly-launcher</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-plugin-core</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-plugin-tools</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@
import org.jboss.galleon.util.IoUtils;
import org.jboss.galleon.util.ZipUtils;
import org.wildfly.channel.UnresolvedMavenArtifactException;
import org.wildfly.plugin.common.PropertyNames;
import org.wildfly.plugin.core.MavenJBossLogger;
import org.wildfly.plugin.tools.PluginProgressTracker;

import org.wildfly.plugins.bootablejar.maven.cli.CLIExecutor;
Expand Down Expand Up @@ -386,7 +384,7 @@ public abstract class AbstractBuildBootableJarMojo extends AbstractMojo {
* </pre>
* </p>
*/
@Parameter(alias = "channels", property = PropertyNames.CHANNELS)
@Parameter(alias = "channels", property = "wildfly.channels")
List<ChannelConfiguration> channels;

MavenProjectArtifactVersions artifactVersions;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.plugins.bootablejar.maven.goals;

import java.net.URISyntaxException;
import java.net.URL;

import javax.inject.Inject;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.apache.maven.settings.crypto.SettingsDecryptionResult;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.ModelControllerClientConfiguration;
import org.wildfly.plugin.tools.client.ClientCallbackHandler;

/**
* The default implementation for connecting to a running WildFly instance
*
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
* @author Stuart Douglas
*/
public abstract class AbstractServerConnection extends AbstractMojo {

public static final String DEBUG_MESSAGE_NO_CREDS = "No username and password in settings.xml file - falling back to CLI entry";
public static final String DEBUG_MESSAGE_NO_ID = "No <id> element was found in the POM - Getting credentials from CLI entry";
public static final String DEBUG_MESSAGE_NO_SERVER_SECTION = "No <server> section was found for the specified id";
public static final String DEBUG_MESSAGE_NO_SETTINGS_FILE = "No settings.xml file was found in this Mojo's execution context";
public static final String DEBUG_MESSAGE_POM_HAS_CREDS = "Getting credentials from the POM";
public static final String DEBUG_MESSAGE_SETTINGS_HAS_CREDS = "Found username and password in the settings.xml file";
public static final String DEBUG_MESSAGE_SETTINGS_HAS_ID = "Found the server's id in the settings.xml file";

static {
// This is odd, but if not set we should set the JBoss Logging provider to slf4j as that is what Maven uses
final String provider = System.getProperty("org.jboss.logging.provider");
if (provider == null || provider.isBlank()) {
System.setProperty("org.jboss.logging.provider", "slf4j");
}
}

/**
* The protocol used to connect to the server for management.
*/
@Parameter(property = "wildfly.protocol")
private String protocol;

/**
* Specifies the host name of the server where the deployment plan should be executed.
*/
@Parameter(defaultValue = "localhost", property = "wildfly.hostname")
private String hostname;

/**
* Specifies the port number the server is listening on.
*/
@Parameter(defaultValue = "9990", property = "wildfly.port")
private int port;

/**
* Specifies the id of the server if the username and password is to be
* retrieved from the settings.xml file
*/
@Parameter(property = "wildfly.id")
private String id;

/**
* Provides a reference to the settings file.
*/
@Parameter(property = "settings", readonly = true, required = true, defaultValue = "${settings}")
private Settings settings;

/**
* Specifies the username to use if prompted to authenticate by the server.
* <p/>
* If no username is specified and the server requests authentication the user
* will be prompted to supply the username,
*/
@Parameter(property = "wildfly.username")
private String username;

/**
* Specifies the password to use if prompted to authenticate by the server.
* <p/>
* If no password is specified and the server requests authentication the user
* will be prompted to supply the password,
*/
@Parameter(property = "wildfly.password")
private String password;

/**
* The timeout, in seconds, to wait for a management connection.
*/
@Parameter(property = "wildfly.timeout", defaultValue = "60")
protected int timeout;

/**
* A URL which points to the authentication configuration ({@code wildfly-config.xml}) the client uses to
* authenticate with the server.
*/
@Parameter(alias = "authentication-config", property = "wildfly.authConfig")
private URL authenticationConfig;

@Inject
private SettingsDecrypter settingsDecrypter;

/**
* The goal of the deployment.
*
* @return the goal of the deployment.
*/
public abstract String goal();

/**
* Creates a new client.
*
* @return the client
*/
protected ModelControllerClient createClient() {
return ModelControllerClient.Factory.create(getClientConfiguration());
}

/**
* Gets a client configuration used to create a new {@link ModelControllerClient}.
*
* @return the configuration to use
*/
protected synchronized ModelControllerClientConfiguration getClientConfiguration() {
final Log log = getLog();
String username = this.username;
String password = this.password;
if (username == null && password == null) {
if (id != null) {
if (settings != null) {
Server server = settings.getServer(id);
if (server != null) {
log.debug(DEBUG_MESSAGE_SETTINGS_HAS_ID);
password = decrypt(server);
username = server.getUsername();
if (username != null && password != null) {
log.debug(DEBUG_MESSAGE_SETTINGS_HAS_CREDS);
} else {
log.debug(DEBUG_MESSAGE_NO_CREDS);
}
} else {
log.debug(DEBUG_MESSAGE_NO_SERVER_SECTION);
}
} else {
log.debug(DEBUG_MESSAGE_NO_SETTINGS_FILE);
}
} else {
log.debug(DEBUG_MESSAGE_NO_ID);
}
} else {
log.debug(DEBUG_MESSAGE_POM_HAS_CREDS);
}
final ModelControllerClientConfiguration.Builder builder = new ModelControllerClientConfiguration.Builder()
.setProtocol(protocol)
.setHostName(getManagementHostName())
.setPort(getManagementPort())
.setConnectionTimeout(timeout * 1000);
if (authenticationConfig != null) {
try {
builder.setAuthenticationConfigUri(authenticationConfig.toURI());
} catch (URISyntaxException e) {
throw new RuntimeException("Failed to create URI from " + authenticationConfig, e);
}
} else {
builder.setHandler(new ClientCallbackHandler(username, password));
}
return builder.build();
}

protected int getManagementPort() {
return port;
}

protected String getManagementHostName() {
return hostname;
}

private String decrypt(final Server server) {
SettingsDecryptionResult decrypt = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
return decrypt.getServer().getPassword();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/
package org.wildfly.plugins.bootablejar.maven.goals;

import java.io.Console;
import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.RealmCallback;
import javax.security.sasl.RealmChoiceCallback;

/**
* A CallbackHandler implementation to supply the username and password if required when
* connecting to the server - if these are not available the user will be prompted to
* supply them.
*
* @author <a href="mailto:darran.lofthouse@jboss.com">Darran Lofthouse</a>
*/
public class ClientCallbackHandler implements CallbackHandler {

private final Console console;
private boolean promptShown = false;
private String username;
private char[] password;

public ClientCallbackHandler(final String username, final String password) {
console = System.console();
this.username = username;
if (password != null) {
this.password = password.toCharArray();
}
}

@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
// Special case for anonymous authentication to avoid prompting user for their name.
if (callbacks.length == 1 && callbacks[0] instanceof NameCallback) {
((NameCallback) callbacks[0]).setName("anonymous demo user");
return;
}

for (Callback current : callbacks) {
if (current instanceof RealmCallback) {
final RealmCallback rcb = (RealmCallback) current;
final String defaultText = rcb.getDefaultText();
rcb.setText(defaultText); // For now just use the realm suggested.

prompt(defaultText);
} else if (current instanceof RealmChoiceCallback) {
throw new UnsupportedCallbackException(current, "Realm choice not currently supported.");
} else if (current instanceof NameCallback) {
final NameCallback ncb = (NameCallback) current;
final String userName = obtainUsername("Username:");

ncb.setName(userName);
} else if (current instanceof PasswordCallback) {
PasswordCallback pcb = (PasswordCallback) current;
char[] password = obtainPassword("Password:");

pcb.setPassword(password);
} else {
throw new UnsupportedCallbackException(current);
}
}
}

private void prompt(final String realm) {
if (!promptShown) {
promptShown = true;
}
}

private String obtainUsername(final String prompt) {
if (username == null) {
checkConsole();
username = console.readLine(prompt);
}
return username;
}

private char[] obtainPassword(final String prompt) {
if (password == null) {
checkConsole();
password = console.readPassword(prompt);
}

return password;
}

private void checkConsole() {
if (console == null) {
throw new IllegalStateException(
"The environment does not have a usable console. Cannot prompt for user name and password");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
import org.jboss.as.controller.client.helpers.Operations;
import org.jboss.dmr.ModelNode;
import org.wildfly.core.launcher.BootableJarCommandBuilder;
import org.wildfly.plugin.common.PropertyNames;

/**
* Build and start a bootable JAR for dev-watch mode. This goal monitors the
Expand Down Expand Up @@ -170,19 +169,19 @@ public final class DevWatchBootableJarMojo extends AbstractDevBootableJarMojo {
* Specifies the host name of the server where the deployment plan should be
* executed.
*/
@Parameter(defaultValue = "localhost", property = PropertyNames.HOSTNAME)
@Parameter(defaultValue = "localhost", property = "wildfly.hostname")
private String hostname;

/**
* Specifies the port number the server is listening on.
*/
@Parameter(defaultValue = "9990", property = PropertyNames.PORT)
@Parameter(defaultValue = "9990", property = "wildfly.port")
private int port;

/**
* The timeout, in seconds, to wait for a management connection.
*/
@Parameter(property = PropertyNames.TIMEOUT, defaultValue = "60")
@Parameter(property = "wildfly.timeout", defaultValue = "60")
protected int timeout;

@Parameter(defaultValue = "${project.remotePluginRepositories}", readonly = true, required = true)
Expand Down
Loading

0 comments on commit fd68da1

Please sign in to comment.