org.apache.hadoop.ha.HAZKUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.ha.HAZKUtil.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.hadoop.ha;

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

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;

import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.io.Files;

/**
 * Utilities for working with ZooKeeper.
 */
@InterfaceAudience.Private
public class HAZKUtil {

    /**
     * Parse ACL permission string, partially borrowed from
     * ZooKeeperMain private method
     */
    private static int getPermFromString(String permString) {
        int perm = 0;
        for (int i = 0; i < permString.length(); i++) {
            char c = permString.charAt(i);
            switch (c) {
            case 'r':
                perm |= ZooDefs.Perms.READ;
                break;
            case 'w':
                perm |= ZooDefs.Perms.WRITE;
                break;
            case 'c':
                perm |= ZooDefs.Perms.CREATE;
                break;
            case 'd':
                perm |= ZooDefs.Perms.DELETE;
                break;
            case 'a':
                perm |= ZooDefs.Perms.ADMIN;
                break;
            default:
                throw new BadAclFormatException(
                        "Invalid permission '" + c + "' in permission string '" + permString + "'");
            }
        }
        return perm;
    }

    /**
     * Parse comma separated list of ACL entries to secure generated nodes, e.g.
     * <code>sasl:hdfs/host1@MY.DOMAIN:cdrwa,sasl:hdfs/host2@MY.DOMAIN:cdrwa</code>
     *
     * @return ACL list
     * @throws HadoopIllegalArgumentException if an ACL is invalid
     */
    public static List<ACL> parseACLs(String aclString) {
        List<ACL> acl = Lists.newArrayList();
        if (aclString == null) {
            return acl;
        }

        List<String> aclComps = Lists
                .newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(aclString));
        for (String a : aclComps) {
            // from ZooKeeperMain private method
            int firstColon = a.indexOf(':');
            int lastColon = a.lastIndexOf(':');
            if (firstColon == -1 || lastColon == -1 || firstColon == lastColon) {
                throw new BadAclFormatException("ACL '" + a + "' not of expected form scheme:id:perm");
            }

            ACL newAcl = new ACL();
            newAcl.setId(new Id(a.substring(0, firstColon), a.substring(firstColon + 1, lastColon)));
            newAcl.setPerms(getPermFromString(a.substring(lastColon + 1)));
            acl.add(newAcl);
        }

        return acl;
    }

    /**
     * Parse a comma-separated list of authentication mechanisms. Each
     * such mechanism should be of the form 'scheme:auth' -- the same
     * syntax used for the 'addAuth' command in the ZK CLI.
     * 
     * @param authString the comma-separated auth mechanisms
     * @return a list of parsed authentications
     */
    public static List<ZKAuthInfo> parseAuth(String authString) {
        List<ZKAuthInfo> ret = Lists.newArrayList();
        if (authString == null) {
            return ret;
        }

        List<String> authComps = Lists
                .newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(authString));

        for (String comp : authComps) {
            String parts[] = comp.split(":", 2);
            if (parts.length != 2) {
                throw new BadAuthFormatException("Auth '" + comp + "' not of expected form scheme:auth");
            }
            ret.add(new ZKAuthInfo(parts[0], parts[1].getBytes(Charsets.UTF_8)));
        }
        return ret;
    }

    /**
     * Because ZK ACLs and authentication information may be secret,
     * allow the configuration values to be indirected through a file
     * by specifying the configuration as "@/path/to/file". If this
     * syntax is used, this function will return the contents of the file
     * as a String.
     * 
     * @param valInConf the value from the Configuration 
     * @return either the same value, or the contents of the referenced
     * file if the configured value starts with "@"
     * @throws IOException if the file cannot be read
     */
    public static String resolveConfIndirection(String valInConf) throws IOException {
        if (valInConf == null)
            return null;
        if (!valInConf.startsWith("@")) {
            return valInConf;
        }
        String path = valInConf.substring(1).trim();
        return Files.toString(new File(path), Charsets.UTF_8).trim();
    }

    /**
     * An authentication token passed to ZooKeeper.addAuthInfo
     */
    static class ZKAuthInfo {
        private final String scheme;
        private final byte[] auth;

        public ZKAuthInfo(String scheme, byte[] auth) {
            super();
            this.scheme = scheme;
            this.auth = auth;
        }

        String getScheme() {
            return scheme;
        }

        byte[] getAuth() {
            return auth;
        }
    }

    static class BadAclFormatException extends HadoopIllegalArgumentException {
        private static final long serialVersionUID = 1L;

        public BadAclFormatException(String message) {
            super(message);
        }
    }

    static class BadAuthFormatException extends HadoopIllegalArgumentException {
        private static final long serialVersionUID = 1L;

        public BadAuthFormatException(String message) {
            super(message);
        }
    }

}