com.shazam.dataengineering.pipelinebuilder.PipelineBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.shazam.dataengineering.pipelinebuilder.PipelineBuilder.java

Source

/*
 * Copyright 2015 Shazam Entertainment Limited
 *
 * 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 com.shazam.dataengineering.pipelinebuilder;

import com.amazonaws.auth.BasicAWSCredentials;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.security.Permission;
import hudson.security.PermissionGroup;
import hudson.security.PermissionScope;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import hudson.util.FormValidation;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class PipelineBuilder extends Builder {
    public static final PermissionGroup PERMISSIONS = new PermissionGroup(PipelineBuilder.class,
            Messages._PipelineBuilder_PermissionsTitle());
    /**
     * Permission to trigger pipeline deploys.
     */
    public static final Permission DEPLOY_PERMISSION = new Permission(PERMISSIONS, "Deploy",
            Messages._PipelineBuilder_DeployPermission_Description(), null, PermissionScope.ITEM);
    private static ProductionEnvironment productionEnvironment = new ProductionEnvironment("Production");
    private static DevelopmentEnvironment developmentEnvironment = new DevelopmentEnvironment("Development");
    private Environment[] configParams;
    private String file;
    private String s3Prefix;

    // Fields in config.jelly must match the parameter names in the "DataBoundConstructor"
    @DataBoundConstructor
    public PipelineBuilder(String filePath, String s3Prefix, Environment[] environment) {
        this.configParams = environment;
        this.file = filePath;
        setS3Prefix(s3Prefix);
    }

    @Override
    public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener)
            throws IOException, InterruptedException {
        FilePath ws = build.getWorkspace();
        FilePath input = ws.child(file);

        PipelineProcessor processor = new PipelineProcessor(build, launcher, listener);
        if (configParams.length > 0) {
            processor.setEnvironments(configParams);
        } else {
            listener.getLogger().println("[WARN] No environments for AWS Data pipeline defined, skipping");
            return true;
        }
        processor.setS3Prefix(s3Prefix);

        boolean result = processor.process(input);
        if (result) {
            build.addAction(new DeploymentAction(build, processor.getS3Urls(),
                    new BasicAWSCredentials(getDescriptor().getAccessId(), getDescriptor().getSecretKey())));
        }

        return result;
    }

    /**
     * We'll use this from the <tt>config.jelly</tt>.
     */
    public Environment[] getConfigParams() {
        return configParams;
    }

    public String getFilePath() {
        return file;
    }

    public String getDisplayName() {
        return "AWS Data Pipeline";
    }

    public List<Environment> getEnvironmentList() {
        ArrayList<Environment> env = new ArrayList<Environment>();
        if (configParams != null) {
            for (Environment environment : configParams) {
                env.add(environment);
            }
        }
        return env;
    }

    public String getS3Prefix() {
        return s3Prefix;
    }

    public void setS3Prefix(String s3Prefix) {
        if (s3Prefix.endsWith("/")) {
            this.s3Prefix = s3Prefix;
        } else {
            this.s3Prefix = s3Prefix + "/";
        }
    }

    @Override
    public DescriptorImpl getDescriptor() {
        return (DescriptorImpl) super.getDescriptor();
    }

    /**
     * Descriptor for {@link PipelineBuilder}. Used as a singleton.
     * The class is marked as public so that it can be accessed from views.
     * <p/>
     */
    @Extension // This indicates to Jenkins that this is an implementation of an extension point.
    public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
        /**
         * To persist global configuration information,
         * simply store it in a field and call save().
         * <p/>
         * <p/>
         * If you don't want fields to be persisted, use <tt>transient</tt>.
         */
        public String accessId;
        public String secretKey;

        /**
         * In order to load the persisted global configuration, you have to
         * call load() in the constructor.
         */
        public DescriptorImpl() {
            load();
        }

        /**
         * Populates the "Add configuration" button with choices for environments
         *
         * @param project Instance
         * @return
         */
        public static List<Descriptor<Environment>> getEnvironmentDescriptions(AbstractProject<?, ?> project) {
            ArrayList<Descriptor<Environment>> descriptors = new ArrayList<Descriptor<Environment>>();
            descriptors.add(productionEnvironment.getDescriptor());
            descriptors.add(developmentEnvironment.getDescriptor());
            return descriptors;
        }

        public boolean isApplicable(Class<? extends AbstractProject> aClass) {
            // Indicates that this builder can be used with all kinds of project types
            return true;
        }

        public FormValidation doCheckS3Prefix(@QueryParameter String value) {
            if (!value.isEmpty() && !value.matches("^s3://([^/]+)/(.*)")) {
                return FormValidation.error("URL must be in the form \"s3://bucket/key/\"");
            } else {
                return FormValidation.ok();
            }
        }

        /**
         * This human readable name is used in the configuration screen.
         */
        public String getDisplayName() {
            return "AWS Data Pipeline";
        }

        @Override
        public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
            accessId = formData.getString("accessId");
            secretKey = formData.getString("secretKey");

            save();
            return super.configure(req, formData);
        }

        public String getAccessId() {
            return accessId;
        }

        public String getSecretKey() {
            return secretKey;
        }
    }
}