You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by to...@apache.org on 2011/05/11 03:03:32 UTC
svn commit: r1101714 - in /hadoop/common/trunk: ./
src/java/org/apache/hadoop/tools/ src/test/core/org/apache/hadoop/tools/
Author: todd
Date: Wed May 11 01:03:31 2011
New Revision: 1101714
URL: http://svn.apache.org/viewvc?rev=1101714&view=rev
Log:
HADOOP-7214. Add Common functionality necessary to provide an equivalent of /usr/bin/groups for Hadoop. Contributed by Aaron T. Myers.
Added:
hadoop/common/trunk/src/java/org/apache/hadoop/tools/
hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetGroupsBase.java
hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetUserMappingsProtocol.java
hadoop/common/trunk/src/test/core/org/apache/hadoop/tools/
hadoop/common/trunk/src/test/core/org/apache/hadoop/tools/GetGroupsTestBase.java
Modified:
hadoop/common/trunk/CHANGES.txt
Modified: hadoop/common/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/CHANGES.txt?rev=1101714&r1=1101713&r2=1101714&view=diff
==============================================================================
--- hadoop/common/trunk/CHANGES.txt (original)
+++ hadoop/common/trunk/CHANGES.txt Wed May 11 01:03:31 2011
@@ -29,6 +29,8 @@ Trunk (unreleased changes)
HADOOP-6920. Metrics instrumentation to move new metrics2 framework.
(Luke Lu via suresh)
+ HADOOP-7214. Add Common functionality necessary to provide an equivalent
+ of /usr/bin/groups for Hadoop. (Aaron T. Myers via todd)
IMPROVEMENTS
Added: hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetGroupsBase.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetGroupsBase.java?rev=1101714&view=auto
==============================================================================
--- hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetGroupsBase.java (added)
+++ hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetGroupsBase.java Wed May 11 01:03:31 2011
@@ -0,0 +1,107 @@
+/**
+ * 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.tools;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.InetSocketAddress;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.ipc.RPC;
+import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.util.Tool;
+
+/**
+ * Base class for the HDFS and MR implementations of tools which fetch and
+ * display the groups that users belong to.
+ */
+public abstract class GetGroupsBase extends Configured implements Tool {
+
+ private PrintStream out;
+
+ /**
+ * Create an instance of this tool using the given configuration.
+ * @param conf
+ */
+ protected GetGroupsBase(Configuration conf) {
+ this(conf, System.out);
+ }
+
+ /**
+ * Used exclusively for testing.
+ *
+ * @param conf The configuration to use.
+ * @param out The PrintStream to write to, instead of System.out
+ */
+ protected GetGroupsBase(Configuration conf, PrintStream out) {
+ super(conf);
+ this.out = out;
+ }
+
+ /**
+ * Get the groups for the users given and print formatted output to the
+ * {@link PrintStream} configured earlier.
+ */
+ @Override
+ public int run(String[] args) throws Exception {
+ if (args.length == 0) {
+ args = new String[] { UserGroupInformation.getCurrentUser().getUserName() };
+ }
+
+ for (String username : args) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(username + " :");
+ for (String group : getUgmProtocol().getGroupsForUser(username)) {
+ sb.append(" ");
+ sb.append(group);
+ }
+ out.println(sb);
+ }
+
+ return 0;
+ }
+
+ /**
+ * Must be overridden by subclasses to get the address where the
+ * {@link GetUserMappingsProtocol} implementation is running.
+ *
+ * @param conf The configuration to use.
+ * @return The address where the service is listening.
+ * @throws IOException
+ */
+ protected abstract InetSocketAddress getProtocolAddress(Configuration conf)
+ throws IOException;
+
+ /**
+ * Get a client of the {@link GetUserMappingsProtocol}.
+ * @return A {@link GetUserMappingsProtocol} client proxy.
+ * @throws IOException
+ */
+ private GetUserMappingsProtocol getUgmProtocol() throws IOException {
+ GetUserMappingsProtocol userGroupMappingProtocol =
+ RPC.getProxy(GetUserMappingsProtocol.class,
+ GetUserMappingsProtocol.versionID,
+ getProtocolAddress(getConf()), UserGroupInformation.getCurrentUser(),
+ getConf(), NetUtils.getSocketFactory(getConf(),
+ GetUserMappingsProtocol.class));
+ return userGroupMappingProtocol;
+ }
+
+}
Added: hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetUserMappingsProtocol.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetUserMappingsProtocol.java?rev=1101714&view=auto
==============================================================================
--- hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetUserMappingsProtocol.java (added)
+++ hadoop/common/trunk/src/java/org/apache/hadoop/tools/GetUserMappingsProtocol.java Wed May 11 01:03:31 2011
@@ -0,0 +1,46 @@
+/**
+ * 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.tools;
+
+import java.io.IOException;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.ipc.VersionedProtocol;
+
+/**
+ * Protocol implemented by the Name Node and Job Tracker which maps users to
+ * groups.
+ */
+@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
+@InterfaceStability.Evolving
+public interface GetUserMappingsProtocol extends VersionedProtocol {
+
+ /**
+ * Version 1: Initial version.
+ */
+ public static final long versionID = 1L;
+
+ /**
+ * Get the groups which are mapped to the given user.
+ * @param user The user to get the groups for.
+ * @return The set of groups the user belongs to.
+ * @throws IOException
+ */
+ public String[] getGroupsForUser(String user) throws IOException;
+}
Added: hadoop/common/trunk/src/test/core/org/apache/hadoop/tools/GetGroupsTestBase.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/test/core/org/apache/hadoop/tools/GetGroupsTestBase.java?rev=1101714&view=auto
==============================================================================
--- hadoop/common/trunk/src/test/core/org/apache/hadoop/tools/GetGroupsTestBase.java (added)
+++ hadoop/common/trunk/src/test/core/org/apache/hadoop/tools/GetGroupsTestBase.java Wed May 11 01:03:31 2011
@@ -0,0 +1,127 @@
+/**
+ * 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.tools;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Before;
+import org.junit.Test;
+
+public abstract class GetGroupsTestBase {
+
+ protected Configuration conf;
+ private UserGroupInformation testUser1;
+ private UserGroupInformation testUser2;
+
+ protected abstract Tool getTool(PrintStream o);
+
+ @Before
+ public void setUpUsers() throws IOException {
+ // Make sure the current user's info is in the list of test users.
+ UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
+ UserGroupInformation.createUserForTesting(currentUser.getUserName(), currentUser.getGroupNames());
+
+ testUser1 = UserGroupInformation.createUserForTesting("foo", new String[]{"bar", "baz"});
+ testUser2 = UserGroupInformation.createUserForTesting("fiz", new String[]{"buz", "boz"});
+ }
+
+ @Test
+ public void testNoUserGiven() throws Exception {
+ String actualOutput = runTool(conf, new String[0], true);
+ UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
+ assertEquals("No user provided should default to current user",
+ getExpectedOutput(currentUser), actualOutput);
+ }
+
+ @Test
+ public void testExistingUser() throws Exception {
+ String actualOutput = runTool(conf, new String[]{testUser1.getUserName()}, true);
+ assertEquals("Show only the output of the user given",
+ getExpectedOutput(testUser1), actualOutput);
+ }
+
+ @Test
+ public void testMultipleExistingUsers() throws Exception {
+ String actualOutput = runTool(conf,
+ new String[]{testUser1.getUserName(), testUser2.getUserName()}, true);
+ assertEquals("Show the output for both users given",
+ getExpectedOutput(testUser1) + getExpectedOutput(testUser2), actualOutput);
+ }
+
+ @Test
+ public void testNonExistentUser() throws Exception {
+ String actualOutput = runTool(conf,
+ new String[]{"does-not-exist"}, true);
+ assertEquals("Show the output for only the user given, with no groups",
+ getExpectedOutput(UserGroupInformation.createRemoteUser("does-not-exist")),
+ actualOutput);
+ }
+
+ @Test
+ public void testMultipleNonExistingUsers() throws Exception {
+ String actualOutput = runTool(conf,
+ new String[]{"does-not-exist1", "does-not-exist2"}, true);
+ assertEquals("Show the output for only the user given, with no groups",
+ getExpectedOutput(UserGroupInformation.createRemoteUser("does-not-exist1")) +
+ getExpectedOutput(UserGroupInformation.createRemoteUser("does-not-exist2")),
+ actualOutput);
+ }
+
+ @Test
+ public void testExistingInterleavedWithNonExistentUsers() throws Exception {
+ String actualOutput = runTool(conf,
+ new String[]{"does-not-exist1", testUser1.getUserName(),
+ "does-not-exist2", testUser2.getUserName()}, true);
+ assertEquals("Show the output for only the user given, with no groups",
+ getExpectedOutput(UserGroupInformation.createRemoteUser("does-not-exist1")) +
+ getExpectedOutput(testUser1) +
+ getExpectedOutput(UserGroupInformation.createRemoteUser("does-not-exist2")) +
+ getExpectedOutput(testUser2),
+ actualOutput);
+ }
+
+ private static String getExpectedOutput(UserGroupInformation user) {
+ String expectedOutput = user.getUserName() + " :";
+ for (String group : user.getGroupNames()) {
+ expectedOutput += " " + group;
+ }
+ return expectedOutput + "\n";
+ }
+
+ private String runTool(Configuration conf, String[] args, boolean success)
+ throws Exception {
+ ByteArrayOutputStream o = new ByteArrayOutputStream();
+ PrintStream out = new PrintStream(o, true);
+ try {
+ int ret = ToolRunner.run(getTool(out), args);
+ assertEquals(success, ret == 0);
+ return o.toString();
+ } finally {
+ o.close();
+ out.close();
+ }
+ }
+}