public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(IOwned <TService> serviceInstance) where TService : class { if (serviceInstance is null) { throw new ArgumentNullException(nameof(serviceInstance)); } var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.Value.GetType(), true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { var serviceInstanceId = RpcObjectId.NewId(); var publishedServices = this.PublishInstanceCore_Locked(allServices, serviceInstance, serviceInstanceId, false); Func <ValueTask> disposeAction = () => this.UnpublishInstanceAsync(serviceInstanceId); return(OwnedObject.Create(new RpcObjectRef <TService>( connectionInfo, serviceInstanceId, publishedServices.ToArray()), disposeAction)); } }
public async Task UnavailableService_ShouldThrowRpcServiceUnavailableException(TestOperationType operationType) { var serviceRegistrator = new RpcServiceDefinitionsBuilder(); serviceRegistrator .RegisterService <IBlockingService>() .RegisterService <ISimpleService>(); var(host, connection) = this.CreateServerAndConnection(serviceRegistrator); using (var publishedInstanceScope = host.ServicePublisher.PublishInstance <IBlockingService>(new TestBlockingServiceImpl())) { var objectId = RpcObjectId.NewId(); var blockingClientService = connection.GetServiceInstance <IBlockingServiceClient>(objectId); var simpleService = connection.GetServiceInstance <ISimpleService>(objectId); host.Start(); try { // Invoke unknown service instance switch (operationType) { case TestOperationType.BlockingBlocking: Assert.Throws <RpcServiceUnavailableException>(() => blockingClientService.Add(12, 13)); break; case TestOperationType.AsyncBlocking: // Async/blocking (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => blockingClientService.AddAsync(12, 13)); break; case TestOperationType.BlockingBlockingVoid: Assert.Throws <RpcServiceUnavailableException>(() => blockingClientService.Value = 23); break; case TestOperationType.AsyncBlockingVoid: // Async/blocking void (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => blockingClientService.SetValueAsync(13)); break; case TestOperationType.AsyncAsync: // Async/async (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => simpleService.AddAsync(12, 13)); break; case TestOperationType.AsyncAsyncVoid: // Async/async void (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => simpleService.SetValueAsync(12)); break; } var exisingService = connection.GetServiceInstance <IBlockingServiceClient>(publishedInstanceScope.Value); // Make sure that the connection is still usable after exception Assert.AreEqual(12 + 13, exisingService.Add(12, 13)); } finally { await host.ShutdownAsync(); } } }
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); }
public async Task GenerateSimpleServiceStubTest() { var binder = new TestLightweightMethodBinder(); CreateSimpleServiceStub <ISimpleService>(new TestSimpleServiceImpl(), binder); LightweightMethodStub addStub = binder.GetHandler <RpcObjectRequest <int, int>, RpcResponse <int> >("SciTech.Rpc.Tests.SimpleService.Add"); Assert.NotNull(addStub); var objectId = RpcObjectId.NewId(); var request = new RpcObjectRequest <int, int>(objectId, 5, 6); RpcResponse <int> addResponse = await LightweightStubHelper.SendReceiveAsync <RpcObjectRequest <int, int>, RpcResponse <int> >(addStub, request, DefaultSerializer); Assert.AreEqual(11, addResponse.Result); LightweightMethodStub setStub = binder.GetHandler <RpcObjectRequest <double>, RpcResponse>("SciTech.Rpc.Tests.SimpleService.SetValue"); Assert.NotNull(setStub); var setResponse = await LightweightStubHelper.SendReceiveAsync <RpcObjectRequest <double>, RpcResponse>(setStub, new RpcObjectRequest <double>(objectId, 20), DefaultSerializer); Assert.NotNull(setResponse); LightweightMethodStub getStub = binder.GetHandler <RpcObjectRequest, RpcResponse <double> >("SciTech.Rpc.Tests.SimpleService.GetValue"); Assert.NotNull(getStub); var getResponse = await LightweightStubHelper.SendReceiveAsync <RpcObjectRequest, RpcResponse <double> >(getStub, new RpcObjectRequest(objectId), DefaultSerializer); Assert.AreEqual(20, getResponse.Result); }
public void HostNotFoundTest() { var serviceRegistrator = new RpcServiceDefinitionsBuilder(); serviceRegistrator .RegisterService <IBlockingService>();; var(_, connection) = this.CreateServerAndConnection(serviceRegistrator); var objectId = RpcObjectId.NewId(); var clientService = connection.GetServiceInstance <IBlockingServiceClient>(objectId); // Invoke client operation without starting host Assert.Throws <RpcCommunicationException>(() => clientService.Add(12, 13)); }
public async Task SimpleServiceSetGetStubTest() { var binder = new TestMethodBinder(); CreateSimpleServiceStub <ISimpleService>(new TestSimpleServiceImpl(), binder); var callContext = CreateServerCallContext(CancellationToken.None); var objectId = RpcObjectId.NewId(); var setHandler = binder.GetHandler <UnaryServerMethod <RpcObjectRequest <double>, RpcResponse> >("SetValue"); await setHandler(new RpcObjectRequest <double>(objectId, 123.456), callContext); var getHandler = binder.GetHandler <UnaryServerMethod <RpcObjectRequest, RpcResponse <double> > >("GetValue"); var getResponse = await getHandler(new RpcObjectRequest(objectId), callContext); Assert.AreEqual(123.456, getResponse.Result); }
public async Task GenerateSimpleServiceStubTest() { var binder = new TestMethodBinder(); CreateSimpleServiceStub <ISimpleService>(new TestSimpleServiceImpl(), binder); var callContext = CreateServerCallContext(CancellationToken.None); var addHandler = binder.GetHandler <GrpcCore.UnaryServerMethod <RpcObjectRequest <int, int>, RpcResponse <int> > >("Add"); Assert.NotNull(addHandler); var objectId = RpcObjectId.NewId(); var addResponseTask = addHandler.Invoke(new RpcObjectRequest <int, int>(objectId, 5, 6), callContext); var response = await addResponseTask.DefaultTimeout(); Assert.AreEqual(11, response.Result); }
public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(Func <IServiceProvider?, RpcObjectId, IOwned <TService> > factory) where TService : class { var allServices = RpcBuilderUtil.GetAllServices(typeof(TService), RpcServiceDefinitionSide.Server, true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { var objectId = RpcObjectId.NewId(); var publishedServices = this.PublishInstanceFactoryCore_Locked(allServices, objectId, factory); return(OwnedObject.Create(new RpcObjectRef <TService>( connectionInfo, objectId, publishedServices.ToArray()), () => this.UnpublishInstanceAsync(objectId))); } }
public RpcObjectRef <TService> GetOrPublishInstance <TService>(TService serviceInstance) where TService : class { if (serviceInstance is null) { throw new ArgumentNullException(nameof(serviceInstance)); } InstanceKey key; lock (this.syncRoot) { key = new InstanceKey(serviceInstance); if (this.serviceImplToId.TryGetValue(key, out var instanceId)) { return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray())); } } // Not published, so we try to register the serviceInstance's service definitions // and then publish it. var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.GetType(), true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { // Let's try again. if (this.serviceImplToId.TryGetValue(key, out var instanceId)) { // Somebody beat us to it. return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray())); } var objectId = RpcObjectId.NewId(); var newPublishedServices = this.PublishInstanceCore_Locked(allServices, OwnedObject.CreateUnowned(serviceInstance), objectId, true); return(new RpcObjectRef <TService>(connectionInfo, objectId, newPublishedServices.ToArray())); } }
public async Task BlockingStubTest() { // TODO: Should use a mock instead. var serviceImpl = new TestBlockingSimpleServiceImpl(); var binder = new TestMethodBinder(); CreateSimpleServiceStub <IBlockingService>(serviceImpl, binder); var callContext = CreateServerCallContext(CancellationToken.None); var objectId = RpcObjectId.NewId(); var setMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "SetValue"); Assert.NotNull(setMethod); var setValueHandler = (UnaryServerMethod <RpcObjectRequest <double>, RpcResponse>)setMethod.Item2; await setValueHandler(new RpcObjectRequest <double>(objectId, 123.456), callContext); //await (Task<RpcResponse>)setMethod.Invoke(serviceStub, new object[] { new RpcObjectRequest<double>(objectId, 123.456), callContext }); Assert.AreEqual(1, serviceImpl.nBlockingSetValue); var getMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "GetValue"); Assert.NotNull(getMethod); var getValueHandler = (UnaryServerMethod <RpcObjectRequest, RpcResponse <double> >)getMethod.Item2; var getResponse = await getValueHandler(new RpcObjectRequest(objectId), callContext); Assert.AreEqual(1, serviceImpl.nBlockingGetValue); Assert.AreEqual(123.456, getResponse.Result); var addMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "Add"); var addHandler = (UnaryServerMethod <RpcObjectRequest <int, int>, RpcResponse <int> >)addMethod.Item2; var addResponse = await addHandler(new RpcObjectRequest <int, int>(objectId, 8, 9), callContext); Assert.AreEqual(1, serviceImpl.nBlockingAdd); Assert.AreEqual(17, addResponse.Result); }
public async Task DeviceServiceTest() { var serviceImpl = new ThermostatServiceImpl(); var implProviderMock = new Mock <IRpcServiceActivator>(); implProviderMock.Setup(p => p.GetActivatedService <IDeviceService>(It.IsAny <IServiceProvider>(), It.IsAny <RpcObjectId>())).Returns(new ActivatedService <IDeviceService>(serviceImpl, null)); var callContext = CreateServerCallContext(CancellationToken.None); var binder = new TestMethodBinder(); CreateSimpleServiceStub <IDeviceService>(serviceImpl, binder); var objectId = RpcObjectId.NewId(); var getMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "GetDeviceAcoId"); Assert.NotNull(getMethod); var getValueHandler = (UnaryServerMethod <RpcObjectRequest, RpcResponse <Guid> >)getMethod.Item2; var getResponse = await getValueHandler(new RpcObjectRequest(objectId), callContext); Assert.AreEqual(serviceImpl.DeviceAcoId, getResponse.Result); }
public void IncorrectServiceFault_ShouldThrowDefinitionException() { var serviceRegistrator = new RpcServiceDefinitionsBuilder(); var(_, connection) = this.CreateServerAndConnection(serviceRegistrator); Assert.Throws <RpcDefinitionException>(() => connection.GetServiceInstance <IIncorrectServiceFaultServiceClient>(RpcObjectId.NewId())); }
public async Task EventHandlerTest() { var serviceImpl = new TestServiceWithEventsImpl(); var binder = new TestMethodBinder(); CreateSimpleServiceStub <ISimpleServiceWithEvents>(serviceImpl, binder); var beginHandler = binder.GetHandler <GrpcCore.ServerStreamingServerMethod <RpcObjectRequest, EventArgs> >("BeginValueChanged"); var objectId = RpcObjectId.NewId(); //var valueChangedMethod = stubType.GetMethod($"Begin{nameof(IServiceWithEvents.ValueChanged)}"); var valueChangedStreamWriter = new ServerEventStreamWriter <EventArgs>(10); CancellationTokenSource eventListerCancellationSource = new CancellationTokenSource(); var callContext = CreateServerCallContext(eventListerCancellationSource.Token); Task valueChangedTask = beginHandler(new RpcObjectRequest(objectId), valueChangedStreamWriter, callContext); var detailedValueChangedStreamWriter = new ServerEventStreamWriter <ValueChangedEventArgs>(10); var beginDetailedHandler = binder.GetHandler <GrpcCore.ServerStreamingServerMethod <RpcObjectRequest, ValueChangedEventArgs> >("BeginDetailedValueChanged"); CancellationTokenSource detailedEventListerCancellationSource = new CancellationTokenSource(); var detailedCallContext = CreateServerCallContext(detailedEventListerCancellationSource.Token); Task detailedValueChangedTask = beginDetailedHandler(new RpcObjectRequest(objectId), detailedValueChangedStreamWriter, detailedCallContext); await Task.WhenAny(Task.WhenAll(valueChangedStreamWriter.StartedTask, detailedValueChangedStreamWriter.StartedTask), Task.Delay(5000)); Assert.IsTrue(valueChangedStreamWriter.StartedTask.IsCompletedSuccessfully()); Assert.IsTrue(detailedValueChangedStreamWriter.StartedTask.IsCompletedSuccessfully()); Task.Run(async() => { List <Task> tasks = new List <Task>(); for (int i = 0; i < 20; i++) { tasks.Add(serviceImpl.SetValueAsync(18 + i)); } await Task.WhenAll(tasks); } ).Forget(); await Task.WhenAny(Task.WhenAll(valueChangedStreamWriter.CompletedTask, detailedValueChangedStreamWriter.CompletedTask), Task.Delay(5000)); Assert.IsTrue(valueChangedStreamWriter.CompletedTask.IsCompletedSuccessfully()); Assert.IsTrue(detailedValueChangedStreamWriter.CompletedTask.IsCompletedSuccessfully()); eventListerCancellationSource.Cancel(); detailedEventListerCancellationSource.Cancel(); //var endProducerHandler = binder.GetHandler<GrpcCore.UnaryServerMethod<RpcObjectEventRequest, RpcResponse>>(nameof(RpcStub<object>.EndEventProducer)); //var endTask = endProducerHandler(new RpcObjectEventRequest(objectId, eventProducerId), callContext); //var endDetailedTask = endProducerHandler(new RpcObjectEventRequest(objectId, detailedEventProducerId), callContext); //await Task.WhenAll(endTask, endDetailedTask); try { await Task.WhenAll(valueChangedTask, detailedValueChangedTask); } catch (OperationCanceledException) { } Assert.IsTrue(valueChangedTask.IsCompletedSuccessfully() || valueChangedTask.IsCanceled); Assert.IsTrue(detailedValueChangedTask.IsCompletedSuccessfully() || detailedValueChangedTask.IsCanceled); Assert.GreaterOrEqual(valueChangedStreamWriter.GetMessages().Length, 10); // Too timing dependent //Assert.Less(valueChangedStreamWriter.GetMessages().Length, 20); var detailedMessages = detailedValueChangedStreamWriter.GetMessages(); Assert.GreaterOrEqual(detailedMessages.Length, 10); // Too timing dependent //Assert.Less(detailedValueChangedStreamWriter.GetMessages().Length, 20); int oldValue = 0; int newValue = 18; for (int i = 0; i < 10; i++) { var msg = detailedMessages[i]; Assert.AreEqual(oldValue, msg.OldValue); Assert.AreEqual(newValue, msg.NewValue); oldValue = msg.NewValue; newValue = oldValue + 1; } }
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); } }
public void RefObjOfTypeToRefObjTest() { var ms = new MemoryStream(); ToStream(ms, false, new RpcObjectRef <ISimpleService>(new RpcConnectionInfo("Test", null, RpcServerId.NewId()), RpcObjectId.NewId(), null)); string text = Encoding.UTF8.GetString(ms.GetBuffer()); var ms2 = new MemoryStream(); ToStream(ms2, true, new RpcObjectRef <ISimpleService>(new RpcConnectionInfo("Test", null, RpcServerId.NewId()), RpcObjectId.NewId(), null)); ms.Seek(0, SeekOrigin.Begin); var ref1 = FromStream(typeof(RpcObjectRef <IBlockingService>), false, ms); ms2.Seek(0, SeekOrigin.Begin); var ref2 = FromStream(typeof(RpcObjectRef <IBlockingService>), true, ms2); Assert.IsTrue(text.Length > 0); }