/// <summary>Check if a method is supported by the server or not</summary> /// <param name="methodName">a method's name in String format</param> /// <param name="parameterTypes">a method's parameter types</param> /// <returns>true if the method is supported by the server</returns> /// <exception cref="System.IO.IOException"/> public virtual bool IsMethodSupported(string methodName, params Type[] parameterTypes ) { lock (this) { if (!supportServerMethodCheck) { return(true); } MethodInfo method; try { method = Runtime.GetDeclaredMethod(protocol, methodName, parameterTypes); } catch (SecurityException e) { throw new IOException(e); } catch (MissingMethodException e) { throw new IOException(e); } if (!serverMethodsFetched) { FetchServerMethods(method); } if (serverMethods == null) { // client & server have the same protocol return(true); } return(serverMethods.Contains(Extensions.ValueOf(ProtocolSignature.GetFingerprint (method)))); } }
/// <exception cref="System.IO.IOException"/> private void FetchServerMethods(MethodInfo method) { long clientVersion; clientVersion = RPC.GetProtocolVersion(method.DeclaringType); int clientMethodsHash = ProtocolSignature.GetFingerprint(method.DeclaringType.GetMethods ()); ProtocolSignature serverInfo = ((VersionedProtocol)proxy).GetProtocolSignature(RPC .GetProtocolName(protocol), clientVersion, clientMethodsHash); long serverVersion = serverInfo.GetVersion(); if (serverVersion != clientVersion) { throw new RPC.VersionMismatch(protocol.FullName, clientVersion, serverVersion); } int[] serverMethodsCodes = serverInfo.GetMethods(); if (serverMethodsCodes != null) { serverMethods = new HashSet <int>(serverMethodsCodes.Length); foreach (int m in serverMethodsCodes) { this.serverMethods.AddItem(Extensions.ValueOf(m)); } } serverMethodsFetched = true; }
/// <summary>Returns whether the given method is supported or not.</summary> /// <remarks> /// Returns whether the given method is supported or not. /// The protocol signatures are fetched and cached. The connection id for the /// proxy provided is re-used. /// </remarks> /// <param name="rpcProxy">Proxy which provides an existing connection id.</param> /// <param name="protocol">Protocol for which the method check is required.</param> /// <param name="rpcKind">The RpcKind for which the method check is required.</param> /// <param name="version">The version at the client.</param> /// <param name="methodName">Name of the method.</param> /// <returns>true if the method is supported, false otherwise.</returns> /// <exception cref="System.IO.IOException"/> public static bool IsMethodSupported(object rpcProxy, Type protocol, RPC.RpcKind rpcKind, long version, string methodName) { IPEndPoint serverAddress = RPC.GetServerAddress(rpcProxy); IDictionary <long, ProtocolSignature> versionMap = GetVersionSignatureMap(serverAddress , protocol.FullName, rpcKind.ToString()); if (versionMap == null) { Configuration conf = new Configuration(); RPC.SetProtocolEngine(conf, typeof(ProtocolMetaInfoPB), typeof(ProtobufRpcEngine) ); ProtocolMetaInfoPB protocolInfoProxy = GetProtocolMetaInfoProxy(rpcProxy, conf); ProtocolInfoProtos.GetProtocolSignatureRequestProto.Builder builder = ProtocolInfoProtos.GetProtocolSignatureRequestProto .NewBuilder(); builder.SetProtocol(protocol.FullName); builder.SetRpcKind(rpcKind.ToString()); ProtocolInfoProtos.GetProtocolSignatureResponseProto resp; try { resp = protocolInfoProxy.GetProtocolSignature(NullController, ((ProtocolInfoProtos.GetProtocolSignatureRequestProto )builder.Build())); } catch (ServiceException se) { throw ProtobufHelper.GetRemoteException(se); } versionMap = ConvertProtocolSignatureProtos(resp.GetProtocolSignatureList()); PutVersionSignatureMap(serverAddress, protocol.FullName, rpcKind.ToString(), versionMap ); } // Assuming unique method names. MethodInfo desiredMethod; MethodInfo[] allMethods = protocol.GetMethods(); desiredMethod = null; foreach (MethodInfo m in allMethods) { if (m.Name.Equals(methodName)) { desiredMethod = m; break; } } if (desiredMethod == null) { return(false); } int methodHash = ProtocolSignature.GetFingerprint(desiredMethod); return(MethodExists(methodHash, version, versionMap)); }
public virtual void TestHashCode() { // make sure that overriding methods have different hashcodes MethodInfo strMethod = typeof(TestRPCCompatibility.TestProtocol3).GetMethod("echo" , typeof(string)); int stringEchoHash = ProtocolSignature.GetFingerprint(strMethod); MethodInfo intMethod = typeof(TestRPCCompatibility.TestProtocol3).GetMethod("echo" , typeof(int)); int intEchoHash = ProtocolSignature.GetFingerprint(intMethod); NUnit.Framework.Assert.IsFalse(stringEchoHash == intEchoHash); // make sure methods with the same signature // from different declaring classes have the same hash code int intEchoHash1 = ProtocolSignature.GetFingerprint(typeof(TestRPCCompatibility.TestProtocol2 ).GetMethod("echo", typeof(int))); Assert.Equal(intEchoHash, intEchoHash1); // Methods with the same name and parameter types but different returning // types have different hash codes int stringEchoHash1 = ProtocolSignature.GetFingerprint(typeof(TestRPCCompatibility.TestProtocol2 ).GetMethod("echo", typeof(string))); NUnit.Framework.Assert.IsFalse(stringEchoHash == stringEchoHash1); // Make sure that methods with the same returning type and parameter types // but different method names have different hash code int intEchoHashAlias = ProtocolSignature.GetFingerprint(typeof(TestRPCCompatibility.TestProtocol3 ).GetMethod("echo_alias", typeof(int))); NUnit.Framework.Assert.IsFalse(intEchoHash == intEchoHashAlias); // Make sure that methods with the same returning type and method name but // larger number of parameter types have different hash code int intEchoHash2 = ProtocolSignature.GetFingerprint(typeof(TestRPCCompatibility.TestProtocol3 ).GetMethod("echo", typeof(int), typeof(int))); NUnit.Framework.Assert.IsFalse(intEchoHash == intEchoHash2); // make sure that methods order does not matter for method array hash code int hash1 = ProtocolSignature.GetFingerprint(new MethodInfo[] { intMethod, strMethod }); int hash2 = ProtocolSignature.GetFingerprint(new MethodInfo[] { strMethod, intMethod }); Assert.Equal(hash1, hash2); }
public virtual void TestProtocolMetaInfoSSTranslatorPB() { TestRPCCompatibility.TestImpl1 impl = new TestRPCCompatibility.TestImpl1(); server = new RPC.Builder(conf).SetProtocol(typeof(TestRPCCompatibility.TestProtocol1 )).SetInstance(impl).SetBindAddress(Address).SetPort(0).SetNumHandlers(2).SetVerbose (false).Build(); server.AddProtocol(RPC.RpcKind.RpcWritable, typeof(TestRPCCompatibility.TestProtocol0 ), impl); server.Start(); ProtocolMetaInfoServerSideTranslatorPB xlator = new ProtocolMetaInfoServerSideTranslatorPB (server); ProtocolInfoProtos.GetProtocolSignatureResponseProto resp = xlator.GetProtocolSignature (null, CreateGetProtocolSigRequestProto(typeof(TestRPCCompatibility.TestProtocol1 ), RPC.RpcKind.RpcProtocolBuffer)); //No signatures should be found Assert.Equal(0, resp.GetProtocolSignatureCount()); resp = xlator.GetProtocolSignature(null, CreateGetProtocolSigRequestProto(typeof( TestRPCCompatibility.TestProtocol1), RPC.RpcKind.RpcWritable)); Assert.Equal(1, resp.GetProtocolSignatureCount()); ProtocolInfoProtos.ProtocolSignatureProto sig = resp.GetProtocolSignatureList()[0 ]; Assert.Equal(TestRPCCompatibility.TestProtocol1.versionID, sig .GetVersion()); bool found = false; int expected = ProtocolSignature.GetFingerprint(typeof(TestRPCCompatibility.TestProtocol1 ).GetMethod("echo", typeof(string))); foreach (int m in sig.GetMethodsList()) { if (expected == m) { found = true; break; } } Assert.True(found); }
public Invocation(MethodInfo method, object[] parameters) { //This could be different from static writableRpcVersion when received //at server, if client is using a different version. // called when deserializing an invocation this.methodName = method.Name; this.parameterClasses = Runtime.GetParameterTypes(method); this.parameters = parameters; rpcVersion = writableRpcVersion; if (method.DeclaringType.Equals(typeof(VersionedProtocol))) { //VersionedProtocol is exempted from version check. clientVersion = 0; clientMethodsHash = 0; } else { this.clientVersion = RPC.GetProtocolVersion(method.DeclaringType); this.clientMethodsHash = ProtocolSignature.GetFingerprint(method.DeclaringType.GetMethods ()); } this.declaringClassProtocolName = RPC.GetProtocolName(method.DeclaringType); }