diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespa-application-maven-plugin |
Publish
Diffstat (limited to 'vespa-application-maven-plugin')
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; + } +} |