org.apache.hoya.core.build.InstanceBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hoya.core.build.InstanceBuilder.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.hoya.core.build;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hoya.HoyaXmlConfKeys;
import org.apache.hoya.api.OptionKeys;
import org.apache.hoya.api.StatusKeys;
import org.apache.hoya.core.conf.AggregateConf;
import org.apache.hoya.core.conf.ConfTreeOperations;
import org.apache.hoya.core.conf.MapOperations;
import org.apache.hoya.core.persist.ConfPersister;
import org.apache.hoya.core.persist.InstancePaths;
import org.apache.hoya.core.persist.LockAcquireFailedException;
import org.apache.hoya.core.persist.LockHeldAction;
import org.apache.hoya.exceptions.BadClusterStateException;
import org.apache.hoya.exceptions.BadConfigException;
import org.apache.hoya.exceptions.ErrorStrings;
import org.apache.hoya.exceptions.HoyaException;
import org.apache.hoya.tools.CoreFileSystem;
import org.apache.hoya.tools.HoyaUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Map;

import static org.apache.hoya.api.OptionKeys.*;

/**
 * Build up the instance of a cluster.
 */
public class InstanceBuilder {

    private final String clustername;
    private final Configuration conf;
    private final CoreFileSystem coreFS;
    private final InstancePaths instancePaths;
    private AggregateConf instanceDescription;

    private static final Logger log = LoggerFactory.getLogger(InstanceBuilder.class);

    public InstanceBuilder(CoreFileSystem coreFileSystem, Configuration conf, String clustername) {
        this.clustername = clustername;
        this.conf = conf;
        this.coreFS = coreFileSystem;
        Path instanceDir = coreFileSystem.buildHoyaClusterDirPath(clustername);
        instancePaths = new InstancePaths(instanceDir);

    }

    public AggregateConf getInstanceDescription() {
        return instanceDescription;
    }

    public InstancePaths getInstancePaths() {
        return instancePaths;
    }

    @Override
    public String toString() {
        return "Builder working with " + clustername + " at " + getInstanceDir();
    }

    private Path getInstanceDir() {
        return instancePaths.instanceDir;
    }

    /**
     * Initial part of the build process
     * @param configSrcDir
     * @param provider
     */
    public void init(Path configSrcDir, String provider, AggregateConf instanceConf) {

        this.instanceDescription = instanceConf;

        //internal is extended
        ConfTreeOperations internalOps = instanceConf.getInternalOperations();

        Map<String, Object> md = internalOps.getConfTree().metadata;
        long time = System.currentTimeMillis();
        md.put(StatusKeys.INFO_CREATE_TIME_HUMAN, HoyaUtils.toGMTString(time));
        md.put(StatusKeys.INFO_CREATE_TIME_MILLIS, Long.toString(time));

        MapOperations globalOptions = internalOps.getGlobalOptions();
        BuildHelper.addBuildMetadata(md, "create");
        HoyaUtils.setInfoTime(md, StatusKeys.INFO_CREATE_TIME_HUMAN, StatusKeys.INFO_CREATE_TIME_MILLIS,
                System.currentTimeMillis());

        internalOps.set(INTERNAL_AM_TMP_DIR, instancePaths.tmpPathAM.toUri());
        internalOps.set(INTERNAL_SNAPSHOT_CONF_PATH, instancePaths.snapshotConfPath.toUri());
        internalOps.set(INTERNAL_GENERATED_CONF_PATH, instancePaths.generatedConfPath.toUri());
        internalOps.set(INTERNAL_DATA_DIR_PATH, instancePaths.dataPath.toUri());

        internalOps.set(OptionKeys.INTERNAL_PROVIDER_NAME, provider);
        internalOps.set(OptionKeys.APPLICATION_NAME, clustername);

    }

    /**
     * Set up the image/app home path
     * @param appImage path in the DFS to the tar file
     * @param appHomeDir other strategy: home dir
     * @throws BadConfigException if both or neither are found (its an xor)
     */
    public void setImageDetails(Path appImage, String appHomeDir) throws BadConfigException {
        boolean appHomeUnset = HoyaUtils.isUnset(appHomeDir);
        // App home or image
        if (appImage != null) {
            if (!appHomeUnset) {
                // both args have been set
                throw new BadConfigException(ErrorStrings.E_BOTH_IMAGE_AND_HOME_DIR_SPECIFIED);
            }
            instanceDescription.getInternalOperations().set(INTERNAL_APPLICATION_IMAGE_PATH, appImage.toUri());
        } else {
            // the alternative is app home, which now MUST be set
            if (appHomeUnset) {
                // both args have been set
                throw new BadConfigException(ErrorStrings.E_NO_IMAGE_OR_HOME_DIR_SPECIFIED);

            }
            instanceDescription.getInternalOperations().set(INTERNAL_APPLICATION_HOME, appHomeDir);

        }
    }

    /**
     * Propagate any critical principals from the current site config down to the HBase one.
     */
    public void propagatePrincipals() {
        String dfsPrincipal = conf.get(DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY);
        if (dfsPrincipal != null) {
            String siteDfsPrincipal = OptionKeys.SITE_XML_PREFIX + DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY;
            instanceDescription.getAppConfOperations().set(siteDfsPrincipal, dfsPrincipal);
        }
    }

    public void propagateFilename() {
        String fsDefaultName = conf.get(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY);
        instanceDescription.getAppConfOperations()
                .set(OptionKeys.SITE_XML_PREFIX + CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY, fsDefaultName);

        instanceDescription.getAppConfOperations()
                .set(OptionKeys.SITE_XML_PREFIX + HoyaXmlConfKeys.FS_DEFAULT_NAME_CLASSIC, fsDefaultName);

    }

    public void takeSnapshotOfConfDir(Path appconfdir)
            throws IOException, BadConfigException, BadClusterStateException {
        FileSystem srcFS = FileSystem.get(appconfdir.toUri(), conf);
        if (!srcFS.isDirectory(appconfdir)) {
            throw new BadConfigException("Source Configuration directory is not valid: %s", appconfdir.toString());
        }
        // bulk copy
        FsPermission clusterPerms = coreFS.getInstanceDirectoryPermissions();
        // first the original from wherever to the DFS
        HoyaUtils.copyDirectory(conf, appconfdir, instancePaths.snapshotConfPath, clusterPerms);
    }

    /**
     * Persist this
     * @throws IOException
     * @throws HoyaException
     * @throws LockAcquireFailedException
     * @param appconfdir
     */
    public void persist(Path appconfdir) throws IOException, HoyaException, LockAcquireFailedException {
        coreFS.createClusterDirectories(instancePaths);
        ConfPersister persister = new ConfPersister(coreFS, getInstanceDir());
        ConfDirSnapshotAction action = null;
        if (appconfdir != null) {
            action = new ConfDirSnapshotAction(appconfdir);
        }
        persister.save(instanceDescription, action);
    }

    /**
     * Add the ZK paths to the application options. 
     * This is skipped if the zkhosts are not set
     * @param zkhosts
     * @param zookeeperRoot
     * @param zkport
     */
    public void addZKPaths(String zkhosts, String zookeeperRoot, int zkport) {
        if (HoyaUtils.isSet(zkhosts)) {
            MapOperations globalAppOptions = instanceDescription.getAppConfOperations().getGlobalOptions();
            globalAppOptions.put(ZOOKEEPER_PATH, zookeeperRoot);
            globalAppOptions.put(ZOOKEEPER_HOSTS, zkhosts);
            globalAppOptions.put(ZOOKEEPER_PORT, Integer.toString(zkport));
        }
    }

    /**
     * Class to execute the snapshotting of the configuration directory
     * while the persistence lock is held. 
     * 
     * This guarantees that there won't be an attempt to launch a cluster
     * until the snapshot is complete -as the write lock won't be released
     * until afterwards.
     */
    private class ConfDirSnapshotAction implements LockHeldAction {

        private final Path appconfdir;

        private ConfDirSnapshotAction(Path appconfdir) {
            this.appconfdir = appconfdir;
        }

        @Override
        public void execute() throws IOException, HoyaException {

            takeSnapshotOfConfDir(appconfdir);
        }
    }

}