summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Culkin <scorpress@gmail.com>2024-05-15 18:59:22 -0400
committerBenjamin Culkin <scorpress@gmail.com>2024-05-15 18:59:22 -0400
commit68dbb2b7eaae8379bcb185428e46e083a2bf6ecb (patch)
treef74400ff9979c1290e74a51c527fb2abda4969ea
Initial commit
-rw-r--r--.gitignore5
-rw-r--r--pom.xml182
-rw-r--r--src/it/settings.xml37
-rw-r--r--src/it/simple-it/pom.xml34
-rw-r--r--src/it/simple-it/verify.groovy3
-rw-r--r--src/main/java/com/ashardalon/maven/tomcat/TomcatMojo.java141
-rw-r--r--src/test/java/com/ashardalon/maven/tomcat/TomcatMojoTest.java61
-rw-r--r--src/test/resources/project-to-test/pom.xml27
8 files changed, 490 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5d3b77e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.classpath
+.project
+.settings/
+target/
+tags
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d27c3f3
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.ashardalon</groupId>
+ <artifactId>slim-tomcat-maven-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Slim Tomcat Maven Plugin</name>
+
+ <!-- FIXME change it to the project's website -->
+ <url>http://www.example.com</url>
+
+ <prerequisites>
+ <maven>${maven.version}</maven>
+ </prerequisites>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <maven.version>3.3.9</maven.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${maven.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>3.6.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-testing</groupId>
+ <artifactId>maven-plugin-testing-harness</artifactId>
+ <version>3.3.0</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>3.1.0</version>
+ </plugin>
+ <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_maven-plugin_packaging -->
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>3.6.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.22.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-invoker-plugin</artifactId>
+ <version>3.1.0</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>3.6.0</version>
+ <configuration>
+ <!-- <goalPrefix>maven-archetype-plugin</goalPrefix> -->
+ <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+ </configuration>
+ <executions>
+ <execution>
+ <id>mojo-descriptor</id>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>help-goal</id>
+ <goals>
+ <goal>helpmojo</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>run-its</id>
+ <build>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-invoker-plugin</artifactId>
+ <version>3.1.0</version>
+ <configuration>
+ <debug>true</debug>
+ <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+ <pomIncludes>
+ <pomInclude>*/pom.xml</pomInclude>
+ </pomIncludes>
+ <postBuildHookScript>verify</postBuildHookScript>
+ <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
+ <settingsFile>src/it/settings.xml</settingsFile>
+ <goals>
+ <goal>clean</goal>
+ <goal>test-compile</goal>
+ </goals>
+ </configuration>
+ <executions>
+ <execution>
+ <id>integration-test</id>
+ <goals>
+ <goal>install</goal>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/src/it/settings.xml b/src/it/settings.xml
new file mode 100644
index 0000000..000e726
--- /dev/null
+++ b/src/it/settings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+<settings>
+ <profiles>
+ <profile>
+ <id>it-repo</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <repositories>
+ <repository>
+ <id>local.central</id>
+ <url>@localRepositoryUrl@</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>local.central</id>
+ <url>@localRepositoryUrl@</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ </profiles>
+</settings>
diff --git a/src/it/simple-it/pom.xml b/src/it/simple-it/pom.xml
new file mode 100644
index 0000000..0b7e415
--- /dev/null
+++ b/src/it/simple-it/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.ashardalon.it</groupId>
+ <artifactId>simple-it</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <description>A simple IT verifying the basic use case.</description>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>@project.groupId@</groupId>
+ <artifactId>@project.artifactId@</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>touch</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>touch</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/it/simple-it/verify.groovy b/src/it/simple-it/verify.groovy
new file mode 100644
index 0000000..7b307c7
--- /dev/null
+++ b/src/it/simple-it/verify.groovy
@@ -0,0 +1,3 @@
+File touchFile = new File( basedir, "target/touch.txt" );
+
+assert touchFile.isFile()
diff --git a/src/main/java/com/ashardalon/maven/tomcat/TomcatMojo.java b/src/main/java/com/ashardalon/maven/tomcat/TomcatMojo.java
new file mode 100644
index 0000000..e2a030d
--- /dev/null
+++ b/src/main/java/com/ashardalon/maven/tomcat/TomcatMojo.java
@@ -0,0 +1,141 @@
+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.PROCESS_SOURCES )
+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;
+
+ 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?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();
+ System.out.println("auth header: " + auth);
+ 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[4];
+ int num = bis.read(buff);
+ if (num == 2) { // OK
+ break;
+ } else { // FAIL
+ buff = new char[256];
+ num = bis.read(buff);
+ 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;
+ }
+ }
+}
diff --git a/src/test/java/com/ashardalon/maven/tomcat/TomcatMojoTest.java b/src/test/java/com/ashardalon/maven/tomcat/TomcatMojoTest.java
new file mode 100644
index 0000000..f2ef215
--- /dev/null
+++ b/src/test/java/com/ashardalon/maven/tomcat/TomcatMojoTest.java
@@ -0,0 +1,61 @@
+package com.ashardalon.maven.tomcat;
+
+
+import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.plugin.testing.WithoutMojo;
+
+import org.junit.Rule;
+import static org.junit.Assert.*;
+import org.junit.Test;
+import java.io.File;
+
+public class TomcatMojoTest
+{
+ @Rule
+ public MojoRule rule = new MojoRule()
+ {
+ @Override
+ protected void before() throws Throwable
+ {
+ }
+
+ @Override
+ protected void after()
+ {
+ }
+ };
+
+ /**
+ * @throws Exception if any
+ */
+ @Test
+ public void testSomething()
+ throws Exception
+ {
+ File pom = new File( "target/test-classes/project-to-test/" );
+ assertNotNull( pom );
+ assertTrue( pom.exists() );
+
+ TomcatMojo myMojo = ( TomcatMojo ) rule.lookupConfiguredMojo( pom, "deploy" );
+ assertNotNull( myMojo );
+ myMojo.execute();
+
+ File outputDirectory = ( File ) rule.getVariableValueFromObject( myMojo, "outputDirectory" );
+ assertNotNull( outputDirectory );
+ assertTrue( outputDirectory.exists() );
+
+ File touch = new File( outputDirectory, "touch.txt" );
+ assertTrue( touch.exists() );
+
+ }
+
+ /** Do not need the MojoRule. */
+ @WithoutMojo
+ @Test
+ public void testSomethingWhichDoesNotNeedTheMojoAndProbablyShouldBeExtractedIntoANewClassOfItsOwn()
+ {
+ assertTrue( true );
+ }
+
+}
+
diff --git a/src/test/resources/project-to-test/pom.xml b/src/test/resources/project-to-test/pom.xml
new file mode 100644
index 0000000..e7f929d
--- /dev/null
+++ b/src/test/resources/project-to-test/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.ashardalon</groupId>
+ <artifactId>slim-tomcat-maven-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Test MyMojo</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.ashardalon</groupId>
+ <artifactId>slim-tomcat-maven-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <configuration>
+ <!-- Specify the MyMojo parameter -->
+ <serverName>ashardalon-tomcat</serverName>
+ <targetWar>stachetype.war</targetWar>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>