Explorar o código

MAPREDUCE-3053. Better diagnostic message for unknown methods in ProtoBuf RPCs. Contributed by Vinod K V.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1175357 13f79535-47bb-0310-9956-ffa450edef68
Arun Murthy %!s(int64=13) %!d(string=hai) anos
pai
achega
c285cf3114

+ 3 - 0
hadoop-mapreduce-project/CHANGES.txt

@@ -1412,6 +1412,9 @@ Release 0.23.0 - Unreleased
     MAPREDUCE-2990. Fixed display of NodeHealthStatus. (Subroto Sanyal via
     acmurthy) 
 
+    MAPREDUCE-3053. Better diagnostic message for unknown methods in ProtoBuf
+    RPCs. (vinodkv via acmurthy)
+
 Release 0.22.0 - Unreleased
 
   INCOMPATIBLE CHANGES

+ 6 - 0
hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/ipc/ProtoOverHadoopRpcEngine.java

@@ -320,6 +320,12 @@ public class ProtoOverHadoopRpcEngine implements RpcEngine {
             + methodName);
       MethodDescriptor methodDescriptor = service.getDescriptorForType()
           .findMethodByName(methodName);
+      if (methodDescriptor == null) {
+        String msg = "Unknown method " + methodName + " called on "
+            + protocol + " protocol.";
+        LOG.warn(msg);
+        return handleException(new IOException(msg));
+      }
       Message prototype = service.getRequestPrototype(methodDescriptor);
       Message param = prototype.newBuilderForType()
           .mergeFrom(rpcRequest.getRequestProto()).build();

+ 32 - 0
hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/TestRPC.java

@@ -25,9 +25,11 @@ import junit.framework.Assert;
 import org.apache.avro.ipc.Server;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.yarn.api.ClientRMProtocol;
 import org.apache.hadoop.yarn.api.ContainerManager;
 import org.apache.hadoop.yarn.api.protocolrecords.GetContainerStatusRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetContainerStatusResponse;
+import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationIdRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.StartContainerResponse;
 import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequest;
@@ -47,6 +49,7 @@ import org.apache.hadoop.yarn.factory.providers.YarnRemoteExceptionFactoryProvid
 import org.apache.hadoop.yarn.ipc.HadoopYarnProtoRPC;
 import org.apache.hadoop.yarn.ipc.RPCUtil;
 import org.apache.hadoop.yarn.ipc.YarnRPC;
+import org.apache.hadoop.yarn.util.Records;
 import org.junit.Test;
 
 public class TestRPC {
@@ -65,6 +68,35 @@ public class TestRPC {
 //    test(HadoopYarnRPC.class.getName());
 //  }
 
+  @Test
+  public void testUnknownCall() {
+    Configuration conf = new Configuration();
+    conf.set(YarnConfiguration.IPC_RPC_IMPL, HadoopYarnProtoRPC.class
+        .getName());
+    YarnRPC rpc = YarnRPC.create(conf);
+    String bindAddr = "localhost:0";
+    InetSocketAddress addr = NetUtils.createSocketAddr(bindAddr);
+    Server server = rpc.getServer(ContainerManager.class,
+        new DummyContainerManager(), addr, conf, null, 1);
+    server.start();
+
+    // Any unrelated protocol would do
+    ClientRMProtocol proxy = (ClientRMProtocol) rpc.getProxy(
+        ClientRMProtocol.class, NetUtils.createSocketAddr("localhost:"
+            + server.getPort()), conf);
+
+    try {
+      proxy.getNewApplicationId(Records
+          .newRecord(GetNewApplicationIdRequest.class));
+      Assert.fail("Excepted RPC call to fail with unknown method.");
+    } catch (YarnRemoteException e) {
+      Assert.assertEquals("Unknown method getNewApplicationId called on "
+          + "org.apache.hadoop.yarn.proto.ClientRMProtocol"
+          + "$ClientRMProtocolService$BlockingInterface protocol.", e
+          .getMessage());
+    }
+  }
+
   @Test
   public void testHadoopProtoRPC() throws Exception {
     test(HadoopYarnProtoRPC.class.getName());