View Javadoc

1   /*
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.ipc;
21  
22  import org.apache.hadoop.conf.Configurable;
23  import org.apache.hadoop.conf.Configuration;
24  import org.apache.hadoop.hbase.io.HbaseObjectWritable;
25  import org.apache.hadoop.io.VersionedWritable;
26  
27  import java.io.DataInput;
28  import java.io.DataOutput;
29  import java.io.IOException;
30  import java.lang.reflect.Field;
31  import java.lang.reflect.Method;
32  
33  /** A method invocation, including the method name and its parameters.*/
34  public class Invocation extends VersionedWritable implements Configurable {
35    protected String methodName;
36    @SuppressWarnings("rawtypes")
37    protected Class[] parameterClasses;
38    protected Object[] parameters;
39    protected Configuration conf;
40    private long clientVersion;
41    private int clientMethodsHash;
42  
43    private static byte RPC_VERSION = 1;
44  
45    public Invocation() {}
46  
47    public Invocation(Method method, Object[] parameters) {
48      this.methodName = method.getName();
49      this.parameterClasses = method.getParameterTypes();
50      this.parameters = parameters;
51      if (method.getDeclaringClass().equals(VersionedProtocol.class)) {
52        //VersionedProtocol is exempted from version check.
53        clientVersion = 0;
54        clientMethodsHash = 0;
55      } else {
56        try {
57          Field versionField = method.getDeclaringClass().getField("VERSION");
58          versionField.setAccessible(true);
59          this.clientVersion = versionField.getLong(method.getDeclaringClass());
60        } catch (NoSuchFieldException ex) {
61          throw new RuntimeException("The " + method.getDeclaringClass(), ex);
62        } catch (IllegalAccessException ex) {
63          throw new RuntimeException(ex);
64        }
65        this.clientMethodsHash = ProtocolSignature.getFingerprint(method
66            .getDeclaringClass().getMethods());
67      }
68    }
69  
70    /** @return The name of the method invoked. */
71    public String getMethodName() { return methodName; }
72  
73    /** @return The parameter classes. */
74    @SuppressWarnings({ "rawtypes" })
75    public Class[] getParameterClasses() { return parameterClasses; }
76  
77    /** @return The parameter instances. */
78    public Object[] getParameters() { return parameters; }
79  
80    long getProtocolVersion() {
81      return clientVersion;
82    }
83  
84    protected int getClientMethodsHash() {
85      return clientMethodsHash;
86    }
87  
88    /**
89     * Returns the rpc version used by the client.
90     * @return rpcVersion
91     */
92    public long getRpcVersion() {
93      return RPC_VERSION;
94    }
95  
96    public void readFields(DataInput in) throws IOException {
97      super.readFields(in);
98      methodName = in.readUTF();
99      clientVersion = in.readLong();
100     clientMethodsHash = in.readInt();
101     parameters = new Object[in.readInt()];
102     parameterClasses = new Class[parameters.length];
103     HbaseObjectWritable objectWritable = new HbaseObjectWritable();
104     for (int i = 0; i < parameters.length; i++) {
105       parameters[i] = HbaseObjectWritable.readObject(in, objectWritable,
106         this.conf);
107       parameterClasses[i] = objectWritable.getDeclaredClass();
108     }
109   }
110 
111   public void write(DataOutput out) throws IOException {
112     super.write(out);
113     out.writeUTF(this.methodName);
114     out.writeLong(clientVersion);
115     out.writeInt(clientMethodsHash);
116     out.writeInt(parameterClasses.length);
117     for (int i = 0; i < parameterClasses.length; i++) {
118       HbaseObjectWritable.writeObject(out, parameters[i], parameterClasses[i],
119                                  conf);
120     }
121   }
122 
123   @Override
124   public String toString() {
125     StringBuilder buffer = new StringBuilder(256);
126     buffer.append(methodName);
127     buffer.append("(");
128     for (int i = 0; i < parameters.length; i++) {
129       if (i != 0)
130         buffer.append(", ");
131       buffer.append(parameters[i]);
132     }
133     buffer.append(")");
134     buffer.append(", rpc version="+RPC_VERSION);
135     buffer.append(", client version="+clientVersion);
136     buffer.append(", methodsFingerPrint="+clientMethodsHash);
137     return buffer.toString();
138   }
139 
140   public void setConf(Configuration conf) {
141     this.conf = conf;
142   }
143 
144   public Configuration getConf() {
145     return this.conf;
146   }
147 
148   @Override
149   public byte getVersion() {
150     return RPC_VERSION;
151   }
152 }