private (TService, Mock <TestCallInvoker>) CreateServiceInstance <TService>() where TService : class
        {
            var(moduleBuilder, definedTypes) = this.CreateModuleBuilder();
            var proxyBuilder = new RpcServiceProxyBuilder <GrpcProxyBase, GrpcProxyMethod>(RpcBuilderUtil.GetAllServices <TService>(true), moduleBuilder, definedTypes);

            var(proxyType, proxyMethods) = proxyBuilder.BuildObjectProxyType(new Type[] { typeof(GrpcProxyArgs), typeof(GrpcProxyMethod[]) });

            ValidateProxyType <TService>(proxyType);

            var factory = RpcServiceProxyBuilder <GrpcProxyBase, GrpcProxyMethod> .CreateObjectProxyFactory <GrpcProxyArgs>(proxyType);

            var callInvokerMock = new Mock <TestCallInvoker>(MockBehavior.Strict);
            var connectionMock  = new Mock <IRpcConnection>(MockBehavior.Strict);

            connectionMock.Setup(m => m.Options).Returns(ImmutableRpcClientOptions.Empty);
            var serializer = new ProtobufRpcSerializer();

            var args = new GrpcProxyArgs
                       (
                objectId: RpcObjectId.NewId(),
                connection: connectionMock.Object,
                callInvoker: callInvokerMock.Object,
                serializer: serializer,
                methodsCache: new GrpcMethodsCache(serializer),
                implementedServices: null,
                syncContext: null
                       );

            var serviceInstance = factory(args, proxyMethods);

            return((TService)(object)serviceInstance, callInvokerMock);
        }
Example #2
0
        public void GlobalSetup()
        {
            var serverId            = RpcServerId.NewId();
            var definitionsProvider = new RpcServiceDefinitionsBuilder();
            // var serializer = new JsonRpcSerializer();
            var serializer    = new ProtobufRpcSerializer(RuntimeTypeModel.Create());
            var serverOptions = new RpcServerOptions {
                Serializer = serializer
            };

            this.clientOptions = new RpcClientOptions {
                Serializer = serializer
            }.AsImmutable();

            switch (this.ConnectionType)
            {
            //case RpcConnectionType.LightweightInproc:
            //    {
            //        var connector = new InprocRpcConnector(clientOptions);
            //        this.server = new LightweightRpcServer(serverId, definitionsProvider, null, serverOptions);
            //        this.server.AddEndPoint(connector.EndPoint);
            //        this.server.ServicePublisher.PublishSingleton<ISimpleService>(new SimpleServiceImpl());
            //        this.server.Start();

            //        //this.clientConnection = connector.Connection;
            //        //clientService = this.clientConnection.GetServiceSingleton<ISimpleServiceClient>();
            //        break;
            //    }
            case RpcConnectionType.LightweightTcp:
            {
                this.server = new LightweightRpcServer(serverId, definitionsProvider, null, serverOptions);
                this.server.AddEndPoint(new TcpRpcEndPoint("127.0.0.1", 50051, false));
                this.server.ServicePublisher.PublishSingleton <ISimpleService>(new SimpleServiceImpl());
                this.server.Start();

                this.connectionInfo = new RpcConnectionInfo(new Uri("lightweight.tcp://localhost:50051"));
                break;
            }

            case RpcConnectionType.LightweightNamedPipe:
            {
                this.server = new LightweightRpcServer(serverId, definitionsProvider, null, serverOptions);
                this.server.AddEndPoint(new NamedPipeRpcEndPoint("RpcBenchmark"));
                this.server.ServicePublisher.PublishSingleton <ISimpleService>(new SimpleServiceImpl());
                this.server.Start();

                this.connectionInfo = new RpcConnectionInfo(new Uri($"{WellKnownRpcSchemes.LightweightPipe}://./RpcBenchmark"));
                break;
            }
            }
        }
        public void SingletonServiceStub_ShouldUseRpcRequest()
        {
            var builder = new LightweightServiceStubBuilder <ISingletonService>(null);

            //var binderMock = new Mock<ILightweightMethodBinder>();
            //binderMock.Setup(b => b.AddMethod(It.IsAny<LightweightMethodStub>())).Callback<LightweightMethodStub>(m => {
            //    switch(m.OperationName)
            //    {
            //        case "SciTech.Rpc.Tests.SingletonService.Add":
            //            Assert.AreEqual(typeof(RpcRequest<int, int>), m.RequestType);
            //            break;
            //    }
            //});

            var binder             = new TestLightweightMethodBinder();
            var serverMock         = new Mock <IRpcServerCore>();
            var definitionsBuilder = new RpcServiceDefinitionsBuilder();
            var serializer         = new ProtobufRpcSerializer();

            serverMock.SetupGet(m => m.ServiceDefinitionsProvider).Returns(definitionsBuilder);
            serverMock.SetupGet(m => m.Serializer).Returns(serializer);

            var stub = builder.GenerateOperationHandlers(serverMock.Object, binder);;

            var addMethod = binder.methods.Single(m => m.OperationName == "SciTech.Rpc.Tests.SingletonService.Add");

            Assert.AreEqual(typeof(RpcRequest <int, int>), addMethod.RequestType);

            var subMethod = binder.methods.Single(m => m.OperationName == "SciTech.Rpc.Tests.SingletonService.Sub");

            Assert.AreEqual(typeof(RpcRequest <int, int>), subMethod.RequestType);

            var getStringsMethod = binder.methods.Single(m => m.OperationName == "SciTech.Rpc.Tests.SingletonService.GetStrings");

            Assert.AreEqual(typeof(RpcRequest <int>), getStringsMethod.RequestType);
        }
Example #4
0
        /// <summary>
        /// Invokes an operation method.
        /// </summary>
        /// <typeparam name="TT">The task return type.</typeparam>
        /// <param name="method">The method.</param>
        /// <param name="args">The arguments.</param>
        /// <param name="returnType">The real return type.</param>
        /// <returns></returns>
        protected virtual async Task <TT> InvokeOperationAsync <TT>(MethodInfo method, object[] args, Type returnType)
        {
            // build arguments
            Dictionary <string, object> argsPayload = new Dictionary <string, object>();

            ParameterInfo[] argsMethod = method.GetParameters();

            for (int i = 0; i < args.Length; i++)
            {
                argsPayload[argsMethod[i].Name] = args[i];
            }

            // create request
            RpcRequest req = new RpcRequest(_contractAttr.Name != null ? _contractAttr.Name : _typeInfo.Name, method.Name, argsPayload);

            // serialize
            byte[]    requestBody = new ProtobufRpcSerializer().SerializeRequest(req);
            RpcHeader header      = new RpcHeader(RpcHeader.HEADER_VERSION, ProtobufRpcSerializer.SerializerName, RpcMessageType.Single);

            // create headers
            IDictionary <string, object> headers = new Dictionary <string, object>()
            {
                { RpcHeader.HEADER_NAME, header.ToString() }
            };

            // ask or send
            if (method.GetCustomAttribute <RpcOperationAttribute>().NoReply)
            {
                // send operation
                await _channel.SendAsync(requestBody, headers);

                return(default(TT));
            }
            else
            {
                Envelope res = await _channel.AskAsync(requestBody, _configuration.Timeout, headers);

                // transform response
                byte[] responseBody = res.Body;

                // try and get response header
                if (!res.Headers.TryGetValue(RpcHeader.HEADER_NAME, out object resHeaderData))
                {
                    throw new InvalidOperationException("The response envelope is not a valid RPC message");
                }

                RpcHeader resHeader = new RpcHeader(Encoding.UTF8.GetString(resHeaderData as byte[]));

                // deserialize response
                if (!RpcSerializer.Serializers.TryGetValue(resHeader.Serializer, out IRpcSerializer deserializer))
                {
                    throw new NotSupportedException("The response serializer is not supported");
                }

                // deserialize
                RpcResponse resPayload = null;

                if (method.ReturnType == typeof(Task))
                {
                    // deserialize
                    resPayload = deserializer.DeserializeResponse(responseBody, typeof(void));

                    // return result
                    if (resPayload.IsSuccess)
                    {
                        return((TT)(object)true);
                    }
                }
                else
                {
                    // deserialize
                    Type taskType = method.ReturnType.GetGenericArguments()[0];
                    resPayload = deserializer.DeserializeResponse(responseBody, taskType);

                    // return result
                    if (resPayload.IsSuccess)
                    {
                        return((TT)resPayload.Data);
                    }
                }

                // throw error
                throw new RpcException(resPayload.Error);
            }
        }
Example #5
0
        public async Task SimpleServiceServerTest()
        {
            Pipe requestPipe  = new Pipe();
            Pipe responsePipe = new Pipe();

            var serializer              = new ProtobufRpcSerializer();
            var serviceImpl             = new TestBlockingSimpleServiceImpl();
            var hostMock                = new Mock <IRpcServerCore>();
            var serviceImplProviderMock = new Mock <IRpcServiceActivator>();

            serviceImplProviderMock.Setup(p => p.GetActivatedService <ISimpleService>(It.IsAny <IServiceProvider>(), It.IsAny <RpcObjectId>())).Returns(new ActivatedService <ISimpleService>(serviceImpl, null));

            hostMock.Setup(p => p.ServiceActivator).Returns(serviceImplProviderMock.Object);
            hostMock.Setup(p => p.CallInterceptors).Returns(ImmutableArrayList <RpcServerCallInterceptor> .Empty);

            var serviceRegistrator = new RpcServiceDefinitionsBuilder();

            serviceRegistrator.RegisterService <ISimpleService>();

            _ = RpcServerId.NewId();
            using (var host = new LightweightRpcServer(Mock.Of <IRpcServicePublisher>(), serviceImplProviderMock.Object, serviceRegistrator, null, new RpcServerOptions {
                Serializer = serializer
            }))
            {
                host.AddEndPoint(new InprocRpcEndPoint(new DirectDuplexPipe(requestPipe.Reader, responsePipe.Writer)));

                host.Start();

                var objectId = RpcObjectId.NewId();

                var requestFrame = new LightweightRpcFrame(RpcFrameType.UnaryRequest, 1, "SciTech.Rpc.Tests.SimpleService.Add", ImmutableArray <KeyValuePair <string, ImmutableArray <byte> > > .Empty);

                using (var frameWriter = new BufferWriterStreamImpl())
                {
                    var writeState = requestFrame.BeginWrite(frameWriter);

                    var request = new RpcObjectRequest <int, int>(objectId, 5, 6);
                    serializer.Serialize(frameWriter, request, request.GetType());
                    int frameLength = checked ((int)frameWriter.Length);

                    LightweightRpcFrame.EndWrite(frameLength, writeState);

                    frameWriter.CopyTo(requestPipe.Writer);
                }

                await requestPipe.Writer.FlushAsync();

                RpcResponse <int> response = null;
                while (response == null)
                {
                    var readResult = await responsePipe.Reader.ReadAsync();

                    if (!readResult.IsCanceled)
                    {
                        var buffer = readResult.Buffer;
                        if (LightweightRpcFrame.TryRead(ref buffer, LightweightRpcFrame.DefaultMaxFrameLength, out var responseFrame) == RpcFrameState.Full)
                        {
                            Assert.AreEqual(requestFrame.RpcOperation, responseFrame.RpcOperation);
                            Assert.AreEqual(requestFrame.MessageNumber, responseFrame.MessageNumber);

                            response = (RpcResponse <int>)serializer.Deserialize(responseFrame.Payload, typeof(RpcResponse <int>));

                            responsePipe.Reader.AdvanceTo(buffer.Start);
                        }
                        else
                        {
                            if (readResult.IsCompleted)
                            {
                                break;
                            }

                            responsePipe.Reader.AdvanceTo(buffer.Start, buffer.End);
                        }
                    }