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));
        }
Example #6
0
        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);
                                        }
                                    }
                                }
                            }
                        }
        }
Example #7
0
        /// <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&lt;T&gt;"/> 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);
        }
Example #13
0
		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 );
		}
Example #14
0
		/// <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();
		}
Example #15
0
		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 );
		}
Example #16
0
		/// <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();
				}
			}
		}
Example #17
0
 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;
 }
Example #18
0
		/// <summary>
		///		Initializes a new instance of the <see cref="AsyncServiceInvoker&lt;T&gt;"/> 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 );
		}
Example #19
0
 /// <summary>
 ///		Initializes a new instance of the <see cref="AsyncServiceInvoker&lt;T&gt;"/> 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>();
 }
Example #20
0
		/// <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 );
		}