public void TestFromServiceDescription_ServiceIsNull() { var runtime = RpcServerRuntime.Create(RpcServerConfiguration.Default, new SerializationContext()); ServiceDescription service = null; OperationDescription.FromServiceDescription(runtime, service).ToArray(); }
public void TestFromServiceDescription_Overloaded() { var runtime = RpcServerRuntime.Create(RpcServerConfiguration.Default, new SerializationContext()); ServiceDescription service = ServiceDescription.FromServiceType(typeof(Overloaded)); OperationDescription.FromServiceDescription(runtime, service).ToArray(); }
/// <summary> /// Gets service invoker. /// If the concrete type is already created, returns the cached instance. /// Else creates new concrete type and its instance, then returns it. /// </summary> /// <param name="runtime"> /// The <see cref="RpcServerRuntime"/>. /// </param> /// <param name="serviceDescription"> /// <see cref="ServiceDescription"/> which holds the service spec. /// </param> /// <param name="targetOperation"> /// <see cref="MethodInfo"/> of the target operation. /// </param> /// <returns> /// <see cref="AsyncServiceInvoker{T}"/> where T is return type of the target method. /// </returns> public IAsyncServiceInvoker GetServiceInvoker(RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation) { Contract.Requires(runtime != null); Contract.Requires(serviceDescription != null); Contract.Requires(targetOperation != null); bool isReadLockHeld = false; try { try { } finally { this._lock.EnterUpgradeableReadLock(); isReadLockHeld = true; } IAsyncServiceInvoker result; if (this._cache.TryGetValue(targetOperation.MethodHandle, out result)) { return(result); } IAsyncServiceInvoker newInvoker = CreateInvoker(runtime, serviceDescription, targetOperation); bool isWriteLockHeld = false; try { try { } finally { this._lock.EnterWriteLock(); isWriteLockHeld = true; } if (!this._cache.TryGetValue(targetOperation.MethodHandle, out result)) { this._cache[targetOperation.MethodHandle] = newInvoker; result = newInvoker; } return(result); } finally { if (isWriteLockHeld) { this._lock.ExitWriteLock(); } } } finally { if (isReadLockHeld) { this._lock.ExitUpgradeableReadLock(); } } }
public void TestFromServiceDescription_WithOutMethods_Empty() { var runtime = RpcServerRuntime.Create(RpcServerConfiguration.Default, new SerializationContext()); ServiceDescription service = ServiceDescription.FromServiceType(typeof(NoMember)); var result = OperationDescription.FromServiceDescription(runtime, service).ToArray(); Assert.That(result, Is.Not.Null.And.Empty); }
private static OperationDescription FromServiceMethodCore(RpcServerRuntime runtime, ServiceDescription service, MethodInfo operation) { Contract.Requires(runtime != null); Contract.Ensures(Contract.Result <OperationDescription>() != null); var serviceInvoker = ServiceInvokerGenerator.Default.GetServiceInvoker(runtime, service, operation); return(new OperationDescription(service, serviceInvoker.OperationId, serviceInvoker.InvokeAsync)); }
private void TestGetServiceInvokerCore <TArg1, TArg2, TResult>( EventHandler <ServiceInvokedEventArgs <TResult> > invoked, RpcServerConfiguration configuration, TArg1 arg1, TArg2 arg2, Action <ServerResponseContext> assertion ) { using (var target = new ServiceInvokerGenerator(true)) using (var server = new RpcServer()) using (var transportManager = new NullServerTransportManager(server)) using (var transport = new NullServerTransport(transportManager)) { var service = new Service <TArg1, TArg2, TResult>(); service.Invoked += invoked; var serviceDescription = new ServiceDescription("Service", () => service); var targetOperation = service.GetType().GetMethod("Invoke"); using (var requestContext = new ServerRequestContext()) { requestContext.ArgumentsBufferPacker = Packer.Create(requestContext.ArgumentsBuffer, false); requestContext.ArgumentsBufferPacker.PackArrayHeader(2); requestContext.ArgumentsBufferPacker.Pack(arg1); requestContext.ArgumentsBufferPacker.Pack(arg2); requestContext.ArgumentsBuffer.Position = 0; requestContext.MessageId = 123; requestContext.ArgumentsUnpacker = Unpacker.Create(requestContext.ArgumentsBuffer, false); var responseContext = new ServerResponseContext(); responseContext.SetTransport(transport); try { var result = target.GetServiceInvoker(RpcServerRuntime.Create(configuration, this._serializationContext), serviceDescription, targetOperation); result.InvokeAsync(requestContext, responseContext).Wait(TimeSpan.FromSeconds(1)); assertion(responseContext); } finally { if (this._isDumpEnabled) { try { target.Dump(); } catch (Exception ex) { Console.Error.WriteLine("Failed to dump: {0}", ex); } } } } } }
/// <summary> /// Initializes a new instance of the <see cref="Dispatcher"/> class. /// </summary> /// <param name="server">The server which will hold this instance.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="server"/> is <c>null</c>. /// </exception> protected Dispatcher(RpcServer server) { if (server == null) { throw new ArgumentNullException("server"); } Contract.EndContractBlock(); this._server = server; this._runtime = new RpcServerRuntime(server.Configuration, server.SerializationContext); }
private IAsyncServiceInvoker CreateInvoker(RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation) { var parameters = targetOperation.GetParameters(); CheckParameters(parameters); bool isWrapperNeeded = !typeof(Task).IsAssignableFrom(targetOperation.ReturnType); var emitter = new ServiceInvokerEmitter(this._moduleBuilder, Interlocked.Increment(ref this._typeSequence), targetOperation.DeclaringType, targetOperation.ReturnType, this._isDebuggable); EmitInvokeCore(emitter, targetOperation, parameters, typeof(Task), isWrapperNeeded); return(emitter.CreateInstance(runtime, serviceDescription, targetOperation)); }
public void TestFromServiceDescription_WithMethods_CreateForPublicAnnotatedMembers() { var runtime = RpcServerRuntime.Create(RpcServerConfiguration.Default, new SerializationContext()); ServiceDescription service = ServiceDescription.FromServiceType(typeof(Service)); var result = OperationDescription.FromServiceDescription(runtime, service).OrderBy(item => item.Id).ToArray(); Assert.That(result, Is.Not.Null.And.Length.EqualTo(2)); Assert.That(result[0].Id, Is.StringStarting(Service.ExpectedOperationId1)); Assert.That(result[0].Operation, Is.Not.Null); Assert.That(result[0].Service, Is.EqualTo(service)); Assert.That(result[1].Id, Is.StringStarting(Service.ExpectedOperationId2)); Assert.That(result[1].Operation, Is.Not.Null); Assert.That(result[1].Service, Is.EqualTo(service)); }
/// <summary> /// Creates the invoke type built now and returns its new instance. /// </summary> /// <param name="runtime">The <see cref="RpcServerRuntime"/> which provides runtime services.</param> /// <param name="serviceDescription">The <see cref="ServiceDescription"/> which holds the service spec.</param> /// <param name="targetOperation">The <see cref="MethodInfo"/> which holds the operation method spec.</param> /// <returns> /// Newly built <see cref="IAsyncServiceInvoker"/> instance. /// This value will not be <c>null</c>. /// </returns> public IAsyncServiceInvoker CreateInstance(RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation) { var runtimeParameter = Expression.Parameter(typeof(RpcServerRuntime)); var serviceDescriptionParameter = Expression.Parameter(typeof(ServiceDescription)); var targetOperationParameter = Expression.Parameter(typeof(MethodInfo)); return (Expression.Lambda <Func <RpcServerRuntime, ServiceDescription, MethodInfo, IAsyncServiceInvoker> >( Expression.New( this.Create(), runtimeParameter, serviceDescriptionParameter, targetOperationParameter ), runtimeParameter, serviceDescriptionParameter, targetOperationParameter ).Compile()(runtime, serviceDescription, targetOperation)); }
/// <summary> /// Creates the collection of the <see cref="OperationDescription"/> from the service description. /// </summary> /// <param name="runtime">The <see cref="RpcServerRuntime"/> which provides runtime services.</param> /// <param name="service">The target service description.</param> /// <returns> /// Collection of the <see cref="OperationDescription"/> from the service description. /// This value will not be <c>null</c> but might be empty. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="runtime"/> is <c>null</c>. /// Or, <paramref name="service"/> is <c>null</c>. /// </exception> public static IEnumerable <OperationDescription> FromServiceDescription(RpcServerRuntime runtime, ServiceDescription service) { if (runtime == null) { throw new ArgumentNullException("runtime"); } if (service == null) { throw new ArgumentNullException("service"); } Contract.Ensures(Contract.Result <IEnumerable <OperationDescription> >() != null); Contract.Ensures(Contract.ForAll(Contract.Result <IEnumerable <OperationDescription> >(), item => item != null)); var generated = new HashSet <string>(); return (service.ServiceType.GetMethods() .Where(method => method.IsDefined(typeof(MessagePackRpcMethodAttribute), true)) .Select(operation => { if (!generated.Add(operation.Name)) { throw new NotSupportedException( String.Format( CultureInfo.CurrentCulture, "Method '{0}' is overloaded. Method overload is not supported on the MessagePack-RPC.", operation.Name ) ); } return FromServiceMethodCore(runtime, service, operation); } ).ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="AsyncServiceInvoker<T>"/> class. /// </summary> /// <param name="runtime">The <see cref="RpcServerRuntime"/> which provides runtime services.</param> /// <param name="serviceDescription">The service description which defines target operation.</param> /// <param name="targetOperation">The target operation to be invoked.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="runtime"/> is <c>null</c>. /// Or, <paramref name="serviceDescription"/> is <c>null</c>. /// Or, <paramref name="targetOperation"/> is <c>null</c>. /// </exception> internal AsyncServiceInvoker(RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation) { if (runtime == null) { throw new ArgumentNullException("runtime"); } if (serviceDescription == null) { throw new ArgumentNullException("serviceDescription"); } if (targetOperation == null) { throw new ArgumentNullException("targetOperation"); } Contract.EndContractBlock(); this._runtime = runtime; this._serviceDescription = serviceDescription; this._targetOperation = targetOperation; this._operationId = ServiceIdentifier.TruncateGenericsSuffix(targetOperation.Name); }
private static OperationDescription FromServiceMethodCore( RpcServerRuntime runtime, ServiceDescription service, MethodInfo operation ) { Contract.Requires( runtime != null ); Contract.Ensures( Contract.Result<OperationDescription>() != null ); var serviceInvoker = ServiceInvokerGenerator.Default.GetServiceInvoker( runtime, service, operation ); return new OperationDescription( service, serviceInvoker.OperationId, serviceInvoker.InvokeAsync ); }
/// <summary> /// Creates the collection of the <see cref="OperationDescription"/> from the service description. /// </summary> /// <param name="runtime">The <see cref="RpcServerRuntime"/> which provides runtime services.</param> /// <param name="service">The target service description.</param> /// <returns> /// Collection of the <see cref="OperationDescription"/> from the service description. /// This value will not be <c>null</c> but might be empty. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="runtime"/> is <c>null</c>. /// Or, <paramref name="service"/> is <c>null</c>. /// </exception> public static IEnumerable<OperationDescription> FromServiceDescription( RpcServerRuntime runtime, ServiceDescription service ) { if ( runtime == null ) { throw new ArgumentNullException( "runtime" ); } if ( service == null ) { throw new ArgumentNullException( "service" ); } Contract.Ensures( Contract.Result<IEnumerable<OperationDescription>>() != null ); Contract.Ensures( Contract.ForAll( Contract.Result<IEnumerable<OperationDescription>>(), item => item != null ) ); var generated = new HashSet<string>(); return service.ServiceType.GetMethods() .Where( method => method.DeclaringType != objectType && !method.IsDefined( typeof(NoActionAttribute), true ) ) .Select( operation => { if ( !generated.Add( operation.Name ) ) { throw new NotSupportedException( String.Format( CultureInfo.CurrentCulture, "Method '{0}' is overloaded. Method overload is not supported on the MessagePack-RPC.", operation.Name ) ); } return FromServiceMethodCore( runtime, service, operation ); } ).ToArray(); }
private IAsyncServiceInvoker CreateInvoker( RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation ) { var parameters = targetOperation.GetParameters(); CheckParameters( parameters ); bool isWrapperNeeded = !typeof( Task ).IsAssignableFrom( targetOperation.ReturnType ); var emitter = new ServiceInvokerEmitter( this._moduleBuilder, Interlocked.Increment( ref this._typeSequence ), targetOperation.DeclaringType, targetOperation.ReturnType, this._isDebuggable ); EmitInvokeCore( emitter, targetOperation, parameters, typeof( Task ), isWrapperNeeded ); return emitter.CreateInstance( runtime, serviceDescription, targetOperation ); }
/// <summary> /// Gets service invoker. /// If the concrete type is already created, returns the cached instance. /// Else creates new concrete type and its instance, then returns it. /// </summary> /// <param name="runtime"> /// The <see cref="RpcServerRuntime"/>. /// </param> /// <param name="serviceDescription"> /// <see cref="ServiceDescription"/> which holds the service spec. /// </param> /// <param name="targetOperation"> /// <see cref="MethodInfo"/> of the target operation. /// </param> /// <returns> /// <see cref="AsyncServiceInvoker{T}"/> where T is return type of the target method. /// </returns> public IAsyncServiceInvoker GetServiceInvoker( RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation ) { Contract.Requires( runtime != null ); Contract.Requires( serviceDescription != null ); Contract.Requires( targetOperation != null ); bool isReadLockHeld = false; try { try { } finally { this._lock.EnterUpgradeableReadLock(); isReadLockHeld = true; } IAsyncServiceInvoker result; if ( this._cache.TryGetValue( targetOperation.MethodHandle, out result ) ) { return result; } IAsyncServiceInvoker newInvoker = CreateInvoker( runtime, serviceDescription, targetOperation ); bool isWriteLockHeld = false; try { try { } finally { this._lock.EnterWriteLock(); isWriteLockHeld = true; } if ( !this._cache.TryGetValue( targetOperation.MethodHandle, out result ) ) { this._cache[ targetOperation.MethodHandle ] = newInvoker; result = newInvoker; } return result; } finally { if ( isWriteLockHeld ) { this._lock.ExitWriteLock(); } } } finally { if ( isReadLockHeld ) { this._lock.ExitUpgradeableReadLock(); } } }
public Target(Exception fatalError, RpcErrorMessage methodError) : base(RpcServerRuntime.Create(RpcServerConfiguration.Default, new SerializationContext()), new ServiceDescription("Dummy", () => new object ()), typeof(object).GetMethod("ToString")) { this._fatalError = fatalError; this._methodError = methodError; }
/// <summary> /// Initializes a new instance of the <see cref="AsyncServiceInvoker<T>"/> class. /// </summary> /// <param name="runtime">The <see cref="RpcServerRuntime"/> which provides runtime services.</param> /// <param name="serviceDescription">The service description which defines target operation.</param> /// <param name="targetOperation">The target operation to be invoked.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="runtime"/> is <c>null</c>. /// Or, <paramref name="serviceDescription"/> is <c>null</c>. /// Or, <paramref name="targetOperation"/> is <c>null</c>. /// </exception> internal AsyncServiceInvoker( RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation ) { if ( runtime == null ) { throw new ArgumentNullException( "runtime" ); } if ( serviceDescription == null ) { throw new ArgumentNullException( "serviceDescription" ); } if ( targetOperation == null ) { throw new ArgumentNullException( "targetOperation" ); } Contract.EndContractBlock(); this._runtime = runtime; this._serviceDescription = serviceDescription; this._targetOperation = targetOperation; this._operationId = ServiceIdentifier.TruncateGenericsSuffix( targetOperation.Name ); }
/// <summary> /// Initializes a new instance of the <see cref="AsyncServiceInvoker<T>"/> class. /// </summary> /// <param name="runtime">The <see cref="RpcServerRuntime"/> which provides runtime services.</param> /// <param name="serviceDescription">The service description which defines target operation.</param> /// <param name="targetOperation">The target operation to be invoked.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="runtime"/> is <c>null</c>. /// Or, <paramref name="serviceDescription"/> is <c>null</c>. /// Or, <paramref name="targetOperation"/> is <c>null</c>. /// </exception> protected AsyncServiceInvoker(RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation) : base(runtime, serviceDescription, targetOperation) { this._returnValueSerializer = typeof(T) == typeof(Missing) ? null : runtime.SerializationContext.GetSerializer <T>(); }
/// <summary> /// Creates the invoke type built now and returns its new instance. /// </summary> /// <param name="runtime">The <see cref="RpcServerRuntime"/> which provides runtime services.</param> /// <param name="serviceDescription">The <see cref="ServiceDescription"/> which holds the service spec.</param> /// <param name="targetOperation">The <see cref="MethodInfo"/> which holds the operation method spec.</param> /// <returns> /// Newly built <see cref="IAsyncServiceInvoker"/> instance. /// This value will not be <c>null</c>. /// </returns> public IAsyncServiceInvoker CreateInstance( RpcServerRuntime runtime, ServiceDescription serviceDescription, MethodInfo targetOperation ) { var runtimeParameter = Expression.Parameter( typeof( RpcServerRuntime ) ); var serviceDescriptionParameter = Expression.Parameter( typeof( ServiceDescription ) ); var targetOperationParameter = Expression.Parameter( typeof( MethodInfo ) ); return Expression.Lambda<Func<RpcServerRuntime, ServiceDescription, MethodInfo, IAsyncServiceInvoker>>( Expression.New( this.Create(), runtimeParameter, serviceDescriptionParameter, targetOperationParameter ), runtimeParameter, serviceDescriptionParameter, targetOperationParameter ).Compile()( runtime, serviceDescription, targetOperation ); }