org.apache.oozie.action.hadoop.GitMain.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.oozie.action.hadoop.GitMain.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.oozie.action.hadoop;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.attribute.PosixFilePermissions;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.oozie.action.hadoop.GitOperations.GitOperationsException;

import com.google.common.annotations.VisibleForTesting;

public class GitMain extends LauncherMain {

    private static final String OOZIE_ACTION_CONF = "oozie.action.conf.xml";

    private String nameNode;
    private String keyPath;
    private String destinationUri;
    private String gitUri;
    private String gitBranch;

    public static void main(final String[] args) throws Exception {
        run(GitMain.class, args);
    }

    @VisibleForTesting
    void setNameNode(final String nameNode) {
        this.nameNode = nameNode;
    }

    @Override
    protected void run(final String[] args) throws Exception {
        System.out.println("=============================================");
        System.out.println("Oozie Git Action Configuration");
        System.out.println("=============================================");

        final Configuration actionConf = prepareActionConf();
        parseActionConfiguration(actionConf);
        final File localKey = getLocalKeyFile();
        final GitOperations gitRepo = new GitOperations(new URI(gitUri), gitBranch, localKey);

        try {
            gitRepo.cloneRepoToFS(new Path(destinationUri));
        } catch (final IOException | GitOperationsException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }

    @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "File created without user input")
    private Configuration prepareActionConf() {
        final Configuration actionConf = new Configuration(false);

        final String actionXml = System.getProperty(OOZIE_ACTION_CONF);
        if (actionXml == null) {
            throw new RuntimeException("Missing Java System Property [" + OOZIE_ACTION_CONF + "]");
        }
        if (!new File(actionXml).exists()) {
            throw new RuntimeException("Action Configuration XML file [" + actionXml + "] does not exist");
        }

        actionConf.addResource(new Path("file:///", actionXml));
        return actionConf;
    }

    private File getLocalKeyFile() throws IOException, URISyntaxException {
        File localKey = null;

        if (keyPath != null) {
            localKey = getKeyFromFS(new Path(keyPath));
        }

        return localKey;
    }

    /**
     * Gathers the Git authentication key from a FileSystem and copies it to a local
     * filesystem location
     *
     * @param location where the key is located (an HDFS URI)
     * @return the location to where the key was saved
     */
    @VisibleForTesting
    @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "File created without user input")
    File getKeyFromFS(final Path location) throws IOException, URISyntaxException {
        final String keyCopyMsg = "Copied keys to local container!";

        final Configuration conf = new Configuration();
        final FileSystem fs = FileSystem.newInstance(new URI(nameNode), conf);

        final File key = createTempDir("git");

        fs.copyToLocalFile(location, new Path("file:///" + key.getAbsolutePath() + "/privkey"));
        System.out.println(keyCopyMsg);

        return new File(key.getAbsolutePath() + "/privkey");
    }

    /**
     * Create a local temporary directory
     *
     * @param prefix string to use as a prefix to the directory
     * @return file path of temp. directory (will be set to delete on exit)
     */
    @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "File created without user input")
    static File createTempDir(final String prefix) throws IOException {
        final File tempDir = new File(Files
                .createTempDirectory(Paths.get("."), prefix + "_" + Long.toString(System.nanoTime()),
                        PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------")))
                .toString());
        tempDir.deleteOnExit();

        final String localMkdirMsg = "Local mkdir called creating temp. dir at: " + tempDir.getAbsolutePath();
        System.out.println(localMkdirMsg);

        return tempDir;
    }

    /**
     * Validate a URI is well formed and has a scheme
     *
     * @param testUri URI string to test
     * @return URI from string
     * @throws OozieActionConfiguratorException if the <code>testUri</code> fails any validity checks
     */
    private URI isValidUri(final String testUri) throws OozieActionConfiguratorException {
        final URI uri;
        try {
            uri = new URI(testUri);
        } catch (final URISyntaxException e) {
            throw new OozieActionConfiguratorException("Action Configuration does not have " + "a proper URI: "
                    + testUri + " exception " + e.toString());
        }
        if (uri.getScheme() == null) {
            throw new OozieActionConfiguratorException(
                    "Action Configuration does not have " + "a proper URI " + testUri + " null scheme.");
        }
        return uri;
    }

    /**
     * Calls helper function to verify name not null and throw an exception if so.
     * Otherwise, returns actionConf value
     * @param name - actionConf value to return
     */
    String checkAndGetTrimmed(final Configuration actionConf, String name) {
        Objects.requireNonNull(actionConf.getTrimmed(name),
                () -> String.format("Action Configuration does not have [%s] property", name));
        return actionConf.getTrimmed(name);
    }

    /**
     * Parse action configuration and set configuration variables
     *
     * @param actionConf Oozie action configuration
     * @throws OozieActionConfiguratorException upon any required properties missing
     */
    private void parseActionConfiguration(final Configuration actionConf) throws OozieActionConfiguratorException {

        nameNode = checkAndGetTrimmed(actionConf, GitActionExecutor.NAME_NODE);
        destinationUri = checkAndGetTrimmed(actionConf, GitActionExecutor.DESTINATION_URI);
        try {
            final FileSystem fs = FileSystem.get(isValidUri(destinationUri), actionConf);
            destinationUri = fs.makeQualified(new Path(destinationUri)).toString();
        } catch (final IOException e) {
            throw new OozieActionConfiguratorException(
                    "Action Configuration does not have " + "a valid filesystem for URI "
                            + GitActionExecutor.DESTINATION_URI + "exception " + e.toString());
        }
        gitUri = isValidUri(checkAndGetTrimmed(actionConf, GitActionExecutor.GIT_URI)).toString();
        gitBranch = actionConf.get(GitActionExecutor.GIT_BRANCH);
        keyPath = actionConf.get(GitActionExecutor.KEY_PATH);
    }
}