/// <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)); }
/// <exception cref="System.IO.IOException"/> public virtual ProtocolSignature GetProtocolSignature(string protocol, long clientVersion , int clientMethodsHashCode) { Type inter; try { inter = (Type)GetType().GetGenericInterfaces()[0]; } catch (Exception e) { throw new IOException(e); } return(ProtocolSignature.GetProtocolSignature(clientMethodsHashCode, GetProtocolVersion (protocol, clientVersion), inter)); }
private static bool MethodExists(int methodHash, long version, IDictionary <long, ProtocolSignature> versionMap) { ProtocolSignature sig = versionMap[version]; if (sig != null) { foreach (int m in sig.GetMethods()) { if (m == methodHash) { return(true); } } } return(false); }
/// <summary>Get a server protocol's signature</summary> /// <param name="server">server implementation</param> /// <param name="protocol">server protocol</param> /// <param name="clientVersion">client's version</param> /// <param name="clientMethodsHash">client's protocol's hash code</param> /// <returns>the server protocol's signature</returns> /// <exception cref="System.IO.IOException">if any error occurs</exception> public static ProtocolSignature GetProtocolSignature(VersionedProtocol server, string protocol, long clientVersion, int clientMethodsHash) { Type inter; try { inter = (Type)Runtime.GetType(protocol); } catch (Exception e) { throw new IOException(e); } long serverVersion = server.GetProtocolVersion(protocol, clientVersion); return(ProtocolSignature.GetProtocolSignature(clientMethodsHash, serverVersion, inter )); }
/// <exception cref="Com.Google.Protobuf.ServiceException"/> public virtual ProtocolInfoProtos.GetProtocolSignatureResponseProto GetProtocolSignature (RpcController controller, ProtocolInfoProtos.GetProtocolSignatureRequestProto request ) { ProtocolInfoProtos.GetProtocolSignatureResponseProto.Builder builder = ProtocolInfoProtos.GetProtocolSignatureResponseProto .NewBuilder(); string protocol = request.GetProtocol(); string rpcKind = request.GetRpcKind(); long[] versions; try { versions = GetProtocolVersionForRpcKind(RPC.RpcKind.ValueOf(rpcKind), protocol); } catch (TypeLoadException e1) { throw new ServiceException(e1); } if (versions == null) { return((ProtocolInfoProtos.GetProtocolSignatureResponseProto)builder.Build()); } foreach (long v in versions) { ProtocolInfoProtos.ProtocolSignatureProto.Builder sigBuilder = ProtocolInfoProtos.ProtocolSignatureProto .NewBuilder(); sigBuilder.SetVersion(v); try { ProtocolSignature signature = ProtocolSignature.GetProtocolSignature(protocol, v); foreach (int m in signature.GetMethods()) { sigBuilder.AddMethods(m); } } catch (TypeLoadException e) { throw new ServiceException(e); } builder.AddProtocolSignature(((ProtocolInfoProtos.ProtocolSignatureProto)sigBuilder .Build())); } return((ProtocolInfoProtos.GetProtocolSignatureResponseProto)builder.Build()); }
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); }
public virtual void SetUp() { ProtocolSignature.ResetCache(); }
internal ProtocolSigFingerprint(ProtocolSignature sig, int fingerprint) { this.signature = sig; this.fingerprint = fingerprint; }