예제 #1
0
        /// <summary>
        /// Extension method to add the JsonRpc router services to the IoC container
        /// </summary>
        /// <param name="serviceCollection">IoC serivce container to register JsonRpc dependencies</param>
        /// <param name="configureOptions">Configuration action for server wide rpc configuration</param>
        /// <returns>IoC service container</returns>
        public static IServiceCollection AddJsonRpc(this IServiceCollection serviceCollection, Action <RpcServerConfiguration>?configureOptions)
        {
            var configuration = new RpcServerConfiguration();

            configureOptions?.Invoke(configuration);
            return(serviceCollection.AddJsonRpc(configuration));
        }
예제 #2
0
        private static void TestSendNotify(int concurrency, Action <IPEndPoint, CountdownEvent, IProducerConsumerCollection <string> > test)
        {
            var endPoint = new IPEndPoint(IPAddress.Loopback, 57319);
            var config   = new RpcServerConfiguration();

            config.BindingEndPoint = endPoint;

            using (var arrivalLatch = new CountdownEvent(concurrency))
            {
                var arriveds = new ConcurrentQueue <string>();
                config.DispatcherProvider =
                    s =>
                    new CallbackDispatcher(
                        s,
                        (id, args) =>
                {
                    arriveds.Enqueue(args[0].ToString());
                    arrivalLatch.Signal();
                    return(args);
                }
                        );
                config.PreferIPv4 = true;

                using (var server = new RpcServer(config))
                    using (var transportManager = new TcpServerTransportManager(server))
                    {
                        test(endPoint, arrivalLatch, arriveds);
                    }
            }
        }
예제 #3
0
        public static IRpcBuilder WithOptions(this IRpcBuilder builder, Action <RpcServerConfiguration> configureOptions)
        {
            var configuration = new RpcServerConfiguration();

            configureOptions?.Invoke(configuration);
            builder.Services.Configure(configureOptions);
            return(builder);
        }
예제 #4
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);
                                        }
                                    }
                                }
                            }
                        }
        }
예제 #5
0
        public void ValidErrorResponseSerialization()
        {
            var config     = new RpcServerConfiguration();
            var serializer = new DefaultRpcResponseSerializer(Options.Create(config));

            const string expectedResponseString = "{\"id\":2,\"jsonrpc\":\"2.0\",\"error\":{\"code\":2,\"message\":\"error\",\"data\":\"data\"}}";
            var          response       = new RpcResponse(2, new RpcError(2, "error", "data"));
            string       responseString = serializer.Serialize(response);

            Assert.Equal(expectedResponseString, responseString, ignoreCase: false, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true);
        }
예제 #6
0
        public void ValidResponseSerialization()
        {
            var config     = new RpcServerConfiguration();
            var serializer = new DefaultRpcResponseSerializer(Options.Create(config));

            const string expectedResponseString = "{\"id\":1,\"jsonrpc\":\"2.0\",\"result\":\"result\"}";
            var          response       = new RpcResponse(1, "result");
            string       responseString = serializer.Serialize(response);

            Assert.Equal(expectedResponseString, responseString, ignoreCase: false, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true);
        }
        public void TestDispatch_MethodExists_Success()
        {
            var svcFile = ".\\Services.svc";

            File.WriteAllText(
                svcFile,
                String.Format(CultureInfo.InvariantCulture, "<% @ ServiceHost Service=\"{0}\" %>", typeof(TestService).FullName)
                );
            try
            {
                var configuration = new RpcServerConfiguration();
                configuration.ServiceTypeLocatorProvider = conf => new FileBasedServiceTypeLocator();

                using (var server = new RpcServer(configuration))
                    using (var transportManager = new NullServerTransportManager(server))
                        using (var transport = new NullServerTransport(transportManager))
                            using (var requestContext = DispatchTestHelper.CreateRequestContext())
                                using (var argumentsBuffer = new MemoryStream())
                                    using (var waitHandle = new ManualResetEventSlim())
                                    {
                                        var message = Guid.NewGuid().ToString();
                                        using (var argumentsPacker = Packer.Create(argumentsBuffer, false))
                                        {
                                            argumentsPacker.PackArrayHeader(1);
                                            argumentsPacker.Pack(message);
                                        }

                                        argumentsBuffer.Position = 0;

                                        var target = new LocatorBasedDispatcher(server);
                                        MessagePackObject response = MessagePackObject.Nil;
                                        requestContext.MethodName = "Echo:TestService:1";
                                        requestContext.MessageId  = 1;
                                        requestContext.SetTransport(transport);
                                        requestContext.ArgumentsUnpacker = Unpacker.Create(argumentsBuffer);
                                        transport.Sent +=
                                            (sender, e) =>
                                        {
                                            response = Unpacking.UnpackString(e.Context.GetReturnValueData()).Value;
                                            waitHandle.Set();
                                        };
                                        target.Dispatch(transport, requestContext);

                                        Assert.That(waitHandle.Wait(TimeSpan.FromSeconds(1)));

                                        Assert.That(message == response, "{0} != {1}", message, response);
                                    }
            }
            finally
            {
                File.Delete(svcFile);
            }
        }
		public void TestDispatch_MethodExists_Success()
		{
			var svcFile = ".\\Services.svc";
			File.WriteAllText(
				svcFile,
				String.Format( CultureInfo.InvariantCulture, "<% @ ServiceHost Service=\"{0}\" %>", typeof( TestService ).FullName )
			);
			try
			{
				var configuration = new RpcServerConfiguration();
				configuration.ServiceTypeLocatorProvider = conf => new FileBasedServiceTypeLocator();

				using ( var server = new RpcServer( configuration ) )
				using ( var transportManager = new NullServerTransportManager( server ) )
				using ( var transport = new NullServerTransport( transportManager ) )
				using ( var requestContext = DispatchTestHelper.CreateRequestContext() )
				using ( var argumentsBuffer = new MemoryStream() )
				using ( var waitHandle = new ManualResetEventSlim() )
				{
					var message = Guid.NewGuid().ToString();
					using ( var argumentsPacker = Packer.Create( argumentsBuffer, false ) )
					{
						argumentsPacker.PackArrayHeader( 1 );
						argumentsPacker.Pack( message );
					}

					argumentsBuffer.Position = 0;

					var target = new LocatorBasedDispatcher( server );
					MessagePackObject response = MessagePackObject.Nil;
					requestContext.MethodName = "Echo:TestService:1";
					requestContext.MessageId = 1;
					requestContext.SetTransport( transport );
					requestContext.ArgumentsUnpacker = Unpacker.Create( argumentsBuffer );
					transport.Sent +=
						( sender, e ) =>
						{
							response = Unpacking.UnpackString( e.Context.GetReturnValueData() ).Value;
							waitHandle.Set();
						};
					target.Dispatch( transport, requestContext );

					Assert.That( waitHandle.Wait( TimeSpan.FromSeconds( 1 ) ) );

					Assert.That( message == response, "{0} != {1}", message, response );
				}
			}
			finally
			{
				File.Delete( svcFile );
			}
		}
예제 #9
0
        public void ValidBulkResponseSerialization()
        {
            var config     = new RpcServerConfiguration();
            var serializer = new DefaultRpcResponseSerializer(Options.Create(config));

            const string expectedResponseString = "[{\"id\":1,\"jsonrpc\":\"2.0\",\"result\":\"result\"},{\"id\":2,\"jsonrpc\":\"2.0\",\"error\":{\"code\":2,\"message\":\"error\",\"data\":\"data\"}},{\"id\":3,\"jsonrpc\":\"2.0\",\"result\":\"result3\"}]";
            var          response       = new RpcResponse(1, "result");
            var          errorResponse  = new RpcResponse(2, new RpcError(2, "error", "data"));
            var          response2      = new RpcResponse(3, "result3");
            string       responseString = serializer.SerializeBulk(new[] { response, errorResponse, response2 });

            Assert.Equal(expectedResponseString, responseString, ignoreCase: false, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true);
        }
예제 #10
0
        private DefaultRpcInvoker GetInvoker()
        {
            var authorizationService = new Mock <IAuthorizationService>();
            var policyProvider       = new Mock <IAuthorizationPolicyProvider>();
            var logger  = new Mock <ILogger <DefaultRpcInvoker> >();
            var options = new Mock <IOptions <RpcServerConfiguration> >();
            var config  = new RpcServerConfiguration();

            config.ShowServerExceptions = true;
            options
            .SetupGet(o => o.Value)
            .Returns(config);

            return(new DefaultRpcInvoker(authorizationService.Object, policyProvider.Object, logger.Object, options.Object));
        }
        /// <summary>
        ///		Initializes a new instance of the <see cref="ServerResponseContext"/> class with specified configuration.
        /// </summary>
        /// <param name="configuration">
        ///		An <see cref="RpcServerConfiguration"/> to tweak this instance initial state.
        /// </param>
        public ServerResponseContext(RpcServerConfiguration configuration)
        {
            this._errorDataBuffer =
                new MemoryStream((configuration ?? RpcServerConfiguration.Default).InitialErrorBufferLength);
            this._returnDataBuffer =
                new MemoryStream((configuration ?? RpcServerConfiguration.Default).InitialReturnValueBufferLength);
            this.SendingBuffer    = new ArraySegment <byte> [4];
            this.SendingBuffer[0] = _responseHeader;
#if MONO
            this._unifiedSendingBuffer = new MemoryStream((configuration ?? RpcServerConfiguration.Default).InitialReceiveBufferLength);
            this._unifiedSendingBuffer.Write(this.SendingBuffer[0].Array, this.SendingBuffer[0].Offset, this.SendingBuffer[0].Count);
#endif
            this._returnDataPacker = Packer.Create(this._returnDataBuffer, false);
            this._errorDataPacker  = Packer.Create(this._errorDataBuffer, false);
        }
예제 #12
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            var builder = new ConfigurationBuilder()
                          .AddJsonFile(
                path: "appsettings.json",
                optional: false,
                reloadOnChange: true);

            var configuration = builder.Build();

            _container = ServicesConfiguration.Configure(configuration);
            _rpcServer = RpcServerConfiguration.Configure(_container, configuration);

            _rpcServer.Start();

            return(Task.CompletedTask);
        }
예제 #13
0
        private DefaultRpcInvoker GetInvoker()
        {
            var authorizationService = new Mock <IAuthorizationService>();
            var policyProvider       = new Mock <IAuthorizationPolicyProvider>();
            var logger  = new Mock <ILogger <DefaultRpcInvoker> >();
            var options = new Mock <IOptions <RpcServerConfiguration> >();
            var logger2 = new Mock <ILogger <DefaultRequestMatcher> >();
            //TODO mock and make other tests for this
            var rpcRequestMatcher = new DefaultRequestMatcher(logger2.Object, options.Object);
            var config            = new RpcServerConfiguration();

            config.ShowServerExceptions = true;
            options
            .SetupGet(o => o.Value)
            .Returns(config);

            return(new DefaultRpcInvoker(authorizationService.Object, policyProvider.Object, logger.Object, options.Object, rpcRequestMatcher));
        }
예제 #14
0
        /// <summary>
        /// Extension method to add the JsonRpc router services to the IoC container
        /// </summary>
        /// <param name="serviceCollection">IoC serivce container to register JsonRpc dependencies</param>
        /// <param name="configureOptions">Action to configure the router properties</param>
        /// <returns>IoC service container</returns>
        public static IServiceCollection AddJsonRpc(this IServiceCollection serviceCollection, Action <RpcServerConfiguration> configureOptions = null)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }
            RpcServerConfiguration configuration = new RpcServerConfiguration();

            configureOptions?.Invoke(configuration);

            return(serviceCollection
                   .AddRouting()
                   .AddAuthorization()
                   .Configure <RpcServerConfiguration>(configureOptions ?? (options => { }))
                   .AddSingleton <IRpcInvoker, DefaultRpcInvoker>()
                   .AddSingleton <IRpcParser, DefaultRpcParser>()
                   .AddSingleton <IRpcCompressor, DefaultRpcCompressor>());
        }
    public static void Main(string[] args1)
    {
        var config = new RpcServerConfiguration();
        config.BindingEndPoint = new IPEndPoint(IPAddress.Loopback, 8089);
        config.PreferIPv4 = true;
        config.IsDebugMode = true;
 //UseFullMethodName is a property that if it is false allows you in the CLIENT to call the         methods only by it's name, check example further.
        config.UseFullMethodName = false;
        var defaultServiceTypeLocator = new DefaultServiceTypeLocator();
        //Methods is the class I created with all the methods to be called.
        defaultServiceTypeLocator.AddService(typeof(Methods));
        config.ServiceTypeLocatorProvider = conf => defaultServiceTypeLocator;
        using (var server = new RpcServer(config))
        {
            server.Start();
            Console.ReadKey();
        }
    }
		private static void TestSendReceiveRequest( Action<IPEndPoint, UdpServerTransportManager> test )
		{
			var endPoint = new IPEndPoint( IPAddress.Loopback, 57319 );
			var config = new RpcServerConfiguration();
			config.BindingEndPoint = endPoint;
			config.DispatcherProvider =
				s =>
					new CallbackDispatcher(
						s,
						( id, args ) => args
					);
			config.PreferIPv4 = true;

			using ( var server = new RpcServer( config ) )
			using ( var transportManager = new UdpServerTransportManager( server ) )
			{
				test( endPoint, transportManager );
			}
		}
예제 #17
0
        private static void TestSendReceiveRequest(Action <IPEndPoint, TcpServerTransportManager> test)
        {
            var endPoint = new IPEndPoint(IPAddress.Loopback, 57319);
            var config   = new RpcServerConfiguration();

            config.BindingEndPoint    = endPoint;
            config.DispatcherProvider =
                s =>
                new CallbackDispatcher(
                    s,
                    (id, args) => args
                    );
            config.PreferIPv4 = true;

            using (var server = new RpcServer(config))
                using (var transportManager = new TcpServerTransportManager(server))
                {
                    test(endPoint, transportManager);
                }
        }
예제 #18
0
        public void TestListen_NotIPv6OnlyOnWinNT6OrLator()
        {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
            {
                Assert.Ignore("This test can be run on WinNT 6 or later.");
            }

            var config = new RpcServerConfiguration()
            {
                PreferIPv4 = false
            };

            using (var server = new RpcServer())
                using (var target = new TcpServerTransportManager(server))
                {
                    Socket listeningSocket = null;
                    target.GetListeningSocket(ref listeningSocket);
                    Assert.That(listeningSocket.GetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only), Is.EqualTo(0));
                }
        }
예제 #19
0
        private DefaultRpcInvoker GetInvoker(MethodInfo?methodInfo, RpcPath?path       = null,
                                             Action <RpcServerConfiguration>?configure = null)

        {
            var        logger         = new Mock <ILogger <DefaultRpcInvoker> >(MockBehavior.Loose);
            var        options        = new Mock <IOptions <RpcServerConfiguration> >(MockBehavior.Strict);
            var        matcher        = new Mock <IRpcRequestMatcher>(MockBehavior.Strict);
            var        accessor       = new Mock <IRpcContextAccessor>(MockBehavior.Strict);
            RpcContext requestContext = this.GetRouteContext(path);

            accessor
            .Setup(a => a.Get())
            .Returns(requestContext);
            Moq.Language.Flow.ISetup <IRpcRequestMatcher, IRpcMethodInfo> matcherSetup = matcher
                                                                                         .Setup(m => m.GetMatchingMethod(It.IsAny <RpcRequestSignature>()));
            if (methodInfo != null)
            {
                //TODO better way of getting this for unit tests?
                DefaultRpcMethodInfo method = DefaultRpcMethodInfo.FromMethodInfo(methodInfo);
                matcherSetup.Returns(method);
            }
            else
            {
                matcherSetup.Throws(new RpcException(RpcErrorCode.MethodNotFound, "Method not found"));
            }
            var config = new RpcServerConfiguration();

            config.ShowServerExceptions = true;
            configure?.Invoke(config);
            options
            .SetupGet(o => o.Value)
            .Returns(config);
            var authHandler = new Mock <IRpcAuthorizationHandler>(MockBehavior.Strict);

            authHandler
            .Setup(h => h.IsAuthorizedAsync(It.IsAny <IRpcMethodInfo>()))
            .Returns(Task.FromResult(true));

            return(new DefaultRpcInvoker(logger.Object, options.Object, matcher.Object, accessor.Object, authHandler.Object));
        }
예제 #20
0
        /// <summary>
        /// Extension method to add the JsonRpc router services to the IoC container
        /// </summary>
        /// <param name="serviceCollection">IoC serivce container to register JsonRpc dependencies</param>
        /// <param name="configuration">(Optional) Server wide rpc configuration</param>
        /// <returns>IoC service container</returns>
        public static IServiceCollection AddJsonRpc(this IServiceCollection serviceCollection, RpcServerConfiguration?configuration = null)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

            serviceCollection.AddSingleton(new RpcServicesMarker());
            serviceCollection
            .TryAddScoped <IRpcInvoker, DefaultRpcInvoker>();
            serviceCollection
            .TryAddScoped <IRpcParser, DefaultRpcParser>();
            serviceCollection
            .TryAddScoped <IRpcRequestHandler, RpcRequestHandler>();
            serviceCollection
            .TryAddScoped <IStreamCompressor, DefaultStreamCompressor>();
            serviceCollection
            .TryAddScoped <IRpcResponseSerializer, DefaultRpcResponseSerializer>();
            serviceCollection
            .TryAddScoped <IRpcRequestMatcher, DefaultRequestMatcher>();
            serviceCollection
            .TryAddScoped <IRpcContextAccessor, DefaultContextAccessor>();
            serviceCollection
            .TryAddScoped <IRpcAuthorizationHandler, DefaultAuthorizationHandler>();
            serviceCollection
            .TryAddScoped <IRpcMethodProvider, StaticRpcMethodProvider>();
            serviceCollection
            .TryAddSingleton <StaticRpcMethodDataAccessor>();
            serviceCollection.AddHttpContextAccessor();

            if (configuration == null)
            {
                configuration = new RpcServerConfiguration();
            }
            return(serviceCollection
                   .AddSingleton(Options.Create(configuration))
                   .AddRouting()
                   .AddAuthorizationCore());
        }
		public void TestListen_NotIPv6OnlyOnWinNT6OrLator()
		{
			if ( Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6 )
			{
				Assert.Ignore( "This test can be run on WinNT 6 or later." );
			}

			var config = new RpcServerConfiguration() { PreferIPv4 = false };
			using ( var server = new RpcServer() )
			using ( var target = new UdpServerTransportManager( server ) )
			{
				Socket listeningSocket = null;
				target.GetListeningSocket( ref listeningSocket );
				Assert.That( listeningSocket.GetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.IPv6Only ), Is.EqualTo( 0 ) );
			}
		}
		private static void TestSendNotify( int concurrency, Action<IPEndPoint, CountdownEvent, IProducerConsumerCollection<string>> test )
		{
			var endPoint = new IPEndPoint( IPAddress.Loopback, 57319 );
			var config = new RpcServerConfiguration();
			config.BindingEndPoint = endPoint;

			using ( var arrivalLatch = new CountdownEvent( concurrency ) )
			{
				var arriveds = new ConcurrentQueue<string>();
				config.DispatcherProvider =
					s =>
						new CallbackDispatcher(
							s,
							( id, args ) =>
							{
								arriveds.Enqueue( args[ 0 ].ToString() );
								arrivalLatch.Signal();
								return args;
							}
						);
				config.PreferIPv4 = true;

				using ( var server = new RpcServer( config ) )
				using ( var transportManager = new UdpServerTransportManager( server ) )
				{
					test( endPoint, arrivalLatch, arriveds );
				}
			}
		}
예제 #23
0
		/// <summary>
		///		Initializes a new instance of the <see cref="ServerRequestContext"/> class with specified configuration.
		/// </summary>
		/// <param name="configuration">
		///		An <see cref="RpcServerConfiguration"/> to tweak this instance initial state.
		/// </param>
		public ServerRequestContext( RpcServerConfiguration configuration )
			: base( ( configuration ?? RpcServerConfiguration.Default ).InitialReceiveBufferLength )
		{
			this.ArgumentsBuffer =
				new MemoryStream( ( configuration ?? RpcServerConfiguration.Default ).InitialArgumentsBufferLength );
		}
예제 #24
0
 public static IRpcBuilder WithOptions(this IRpcBuilder builder, RpcServerConfiguration configuration)
 {
     builder.Services.AddSingleton <IOptions <RpcServerConfiguration> >(Options.Create(configuration));
     return(builder);
 }
 /// <summary>
 ///		Initializes a new instance of the <see cref="ServerRequestContext"/> class with specified configuration.
 /// </summary>
 /// <param name="configuration">
 ///		An <see cref="RpcServerConfiguration"/> to tweak this instance initial state.
 /// </param>
 public ServerRequestContext(RpcServerConfiguration configuration)
     : base((configuration ?? RpcServerConfiguration.Default).InitialReceiveBufferLength)
 {
     this.ArgumentsBuffer =
         new MemoryStream((configuration ?? RpcServerConfiguration.Default).InitialArgumentsBufferLength);
 }