All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.atlassian.bamboo.specs.util.BambooServer Maven / Gradle / Ivy

There is a newer version: 10.1.0
Show newest version
package com.atlassian.bamboo.specs.util;

import com.atlassian.bamboo.specs.api.builders.RootEntityPropertiesBuilder;
import com.atlassian.bamboo.specs.api.exceptions.BambooSpecsPublishingException;
import com.atlassian.bamboo.specs.api.exceptions.BambooSpecsPublishingException.ErrorType;
import com.atlassian.bamboo.specs.api.rsbs.RunnerSettings;
import com.atlassian.bamboo.specs.exceptions.BambooSpecsRestRequestException;
import com.atlassian.bamboo.specs.util.Logger.LogLevel;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.conn.UnsupportedSchemeException;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedWriter;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URI;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Represents an instance of Bamboo server for publishing {@link RootEntityPropertiesBuilder entities}.
 */
public class BambooServer {
    private static final Logger log = Logger.getLogger(BambooServer.class);

    private final URI baseUrl;
    private final UserPasswordCredentials userPasswordCredentials;

    private static final AtomicLong COUNTER = new AtomicLong();

    /**
     * Create an instance of Bamboo server with default {@link FileUserPasswordCredentials}.
     *
     * @param baseUrl base URL of the Bamboo server, e.g. http://bamboo.example.com/
     */
    public BambooServer(@NotNull String baseUrl) {
        this(baseUrl, RunnerSettings.isRestEnabled() ? new FileUserPasswordCredentials() : new SimpleUserPasswordCredentials("none", "none"));
    }

    /**
     * Create an instance of Bamboo server with specified {@link UserPasswordCredentials}.
     *
     * @param baseUrl                 base URL of the Bamboo server, e.g. http://bamboo.example.com/
     * @param userPasswordCredentials credentials to use for contacting Bamboo
     */
    public BambooServer(@NotNull String baseUrl, @NotNull UserPasswordCredentials userPasswordCredentials) {
        this.baseUrl = URI.create(baseUrl + '/');
        this.userPasswordCredentials = userPasswordCredentials;
    }

    /**
     * Get base URL for the Bamboo server.
     */
    public URI getBaseUrl() {
        return baseUrl;
    }

    /**
     * Publishes the given entity to Bamboo server.
     *
     * @param entityProperties entity to publish
     * @return result of the publishing
     * @throws BambooSpecsPublishingException if publishing fails
     */
    public Object publish(@NotNull final RootEntityPropertiesBuilder entityProperties) {
        log.info("Publishing " + entityProperties.humanReadableId());

        final String yaml = BambooSpecSerializer.dump(entityProperties);

        final Path yamlDir = RunnerSettings.getYamlDir();
        if (yamlDir != null) {
            final Path outputPath = yamlDir.resolve(getFileName(entityProperties));
            log.info("Writing specs into " + outputPath);
            try (BufferedWriter bw = Files.newBufferedWriter(outputPath)) {
                bw.write(yaml);
            } catch (final IOException e) {
                throw new RuntimeException(e);
            }
        }

        if (!RunnerSettings.isRestEnabled()) {
            return new Object();
        }

        final RestTaskFactory.RestTask restTask = RestTaskFactory.create(getBaseUrl(), userPasswordCredentials, entityProperties, yaml);
        final RestTaskResult result = SendQueue.put(restTask);

        if (result.getException() != null) {
            final BambooSpecsPublishingException exception = translateException(entityProperties, result.getException());
            log.info(exception.getMessage());
            if (StringUtils.isNotEmpty(exception.getDebugMessage())) {
                LogUtils.hintLogLevel(log, LogLevel.DEBUG);
                log.debug(exception.getDebugMessage());
            }
            throw exception;
        } else {
            log.info("Successfully published " + entityProperties.humanReadableId());
            return result.getResult();
        }
    }

    private static String getFileName(@NotNull final RootEntityPropertiesBuilder entityProperties) {
        return String.format("%05d-%s.yaml", COUNTER.getAndIncrement(), entityProperties.humanReadableId().replaceAll(" ", "-"));
    }

    @NotNull
    private BambooSpecsPublishingException translateException(@NotNull RootEntityPropertiesBuilder entityProperties,
                                                              @NotNull Exception exception) {
        if (exception instanceof UnknownHostException) {
            return new BambooSpecsPublishingException(
                    entityProperties,
                    ErrorType.UNKNOWN_HOST,
                    String.format("Could not reach Bamboo at %s - please make sure the URL is correct and that there are no network problems", getBaseUrl()),
                    null,
                    exception);
        } else if (exception instanceof ConnectException) {
            return new BambooSpecsPublishingException(
                    entityProperties,
                    ErrorType.CONNECTION_ERROR,
                    String.format("Could not connect to Bamboo at %s - please make sure the URL is correct and that Bamboo is running", getBaseUrl()),
                    null,
                    exception);
        } else if (exception instanceof ClientProtocolException
                || exception instanceof UnsupportedSchemeException) {
            return new BambooSpecsPublishingException(
                    entityProperties,
                    ErrorType.PROTOCOL_ERROR,
                    String.format("Could not connect to Bamboo at %s - please make sure the URL is valid and that it uses HTTP(S) protocol", getBaseUrl()),
                    null,
                    exception);
        } else if (exception instanceof BambooSpecsRestRequestException) {
            return translateRestException(entityProperties, (BambooSpecsRestRequestException) exception);
        } else {
            // unknown error - throw generic exception
            return new BambooSpecsPublishingException(entityProperties, null, null, null, exception);
        }
    }

    @NotNull
    private BambooSpecsPublishingException translateRestException(@NotNull RootEntityPropertiesBuilder entityProperties,
                                                                  @NotNull BambooSpecsRestRequestException restException) {
        switch (restException.getStatusCode()) {
            case HttpStatus.SC_UNAUTHORIZED: {
                final String errorMessage = String.format(
                        "Could not authenticate user in Bamboo at %s - please make sure the credentials are correct: %s",
                        getBaseUrl(), userPasswordCredentials);
                return new BambooSpecsPublishingException(
                        entityProperties,
                        ErrorType.UNAUTHORIZED,
                        errorMessage,
                        restException.getResponseEntity(),
                        restException);
            }
            default: {
                final String errorMessage = StringUtils.defaultString(
                        restException.getMessage(),
                        String.format("Unknown response from Bamboo at %s (HTTP %d)", getBaseUrl(), restException.getStatusCode()));
                return new BambooSpecsPublishingException(
                        entityProperties,
                        null,
                        errorMessage,
                        restException.getResponseEntity(),
                        restException);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy