InstallPackagesMojo.java

  1. /*
  2.  * #%L
  3.  * wcm.io
  4.  * %%
  5.  * Copyright (C) 2017 wcm.io
  6.  * %%
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *      http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  * #L%
  19.  */
  20. package io.wcm.devops.conga.plugins.aem.maven;

  21. import static io.wcm.devops.conga.generator.util.FileUtil.getCanonicalPath;

  22. import java.io.File;
  23. import java.util.List;

  24. import javax.inject.Inject;

  25. import org.apache.maven.execution.MavenSession;
  26. import org.apache.maven.model.Plugin;
  27. import org.apache.maven.plugin.BuildPluginManager;
  28. import org.apache.maven.plugin.MavenPluginManager;
  29. import org.apache.maven.plugin.MojoExecution;
  30. import org.apache.maven.plugin.MojoExecutionException;
  31. import org.apache.maven.plugin.MojoFailureException;
  32. import org.apache.maven.plugin.descriptor.MojoDescriptor;
  33. import org.apache.maven.plugin.descriptor.PluginDescriptor;
  34. import org.apache.maven.plugins.annotations.Mojo;
  35. import org.apache.maven.plugins.annotations.Parameter;
  36. import org.apache.maven.project.MavenProject;
  37. import org.codehaus.plexus.configuration.PlexusConfiguration;
  38. import org.codehaus.plexus.configuration.PlexusConfigurationException;
  39. import org.codehaus.plexus.util.xml.Xpp3Dom;

  40. import io.wcm.devops.conga.plugins.aem.maven.model.BundleFile;
  41. import io.wcm.devops.conga.plugins.aem.maven.model.InstallableFile;
  42. import io.wcm.devops.conga.plugins.aem.maven.model.ModelContentPackageFile;
  43. import io.wcm.devops.conga.plugins.aem.maven.model.ModelParser;
  44. import io.wcm.tooling.commons.packmgr.install.PackageFile;
  45. import io.wcm.tooling.commons.packmgr.install.PackageInstaller;

  46. /**
  47.  * Installs all AEM content packages and OSGi bundles to AEM which are referenced in a model.yaml
  48.  * generated by CONGA for a node.
  49.  */
  50. @Mojo(name = "package-install", threadSafe = true, requiresProject = false)
  51. public final class InstallPackagesMojo extends AbstractContentPackageMojo {

  52.   /**
  53.    * Directory with the generated CONGA configuration containing the model.yaml.
  54.    */
  55.   @Parameter(required = true, property = "conga.nodeDirectory")
  56.   private File nodeDirectory;

  57.   /**
  58.    * Whether to install (unpack) the uploaded package automatically or not.
  59.    */
  60.   @Parameter(property = "vault.install", defaultValue = "true")
  61.   private boolean install;

  62.   /**
  63.    * Force upload and install of content package. If set to:
  64.    * <ul>
  65.    * <li><code>true</code>: Package is always installed, even if it was already uploaded before.</li>
  66.    * <li><code>false</code>: Package is only installed if it was not already uploade before.</li>
  67.    * <li>nothing (default): Force is applied to packages with the string "-SNAPSHOT" in it's filename.</li>
  68.    * </ul>
  69.    */
  70.   @Parameter(property = "vault.force")
  71.   private Boolean force;

  72.   /**
  73.    * If set to true nested packages get installed as well.
  74.    */
  75.   @Parameter(property = "vault.recursive", defaultValue = "true")
  76.   private boolean recursive;

  77.   /**
  78.    * Delay further steps after package installation by this amount of seconds
  79.    */
  80.   @Parameter(property = "vault.delayAfterInstallSec")
  81.   private Integer delayAfterInstallSec;

  82.   /**
  83.    * Replicate package(s) to publish instance after upload.
  84.    */
  85.   @Parameter(property = "vault.replicatePackage")
  86.   private boolean replicate;

  87.   /**
  88.    * Version of Sling plugin
  89.    */
  90.   @Parameter(property = "sling.plugin.version", required = true, defaultValue = "2.4.2")
  91.   private String slingPluginVersion;

  92.   @Parameter(defaultValue = "${project}", readonly = true)
  93.   private MavenProject project;
  94.   @Parameter(defaultValue = "${session}", readonly = true)
  95.   private MavenSession session;
  96.   @Inject
  97.   private MavenPluginManager pluginManager;
  98.   @Inject
  99.   private BuildPluginManager buildPluginManager;

  100.   @Override
  101.   public void execute() throws MojoExecutionException, MojoFailureException {
  102.     if (isSkip()) {
  103.       return;
  104.     }

  105.     if (!nodeDirectory.exists() || !nodeDirectory.isDirectory()) {
  106.       throw new MojoFailureException("Node directory not found: " + getCanonicalPath(nodeDirectory));
  107.     }

  108.     getLog().info("Get AEM content packages from " + getCanonicalPath(nodeDirectory));

  109.     // collect files to install
  110.     ModelParser modelParser = new ModelParser(nodeDirectory);
  111.     List<InstallableFile> items = modelParser.getInstallableFilesForNode();

  112.     // ensure any file exist
  113.     if (items.isEmpty()) {
  114.       getLog().warn("No file found for installing.");
  115.       return;
  116.     }

  117.     // install files
  118.     PackageInstaller installer = new PackageInstaller(getPackageManagerProperties());
  119.     installer.setReplicate(this.replicate);

  120.     for (InstallableFile item : items) {
  121.       if (item instanceof ModelContentPackageFile) {
  122.         PackageFile packageFile = toPackageFile((ModelContentPackageFile)item);
  123.         installer.installFile(packageFile);
  124.       }
  125.       else if (item instanceof BundleFile) {
  126.         BundleFile bundleFile = (BundleFile)item;
  127.         if (bundleFile.getInstall() == null || bundleFile.getInstall()) {
  128.           installBundleViaSlingPlugin(bundleFile.getFile());
  129.         }
  130.       }
  131.       else {
  132.         getLog().warn("Unsupported file: " + getCanonicalPath(item.getFile()));
  133.       }
  134.     }
  135.   }

  136.   private PackageFile toPackageFile(ModelContentPackageFile item) {
  137.     PackageFile output = new PackageFile();

  138.     output.setFile(item.getFile());
  139.     Boolean installParam = item.getInstall();
  140.     if (installParam != null) {
  141.       output.setInstall(installParam);
  142.     }
  143.     else {
  144.       output.setInstall(this.install);
  145.     }
  146.     Boolean forcePAram = item.getForce();
  147.     if (forcePAram != null) {
  148.       output.setForce(forcePAram);
  149.     }
  150.     else {
  151.       output.setForce(this.force);
  152.     }
  153.     Boolean recursiveParam = item.getRecursive();
  154.     if (recursiveParam != null) {
  155.       output.setRecursive(recursiveParam);
  156.     }
  157.     else {
  158.       output.setRecursive(this.recursive);
  159.     }
  160.     Integer delayAfterInstallSecParam = item.getDelayAfterInstallSec();
  161.     if (delayAfterInstallSecParam != null) {
  162.       output.setDelayAfterInstallSec(delayAfterInstallSecParam);
  163.     }
  164.     else if (this.delayAfterInstallSec != null) {
  165.       output.setDelayAfterInstallSec(this.delayAfterInstallSec);
  166.     }
  167.     else {
  168.       output.setDelayAfterInstallSecAutoDetect();
  169.     }
  170.     output.setHttpSocketTimeoutSec(item.getHttpSocketTimeoutSec());

  171.     return output;
  172.   }

  173.   /**
  174.    * Executes the sling-maven-plugin directly from the current project to install OSGi bundles.
  175.    */
  176.   private void installBundleViaSlingPlugin(File file) throws MojoExecutionException {
  177.     Plugin plugin = new Plugin();
  178.     plugin.setGroupId("org.apache.sling");
  179.     plugin.setArtifactId("sling-maven-plugin");
  180.     plugin.setVersion(this.slingPluginVersion);

  181.     try {
  182.       PluginDescriptor pluginDescriptor = pluginManager.getPluginDescriptor(plugin,
  183.           project.getRemotePluginRepositories(), session.getRepositorySession());
  184.       MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo("install-file");
  185.       MojoExecution mojoExecution = new MojoExecution(pluginDescriptor.getMojo("install-file"));

  186.       Xpp3Dom config = convertConfiguration(mojoDescriptor.getMojoConfiguration());
  187.       config.getChild("slingUrl").setValue(buildConsoleUrl());
  188.       config.getChild("user").setValue(this.getConsoleUser());
  189.       config.getChild("password").setValue(this.getConsolePassword());
  190.       config.getChild("mountByFS").setValue("false");
  191.       config.getChild("bundleFileName").setValue(file.getAbsolutePath());
  192.       mojoExecution.setConfiguration(config);

  193.       buildPluginManager.executeMojo(session, mojoExecution);
  194.     }
  195.     catch (Exception ex) {
  196.       throw new MojoExecutionException("Faild to execute plugin: " + plugin, ex);
  197.     }
  198.   }

  199.   private Xpp3Dom convertConfiguration(PlexusConfiguration plexusConfig) throws PlexusConfigurationException {
  200.     Xpp3Dom config = new Xpp3Dom(plexusConfig.getName());
  201.     config.setValue(plexusConfig.getValue());
  202.     for (String attribute : plexusConfig.getAttributeNames()) {
  203.       config.setAttribute(attribute, plexusConfig.getAttribute(attribute));
  204.     }
  205.     for (PlexusConfiguration child : plexusConfig.getChildren()) {
  206.       config.addChild(convertConfiguration(child));
  207.     }
  208.     return config;
  209.   }

  210. }