/amps-maven-plugin/src/main/java/com/atlassian/maven/plugins/amps/product/CrowdProductHandler.java
Java | 245 lines | 211 code | 21 blank | 13 comment | 4 complexity | 43f28f0a4c98c797a79ff8ee7468591b MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
- package com.atlassian.maven.plugins.amps.product;
- import com.atlassian.maven.plugins.amps.MavenContext;
- import com.atlassian.maven.plugins.amps.MavenGoals;
- import com.atlassian.maven.plugins.amps.Product;
- import com.atlassian.maven.plugins.amps.ProductArtifact;
- import com.atlassian.maven.plugins.amps.product.manager.WebAppManager;
- import com.google.common.collect.ImmutableMap;
- import org.apache.commons.io.FileUtils;
- import org.apache.maven.artifact.resolver.ArtifactResolver;
- import org.apache.maven.plugin.MojoExecutionException;
- import org.apache.maven.repository.RepositorySystem;
- import javax.annotation.Nonnull;
- import java.io.File;
- import java.io.IOException;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import static com.atlassian.maven.plugins.amps.product.ProductHandlerFactory.CROWD;
- import static com.atlassian.maven.plugins.amps.util.ConfigFileUtils.replaceAll;
- import static com.atlassian.maven.plugins.amps.util.ConfigFileUtils.updateProperties;
- import static java.util.Collections.singleton;
- public class CrowdProductHandler extends AbstractWebappProductHandler {
- private static final String LOCAL_CROWD_CONFIG = "crowd.cfg.xml";
- private static final String SHARED_CROWD_CONFIG = "shared/crowd.cfg.xml";
- public CrowdProductHandler(final MavenContext context, final MavenGoals goals,
- final RepositorySystem repositorySystem, final ArtifactResolver artifactResolver,
- final WebAppManager webAppManager) {
- super(context, goals, new CrowdPluginProvider(), repositorySystem, artifactResolver, webAppManager);
- }
- @Nonnull
- @Override
- public String getId() {
- return CROWD;
- }
- @Nonnull
- @Override
- public ProductArtifact getArtifact() {
- return new ProductArtifact("com.atlassian.crowd", "crowd-web-app", "RELEASE");
- }
- @Nonnull
- @Override
- public Optional<ProductArtifact> getTestResourcesArtifact() {
- return Optional.of(new ProductArtifact("com.atlassian.crowd.distribution", "crowd-plugin-test-resources"));
- }
- @Override
- public int getDefaultHttpPort() {
- return 4990;
- }
- @Override
- public int getDefaultHttpsPort() {
- return 8444;
- }
- @Override
- @Nonnull
- protected Map<String, String> getProductSpecificSystemProperties(final Product product, final int nodeIndex) {
- final ImmutableMap.Builder<String, String> systemProperties = ImmutableMap.builder();
- systemProperties.put("cargo.servlet.uriencoding", "UTF-8");
- final List<File> homeDirectories = getHomeDirectories(product);
- // Use the first node's shared home as the cluster's shared home (it already exists in ZIP files)
- final File sharedHome = new File(homeDirectories.get(0), "shared");
- final String homeDirectory = homeDirectories.get(nodeIndex).getPath();
- // Crowd's DefaultHomeLocator reads this property
- systemProperties.put("crowd.home", homeDirectory);
- // Crowd's HomeDirectoryServiceImpl reads this property
- systemProperties.put("crowd.shared.home", sharedHome.getPath());
- // Synthesise a node name (read in Crowd by NodeDataProvider#getNodeName)
- systemProperties.put("cluster.node.name", product.getInstanceId() + "-" + nodeIndex);
- return systemProperties.build();
- }
- @Nonnull
- @Override
- public Optional<File> getUserInstalledPluginsDirectory(
- final Product product, final File webappDir, final File homeDir) {
- final File sharedHomeDir = new File(homeDir, "shared");
- if (sharedHomeDir.exists()) {
- return Optional.of(new File(sharedHomeDir, "plugins"));
- } else {
- return Optional.of(new File(homeDir, "plugins"));
- }
- }
- @Override
- @Nonnull
- public List<ProductArtifact> getExtraContainerDependencies() {
- return Arrays.asList(
- new ProductArtifact("hsqldb", "hsqldb", "1.8.0.7"),
- new ProductArtifact("javax.transaction", "jta", "1.1"),
- new ProductArtifact("javax.mail", "mail", "1.4"),
- new ProductArtifact("javax.activation", "activation", "1.0.2")
- );
- }
- @Nonnull
- @Override
- protected Collection<String> getExtraJarsToSkipWhenScanningForTldsAndWebFragments() {
- // AMPS-1524: mail-1.4.jar has `activation.jar` in its Class-Path manifest header, not activation-1.0.2.jar
- return singleton("mail-*.jar");
- }
- @Override
- @Nonnull
- public File getBundledPluginPath(Product product, File productDir) {
- return new File(productDir, "WEB-INF/classes/atlassian-bundled-plugins.zip");
- }
- @Override
- public void processHomeDirectory(final Product product, final int nodeIndex, final File homeDir)
- throws MojoExecutionException {
- super.processHomeDirectory(product, nodeIndex, homeDir);
- try {
- updateLicenseInSharedConfig(homeDir, product);
- updateClusteringEnabledFlag(homeDir, product);
- updateHsqlUrlInCrowdConfig(homeDir);
- updateCrowdDotProperties(product, nodeIndex, homeDir);
- } catch (final IOException e) {
- throw new MojoExecutionException(e.getMessage());
- }
- }
- @Override
- protected boolean useBackdoorToInstallLicense() {
- // Crowd reads certain license attributes at startup, so using the plugin is too late. We therefore apply the
- // user-provided license before startup, see updateLicenseInSharedConfig below.
- return false;
- }
- /*
- Because Crowd's NodeDataProvider memoizes whether clustering is enabled at startup time, using the license
- backdoor plugin to replace the license later cannot enable DC mode. We therefore have to put the user-provided
- license into the Crowd configuration before the product starts up.
- */
- private void updateLicenseInSharedConfig(final File homeDir, final Product product) throws MojoExecutionException {
- final Optional<String> license = product.getUserConfiguredLicense();
- if (license.isPresent()) { // no ifPresent lambda because exception thrown below
- replaceAll(new File(homeDir, SHARED_CROWD_CONFIG),
- "(<property name=\"license\">).+(</property>)", "$1" + license.get() + "$2");
- }
- }
- private void updateClusteringEnabledFlag(final File homeDir, final Product product)
- throws MojoExecutionException {
- if (product.isMultiNode()) {
- replaceAll(new File(homeDir, SHARED_CROWD_CONFIG),
- "crowd.clustering.enabled\">false<", "crowd.clustering.enabled\">true<");
- }
- }
- // Crowd still uses HSQLDB as of 4.3.0
- private void updateHsqlUrlInCrowdConfig(final File homeDir) throws IOException, MojoExecutionException {
- final String jdbcDir = homeDir.getCanonicalPath().replace("\\", "/");
- final String hsqldbUrl = "jdbc:hsqldb:" + jdbcDir + "/database/defaultdb";
- replaceAll(new File(homeDir, SHARED_CROWD_CONFIG),
- "jdbc:hsqldb:.*/(crowd-)?home/database/defaultdb",
- hsqldbUrl);
- replaceAll(new File(homeDir, LOCAL_CROWD_CONFIG),
- "jdbc:hsqldb:.*/(crowd-)?home/database/defaultdb",
- hsqldbUrl);
- }
- private void updateCrowdDotProperties(final Product product, final int nodeIndex, final File homeDir)
- throws MojoExecutionException {
- final String baseUrl = getBaseUrl(product, nodeIndex);
- final Map<String, String> newProperties = ImmutableMap.of(
- "crowd.server.url", baseUrl + "/services",
- "application.login.url", baseUrl
- );
- updateProperties(new File(homeDir, "crowd.properties"), newProperties);
- }
- private String getBaseUrl(final Product product, final int nodeIndex) throws MojoExecutionException {
- // Crowd connects back to itself; use 'localhost' rather than the hostname an external client would see
- try {
- return withLocalhostAsHostname(product.getBaseUrlForNode(nodeIndex));
- } catch (URISyntaxException e) {
- throw new MojoExecutionException("Unable to process Crowd service URL", e);
- }
- }
- static String withLocalhostAsHostname(@Nonnull final String uri) throws URISyntaxException {
- final URI base = new URI(uri);
- final URI baseWithLocalhost = new URI(
- base.getScheme(),
- base.getUserInfo(),
- "localhost",
- base.getPort(),
- base.getPath(),
- base.getQuery(),
- base.getFragment());
- return baseWithLocalhost.toString();
- }
- private static class CrowdPluginProvider extends AbstractPluginProvider {
- @Override
- protected Collection<ProductArtifact> getSalArtifacts(final String salVersion) {
- return Arrays.asList(
- new ProductArtifact("com.atlassian.sal", "sal-api", salVersion),
- new ProductArtifact("com.atlassian.sal", "sal-crowd-plugin", salVersion));
- }
- @Override
- protected Collection<ProductArtifact> getPdkInstallArtifacts(final String pdkInstallVersion) {
- final List<ProductArtifact> plugins = new ArrayList<>(super.getPdkInstallArtifacts(pdkInstallVersion));
- plugins.add(new ProductArtifact("commons-fileupload", "commons-fileupload", "1.2.1"));
- return plugins;
- }
- }
- @Override
- protected void cleanupProductHomeForZip(@Nonnull final Product product, @Nonnull final File homeDirectory)
- throws MojoExecutionException, IOException {
- super.cleanupProductHomeForZip(product, homeDirectory);
- FileUtils.deleteQuietly(new File(homeDirectory, "caches"));
- FileUtils.deleteQuietly(new File(homeDirectory, "logs"));
- }
- @Nonnull
- @Override
- protected List<File> getConfigFiles(@Nonnull final Product product, @Nonnull final File snapshotDir) {
- final List<File> configFiles = super.getConfigFiles(product, snapshotDir);
- configFiles.add(new File(snapshotDir, "database.log"));
- configFiles.add(new File(snapshotDir, LOCAL_CROWD_CONFIG));
- configFiles.add(new File(snapshotDir, SHARED_CROWD_CONFIG));
- configFiles.add(new File(snapshotDir, "crowd.properties"));
- return configFiles;
- }
- }