aboutsummaryrefslogtreecommitdiffstats
path: root/vespa-application-maven-plugin
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespa-application-maven-plugin
Publish
Diffstat (limited to 'vespa-application-maven-plugin')
-rw-r--r--vespa-application-maven-plugin/.gitignore2
-rw-r--r--vespa-application-maven-plugin/OWNERS1
-rw-r--r--vespa-application-maven-plugin/pom.xml89
-rw-r--r--vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/ApplicationMojo.java116
-rw-r--r--vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/Compression.java68
5 files changed, 276 insertions, 0 deletions
diff --git a/vespa-application-maven-plugin/.gitignore b/vespa-application-maven-plugin/.gitignore
new file mode 100644
index 00000000000..12251442258
--- /dev/null
+++ b/vespa-application-maven-plugin/.gitignore
@@ -0,0 +1,2 @@
+/target
+/pom.xml.build
diff --git a/vespa-application-maven-plugin/OWNERS b/vespa-application-maven-plugin/OWNERS
new file mode 100644
index 00000000000..3b2ba1ede81
--- /dev/null
+++ b/vespa-application-maven-plugin/OWNERS
@@ -0,0 +1 @@
+gjoranv
diff --git a/vespa-application-maven-plugin/pom.xml b/vespa-application-maven-plugin/pom.xml
new file mode 100644
index 00000000000..1ad7a335d47
--- /dev/null
+++ b/vespa-application-maven-plugin/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<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>
+ <parent>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>parent</artifactId>
+ <version>6-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+ <artifactId>vespa-application-maven-plugin</artifactId>
+ <version>6-SNAPSHOT</version>
+ <packaging>maven-plugin</packaging>
+ <description>Maven Plugin for assembling a vespa application package</description>
+ <prerequisites>
+ <maven>2.2.0</maven>
+ </prerequisites>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.scala-lang</groupId>
+ <artifactId>scala-library</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.scala-tools</groupId>
+ <artifactId>maven-scala-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>add-source</goal>
+ <goal>compile</goal>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <args>
+ <arg>-unchecked</arg>
+ <arg>-deprecation</arg>
+ <arg>-explaintypes</arg>
+ </args>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/ApplicationMojo.java b/vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/ApplicationMojo.java
new file mode 100644
index 00000000000..4fdb0f17319
--- /dev/null
+++ b/vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/ApplicationMojo.java
@@ -0,0 +1,116 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.plugin.mojo;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+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.project.MavenProject;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author tonytv
+ */
+@Mojo(name = "packageApplication", defaultPhase = LifecyclePhase.PACKAGE)
+public class ApplicationMojo extends AbstractMojo {
+
+ @Component
+ protected MavenProject project;
+
+ @Parameter(defaultValue = "src/main/application")
+ private String sourceDir;
+
+ @Parameter(defaultValue = "target/application")
+ private String destinationDir;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ File applicationPackage = new File(project.getBasedir(), sourceDir);
+ File applicationDestination = new File(project.getBasedir(), destinationDir);
+ copyApplicationPackage(applicationPackage, applicationDestination);
+
+ File componentsDir = createComponentsDir(applicationDestination);
+ copyModuleBundles(project.getBasedir(), componentsDir);
+ copyBundlesForSubModules(componentsDir);
+
+ try {
+ Compression.zipDirectory(applicationDestination);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Failed zipping application.", e);
+ }
+ }
+
+ private void copyBundlesForSubModules(File componentsDir) throws MojoExecutionException {
+ List<String> modules = emptyListIfNull(project.getModules());
+ for (String module : modules) {
+ File moduleDir = new File(project.getBasedir(), module);
+ if (moduleDir.exists()) {
+ copyModuleBundles(moduleDir, componentsDir);
+ }
+ }
+ }
+
+ private File createComponentsDir(File applicationDestination) throws MojoExecutionException {
+ File componentsDir = new File(applicationDestination, "components");
+ componentsDir.mkdir();
+ if (!componentsDir.exists() || !componentsDir.isDirectory()) {
+ throw new MojoExecutionException("Failed creating components directory (" + componentsDir + ")");
+ }
+ return componentsDir;
+ }
+
+ private void copyApplicationPackage(File applicationPackage, File applicationDestination) throws MojoExecutionException {
+ if (applicationPackage.exists()) {
+ try {
+ FileUtils.copyDirectory(applicationPackage, applicationDestination);
+ } catch (IOException e) {
+ throw new MojoExecutionException("Failed copying applicationPackage", e);
+ }
+ }
+ }
+
+ private void copyModuleBundles(File moduleDir, File componentsDir) throws MojoExecutionException {
+ File moduleTargetDir = new File(moduleDir, "target");
+ if (moduleTargetDir.exists()) {
+ File[] bundles = moduleTargetDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith("-deploy.jar") || name.endsWith("-jar-with-dependencies.jar");
+ }
+ });
+
+ for (File bundle : bundles) {
+ try {
+ copyFile(bundle, new File(componentsDir, bundle.getName()));
+ } catch (IOException e) {
+ throw new MojoExecutionException("Failed copying bundle " + bundle, e);
+ }
+ }
+ }
+ }
+
+ private void copyFile(File source, File destination) throws IOException {
+ try (FileInputStream sourceStream = new FileInputStream(source);
+ FileOutputStream destinationStream = new FileOutputStream(destination)) {
+ Compression.copyBytes(sourceStream, destinationStream);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> List<T> emptyListIfNull(List modules) {
+ return modules == null ?
+ Collections.emptyList():
+ modules;
+ }
+}
diff --git a/vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/Compression.java b/vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/Compression.java
new file mode 100644
index 00000000000..0880b567343
--- /dev/null
+++ b/vespa-application-maven-plugin/src/main/java/com/yahoo/container/plugin/mojo/Compression.java
@@ -0,0 +1,68 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.plugin.mojo;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * @author tonytv
+ */
+public class Compression {
+ static public void zipDirectory(File dir) throws Exception {
+ FileOutputStream zipFile = new FileOutputStream(new File(dir.getParent(), dir.getName() + ".zip"));
+ ZipOutputStream zipOutputStream = new ZipOutputStream(zipFile);
+ try {
+ addDirectory(zipOutputStream, dir.getName(), dir, "");
+ } finally {
+ zipOutputStream.close();
+ }
+ }
+
+ private static void addDirectory(ZipOutputStream zipOutputStream, String zipTopLevelDir, File baseDir, String relativePath) throws IOException {
+ File currentDir = new File(baseDir, relativePath);
+
+ for (File child : currentDir.listFiles()) {
+ if (child.isDirectory()) {
+ addDirectory(zipOutputStream, zipTopLevelDir, baseDir, composePath(relativePath, child.getName()));
+ } else {
+ addFile(zipOutputStream, zipTopLevelDir, relativePath, child);
+ }
+ }
+ }
+
+ private static void addFile(ZipOutputStream zipOutputStream, String zipTopLevelDir, String relativePath, File child) throws IOException {
+ ZipEntry entry = new ZipEntry(composePath(zipTopLevelDir, composePath(relativePath, child.getName())));
+ zipOutputStream.putNextEntry(entry);
+ try {
+ FileInputStream fileInput = new FileInputStream(child);
+ try {
+ copyBytes(fileInput, zipOutputStream);
+ } finally {
+ fileInput.close();
+ }
+ } finally {
+ zipOutputStream.closeEntry();
+ }
+ }
+
+ public static void copyBytes(InputStream input, OutputStream output) throws IOException {
+ byte[] b = new byte[1024];
+ int numRead = 0;
+
+ while((numRead = input.read(b)) != -1) {
+ output.write(b, 0, numRead);
+ }
+ }
+
+ private static String composePath(String relativePath, String subDir) {
+ return relativePath.isEmpty() ?
+ subDir :
+ relativePath + File.separator + subDir;
+ }
+}