001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.tools; 019 020import java.io.IOException; 021import java.io.PrintStream; 022import java.net.InetSocketAddress; 023 024import org.apache.hadoop.conf.Configuration; 025import org.apache.hadoop.conf.Configured; 026import org.apache.hadoop.ipc.RPC; 027import org.apache.hadoop.net.NetUtils; 028import org.apache.hadoop.security.UserGroupInformation; 029import org.apache.hadoop.util.Tool; 030 031/** 032 * Base class for the HDFS and MR implementations of tools which fetch and 033 * display the groups that users belong to. 034 */ 035public abstract class GetGroupsBase extends Configured implements Tool { 036 037 private PrintStream out; 038 039 /** 040 * Create an instance of this tool using the given configuration. 041 * @param conf 042 */ 043 protected GetGroupsBase(Configuration conf) { 044 this(conf, System.out); 045 } 046 047 /** 048 * Used exclusively for testing. 049 * 050 * @param conf The configuration to use. 051 * @param out The PrintStream to write to, instead of System.out 052 */ 053 protected GetGroupsBase(Configuration conf, PrintStream out) { 054 super(conf); 055 this.out = out; 056 } 057 058 /** 059 * Get the groups for the users given and print formatted output to the 060 * {@link PrintStream} configured earlier. 061 */ 062 @Override 063 public int run(String[] args) throws Exception { 064 if (args.length == 0) { 065 args = new String[] { UserGroupInformation.getCurrentUser().getUserName() }; 066 } 067 068 for (String username : args) { 069 StringBuilder sb = new StringBuilder(); 070 sb.append(username + " :"); 071 for (String group : getUgmProtocol().getGroupsForUser(username)) { 072 sb.append(" "); 073 sb.append(group); 074 } 075 out.println(sb); 076 } 077 078 return 0; 079 } 080 081 /** 082 * Must be overridden by subclasses to get the address where the 083 * {@link GetUserMappingsProtocol} implementation is running. 084 * 085 * @param conf The configuration to use. 086 * @return The address where the service is listening. 087 * @throws IOException 088 */ 089 protected abstract InetSocketAddress getProtocolAddress(Configuration conf) 090 throws IOException; 091 092 /** 093 * Get a client of the {@link GetUserMappingsProtocol}. 094 * @return A {@link GetUserMappingsProtocol} client proxy. 095 * @throws IOException 096 */ 097 protected GetUserMappingsProtocol getUgmProtocol() throws IOException { 098 GetUserMappingsProtocol userGroupMappingProtocol = 099 RPC.getProxy(GetUserMappingsProtocol.class, 100 GetUserMappingsProtocol.versionID, 101 getProtocolAddress(getConf()), UserGroupInformation.getCurrentUser(), 102 getConf(), NetUtils.getSocketFactory(getConf(), 103 GetUserMappingsProtocol.class)); 104 return userGroupMappingProtocol; 105 } 106 107}