package com.ashardalon.maven.tomcat; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.settings.DefaultMavenSettingsBuilder; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; import org.apache.maven.settings.building.DefaultSettingsBuildingRequest; import org.apache.maven.settings.building.SettingsBuilder; import org.apache.maven.settings.building.SettingsBuildingException; import org.apache.maven.settings.building.SettingsBuildingRequest; import org.apache.maven.settings.crypto.DefaultSettingsDecrypter; import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; /** * Goal that uploads a WAR file to a remote tomcat server * * @author bjculkin */ @Mojo( name = "deploy", defaultPhase = LifecyclePhase.DEPLOY ) public class TomcatMojo extends AbstractMojo { @Component SettingsDecrypter decrypter; @Component SettingsBuilder builder; //---------------------------------------- // Mojo parameters //--------------------------------------- /** * Location of the file. */ @Parameter( defaultValue = "${project.build.directory}/${project.build.finalName}.war", property = "targetWar", required = false ) private File targetWar; @Parameter (property = "serverName", required = true) private String serverName; @Parameter (defaultValue = "http://localhost:8080", property = "serverURL", required = true) private String serverURL; @Parameter(defaultValue = "/${project.build.finalName}", property = "appPath", required = false) private String appPath; @Parameter(defaultValue = "false", property = "update", required = false) private String update; public void execute() throws MojoExecutionException { Path propFile = Paths.get(System.getProperty("user.home"), ".m2", "settings.xml"); URL url; try { url = new URL(serverURL + "/manager/text/deploy?update=" + Boolean.valueOf(update) + "&path=" + appPath); } catch (MalformedURLException e) { throw new MojoExecutionException("Error creating target URL", e); } try { SettingsBuildingRequest req = new DefaultSettingsBuildingRequest(); req.setUserSettingsFile(propFile.toFile()); Settings settings = builder.build(req).getEffectiveSettings(); Server server = settings.getServer(serverName); SettingsDecryptionRequest decRequest = new DefaultSettingsDecryptionRequest(server); SettingsDecryptionResult decrypt = decrypter.decrypt(decRequest); Server decServer = decrypt.getServer(); String auth = decServer.getUsername() + ":" + decServer.getPassword(); byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8)); String authHeaderValue = "Basic " + new String(encodedAuth); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("PUT"); conn.setRequestProperty("Authorization", authHeaderValue); OutputStream output = conn.getOutputStream(); InputStream input = new FileInputStream(targetWar); int res = input.read(); while (res != -1) { output.write(res); res = input.read(); } output.close(); input.close(); int responseCode = conn.getResponseCode(); switch (responseCode) { case 200: BufferedReader bis = new BufferedReader(new InputStreamReader(conn.getInputStream())); char[] buff = new char[256]; int num = bis.read(buff); if (buff[0] == 'O' && buff[1] == 'K') { // OK break; } else { // FAIL throw new MojoExecutionException("Attempt to deploy app failed: " + new String(buff)); } case 401: String authHeader = conn.getHeaderField("WWW-Authenticate"); throw new MojoExecutionException("Unable to authenticate to Tomcat (" + authHeader + "). Are your username/password correct?"); default: throw new MojoExecutionException("Received unexpected HTTP status code: " + responseCode); } } catch (IOException e) { MojoExecutionException exception = new MojoExecutionException("I/O exception attempting to deploy (URL " + url.toString() + ")"); exception.initCause(e); throw exception; } catch (SettingsBuildingException e) { MojoExecutionException exception = new MojoExecutionException("Exception partinsing settings attempting to deploy"); exception.initCause(e); throw exception; } } }