1   package com.atlassian.maven.plugins.amps;
2   
3   import com.atlassian.maven.plugins.amps.product.ProductHandler;
4   import org.apache.commons.io.IOUtils;
5   import org.apache.maven.plugin.MojoExecutionException;
6   import org.apache.maven.plugin.MojoFailureException;
7   import org.apache.maven.artifact.Artifact;
8   import org.jfrog.maven.annomojo.annotations.MojoExecute;
9   import org.jfrog.maven.annomojo.annotations.MojoGoal;
10  import org.jfrog.maven.annomojo.annotations.MojoParameter;
11  import org.jfrog.maven.annomojo.annotations.MojoRequiresDependencyResolution;
12  
13  import java.io.File;
14  import java.io.FileOutputStream;
15  import java.io.IOException;
16  import java.io.OutputStream;
17  import java.util.Collections;
18  import java.util.HashMap;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Properties;
22  
23  import static org.apache.commons.lang.StringUtils.isBlank;
24  
25  /**
26   * Run the webapp
27   */
28  @MojoGoal ("run")
29  @MojoExecute (phase = "package")
30  @MojoRequiresDependencyResolution
31  public class RunMojo extends AbstractTestGroupsHandlerMojo
32  {
33      private static final char CONTROL_C = (char) 27;
34  
35      @MojoParameter (expression = "${wait}", defaultValue = "true")
36      private boolean wait;
37  
38      /**
39       * Whether or not to write properties used by the plugin to amps.properties.
40       */
41      @MojoParameter (expression = "${amps.properties}", required = true, defaultValue = "false")
42      protected boolean writePropertiesToFile;
43  
44      /**
45       * Instance id to run.  If provided, used to determine the product to run instead of just the product ID.
46       */
47      @MojoParameter(expression = "${instanceId}")
48      protected String instanceId;
49  
50      /**
51       * Test group to run.  If provided, used to determine the products to run.
52       */
53      @MojoParameter(expression = "${testGroup}")
54      protected String testGroup;
55      
56      /**
57       * The properties actually used by the mojo when running
58       */
59      protected final Map<String, String> properties = new HashMap<String, String>();
60  
61      protected void doExecute() throws MojoExecutionException, MojoFailureException
62      {
63          final List<ProductExecution> productExecutions = getProductExecutions();
64  
65          startProducts(productExecutions);
66      }
67  
68      protected void startProducts(List<ProductExecution> productExecutions) throws MojoExecutionException
69      {
70          for (ProductExecution productExecution : productExecutions)
71          {
72              final ProductHandler productHandler = productExecution.getProductHandler();
73              final Product product = productExecution.getProduct();
74              product.setInstallPlugin(shouldInstallPlugin());
75  
76              int actualHttpPort = productHandler.start(product);
77  
78              getLog().info(product.getInstanceId() + " started successfully and available at http://localhost:" + actualHttpPort + product.getContextPath());
79  
80              if (writePropertiesToFile)
81              {
82                  if (productExecutions.size() == 1)
83                  {
84                      properties.put("http.port", String.valueOf(actualHttpPort));
85                      properties.put("context.path", product.getContextPath());
86                  }
87  
88                  properties.put("http." + product.getInstanceId() + ".port", String.valueOf(actualHttpPort));
89                  properties.put("context." + product.getInstanceId() + ".path", product.getContextPath());
90              }
91          }
92  
93          if (writePropertiesToFile)
94          {
95              writePropertiesFile();
96          }
97  
98          if (wait)
99          {
100             getLog().info("Type CTRL-C to exit");
101             try
102             {
103                 while (System.in.read() != CONTROL_C)
104                 {
105                 }
106             }
107             catch (final IOException e)
108             {
109                 // ignore
110             }
111         }
112     }
113 
114     protected List<ProductExecution> getProductExecutions() throws MojoExecutionException
115     {
116         final List<ProductExecution> productExecutions;
117         final MavenGoals goals = getMavenGoals();
118         if (!isBlank(testGroup))
119         {
120             productExecutions = getTestGroupProductExecutions(testGroup);
121         }
122         else if (!isBlank(instanceId))
123         {
124             Product ctx = getProductContexts(goals).get(instanceId);
125             if (ctx == null)
126             {
127                 throw new MojoExecutionException("No product with instance ID '" + instanceId + "'");
128             }
129             ProductHandler product = createProductHandler(ctx.getId());
130             productExecutions = Collections.singletonList(new ProductExecution(ctx, product));
131         }
132         else
133         {
134             Product ctx = getProductContexts(goals).get(getProductId());
135             ProductHandler product = createProductHandler(ctx.getId());
136             productExecutions = Collections.singletonList(new ProductExecution(ctx, product));
137         }
138         return productExecutions;
139     }
140 
141     /**
142      * Only install a plugin if the installPlugin flag is true and the project is a jar.  If the test plugin was built,
143      * it will be installed as well.
144      */
145     private boolean shouldInstallPlugin()
146     {
147         Artifact artifact = getMavenContext().getProject().getArtifact();
148         return installPlugin &&
149                 (artifact != null && !"pom".equalsIgnoreCase(artifact.getType()));
150     }
151 
152     private void writePropertiesFile() throws MojoExecutionException
153     {
154         final Properties props = new Properties();
155 
156         for (Map.Entry<String, String> entry : properties.entrySet())
157         {
158             props.setProperty(entry.getKey(), entry.getValue());
159         }
160 
161         final File ampsProperties = new File(getMavenContext().getProject().getBuild().getDirectory(), "amps.properties");
162         OutputStream out = null;
163         try
164         {
165             out = new FileOutputStream(ampsProperties);
166             props.store(out, "");
167         }
168         catch (IOException e)
169         {
170             throw new MojoExecutionException("Error writing " + ampsProperties.getAbsolutePath(), e);
171         }
172         finally
173         {
174             IOUtils.closeQuietly(out);
175         }
176     }
177 }