hadoop CompositeGroupsMapping 源码

  • 2022-10-20
  • 浏览 (395)

haddop CompositeGroupsMapping 代码

文件路径:/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/CompositeGroupsMapping.java

/**
 * 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.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.util.ReflectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An implementation of {@link GroupMappingServiceProvider} which
 * composites other group mapping providers for determining group membership.
 * This allows to combine existing provider implementations and composite 
 * a virtually new provider without customized development to deal with complex situation. 
 */
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Evolving
public class CompositeGroupsMapping
    implements GroupMappingServiceProvider, Configurable {
  
  public static final String MAPPING_PROVIDERS_CONFIG_KEY = GROUP_MAPPING_CONFIG_PREFIX + ".providers";
  public static final String MAPPING_PROVIDERS_COMBINED_CONFIG_KEY = MAPPING_PROVIDERS_CONFIG_KEY + ".combined";
  public static final String MAPPING_PROVIDER_CONFIG_PREFIX = GROUP_MAPPING_CONFIG_PREFIX + ".provider";
  
  private static final Logger LOG =
      LoggerFactory.getLogger(CompositeGroupsMapping.class);

  private List<GroupMappingServiceProvider> providersList = 
		  new ArrayList<GroupMappingServiceProvider>();
  
  private Configuration conf;
  private boolean combined;



  /**
   * Returns list of groups for a user.
   * 
   * @param user get groups for this user
   * @return list of groups for a given user
   */
  @Override
  public synchronized List<String> getGroups(String user) throws IOException {
    Set<String> groupSet = new TreeSet<String>();

    for (GroupMappingServiceProvider provider : providersList) {
      List<String> groups = Collections.emptyList();
      try {
        groups = provider.getGroups(user);
      } catch (Exception e) {
        LOG.warn("Unable to get groups for user {} via {} because: {}",
            user, provider.getClass().getSimpleName(), e.toString());
        LOG.debug("Stacktrace: ", e);
      }        
      if (!groups.isEmpty()) {
        groupSet.addAll(groups);
        if (!combined) break;
      }
    }

    return new ArrayList<>(groupSet);
  }

  /**
   * Caches groups, no need to do that for this provider
   */
  @Override
  public void cacheGroupsRefresh() throws IOException {
    // does nothing in this provider of user to groups mapping
  }

  /** 
   * Adds groups to cache, no need to do that for this provider
   *
   * @param groups unused
   */
  @Override
  public void cacheGroupsAdd(List<String> groups) throws IOException {
    // does nothing in this provider of user to groups mapping
  }

  @Override
  public synchronized Set<String> getGroupsSet(String user) throws IOException {
    Set<String> groupSet = new HashSet<>();

    Set<String> groups = null;
    for (GroupMappingServiceProvider provider : providersList) {
      try {
        groups = provider.getGroupsSet(user);
      } catch (Exception e) {
        LOG.warn("Unable to get groups for user {} via {} because: {}",
            user, provider.getClass().getSimpleName(), e.toString());
        LOG.debug("Stacktrace: ", e);
      }
      if (groups != null && !groups.isEmpty()) {
        groupSet.addAll(groups);
        if (!combined) {
          break;
        }
      }
    }
    return groupSet;
  }

  @Override
  public synchronized Configuration getConf() {
    return conf;
  }

  @Override
  public synchronized void setConf(Configuration conf) {
    this.conf = conf;
    
    this.combined = conf.getBoolean(MAPPING_PROVIDERS_COMBINED_CONFIG_KEY, true);
    
    loadMappingProviders();
  }
  
  private void loadMappingProviders() {
    String[] providerNames = conf.getStrings(MAPPING_PROVIDERS_CONFIG_KEY, new String[]{});

    String providerKey;
    for (String name : providerNames) {
      providerKey = MAPPING_PROVIDER_CONFIG_PREFIX + "." + name;
      Class<?> providerClass = conf.getClass(providerKey, null);
      if (providerClass == null) {
        LOG.error("The mapping provider, " + name + " does not have a valid class");
      } else {
        addMappingProvider(name, providerClass);
      }
    }
  }
    
  private void addMappingProvider(String providerName, Class<?> providerClass) {
    Configuration newConf = prepareConf(providerName);
    GroupMappingServiceProvider provider = 
        (GroupMappingServiceProvider) ReflectionUtils.newInstance(providerClass, newConf);
    providersList.add(provider);

  }

  /*
   * For any provider specific configuration properties, such as "hadoop.security.group.mapping.ldap.url" 
   * and the like, allow them to be configured as "hadoop.security.group.mapping.provider.PROVIDER-X.ldap.url",
   * so that a provider such as LdapGroupsMapping can be used to composite a complex one with other providers.
   */
  private Configuration prepareConf(String providerName) {
    Configuration newConf = new Configuration();
    Iterator<Map.Entry<String, String>> entries = conf.iterator();
    String providerKey = MAPPING_PROVIDER_CONFIG_PREFIX + "." + providerName;
    while (entries.hasNext()) {
      Map.Entry<String, String> entry = entries.next();
      String key = entry.getKey();
      // get a property like "hadoop.security.group.mapping.provider.PROVIDER-X.ldap.url"
      if (key.startsWith(providerKey) && !key.equals(providerKey)) {
        // restore to be the one like "hadoop.security.group.mapping.ldap.url" 
        // so that can be used by original provider.
        key = key.replace(".provider." + providerName, "");
        newConf.set(key, entry.getValue());
      }
    }
    return newConf;
  }  
}

相关信息

hadoop 源码目录

相关文章

hadoop AccessControlException 源码

hadoop AnnotatedSecurityInfo 源码

hadoop AuthenticationFilterInitializer 源码

hadoop Credentials 源码

hadoop FastSaslClientFactory 源码

hadoop FastSaslServerFactory 源码

hadoop GroupMappingServiceProvider 源码

hadoop Groups 源码

hadoop HadoopKerberosName 源码

hadoop HttpCrossOriginFilterInitializer 源码

0  赞