org.cloudfoundry.maven.AbstractCloudFoundryMojo.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudfoundry.maven.AbstractCloudFoundryMojo.java

Source

/*
 * Copyright 2009-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cloudfoundry.maven;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.settings.Proxy;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.cloudfoundry.client.lib.CloudCredentials;
import org.cloudfoundry.client.lib.CloudFoundryClient;
import org.cloudfoundry.client.lib.CloudFoundryException;
import org.cloudfoundry.client.lib.HttpProxyConfiguration;
import org.cloudfoundry.client.lib.tokens.TokensFile;
import org.cloudfoundry.maven.common.Assert;
import org.cloudfoundry.maven.common.DefaultConstants;
import org.cloudfoundry.maven.common.SystemProperties;
import org.cloudfoundry.maven.common.WarningBypassingResponseErrorHandler;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.web.client.ResourceAccessException;

/**
 * Abstract goal that provides common configuration for the Cloud Foundry Maven
 * Plugin.
 *
 * @author Gunnar Hillert
 * @author Ali Moghadam
 * @author Scott Frederick
 * @since 1.0.0
 */
@SuppressWarnings("UnusedDeclaration")
public abstract class AbstractCloudFoundryMojo extends AbstractMojo {

    /**
     * @parameter expression="${project.artifactId}"
     */
    private String artifactId;

    protected CloudFoundryClient client;
    protected TokensFile tokensFile = new TokensFile();
    protected WarningBypassingResponseErrorHandler responseErrorHandler = new WarningBypassingResponseErrorHandler();

    /**
     * @parameter expression="${cf.password}"
     */
    protected String password;

    /**
     * @parameter expression="${cf.server}"
     */
    private String server;

    /**
     * @parameter expression="${session}"
     */
    private MavenSession session;

    /**
     * @parameter expression="${cf.target}"
     */
    private String target;

    /**
     * @parameter expression="${cf.username}"
     */
    protected String username;

    /**
     * @parameter expression="${cf.org}"
     */
    private String org;

    /**
     * @parameter expression="${cf.space}"
     */
    private String space;

    /**
     * @parameter expression="${cf.trustSelfSignedCerts}"
     */
    private boolean trustSelfSignedCerts;

    /**
     * Skip any and all execution of this plugin.
     * @parameter expression="${cf.skip}" default-value="false"
     */
    private boolean skip;

    /**
     * The Maven Wagon manager to use when obtaining server authentication details.
     *
     * @component role="org.apache.maven.artifact.manager.WagonManager"
     * @required
     * @readonly
     */
    private WagonManager wagonManager;

    /**
     * Default Constructor.
     */
    public AbstractCloudFoundryMojo() {
        super();
    }

    public AbstractCloudFoundryMojo(TokensFile tokensFile) {
        this.tokensFile = tokensFile;
    }

    /**
     * Retrieve Token from ~/.cf/tokens.yml
     *
     * @return token (String)
     */
    protected OAuth2AccessToken retrieveToken() throws MojoExecutionException {
        final OAuth2AccessToken token = tokensFile.retrieveToken(getTarget());

        if (token == null) {
            throw new MojoExecutionException(String.format("Can not authenticate to target '%s'. "
                    + "Configure a username and password, or use the login goal.", getTarget().toString()));
        }

        return token;
    }

    /**
     * Cloud Controller Version 2 Client (Token)
     */
    protected CloudFoundryClient createCloudFoundryClient(OAuth2AccessToken token, URI target, String org,
            String space, boolean trustSelfSignedCerts) throws MojoExecutionException {

        Assert.configurationNotNull(org, "org", SystemProperties.ORG);
        Assert.configurationNotNull(space, "space", SystemProperties.SPACE);

        getLog().debug(String.format("Connecting to Cloud Foundry at '%s' using token", target.toString()));

        final CloudCredentials credentials = new CloudCredentials(token);
        return createConnection(credentials, target, org, space, trustSelfSignedCerts);
    }

    /**
     * Cloud Controller Version 2 Client
     */
    protected CloudFoundryClient createCloudFoundryClient(String username, String password, URI target, String org,
            String space, boolean trustSelfSignedCerts) throws MojoExecutionException {

        Assert.configurationNotNull(username, "username", SystemProperties.USERNAME);
        Assert.configurationNotNull(password, "password", SystemProperties.PASSWORD);
        Assert.configurationNotNull(org, "org", SystemProperties.ORG);
        Assert.configurationNotNull(space, "space", SystemProperties.SPACE);

        getLog().debug(String.format("Connecting to Cloud Foundry at '%s' with username: '%s'", target, username));

        final CloudCredentials credentials = new CloudCredentials(username, password);
        CloudFoundryClient client = createConnection(credentials, target, org, space, trustSelfSignedCerts);
        connectToCloudFoundry(client);
        return client;
    }

    private CloudFoundryClient createConnection(CloudCredentials credentials, URI target, String org, String space,
            boolean trustSelfSignedCert) throws MojoExecutionException {
        try {
            CloudFoundryClient cloudFoundryClient = new CloudFoundryClient(credentials, target.toURL(), org, space,
                    getHttpProxyConfiguration(target), trustSelfSignedCert);
            cloudFoundryClient.setResponseErrorHandler(responseErrorHandler);
            return cloudFoundryClient;
        } catch (MalformedURLException e) {
            throw new MojoExecutionException(String.format(
                    "Incorrect Cloud Foundry target URL '%s'. Make sure the URL contains a scheme, e.g. http://...",
                    target), e);
        }
    }

    private HttpProxyConfiguration getHttpProxyConfiguration(URI target) {
        Proxy proxy = getMavenProxy();
        if (proxy != null) {
            if (!targetIsExcludedFromProxy(target.getHost(), proxy)) {
                return new HttpProxyConfiguration(proxy.getHost(), proxy.getPort());
            }
        }
        return null;
    }

    protected Proxy getMavenProxy() {
        List<Proxy> proxies = session.getSettings().getProxies();
        if (proxies == null || proxies.isEmpty())
            return null;

        for (Proxy proxy : proxies) {
            if (proxy.isActive() && "http".equalsIgnoreCase(proxy.getProtocol())) {
                return proxy;
            }
        }

        return null;
    }

    private boolean targetIsExcludedFromProxy(String targetHost, Proxy proxy) {
        if (proxy.getNonProxyHosts() != null) {
            List<String> nonProxyHosts = Arrays.asList(proxy.getNonProxyHosts().split("\\|"));
            return nonProxyHosts.contains(targetHost);
        }
        return false;
    }

    /**
     * Cloud Foundry Connection Login
     */
    protected void connectToCloudFoundry(CloudFoundryClient client) throws MojoExecutionException {
        try {
            client.login();
        } catch (CloudFoundryException e) {
            if (HttpStatus.FORBIDDEN.equals(e.getStatusCode())) {
                throw new MojoExecutionException(String.format(
                        "Login failed to '%s' using username '%s'. Please verify your login credentials.", target,
                        username), e);
            } else if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
                throw new MojoExecutionException(String.format(
                        "The target host '%s' exists but it does not appear to be a valid Cloud Foundry target url.",
                        target), e);
            } else {
                throw e;
            }
        } catch (ResourceAccessException e) {
            throw new MojoExecutionException(String.format("Cannot access host at '%s'.", target), e);
        }
    }

    /**
     *  Goals will typically override this method.
     */
    protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;

    /**
     * Base execute method. Will perform the login and logout into Cloud Foundry.
     * Delegates to doExecute() for the actual business logic.
     */
    public void execute() throws MojoExecutionException, MojoFailureException {
        if (skip) {
            getLog().info("Skipping execution of Cloud Foundry Maven Plugin");
            return;
        }

        Assert.configurationNotNull(target, "target", SystemProperties.TARGET);

        try {
            if (getUsername() != null && getPassword() != null) {
                client = createCloudFoundryClient(getUsername(), getPassword(), getTarget(), getOrg(), getSpace(),
                        getTrustSelfSignedCerts());
            } else {
                client = createCloudFoundryClient(retrieveToken(), getTarget(), getOrg(), getSpace(),
                        getTrustSelfSignedCerts());
            }

            doExecute();
        } catch (RuntimeException e) {
            throw new MojoExecutionException("An exception was caught while executing Mojo.", e);
        }
    }

    //~~~~Getters~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    /**
     * @return Returns the Maven artifactId. Will never return null.
     */
    public String getArtifactId() {
        Assert.notNull(artifactId, "The artifactId is not set.");
        return artifactId;
    }

    public CloudFoundryClient getClient() {
        return client;
    }

    /**
     * See http://maven.apache.org/plugin-developers/common-bugs.html#Using_System_Properties
     *
     * @param property Supported system properties
     * @return Null if the property is not found, otherwise returns the property
     */
    public String getCommandlineProperty(SystemProperties property) {
        return session.getExecutionProperties().getProperty(property.getProperty());
    }

    public String getPassword() {

        final String passwordProperty = getCommandlineProperty(SystemProperties.PASSWORD);

        if (passwordProperty != null) {
            return passwordProperty;
        }

        if (this.password == null) {

            getLog().debug(
                    "No password defined in pom.xml and " + "no system property defined either. Trying to look up "
                            + "password in settings.xml under server element " + this.getServer());

            AuthenticationInfo authenticationInfo = this.wagonManager.getAuthenticationInfo(this.getServer());

            if (authenticationInfo == null) {
                getLog().debug(
                        String.format("In settings.xml server element '%s' was not defined.", this.getServer()));
                return null;
            }

            if (authenticationInfo.getPassword() != null) {
                return authenticationInfo.getPassword();
            } else {
                getLog().debug(String.format(
                        "In settings.xml no password was found for server element '%s'. Does the element exist?",
                        this.getServer()));
                return null;
            }

        } else {
            return this.password;
        }

    }

    /**
     * Maven allows for externalizing the credential for server connections to
     * be externalized into settings.xml.
     *
     * If a property was provided on the command line, use that property. Otherwise
     * use the property that was injected via Maven. If that is Null as well, default
     * to the value specified in {@link DefaultConstants}
     *
     * @return The name of the Maven Server property used to resolved Cloud Foundry credentials. Never returns null.
     *
     */
    public String getServer() {

        final String serverProperty = getCommandlineProperty(SystemProperties.SETTINGS_SERVER);

        if (serverProperty != null) {
            return serverProperty;
        }

        if (this.server == null) {
            return DefaultConstants.MAVEN_DEFAULT_SERVER;
        }

        return this.server;
    }

    /**
     * If the target property was provided via the command line, use that property.
     * Otherwise use the property that was injected via Maven. If that is Null
     * as well, Null is returned.
     *
     * @return Returns the Cloud Foundry Target Url - Can return Null.
     *
     */
    public URI getTarget() {

        final String targetProperty = getCommandlineProperty(SystemProperties.TARGET);

        if (targetProperty != null) {
            try {

                URI uri = new URI(targetProperty);

                if (uri.isAbsolute()) {
                    return uri;
                } else {
                    throw new URISyntaxException(targetProperty, "URI is not opaque.");
                }

            } catch (URISyntaxException e) {
                throw new IllegalStateException(String.format(
                        "The Url parameter '%s' " + "which was passed in as system property is not valid.",
                        targetProperty));
            }
        }

        if (this.target == null) {
            return null;
        }

        try {
            return new URI(this.target);
        } catch (URISyntaxException e) {
            throw new IllegalStateException(String.format(
                    "The Url parameter '%s' "
                            + "which was passed in as pom.xml configiuration parameter is not valid.",
                    this.target));
        }

    }

    public String getUsername() {

        final String usernameProperty = getCommandlineProperty(SystemProperties.USERNAME);

        if (usernameProperty != null) {
            return usernameProperty;
        }

        if (this.username == null) {

            getLog().debug(
                    "No username defined in pom.xml and " + "no system property defined either. Trying to look up "
                            + "username in settings.xml under server element " + this.getServer());

            AuthenticationInfo authenticationInfo = this.wagonManager.getAuthenticationInfo(this.getServer());

            if (authenticationInfo == null) {
                getLog().debug(
                        String.format("In settings.xml server element '%s' was not defined.", this.getServer()));
                return null;
            }

            if (authenticationInfo.getUserName() != null) {
                return authenticationInfo.getUserName();
            } else {
                super.getLog().debug(String.format(
                        "In settings.xml no username was found for server element '%s'. Does the element exist?",
                        this.getServer()));
                return null;
            }

        } else {
            return username;
        }

    }

    public String getOrg() {
        return getOrg(true);
    }

    protected String getOrg(boolean assertExistence) {
        if (assertExistence) {
            Assert.notNull(org, "The org is not set.");
        }
        return org;
    }

    public String getSpace() {
        return getSpace(true);
    }

    protected String getSpace(boolean assertExistence) {
        if (assertExistence) {
            Assert.notNull(space, "The space is not set.");
        }
        return space;
    }

    public boolean getTrustSelfSignedCerts() {
        return trustSelfSignedCerts;
    }
}