private protected ServerMethodInvokerBase(
     Method <TRequest, TResponse> method,
     MethodOptions options,
     IGrpcServiceActivator <TService> serviceActivator)
 {
     Method           = method;
     Options          = options;
     ServiceActivator = serviceActivator;
 }
        public DuplexStreamingServerMethodInvoker(
            DuplexStreamingServerMethod <TService, TRequest, TResponse> invoker,
            Method <TRequest, TResponse> method,
            MethodOptions options,
            IGrpcServiceActivator <TService> serviceActivator)
            : base(method, options, serviceActivator)
        {
            _invoker = invoker;

            if (Options.HasInterceptors)
            {
                var interceptorPipeline = new InterceptorPipelineBuilder <TRequest, TResponse>(Options.Interceptors);
                _pipelineInvoker = interceptorPipeline.DuplexStreamingPipeline(ResolvedInterceptorInvoker);
            }
        }
Exemplo n.º 3
0
        private void AddMethodCore <TRequest, TResponse>(
            Method <TRequest, TResponse> method,
            HttpRule httpRule,
            string pattern,
            string httpVerb,
            string body,
            string responseBody,
            MethodDescriptor methodDescriptor)
            where TRequest : class
            where TResponse : class
        {
            try
            {
                if (!pattern.StartsWith('/'))
                {
                    // This validation is consistent with grpc-gateway code generation.
                    // We should match their validation to be a good member of the eco-system.
                    throw new InvalidOperationException($"Path template must start with /: {pattern}");
                }

                var(invoker, metadata) = CreateModelCore <UnaryServerMethod <TService, TRequest, TResponse> >(
                    method.Name,
                    new[] { typeof(TRequest), typeof(ServerCallContext) },
                    httpVerb,
                    httpRule,
                    methodDescriptor);

                var methodContext = MethodOptions.Create(new[] { _globalOptions, _serviceOptions });

                var routePattern = RoutePatternFactory.Parse(pattern);
                var routeParameterDescriptors =
                    ServiceDescriptorHelpers.ResolveRouteParameterDescriptors(routePattern, methodDescriptor.InputType);

                ServiceDescriptorHelpers.ResolveBodyDescriptor(body, methodDescriptor, out var bodyDescriptor,
                                                               out var bodyFieldDescriptors, out var bodyDescriptorRepeated);

                FieldDescriptor?responseBodyDescriptor = null;
                if (!string.IsNullOrEmpty(responseBody))
                {
                    responseBodyDescriptor = methodDescriptor.OutputType.FindFieldByName(responseBody);
                    if (responseBodyDescriptor == null)
                    {
                        throw new InvalidOperationException(
                                  $"Couldn't find matching field for response body '{responseBody}' on {methodDescriptor.OutputType.Name}.");
                    }
                }

                var unaryInvoker =
                    new UnaryServerMethodInvoker <TService, TRequest, TResponse>(invoker, method, methodContext,
                                                                                 _serviceActivator);
                var unaryServerCallHandler = new UnaryServerCallHandler <TService, TRequest, TResponse>(
                    unaryInvoker,
                    responseBodyDescriptor,
                    bodyDescriptor,
                    bodyDescriptorRepeated,
                    bodyFieldDescriptors,
                    routeParameterDescriptors);

                _context.AddMethod(method, routePattern, metadata, unaryServerCallHandler.HandleCallAsync);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(
                          $"Error binding {method.Name} on {typeof(TService).Name} to HTTP API.", ex);
            }
        }