Example #1
0
        static async Task TestAwsIam(string[] args)
        {
            var nowUtc   = DateTime.UtcNow;
            var awsCreds = FallbackCredentialsFactory.GetCredentials().GetCredentials();
            var httpBody = new ByteArrayContent(
                Encoding.UTF8.GetBytes("Action=GetCallerIdentity&Version=2011-06-15"));

            httpBody.Headers.ContentType = MediaTypeHeaderValue.Parse(
                "application/x-www-form-urlencoded");
            var httpRequ = new HttpRequestMessage(HttpMethod.Post, "https://sts.amazonaws.com")
            {
                Content = httpBody,
            };
            var httpClient = new HttpClient();
            var sig        = await AwsSignatureVersion4.Private.Signer.SignAsync(
                httpClient, httpRequ, nowUtc, "us-east-1", "sts", awsCreds);

            var authRequ = new Server.AwsIamAuthRequest
            {
                StsAmzIso8601Date = nowUtc.ToString("yyyyMMddTHHmmssZ"),
                StsAuthorization  = sig.AuthorizationHeader,
            };

            foreach (var h in httpRequ.Headers)
            {
                if (h.Key == "Authorization")
                {
                    continue;
                }
                authRequ.StsAdditionalHeaders.Add(h.Key, new Server.AwsIamAuthRequest.Types.HeaderValues
                {
                    Values = { h.Value, },
                });
            }

            // During testing and development, ignore Server TLS Cert errors
            var channelOptions = new Grpc.Net.Client.GrpcChannelOptions
            {
                HttpHandler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback =
                        HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
                }
            };
            var channel   = Grpc.Net.Client.GrpcChannel.ForAddress("https://localhost:5001", channelOptions);
            var mapper    = new Server.AwsIamMapper.AwsIamMapperClient(channel);
            var authReply = await mapper.AwsIamAuthAsync(authRequ);

            Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(
                                  authReply, new System.Text.Json.JsonSerializerOptions {
                WriteIndented = true,
            }));
        }
        private static GrpcNet.Client.GrpcChannelOptions ExtractOptions(IRpcClientOptions?options, GrpcNet.Client.GrpcChannelOptions?channelOptions)
        {
            if (channelOptions != null && options == null)
            {
                return(channelOptions);
            }

            var extractedOptions = new GrpcNet.Client.GrpcChannelOptions();

            if (channelOptions != null)
            {
                var o = extractedOptions;

                o.CompressionProviders  = channelOptions.CompressionProviders;
                o.Credentials           = channelOptions.Credentials;
                o.DisposeHttpClient     = channelOptions.DisposeHttpClient;
                o.HttpClient            = channelOptions.HttpClient;
                o.LoggerFactory         = channelOptions.LoggerFactory;
                o.MaxReceiveMessageSize = channelOptions.MaxReceiveMessageSize;
                o.MaxSendMessageSize    = channelOptions.MaxSendMessageSize;
                o.ThrowOperationCanceledOnCancellation = channelOptions.ThrowOperationCanceledOnCancellation;
            }

            if (options?.SendMaxMessageSize != null)
            {
                if (extractedOptions.MaxSendMessageSize == null)
                {
                    extractedOptions.MaxSendMessageSize = options.SendMaxMessageSize;
                }
                else
                {
                    // TODO: Logger.Warn($"MaxSendMessageLength is already specified by ChannelOptions, ignoring {nameof(options.SendMaxMessageSize)} in {nameof(RpcClientOptions)}.");
                }
            }

            if (options?.ReceiveMaxMessageSize != null)
            {
                if (extractedOptions.MaxReceiveMessageSize == null)
                {
                    extractedOptions.MaxReceiveMessageSize = options.ReceiveMaxMessageSize;
                }
                else
                {
                    // TODO: Logger.Warn($"MaxReceiveMessageLength is already specified by ChannelOptions, ignoring {nameof(options.ReceiveMaxMessageSize)} in {nameof(RpcClientOptions)}.");
                }
            }

            return(extractedOptions);
        }
        internal NetGrpcConnection(
            RpcConnectionInfo connectionInfo,
            IRpcClientOptions?options,
            GrpcProxyGenerator proxyGenerator,
            GrpcNet.Client.GrpcChannelOptions?channelOptions)
            : base(connectionInfo, options, proxyGenerator)
        {
            if (connectionInfo is null)
            {
                throw new ArgumentNullException(nameof(connectionInfo));
            }

            var scheme = connectionInfo.HostUrl?.Scheme;

            if (connectionInfo.HostUrl != null &&
                (scheme == WellKnownRpcSchemes.Grpc || scheme == "https" || scheme == "http"))
            {
                GrpcNet.Client.GrpcChannelOptions actualChannelOptions = ExtractOptions(options, channelOptions);

                this.isSecure = scheme == "https" || scheme == WellKnownRpcSchemes.Grpc;

                var interceptors  = options?.Interceptors ?? ImmutableList <RpcClientCallInterceptor> .Empty;
                int nInterceptors = interceptors.Count;
                if (nInterceptors > 0)
                {
                    GrpcCore.CallCredentials callCredentials;
                    if (nInterceptors > 1)
                    {
                        GrpcCore.CallCredentials[] allCallCredentials = new GrpcCore.CallCredentials[nInterceptors];
                        for (int index = 0; index < nInterceptors; index++)
                        {
                            var callInterceptor = interceptors[index];
                            allCallCredentials[index] = GrpcCore.CallCredentials.FromInterceptor((context, metadata) => callInterceptor(new GrpcCallMetadata(metadata)));
                        }

                        callCredentials = GrpcCore.CallCredentials.Compose(allCallCredentials);
                    }
                    else
                    {
                        var callInterceptor = interceptors[0];
                        callCredentials = GrpcCore.CallCredentials.FromInterceptor((context, metadata) => callInterceptor(new GrpcCallMetadata(metadata)));
                    }

                    var channelCredentials = actualChannelOptions.Credentials;
                    if (channelCredentials == null)
                    {
                        if (this.isSecure)
                        {
                            channelCredentials = new GrpcCore.SslCredentials();
                        }
                        else
                        {
                            channelCredentials = GrpcCore.ChannelCredentials.Insecure;
                        }
                    }

                    actualChannelOptions.Credentials = GrpcCore.ChannelCredentials.Create(channelCredentials, callCredentials);
                }


                var channelUri = scheme == WellKnownRpcSchemes.Grpc
                    ? new Uri($"https://{connectionInfo.HostUrl.Authority}/")
                    : connectionInfo.HostUrl;

                this.Channel = GrpcNet.Client.GrpcChannel.ForAddress(channelUri, actualChannelOptions);

                this.CallInvoker = this.Channel.CreateCallInvoker();
            }
            else
            {
                throw new NotImplementedException($"NetGrpcConnection is only implemented for the '{WellKnownRpcSchemes.Grpc}' scheme.");
            }
        }
        /// <summary>
        /// TODO: Use factories instead of using this.connnectionType.
        /// </summary>
        /// <param name="serviceDefinitionsProvider"></param>
        /// <param name="proxyDefinitionsProvider"></param>
        /// <returns></returns>
        protected (IRpcServerHost, IRpcChannel) CreateServerAndConnection(
            IRpcServiceDefinitionsProvider serviceDefinitionsProvider = null,
            Action <RpcServerOptions> configServerOptions             = null,
            Action <RpcClientOptions> configClientOptions             = null,
            Action <IServiceCollection> configureServices             = null)
        {
            var rpcServerId = RpcServerId.NewId();

            var serverOptions = new RpcServerOptions {
                Serializer = this.serializer
            };
            var clientOptions = new RpcClientOptions {
                Serializer = this.serializer
            };

            configServerOptions?.Invoke(serverOptions);
            configClientOptions?.Invoke(clientOptions);

            IServiceProvider services = GetServiceProvider(configureServices);

            switch (this.ConnectionType)
            {
            case RpcConnectionType.LightweightTcp:
            case RpcConnectionType.LightweightSslTcp:
            {
                var host = new LightweightRpcServer(rpcServerId, serviceDefinitionsProvider, services, serverOptions, this.LightweightOptions,
                                                    loggerFactory: services.GetService <ILoggerFactory>());

                SslServerOptions sslServerOptions = null;
                if (this.ConnectionType == RpcConnectionType.LightweightSslTcp)
                {
                    sslServerOptions = new SslServerOptions(new X509Certificate2(TestCertificates.ServerPFXPath, "1111"));
                }

                host.AddEndPoint(new TcpRpcEndPoint("127.0.0.1", TcpTestPort, false, sslServerOptions));

                SslClientOptions sslClientOptions = null;
                if (this.ConnectionType == RpcConnectionType.LightweightSslTcp)
                {
                    sslClientOptions = new SslClientOptions {
                        RemoteCertificateValidationCallback = this.ValidateTestCertificate
                    };
                }
                var connection = new TcpRpcConnection(
                    new RpcConnectionInfo("TCP", new Uri($"lightweight.tcp://127.0.0.1:{TcpTestPort}"), rpcServerId),
                    sslClientOptions,
                    clientOptions.AsImmutable(),
                    this.LightweightOptions);

                return(host, connection);
            }

            case RpcConnectionType.LightweightNamedPipe:
            {
                var server = new LightweightRpcServer(rpcServerId, serviceDefinitionsProvider, services, serverOptions, this.LightweightOptions,
                                                      loggerFactory: services.GetService <ILoggerFactory>());
                server.AddEndPoint(new NamedPipeRpcEndPoint("testpipe"));

                var connection = new NamedPipeRpcConnection(
                    new RpcConnectionInfo(new Uri("lightweight.pipe://./testpipe")),
                    clientOptions.AsImmutable(),
                    this.LightweightOptions);

                return(server, connection);
            }

            case RpcConnectionType.LightweightInproc:
            {
                Pipe requestPipe  = new Pipe(new PipeOptions(readerScheduler: PipeScheduler.ThreadPool));
                Pipe responsePipe = new Pipe(new PipeOptions(readerScheduler: PipeScheduler.Inline));

                var host = new LightweightRpcServer(rpcServerId, serviceDefinitionsProvider, services, serverOptions,
                                                    loggerFactory: services.GetService <ILoggerFactory>());
                host.AddEndPoint(new InprocRpcEndPoint(new DirectDuplexPipe(requestPipe.Reader, responsePipe.Writer)));

                var connection = new InprocRpcConnection(new RpcConnectionInfo("Direct", new Uri("direct:localhost"), rpcServerId),
                                                         new DirectDuplexPipe(responsePipe.Reader, requestPipe.Writer), clientOptions.AsImmutable());
                return(host, connection);
            }

            case RpcConnectionType.Grpc:
            {
                var host = new GrpcServer(rpcServerId, serviceDefinitionsProvider, services, serverOptions);
                host.AddEndPoint(GrpcCoreFullStackTestsBase.CreateEndPoint());

                var connection = new GrpcConnection(
                    new RpcConnectionInfo("TCP", new Uri($"grpc://localhost:{GrpcCoreFullStackTestsBase.GrpcTestPort}"), rpcServerId),
                    TestCertificates.GrpcSslCredentials, clientOptions.AsImmutable());
                return(host, connection);
            }

#if PLAT_NET_GRPC
            case RpcConnectionType.NetGrpc:
            {
                var server = CreateNetGrpcServer(serviceDefinitionsProvider, rpcServerId, serverOptions, configureServices);
                //var host = new GrpcServer(rpcServerId, serviceDefinitionsBuilder, null, options);
                //host.AddEndPoint(GrpcCoreFullStackTestsBase.CreateEndPoint());

                var handler = new System.Net.Http.HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback =
                    (httpRequestMessage, cert, cetChain, policyErrors) =>
                {
                    return(true);
                };
                var channelOptions = new GrpcNet.Client.GrpcChannelOptions()
                {
                    HttpClient        = new System.Net.Http.HttpClient(handler),
                    DisposeHttpClient = true
                };


                var connection = new NetGrpcConnection(
                    new RpcConnectionInfo("net-grpc", new Uri($"grpc://localhost:{GrpcCoreFullStackTestsBase.GrpcTestPort}"), rpcServerId),
                    clientOptions.AsImmutable(), channelOptions);
                return(server, connection);
            }
#endif
            }

            throw new NotSupportedException();
        }