/amps-maven-plugin/src/main/java/com/atlassian/maven/plugins/amps/Product.java
Java | 1464 lines | 665 code | 216 blank | 583 comment | 81 complexity | fd092d1e653b8db1c59743fa0d930e2e MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
- package com.atlassian.maven.plugins.amps;
- import com.atlassian.maven.plugins.amps.util.ArtifactRetriever;
- import com.atlassian.maven.plugins.amps.util.MapUtils;
- import com.google.common.annotations.VisibleForTesting;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.maven.plugin.logging.Log;
- import javax.annotation.Nonnull;
- import javax.annotation.Nullable;
- import java.io.File;
- import java.net.URI;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Objects;
- import java.util.Optional;
- import java.util.Properties;
- import java.util.function.Function;
- import java.util.function.Supplier;
- import static com.atlassian.maven.plugins.amps.product.manager.BaseUrlUtils.getBaseUrl;
- import static java.lang.String.format;
- import static java.util.Collections.singletonList;
- import static java.util.Collections.unmodifiableList;
- import static java.util.Optional.empty;
- import static org.apache.commons.lang3.StringUtils.defaultString;
- import static org.apache.commons.lang3.StringUtils.isNotBlank;
- import static org.apache.commons.lang3.StringUtils.remove;
- import static org.apache.commons.lang3.StringUtils.stripToNull;
- import static org.apache.commons.lang3.StringUtils.trimToNull;
- /**
- * A software product that AMPS can start.
- */
- public class Product {
- /*
- To add a property to this class:
- - add the private field; must be of a type that Maven can unmarshal from the XML in the user's AMPS config
- - add a getter and setter for it
- - update the merge(Product) method to use the given Product's value for this field, if necessary
- - add a similar field to the AbstractProductHandlerMojo, since users can also configure the product there
- - annotate that field with @Parameter and configure it with a system property if applicable
- - add a line to AbstractProductHandlerMojo#createDefaultProductContext, to copy that new mojo field to the Product
- */
- /**
- * Container artifact to run in if containerId is not specified or containerId is equals to "customContainerArtifact"
- * It has format groupId:artifactId:version[:packaging][:classifier].
- */
- protected String customContainerArtifact;
- /**
- * Id of container to run in
- */
- protected String containerId;
- /**
- * Helper field set by AMPS when containerId in not provided in plugin pom or when containerId equals "productSpecified"
- * It used to decide if AMPS should use container artifact defined in customContainerArtifact field or not
- * Introduced to keep backward compatibility
- */
- protected boolean containerNotSpecified;
- /**
- * HTTP port for the servlet containers
- */
- private int httpPort = 0;
- /**
- * RMI port, for Tomcat this is port used to send shutdown message
- */
- protected int rmiPort = 0;
- /**
- * if we should start with https on port 443
- */
- private Boolean useHttps;
- /**
- * the HTTPS port to use.
- *
- * @since 5.0.4
- */
- private int httpsPort;
- /**
- * The SSL certificate chain option.
- *
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration">Tomcat SSL HOWTO</a>
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support">Tomcat SSL Support</a>
- * @since 5.0.4
- */
- private String httpsClientAuth;
- /**
- * The SSL protocols to use.
- *
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration">Tomcat SSL HOWTO</a>
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support">Tomcat SSL Support</a>
- * @since 5.0.4
- */
- private String httpsSslProtocol;
- /**
- * The pathname of the keystore file.
- *
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration">Tomcat SSL HOWTO</a>
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support">Tomcat SSL Support</a>
- * @since 5.0.4
- */
- private String httpsKeystoreFile;
- /**
- * The password of the keystore file.
- *
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration">Tomcat SSL HOWTO</a>
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support">Tomcat SSL Support</a>
- * @since 5.0.4
- */
- private String httpsKeystorePass;
- /**
- * The alias of the certificate to use.
- *
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration">Tomcat SSL HOWTO</a>
- * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support">Tomcat SSL Support</a>
- * @since 5.0.4
- */
- private String httpsKeyAlias;
- /**
- * Cargo httpSecure flag
- *
- * @see <a href="http://svn.codehaus.org/cargo/core/trunk/containers/tomcat/src/main/java/org/codehaus/cargo/container/tomcat/TomcatPropertySet.java">Cargo Tomcat Properties</a>
- * @since 5.0.4
- */
- private Boolean httpsHttpSecure;
- /**
- * Application context path, in the format: /context-path
- */
- protected String contextPath;
- /**
- * Application server
- */
- protected String server;
- /**
- * Webapp version
- */
- protected String version;
- /**
- * JVM arguments to pass to Cargo
- */
- protected String jvmArgs = "";
- /**
- * Debug arguments to pass to Cargo as JVM arguments
- */
- protected String debugArgs = "";
- /**
- * A log4j properties file
- */
- protected File log4jProperties;
- /**
- * The test resources version
- */
- protected String productDataVersion;
- /**
- * The path to a custom test resources zip or a directory. Takes precedence over dataVersion.
- * The data from this path will be copied into the home directory.
- */
- protected String productDataPath = "";
- /**
- * The path to the product's home directory. Takes precedence over dataPath.
- * The data from this path will be used directly (read/write) by the product.
- */
- protected String dataHome = "";
- /**
- * The path to a zip or a directory to use for home directory overrides. Takes precedence
- * over src/test/resources/{@link #instanceId}-home.
- */
- protected String dataOverridesPath = "";
- /**
- *
- */
- private List<Application> applications = new ArrayList<>();
- /**
- *
- */
- private List<ProductArtifact> pluginArtifacts = new ArrayList<>();
- /**
- *
- */
- private List<ProductArtifact> libArtifacts = new ArrayList<>();
- /**
- *
- */
- private List<ProductArtifact> bundledArtifacts = new ArrayList<>();
- /**
- * SAL version
- */
- private String salVersion;
- /**
- * Atlassian Plugin Development Kit (PDK) version
- */
- private String pdkVersion;
- /**
- * Atlassian REST module version
- */
- private String restVersion;
- /**
- * Version of the Felix OSGi web console
- */
- private String webConsoleVersion;
- /**
- * Flag to indicate whether or not to enable automatic bundling of DevToolbox.
- */
- private Boolean enableDevToolbox;
- /**
- * Version of the Developer Toolbox plugin
- */
- private String devToolboxVersion;
- /**
- * Should QuickReload be enabled.
- */
- private Boolean enableQuickReload;
- /**
- * Version of QuickReload.
- */
- private String quickReloadVersion;
- /**
- * If PluginViewer should be used.
- */
- private Boolean enablePluginViewer;
- /**
- * PluginViewer version should be used.
- */
- private String pluginViewerVersion;
- /**
- * Flag to indicate whether or not to enable automatic bundling of PDE.
- */
- private Boolean enablePde;
- /**
- * Version of the PDE plugin
- */
- private String pdeVersion;
- /**
- * Product id - nickname of the product to run
- */
- protected String id;
- /**
- * The name of the instance of the product
- */
- protected String instanceId;
- private ArtifactRetriever artifactRetriever;
- /**
- * Flag to indicate whether or not to install the plugin
- */
- private Boolean installPlugin;
- /**
- * The system properties to set for the product
- */
- private Map<String, Object> systemProperties = new HashMap<>();
- /**
- * The Cargo XML overrides for the product
- */
- private Collection<XmlOverride> cargoXmlOverrides;
- /**
- * File the container should log to.
- */
- private String output;
- /**
- * Port for debugging
- */
- private int jvmDebugPort;
- /**
- * How long to wait for product startup, in milliseconds; if not specified, default is determined by AbstractProductHandlerMojo
- */
- private int startupTimeout;
- /**
- * How long to wait for product shutdown, in milliseconds; if not specified, default is determined by AbstractProductHandlerMojo
- */
- private int shutdownTimeout;
- /**
- * Waits until the application is up before proceeding to the next one (blocking call).<ul>
- * <li>If -Dparallel is not specified, default is TRUE for all products.</li>
- * <li>If -Dparallel is specified, default is FALSE except for FeCru.</li>
- * <li>The pom.xml overrides the default values.</li>
- * <li>Use -Dparallel to start products in parallel. {@code AbstractProductHandlerMojo#setParallelMode} sets the
- * default values according to this parameter.</li>
- * </ul>
- */
- private Boolean synchronousStartup;
- /**
- * Waits until product is fully started - this is added for Jira - Jira new asynchronous start -
- * Jira is performing minimal initialization and then whole plugin system startup is performed in background.<br>
- * This can interfere with integration tests - AMPS starts them after minimal initialization and some may crash as
- * plugin system is not fully started (if they do not perform check if jira is fully started).<br>
- * This flag prevents such situation and forces product to perform full initialization before continuing to next
- * step.
- */
- private Boolean awaitFullInitialization;
- /**
- * An optional override of the webapp's groupId
- */
- private String groupId;
- /**
- * An optional override of the webapp's artifactId
- */
- private String artifactId;
- /**
- * Registers a JNDI datasource using cargo.datasource.datasource.
- * <ul>
- * <li>Default values depend on the product.</li>
- * <li>Default values will be applied to the first datasource if its definition is incomplete.</li>
- * <li>Only Jira has a datasource by default, and they use HSQL or H2.</li>
- * <li>Other products can use datasources if you configure them this way during the setup process (Requires to
- * start with an empty data home).</li>
- * </ul>
- * Example:
- * <pre>{@code
- * <products>
- * <product>
- * <id>jira</id>
- * <instanceId>jira50</instanceId>
- * <version>5.0</version>
- * <dataVersion>5.0</dataVersion>
- * <dataSources>
- * <dataSource>
- * <jndi>jdbc/JiraDS</jndi>
- * <url>jdbc:postgresql://localhost:5432/jira</url>
- * <driver>org.postgresql.jdbcDriver</driver>
- * <username>jira</username>
- * <password>jira</password>
- * <libArtifacts>
- * <libArtifact>
- * <groupId>postgresql</groupId>
- * <artifactId>postgresql</artifactId>
- * <version>9.1-901-1.jdbc4</version>
- * </libArtifact>
- * </libArtifacts>
- * </dataSource>
- * </dataSources>
- * </product>
- * </products>
- * }
- * </pre>
- */
- private List<DataSource> dataSources;
- // The home directory shared between multiple instances in a cluster (added for Jira)
- private String sharedHome;
- // The port for the Apache JServ Protocol; defaults to the web container's default value
- private int ajpPort;
- // The replacement license string (if any) configured by the user
- private String license;
- // The nodes of this product instance (for backward compatibility, empty implies single-node operation)
- // To get a non-null, non-empty list, call getNodes() instead of accessing this field directly.
- private List<Node> nodes;
- /**
- * Merges {@code this} product with the given one, with {@code this} product's values taking precedence.
- *
- * @param product the product to merge with; it is not modified
- * @return a new product; {@code this} product is not modified
- */
- public Product merge(final Product product) {
- final Product prod = new Product();
- prod.setOutput(output == null ? product.getOutput() : output);
- prod.setSystemPropertyVariables(MapUtils.merge(product.getSystemPropertyVariables(), systemProperties));
- prod.setInstallPlugin(installPlugin == null ? product.isInstallPlugin() : installPlugin);
- prod.setArtifactRetriever(artifactRetriever == null ? product.getArtifactRetriever() : artifactRetriever);
- prod.setId(id == null ? product.getId() : id);
- prod.setInstanceId(instanceId == null ? product.getInstanceId() : instanceId);
- prod.setWebConsoleVersion(webConsoleVersion == null ? product.getWebConsoleVersion() : webConsoleVersion);
- prod.setEnableDevToolbox(enableDevToolbox == null ? product.isEnableDevToolbox() : enableDevToolbox);
- prod.setDevToolboxVersion(devToolboxVersion == null ? product.getDevToolboxVersion() : devToolboxVersion);
- prod.setEnableQuickReload(enableQuickReload == null ? product.isEnableQuickReload() : enableQuickReload);
- prod.setQuickReloadVersion(quickReloadVersion == null ? product.getQuickReloadVersion() : quickReloadVersion);
- prod.setEnablePluginViewer(enablePluginViewer == null ? product.isEnablePluginViewer() : enablePluginViewer);
- prod.setPluginViewerVersion(pluginViewerVersion == null ? product.getPluginViewerVersion() : pluginViewerVersion);
- prod.setEnablePde(enablePde == null ? product.isEnablePde() : enablePde);
- prod.setPdeVersion(pdeVersion == null ? product.getPdeVersion() : pdeVersion);
- prod.setRestVersion(restVersion == null ? product.getRestVersion() : restVersion);
- prod.setPdkVersion(pdkVersion == null ? product.getPdkVersion() : pdkVersion);
- prod.setSalVersion(salVersion == null ? product.getSalVersion() : salVersion);
- prod.setBundledArtifacts(bundledArtifacts.isEmpty() ? product.getBundledArtifacts() : bundledArtifacts);
- prod.setPluginArtifacts(pluginArtifacts.isEmpty() ? product.getPluginArtifacts() : pluginArtifacts);
- prod.setLibArtifacts(libArtifacts.isEmpty() ? product.getLibArtifacts() : libArtifacts);
- prod.setApplications(applications.isEmpty() ? product.getApplications() : applications);
- prod.setDataPath(StringUtils.isBlank(productDataPath) ? product.getDataPath() : productDataPath);
- prod.setDataVersion(productDataVersion == null ? product.getDataVersion() : productDataVersion);
- prod.setDataHome(dataHome == null ? product.getDataHome() : dataHome);
- prod.setDataOverridesPath(dataOverridesPath == null ? product.getDataOverridesPath() : dataOverridesPath);
- prod.setLog4jProperties(log4jProperties == null ? product.getLog4jProperties() : log4jProperties);
- prod.setJvmArgs(stripToNull(jvmArgs) == null ? product.getJvmArgs() : jvmArgs);
- prod.setDebugArgs(stripToNull(debugArgs) == null ? product.getDebugArgs() : debugArgs);
- prod.setDataSources(dataSources == null ? product.getDataSources() : dataSources);
- prod.setGroupId(groupId == null ? product.getGroupId() : groupId);
- prod.setArtifactId(artifactId == null ? product.getArtifactId() : artifactId);
- prod.setVersion(version == null ? product.getVersion() : version);
- prod.setServer(server == null ? product.getServer() : server);
- prod.setContextPath(contextPath == null ? product.getContextPath() : contextPath);
- prod.setCustomContainerArtifact(customContainerArtifact == null ? product.getCustomContainerArtifact() : customContainerArtifact);
- prod.setContainerId(containerId == null ? product.getContainerId() : containerId);
- prod.setContainerNotSpecified(containerNotSpecified && product.isContainerNotSpecified());
- prod.setRmiPort(rmiPort == 0 ? product.getRmiPort() : rmiPort);
- prod.setHttpPort(httpPort == 0 ? product.getHttpPort() : httpPort);
- prod.setAjpPort(ajpPort == 0 ? product.getAjpPort() : ajpPort);
- prod.setJvmDebugPort(jvmDebugPort == 0 ? product.getJvmDebugPort() : jvmDebugPort);
- prod.setUseHttps(useHttps == null ? product.getUseHttps() : useHttps);
- prod.setStartupTimeout(startupTimeout == 0 ? product.getStartupTimeout() : startupTimeout);
- prod.setShutdownTimeout(shutdownTimeout == 0 ? product.getShutdownTimeout() : shutdownTimeout);
- prod.setSynchronousStartup(synchronousStartup == null ? product.getSynchronousStartup() : synchronousStartup);
- prod.setSharedHome(sharedHome == null ? product.getSharedHome() : sharedHome);
- prod.setCargoXmlOverrides(cargoXmlOverrides == null ? product.getCargoXmlOverrides() : cargoXmlOverrides);
- // https related properties
- prod.setHttpsPort(httpsPort == 0 ? product.getHttpsPort() : httpsPort);
- prod.setHttpsClientAuth(httpsClientAuth == null ? product.getHttpsClientAuth() : httpsClientAuth);
- prod.setHttpsSSLProtocol(httpsSslProtocol == null ? product.getHttpsSSLProtocol() : httpsSslProtocol);
- prod.setHttpsKeystoreFile(httpsKeystoreFile == null ? product.getHttpsKeystoreFile() : httpsKeystoreFile);
- prod.setHttpsKeystorePass(httpsKeystorePass == null ? product.getHttpsKeystorePass() : httpsKeystorePass);
- prod.setHttpsKeyAlias(httpsKeyAlias == null ? product.getHttpsKeyAlias() : httpsKeyAlias);
- prod.setHttpsHttpSecure(httpsHttpSecure == null ? product.getHttpsHttpSecure() : httpsHttpSecure);
- prod.setAwaitFullInitialization(
- awaitFullInitialization == null ? product.isAwaitFullInitialization() : awaitFullInitialization);
- prod.setLicense(license == null ? product.getLicense() : license);
- prod.setNodes(nodes == null ? product.nodes : nodes);
- return prod;
- }
- void setLicense(final String license) {
- this.license = license;
- }
- public String getCustomContainerArtifact() {
- return customContainerArtifact;
- }
- public void setCustomContainerArtifact(String customContainerArtifact) {
- this.customContainerArtifact = customContainerArtifact;
- }
- public String getContainerId() {
- return containerId;
- }
- public void setContainerId(String containerId) {
- this.containerId = containerId;
- }
- public String getServer() {
- return server;
- }
- public void setServer(String server) {
- this.server = server;
- }
- /**
- * Returns the user-configured HTTP port. Has package-private access because in reality, a DC product's nodes will
- * each use a separate HTTP port, and our code should call {@link Node#getWebPort()} instead, which also respects
- * the users wishes with regard to using HTTPS. This getter is only for finding out what port the user configured at
- * the product level.
- *
- * @return see above
- */
- int getHttpPort() {
- return httpPort;
- }
- void setHttpPort(int httpPort) {
- this.httpPort = httpPort;
- }
- /**
- * Returns the user-configured RMI port. Has package-private access because in reality, a product's nodes will each
- * use a separate RMI port, so our code should call {@link Node#getRmiPort()} instead. This getter is only for
- * finding out what port the user configured at the product level.
- *
- * @return see above
- */
- @VisibleForTesting
- int getRmiPort() {
- return rmiPort;
- }
- void setRmiPort(int rmiPort) {
- this.rmiPort = rmiPort;
- }
- /**
- * Returns the timeout for this product to change state between up and down.
- *
- * @param startingUp whether the product is starting up (as opposed to shutting down)
- * @return see above
- * @since 8.3
- */
- public int getTimeout(final boolean startingUp) {
- return startingUp ? startupTimeout : shutdownTimeout;
- }
- public Boolean getUseHttps() {
- return useHttps;
- }
- public void setUseHttps(Boolean useHttps) {
- this.useHttps = useHttps;
- }
- /**
- * @since 5.0.4
- */
- void setHttpsPort(final int httpsPort) {
- this.httpsPort = httpsPort;
- }
- /**
- * Returns the user-configured HTTPS port. Has package-private access because in reality, a product's nodes will
- * each use a separate HTTPS port, so our code should call {@link Node#getWebPort()} instead. This getter is only
- * for finding out what port the user configured at the product level.
- *
- * @since 5.0.4
- */
- int getHttpsPort() {
- return this.httpsPort;
- }
- /**
- * @since 5.0.4
- */
- public void setHttpsClientAuth(final String httpsClientAuth) {
- this.httpsClientAuth = httpsClientAuth;
- }
- /**
- * @since 5.0.4
- */
- public String getHttpsClientAuth() {
- return this.httpsClientAuth;
- }
- /**
- * @since 5.0.4
- */
- public void setHttpsSSLProtocol(final String httpsSslProtocol) {
- this.httpsSslProtocol = httpsSslProtocol;
- }
- /**
- * @since 5.0.4
- */
- public String getHttpsSSLProtocol() {
- return this.httpsSslProtocol;
- }
- /**
- * @since 5.0.4
- */
- public void setHttpsKeystoreFile(final String httpsKeystoreFile) {
- this.httpsKeystoreFile = httpsKeystoreFile;
- }
- /**
- * @since 5.0.4
- */
- public String getHttpsKeystoreFile() {
- return this.httpsKeystoreFile;
- }
- /**
- * @since 5.0.4
- */
- public void setHttpsKeystorePass(final String httpsKeystorePass) {
- this.httpsKeystorePass = httpsKeystorePass;
- }
- /**
- * @since 5.0.4
- */
- public String getHttpsKeystorePass() {
- return this.httpsKeystorePass;
- }
- /**
- * @since 5.0.4
- */
- public void setHttpsKeyAlias(final String httpsKeyAlias) {
- this.httpsKeyAlias = httpsKeyAlias;
- }
- /**
- * @since 5.0.4
- */
- public String getHttpsKeyAlias() {
- return this.httpsKeyAlias;
- }
- /**
- * @since 5.0.4
- */
- public void setHttpsHttpSecure(final Boolean httpsHttpSecure) {
- this.httpsHttpSecure = httpsHttpSecure;
- }
- /**
- * @since 5.0.4
- */
- public Boolean getHttpsHttpSecure() {
- return this.httpsHttpSecure;
- }
- public String getContextPath() {
- return contextPath;
- }
- public void setContextPath(String contextPath) {
- this.contextPath = contextPath;
- }
- public String getJvmArgs() {
- return jvmArgs;
- }
- public void setJvmArgs(final String jvmArgs) {
- this.jvmArgs = defaultString(jvmArgs);
- }
- /**
- * If this product's JVM arguments are blank, this method sets them to the given value.
- *
- * @param defaultJvmArgs the default JVM arguments, trimmed to empty
- * @since 8.3
- */
- public void defaultJvmArgs(final String defaultJvmArgs) {
- if (stripToNull(jvmArgs) == null) {
- setJvmArgs(defaultJvmArgs);
- }
- }
- /**
- * Returns the user-configured debug-related JVM arguments. Has package-private access because in reality, a
- * product's nodes will each use their own debug arguments (because they include the node's debug port), so our code
- * should call {@link Node#getDebugArgs()} instead. This getter is only for finding out what debug arguments the
- * user configured at the product level.
- *
- * @return see description
- */
- @VisibleForTesting
- String getDebugArgs() {
- return debugArgs;
- }
- void setDebugArgs(final String debugArgs) {
- this.debugArgs = defaultString(debugArgs, "");
- }
- public ArtifactRetriever getArtifactRetriever() {
- return artifactRetriever;
- }
- public void setArtifactRetriever(final ArtifactRetriever artifactRetriever) {
- this.artifactRetriever = artifactRetriever;
- }
- public String getVersion() {
- return version;
- }
- public void setVersion(String version) {
- this.version = version;
- }
- public String getDataVersion() {
- return productDataVersion;
- }
- public void setDataVersion(String productDataVersion) {
- this.productDataVersion = productDataVersion;
- }
- /**
- * @deprecated since 3.2
- */
- @Deprecated
- public String getProductDataVersion() {
- return productDataVersion;
- }
- /**
- * @deprecated since 3.2
- */
- @Deprecated
- public void setProductDataVersion(String productDataVersion) {
- this.productDataVersion = productDataVersion;
- }
- /**
- * The path to a custom test resources zip or a directory. Takes precedence over dataVersion.
- * The data from this path will be copied into the home directory.
- */
- public String getDataPath() {
- return productDataPath;
- }
- /**
- * The path to a custom test resources zip or a directory. Takes precedence over dataVersion.
- * The data from this path will be copied into the home directory.
- */
- public void setDataPath(String productDataPath) {
- this.productDataPath = productDataPath;
- }
- public String getDataOverridesPath() {
- return dataOverridesPath;
- }
- public void setDataOverridesPath(String productHomeOverridesPath) {
- this.dataOverridesPath = productHomeOverridesPath;
- }
- /**
- * @deprecated since 3.2
- */
- @Deprecated
- public String getProductDataPath() {
- return productDataPath;
- }
- /**
- * @deprecated since 3.2
- */
- @Deprecated
- public void setProductDataPath(String productDataPath) {
- this.productDataPath = productDataPath;
- }
- public List<Application> getApplications() {
- return applications;
- }
- public void setApplications(final List<Application> applications) {
- this.applications = applications;
- }
- public List<ProductArtifact> getPluginArtifacts() {
- return pluginArtifacts;
- }
- public void setPluginArtifacts(List<ProductArtifact> pluginArtifacts) {
- this.pluginArtifacts = pluginArtifacts;
- }
- public List<ProductArtifact> getLibArtifacts() {
- return libArtifacts;
- }
- public void setLibArtifacts(List<ProductArtifact> libArtifacts) {
- this.libArtifacts = libArtifacts;
- }
- public List<ProductArtifact> getBundledArtifacts() {
- return unmodifiableList(bundledArtifacts);
- }
- public void setBundledArtifacts(@Nonnull final List<ProductArtifact> bundledArtifacts) {
- this.bundledArtifacts.clear();
- this.bundledArtifacts.addAll(bundledArtifacts);
- }
- /**
- * Adds the given bundled artifacts.
- *
- * @param newBundledArtifacts the artifacts to add
- * @since 8.3
- */
- public void addBundledArtifacts(final Collection<ProductArtifact> newBundledArtifacts) {
- bundledArtifacts.addAll(newBundledArtifacts);
- }
- public File getLog4jProperties() {
- return log4jProperties;
- }
- public void setLog4jProperties(File log4jProperties) {
- this.log4jProperties = log4jProperties;
- }
- public String getRestVersion() {
- return restVersion;
- }
- public void setRestVersion(String restVersion) {
- this.restVersion = restVersion;
- }
- public String getSalVersion() {
- return salVersion;
- }
- public void setSalVersion(String salVersion) {
- this.salVersion = salVersion;
- }
- public String getPdkVersion() {
- return pdkVersion;
- }
- public void setPdkVersion(String pdkVersion) {
- this.pdkVersion = pdkVersion;
- }
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getInstanceId() {
- return instanceId;
- }
- public void setInstanceId(String instanceId) {
- this.instanceId = instanceId;
- }
- public Boolean isInstallPlugin() {
- return installPlugin;
- }
- public void setInstallPlugin(final Boolean installPlugin) {
- this.installPlugin = installPlugin;
- }
- public String getWebConsoleVersion() {
- return webConsoleVersion;
- }
- public Boolean isEnableDevToolbox() {
- return enableDevToolbox;
- }
- public void setEnableDevToolbox(final Boolean enableDevToolbox) {
- this.enableDevToolbox = enableDevToolbox;
- }
- public String getQuickReloadVersion() {
- return quickReloadVersion;
- }
- public void setQuickReloadVersion(final String quickReloadVersion) {
- this.quickReloadVersion = quickReloadVersion;
- }
- public Boolean isEnableQuickReload() {
- return enableQuickReload;
- }
- public void setEnableQuickReload(final Boolean enableQuickReload) {
- this.enableQuickReload = enableQuickReload;
- }
- public String getPluginViewerVersion() {
- return pluginViewerVersion;
- }
- public void setPluginViewerVersion(String pluginViewerVersion) {
- this.pluginViewerVersion = pluginViewerVersion;
- }
- public Boolean isEnablePluginViewer() {
- return enablePluginViewer;
- }
- public void setEnablePluginViewer(final Boolean enablePluginViewer) {
- this.enablePluginViewer = enablePluginViewer;
- }
- public String getDevToolboxVersion() {
- return devToolboxVersion;
- }
- public void setDevToolboxVersion(String devToolboxVersion) {
- this.devToolboxVersion = devToolboxVersion;
- }
- public Boolean isEnablePde() {
- return enablePde;
- }
- public void setEnablePde(Boolean enablePde) {
- this.enablePde = enablePde;
- }
- public String getPdeVersion() {
- return pdeVersion;
- }
- public void setPdeVersion(String pdeVersion) {
- this.pdeVersion = pdeVersion;
- }
- public void setWebConsoleVersion(final String webConsoleVersion) {
- this.webConsoleVersion = webConsoleVersion;
- }
- /**
- * @deprecated Since 3.2, use systemPropertyVariables
- */
- @Deprecated
- public void setSystemProperties(final Properties systemProperties) {
- systemProperties.forEach(
- (key, value) -> this.systemProperties.put(key.toString(), value));
- }
- /**
- * @deprecated Since 3.2, use systemPropertyVariables
- */
- @Deprecated
- public Properties getSystemProperties() {
- Properties props = new Properties();
- props.putAll(systemProperties);
- return props;
- }
- public void setSystemPropertyVariables(final Map<String, Object> systemProperties) {
- this.systemProperties = systemProperties;
- }
- public Map<String, Object> getSystemPropertyVariables() {
- return systemProperties;
- }
- /**
- * If the given system property is not set for this product, this method sets it to the given value.
- *
- * @param key the name of the property
- * @param valueSupplier provides the value to set (if this key is not already set)
- * @see Map#computeIfAbsent
- * @since 8.3.0
- */
- public void defaultSystemProperty(final String key, final Supplier<String> valueSupplier) {
- systemProperties.computeIfAbsent(key, k -> valueSupplier.get());
- }
- /**
- * Returns the name of the log file for this product.
- *
- * @return see description
- */
- public String getOutput() {
- return output;
- }
- public void setOutput(final String output) {
- this.output = output;
- }
- /**
- * Returns the user-configured debug port. Has package-private access because in reality, a product's nodes will
- * each use a separate debug port, so our code should call {@link Node#getJvmDebugPort()} instead. This getter is only
- * for finding out what port the user configured at the product level.
- *
- * @return see above
- */
- @VisibleForTesting
- int getJvmDebugPort() {
- return jvmDebugPort;
- }
- void setJvmDebugPort(final int jvmDebugPort) {
- this.jvmDebugPort = jvmDebugPort;
- }
- public int getStartupTimeout() {
- return startupTimeout;
- }
- public void setStartupTimeout(final int startupTimeout) {
- this.startupTimeout = startupTimeout;
- }
- public int getShutdownTimeout() {
- return shutdownTimeout;
- }
- public void setShutdownTimeout(final int shutdownTimeout) {
- this.shutdownTimeout = shutdownTimeout;
- }
- public String getGroupId() {
- return groupId;
- }
- public void setGroupId(final String groupId) {
- this.groupId = groupId;
- }
- public String getArtifactId() {
- return artifactId;
- }
- public void setArtifactId(final String artifactId) {
- this.artifactId = artifactId;
- }
- public void setSystemProperties(final Map<String, Object> systemProperties) {
- this.systemProperties = systemProperties;
- }
- public Boolean getSynchronousStartup() {
- return synchronousStartup;
- }
- public void setSynchronousStartup(final Boolean synchronousStartup) {
- this.synchronousStartup = synchronousStartup;
- }
- public String getDataHome() {
- return dataHome;
- }
- /**
- * The path to the product's home directory. Takes precedence over dataPath.
- * The data from this path will be used directly (read/write) by the product.
- */
- public void setDataHome(final String dataHome) {
- this.dataHome = dataHome;
- }
- /**
- * @return the dataSources. Not null, because initialized in {@code AbstractProductHandlerMojo#setDefaultValues}
- * May be empty.
- */
- public List<DataSource> getDataSources() {
- return dataSources;
- }
- /**
- * @param dataSources the dataSources to set
- */
- public void setDataSources(final List<DataSource> dataSources) {
- this.dataSources = dataSources;
- }
- /**
- * Returns the shared home directory for a Data Center cluster.
- *
- * @return null if no shared home is set, otherwise the path to that directory
- */
- public String getSharedHome() {
- return sharedHome;
- }
- /**
- * Sets the shared home directory for a Jira cluster.
- *
- * @param sharedHome the directory path to set (can be null)
- */
- public void setSharedHome(final String sharedHome) {
- this.sharedHome = sharedHome;
- }
- /**
- * Returns the user-configured AJP port. Has package-private access because in reality, a product's nodes will each
- * use a separate AJP port, so our code should call {@link Node#getAjpPort()} instead. This getter is only for
- * finding out what port the user configured at the product level.
- *
- * @return see above
- */
- @VisibleForTesting
- int getAjpPort() {
- return ajpPort;
- }
- /**
- * Sets the AJP port for use by the web container.
- *
- * @param ajpPort the AJP port to set
- */
- void setAjpPort(final int ajpPort) {
- this.ajpPort = ajpPort;
- }
- @Override
- public String toString() {
- return "Product " + id + " [instanceId=" + instanceId + "]";
- }
- /**
- * Returns the base URL for the given node of this product.
- *
- * @param nodeIndex the zero-based index of the node
- * @return the base URL
- * @since 8.3
- */
- public String getBaseUrlForNode(final int nodeIndex) {
- return getBaseUrlForPort(getNodes().get(nodeIndex).getWebPort());
- }
- /**
- * Returns the base URL for this product, when it's running on the given HTTP(S) port.
- *
- * @param actualHttpPort the actual web port
- * @return the base URL
- * @since 8.3
- */
- public String getBaseUrlForPort(final int actualHttpPort) {
- if (actualHttpPort == 0) {
- throw new IllegalArgumentException("Invalid or unresolved web port");
- }
- return getBaseUrl(server, actualHttpPort, contextPath);
- }
- /**
- * Returns the protocol transmission scheme.
- *
- * @return "http" or "https".
- */
- public String getProtocol() {
- return isHttps() ? "https" : "http";
- }
- /**
- * A version of {@link #getUseHttps()} which never returns {@code null}. If {@code useHttps} was not set, it
- * is assumed to be {@code false}.
- *
- * @return {@code true} if {@link #getUseHttps()} is {@code Boolean.TRUE}; otherwise, {@code false}
- * @see #getProtocol() to get the web protocol
- * @see Node#getWebPort() to get the web port
- * @since 6.3
- */
- public boolean isHttps() {
- return Boolean.TRUE.equals(useHttps);
- }
- /**
- * Whether to await full initialization of the product.
- *
- * @return see description
- */
- public boolean isAwaitFullInitialization() {
- if (awaitFullInitialization != null) {
- return awaitFullInitialization;
- }
- return true;
- }
- public void setAwaitFullInitialization(Boolean awaitFullInitialization) {
- this.awaitFullInitialization = awaitFullInitialization;
- }
- /**
- * Returns any configuration overrides that should be passed on cargo start.
- *
- * @since 6.3
- */
- @Nullable
- public Collection<XmlOverride> getCargoXmlOverrides() {
- return cargoXmlOverrides;
- }
- public void setCargoXmlOverrides(final Collection<XmlOverride> cargoXmlOverrides) {
- this.cargoXmlOverrides = cargoXmlOverrides;
- }
- public boolean isContainerNotSpecified() {
- return containerNotSpecified;
- }
- public void setContainerNotSpecified(boolean containerNotSpecified) {
- this.containerNotSpecified = containerNotSpecified;
- }
- /**
- * Returns the license that the user has specified for this product in their AMPS configuration.
- *
- * @return see description
- * @since 8.2
- */
- @Nullable
- String getLicense() {
- return license;
- }
- /**
- * Indicates whether this is the given product.
- *
- * @param productId the product ID to check against
- * @return see description
- * @since 8.3
- */
- public boolean is(final String productId) {
- return Objects.equals(productId, id);
- }
- /**
- * Returns the nodes that make up this product instance.
- *
- * @return a null or empty list if the nodes have not been initialised or configured in the user's POM
- * @see #initialiseNodes()
- * @since 8.3
- */
- public List<Node> getNodes() {
- return nodes;
- }
- /**
- * Initialises this product's nodes. Until this is called, the list returned by {@link #getNodes()} can be
- * {@code null} or empty. The Mojo being invoked is responsible for calling this method at the appropriate time,
- * namely after the user-configured values have been read, but before {@link #getNodes()} is called from outside
- * this class.
- *
- * @since 8.3
- */
- public void initialiseNodes() {
- if (nodes == null || nodes.isEmpty()) {
- // The user configured no nodes => synthesise one for single-node operation
- nodes = singletonList(new Node(isHttps(), ajpPort, jvmDebugPort, httpPort, httpsPort, rmiPort, debugArgs));
- }
- for (final Node node : nodes) {
- node.ensureNonDebugPortsAreSet(instanceId);
- }
- }
- /**
- * Sets this product's nodes.
- *
- * @param nodes the nodes to set
- * @since 8.3
- */
- void setNodes(final List<Node> nodes) {
- this.nodes = nodes;
- }
- /**
- * Sets the startup mode of this Product based on whether the products are being started in parallel.
- *
- * @param parallel the desired parallelism
- * @since 8.3
- */
- public void setSynchronicity(final boolean parallel) {
- if (parallel) {
- if (synchronousStartup == null) {
- synchronousStartup = false;
- }
- } else {
- synchronousStartup = true;
- }
- }
- /**
- * Sets the debug args for each node of this product. The caller must have already set each node's debug port.
- *
- * @param suspend whether to suspend and wait for the user to attach their debugger
- * @param log the Maven log
- * @since 8.3
- * @throws IllegalStateException if the nodes have not been set or their debug ports are zero
- */
- public void setNodeDebugArgs(final boolean suspend, final Log log) {
- if (nodes == null || nodes.isEmpty()) {
- throw new IllegalStateException(format("No nodes set for instance '%s'", instanceId));
- }
- for (int i = 0; i < nodes.size(); i++) {
- final Node node = nodes.get(i);
- final int debugPort = node.getJvmDebugPort();
- if (debugPort == 0) {
- throw new IllegalStateException(
- format("No debug port set for node %d of instance '%s'", i, instanceId));
- }
- node.defaultDebugArgs(suspend);
- log.info(format("Debug port for node %d of %s is %d", i, instanceId, debugPort));
- }
- }
- /**
- * Returns the debug args for this product, assuming single-node operation. Multi-node products should instead call
- * {@link Node#getDebugArgs()} on the relevant node.
- *
- * @return see description
- * @since 8.3
- */
- public String getSingleNodeDebugArgs() {
- return getSingleNodeProperty(Node::getDebugArgs);
- }
- /**
- * Returns the web port for this product, assuming single-node operation. Multi-node products should instead call
- * {@link Node#getWebPort()} on the relevant node.
- *
- * @return see description
- * @since 8.3
- */
- public int getSingleNodeWebPort() {
- return getSingleNodeProperty(Node::getWebPort);
- }
- private <R> R getSingleNodeProperty(final Function<Node, R> accessor) {
- final List<Node> populatedNodes = getNodes();
- if (populatedNodes.size() == 1) {
- return accessor.apply(populatedNodes.get(0)); // happy path
- }
- throw new IllegalStateException("Expected one node but found " + populatedNodes);
- }
- /**
- * Returns the system properties to be applied to the JVM when starting the given node of this product.
- * This is a combination of the product-level and node-level system properties, with the latter taking precedence.
- *
- * @param nodeIndex the zero-based index of the node being started
- * @return see description
- * @since 8.3
- */
- @Nonnull
- public Map<String, String> getSystemPropertiesForNode(final int nodeIndex) {
- final Map<String, String> combinedProperties = new HashMap<>();
- systemProperties.forEach((key, value) -> combinedProperties.put(key, String.valueOf(value)));
- combinedProperties.putAll(getNodes().get(nodeIndex).getSystemProperties());
- return combinedProperties;
- }
- /**
- * Returns the web ports used by the nodes of this product.
- *
- * @return a list of non-null elements (safe to unbox)
- * @throws IllegalStateException if any of the node's web ports are zero (i.e. unresolved)
- * @since 8.3
- */
- @Nonnull
- public List<Integer> getWebPorts() {
- final List<Integer> webPorts = new ArrayList<>();
- for (final Node node : getNodes()) {
- final int webPort = node.getWebPort();
- if (webPort == 0) {
- throw new IllegalStateException("Web port not set for node " + node);
- }
- webPorts.add(webPort);
- }
- return webPorts;
- }
- /**
- * Returns the web port of the given node.
- *
- * @param nodeIndex the zero-based node index
- * @return a non-zero port number
- * @throws IllegalStateException if the node's web port has not been set (is zero)
- * @since 8.3
- */
- public int getWebPortForNode(final int nodeIndex) {
- final int webPort = getNodes().get(nodeIndex).getWebPort();
- if (webPort == 0) {
- throw new IllegalStateException("Web port not set or resolved for node " + nodeIndex);
- }
- return webPort;
- }
- /**
- * Indicates whether this product instance has multiple nodes.
- *
- * @return see description
- * @since 8.3
- */
- public boolean isMultiNode() {
- return getNodes().size() > 1;
- }
- /**
- * Returns the URL that should be called to find out whether the given node is up and healthy.
- *
- * @param nodeIndex the zero-based index of the node being checked
- * @return empty if this product does not have or require such a URL, otherwise a URL that returns 200 if healthy
- * @since 8.3
- */
- public Optional<URI> getStatusUri(final int nodeIndex) {
- if ("confluence".equals(id) && isMultiNode()) {
- final String url = getBaseUrlForNode(nodeIndex) + "/status";
- return Optional.of(URI.create(url));
- }
- return empty();
- }
- /**
- * Returns any user-configured license for this product, as follows:
- * <ol>
- * <li>if {@link #license} is non-blank, it's returned with any spaces removed</li>
- * <li>otherwise, this method returns empty</li>
- * </ol>
- *
- * @param licenseCreator the license creator to use, if necessary
- * @param licensePopulator the license populator to use, if necessary
- * @return see description
- * @since 8.3
- */
- @Nonnull
- public Optional<String> getUserConfiguredLicense() {
- return Optional.ofNullable(trimToNull(remove(license, ' ')));
- }
- /**
- * Indicates whether this product has a user-configured license. This method is faster than calling
- * {@link #getUserConfiguredLicense}, because no license generation is ever performed.
- *
- * @return see description
- * @since 8.3
- */
- public boolean hasUserConfiguredLicense() {
- return isNotBlank(license);
- }
- }