예제 #1
0
        public EventStoreClusterClient(Uri address, IPublisher bus,
                                       Func <HttpMessageHandler> httpMessageHandlerFactory = null)
        {
            HttpMessageHandler httpMessageHandler = httpMessageHandlerFactory?.Invoke() ?? new HttpClientHandler {
                ServerCertificateCustomValidationCallback = (message, certificate, chain, errors) => {
                    if (errors != SslPolicyErrors.None)
                    {
                        Log.Error("Certificate validation failed for certificate: {certificate} due to reason {reason}.", certificate, errors);
                    }
                    return(errors == SslPolicyErrors.None);
                }
            };

            _channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions {
                HttpClient = new HttpClient(httpMessageHandler)
                {
                    Timeout = Timeout.InfiniteTimeSpan,
                    DefaultRequestVersion = new Version(2, 0),
                },
                LoggerFactory = new SerilogLoggerFactory()
            });
            var callInvoker = _channel.CreateCallInvoker();

            _gossipClient    = new EventStore.Cluster.Gossip.GossipClient(callInvoker);
            _electionsClient = new EventStore.Cluster.Elections.ElectionsClient(callInvoker);
            _bus             = bus;
        }
예제 #2
0
        private async Task RunGenericStreamingAsync(GrpcChannel channel, IInterarrivalTimer timer)
        {
            var request   = _cachedByteBufferRequest.Value;
            var stopwatch = new Stopwatch();

            var invoker = channel.CreateCallInvoker();

            using (var call = invoker.AsyncDuplexStreamingCall(GenericService.StreamingCallMethod, host: null, new CallOptions()))
            {
                while (!_stoppedCts.Token.IsCancellationRequested)
                {
                    stopwatch.Restart();
                    await call.RequestStream.WriteAsync(request);

                    await call.ResponseStream.MoveNext();

                    stopwatch.Stop();

                    // spec requires data point in nanoseconds.
                    _threadLocalHistogram.Value !.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos);

                    await timer.WaitForNextAsync();
                }

                // finish the streaming call
                await call.RequestStream.CompleteAsync();

                if (await call.ResponseStream.MoveNext())
                {
                    throw new InvalidOperationException("Expected response stream end.");
                }
            }
        }
예제 #3
0
        public EventStoreOperationsClient(EventStoreClientSettings settings = null)
        {
            settings ??= new EventStoreClientSettings();
            var httpHandler = settings.CreateHttpMessageHandler?.Invoke() ?? new HttpClientHandler();

            _channel = GrpcChannel.ForAddress(settings.ConnectivitySettings.Address ?? new UriBuilder {
                Scheme = Uri.UriSchemeHttps,
                Port   = 2113
            }.Uri, new GrpcChannelOptions {
                HttpClient = new HttpClient(httpHandler)
                {
                    Timeout = Timeout.InfiniteTimeSpan,
                    DefaultRequestVersion = new Version(2, 0),
                },
                LoggerFactory = settings.LoggerFactory
            });
            var connectionName = settings.ConnectionName ?? $"ES-{Guid.NewGuid()}";

            var callInvoker = (settings.Interceptors ?? Array.Empty <Interceptor>()).Aggregate(
                _channel.CreateCallInvoker()
                .Intercept(new TypedExceptionInterceptor())
                .Intercept(new ConnectionNameInterceptor(connectionName)),
                (invoker, interceptor) => invoker.Intercept(interceptor));

            _client = new Operations.OperationsClient(callInvoker);
        }
        protected EventStoreClientBase(EventStoreClientSettings?settings,
                                       IDictionary <string, Func <RpcException, Exception> > exceptionMap)
        {
            Settings     = settings ?? new EventStoreClientSettings();
            _httpHandler = Settings.CreateHttpMessageHandler?.Invoke() ?? new HttpClientHandler();

            var connectionName = Settings.ConnectionName ?? $"ES-{Guid.NewGuid()}";
            Action <Exception>?exceptionNotificationHook = null;

            if (Settings.ConnectivitySettings.GossipSeeds.Length > 0)
            {
                _httpHandler = ClusterAwareHttpHandler.Create(Settings, _httpHandler);
            }

            _channel = GrpcChannel.ForAddress(Settings.ConnectivitySettings.Address, new GrpcChannelOptions {
                HttpClient = new HttpClient(_httpHandler)
                {
                    Timeout = Timeout.InfiniteTimeSpan,
                    DefaultRequestVersion = new Version(2, 0),
                },
                LoggerFactory = Settings.LoggerFactory
            });

            CallInvoker = (Settings.Interceptors ?? Array.Empty <Interceptor>()).Aggregate(
                _channel.CreateCallInvoker()
                .Intercept(new TypedExceptionInterceptor(exceptionMap, exceptionNotificationHook))
                .Intercept(new ConnectionNameInterceptor(connectionName)),
                (invoker, interceptor) => invoker.Intercept(interceptor));
        }
        protected EventStoreClientBase(EventStoreClientSettings?settings,
                                       IDictionary <string, Func <RpcException, Exception> > exceptionMap)
        {
            Settings = settings ?? new EventStoreClientSettings();

            var connectionName = Settings.ConnectionName ?? $"ES-{Guid.NewGuid()}";

            if (Settings.ConnectivitySettings.Address.Scheme == Uri.UriSchemeHttp ||
                !Settings.ConnectivitySettings.GossipOverHttps)
            {
                //this must be switched on before creation of the HttpMessageHandler
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
            }

#if NETCOREAPP3_1
            _innerHttpHandler = Settings.CreateHttpMessageHandler?.Invoke() ?? new SocketsHttpHandler();
#elif NETSTANDARD2_1
            _innerHttpHandler = Settings.CreateHttpMessageHandler?.Invoke() ?? new HttpClientHandler();
#endif

            _httpHandler = Settings.ConnectivitySettings.IsSingleNode
                                ? (HttpMessageHandler) new SingleNodeHttpHandler(Settings)
            {
                InnerHandler = _innerHttpHandler
            }
                                : ClusterAwareHttpHandler.Create(Settings, _innerHttpHandler);

#if NETSTANDARD2_1
            _httpHandler = new DefaultRequestVersionHandler(_httpHandler);
#endif

            _channel = GrpcChannel.ForAddress(new UriBuilder(Settings.ConnectivitySettings.Address)
            {
                Scheme = Uri.UriSchemeHttps
            }.Uri, new GrpcChannelOptions {
                HttpClient = new HttpClient(_httpHandler)
                {
                    Timeout = Timeout.InfiniteTimeSpan,
#if NETCOREAPP3_1
                    DefaultRequestVersion = new Version(2, 0),
#endif
                },
                LoggerFactory = Settings.LoggerFactory,
                Credentials   = Settings.ChannelCredentials
            });

            Action <Exception>?exceptionNotificationHook =
                _httpHandler is ClusterAwareHttpHandler h
                                        ? h.ExceptionOccurred
                                        : new Action <Exception>(ex => { });

            CallInvoker = (Settings.Interceptors ?? Array.Empty <Interceptor>()).Aggregate(
                _channel.CreateCallInvoker()
                .Intercept(new TypedExceptionInterceptor(exceptionMap, exceptionNotificationHook))
                .Intercept(new ConnectionNameInterceptor(connectionName)),
                (invoker, interceptor) => invoker.Intercept(interceptor));
        }
        public EventStoreClient(EventStoreClientSettings settings = null)
        {
            _settings = settings ?? new EventStoreClientSettings();
            var connectionName = _settings.ConnectionName ?? $"ES-{Guid.NewGuid()}";
            Action <Exception> exceptionNotificationHook = null;
            var httpHandler = _settings.CreateHttpMessageHandler?.Invoke() ?? new HttpClientHandler();

            if (_settings.ConnectivitySettings.GossipSeeds.Length > 0)
            {
                ConfigureClusterAwareHandler();
            }

            _channel = GrpcChannel.ForAddress(_settings.ConnectivitySettings.Address, new GrpcChannelOptions {
                HttpClient = new HttpClient(httpHandler)
                {
                    Timeout = Timeout.InfiniteTimeSpan,
                    DefaultRequestVersion = new Version(2, 0),
                },
                LoggerFactory = _settings.LoggerFactory
            });
            var callInvoker = (_settings.Interceptors ?? Array.Empty <Interceptor>()).Aggregate(
                _channel.CreateCallInvoker()
                .Intercept(new TypedExceptionInterceptor(exceptionNotificationHook))
                .Intercept(new ConnectionNameInterceptor(connectionName)),
                (invoker, interceptor) => invoker.Intercept(interceptor));

            _client = new Streams.Streams.StreamsClient(callInvoker);
            PersistentSubscriptions = new EventStorePersistentSubscriptionsClient(callInvoker, _settings);
            ProjectionsManager      = new EventStoreProjectionManagerClient(callInvoker);
            UsersManager            = new EventStoreUserManagerClient(callInvoker);
            _log = _settings.LoggerFactory?.CreateLogger <EventStoreClient>() ?? new NullLogger <EventStoreClient>();

            void ConfigureClusterAwareHandler()
            {
                var clusterAwareHttpHandler = new ClusterAwareHttpHandler(
                    _settings.ConnectivitySettings.NodePreference == NodePreference.Leader,
                    new ClusterEndpointDiscoverer(
                        _settings.ConnectivitySettings.MaxDiscoverAttempts,
                        _settings.ConnectivitySettings.GossipSeeds,
                        _settings.ConnectivitySettings.GossipTimeout,
                        _settings.ConnectivitySettings.DiscoveryInterval,
                        _settings.ConnectivitySettings.NodePreference,
                        httpHandler))
                {
                    InnerHandler = httpHandler
                };

                exceptionNotificationHook = clusterAwareHttpHandler.ExceptionOccurred;
                httpHandler = clusterAwareHttpHandler;
            }
        }
        public EventStoreGrpcOperationsClient(Uri address, Func <HttpClient> createHttpClient = default)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            _channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions {
                HttpClient = createHttpClient?.Invoke(),
            });
            var callInvoker = _channel.CreateCallInvoker().Intercept(new TypedExceptionInterceptor());

            _client = new Operations.OperationsClient(callInvoker);
        }
예제 #8
0
        public EventStoreClusterClient(Uri address, IPublisher bus, Func <X509Certificate, X509Chain, SslPolicyErrors, ValueTuple <bool, string> > serverCertValidator, X509Certificate clientCertificate)
        {
            HttpMessageHandler httpMessageHandler = null;

            if (address.Scheme == Uri.UriSchemeHttps)
            {
                var socketsHttpHandler = new SocketsHttpHandler {
                    SslOptions =
                    {
                        RemoteCertificateValidationCallback = (sender,                         certificate, chain, errors) => {
                            var(isValid, error)             = serverCertValidator(certificate, chain,       errors);
                            if (!isValid && error != null)
                            {
                                Log.Error("Server certificate validation error: {e}", error);
                            }

                            return(isValid);
                        },
                        ClientCertificates                  = new X509CertificateCollection()
                    }
                };
                if (clientCertificate != null)
                {
                    socketsHttpHandler.SslOptions.ClientCertificates.Add(clientCertificate);
                }

                httpMessageHandler = socketsHttpHandler;
            }
            else if (address.Scheme == Uri.UriSchemeHttp)
            {
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
                httpMessageHandler = new SocketsHttpHandler();
            }

            _channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions {
                HttpClient = new HttpClient(httpMessageHandler)
                {
                    Timeout = Timeout.InfiniteTimeSpan,
                    DefaultRequestVersion = new Version(2, 0),
                },
                LoggerFactory = new SerilogLoggerFactory()
            });
            var callInvoker = _channel.CreateCallInvoker();

            _gossipClient    = new EventStore.Cluster.Gossip.GossipClient(callInvoker);
            _electionsClient = new EventStore.Cluster.Elections.ElectionsClient(callInvoker);
            _bus             = bus;
        }
예제 #9
0
        public EventStoreClusterClient(Uri address, IPublisher bus, Func <X509Certificate, X509Chain, SslPolicyErrors, ValueTuple <bool, string> > serverCertValidator, Func <X509Certificate> clientCertificateSelector)
        {
            HttpMessageHandler httpMessageHandler = null;

            if (address.Scheme == Uri.UriSchemeHttps)
            {
                var socketsHttpHandler = new SocketsHttpHandler {
                    SslOptions =
                    {
                        CertificateRevocationCheckMode      = X509RevocationMode.NoCheck,
                        RemoteCertificateValidationCallback = (sender,                        certificate,chain, errors) => {
                            var(isValid, error)             = serverCertValidator(certificate,chain,  errors);
                            if (!isValid && error != null)
                            {
                                Log.Error("Server certificate validation error: {e}", error);
                            }

                            return(isValid);
                        },
                        LocalCertificateSelectionCallback   = delegate {
                            return(clientCertificateSelector());
                        }
                    },
                    PooledConnectionLifetime = ESConsts.HttpClientConnectionLifeTime
                };

                httpMessageHandler = socketsHttpHandler;
            }
            else if (address.Scheme == Uri.UriSchemeHttp)
            {
                httpMessageHandler = new SocketsHttpHandler();
            }

            _channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions {
                HttpClient = new HttpClient(httpMessageHandler)
                {
                    Timeout = Timeout.InfiniteTimeSpan,
                    DefaultRequestVersion = new Version(2, 0),
                },
                LoggerFactory = new SerilogLoggerFactory()
            });
            var callInvoker = _channel.CreateCallInvoker();

            _gossipClient    = new EventStore.Cluster.Gossip.GossipClient(callInvoker);
            _electionsClient = new EventStore.Cluster.Elections.ElectionsClient(callInvoker);
            _bus             = bus;
        }
예제 #10
0
        public EventStoreGrpcClient(Uri address, Func <HttpClient> createHttpClient = default)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            _channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions {
                HttpClient = createHttpClient?.Invoke(),
            });
            var callInvoker = _channel.CreateCallInvoker().Intercept(new TypedExceptionInterceptor());

            _client = new Streams.Streams.StreamsClient(callInvoker);
            PersistentSubscriptions = new EventStorePersistentSubscriptionsGrpcClient(callInvoker);
            ProjectionsManager      = new EventStoreProjectionManagerGrpcClient(callInvoker);
            UsersManager            = new EventStoreUserManagerGrpcClient(callInvoker);
        }
예제 #11
0
        public EventStoreClusterClient(Uri address, IPublisher bus,
                                       Func <HttpMessageHandler> httpMessageHandlerFactory = null)
        {
            _channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions {
                HttpClient = new HttpClient(httpMessageHandlerFactory?.Invoke() ?? new HttpClientHandler())
                {
                    Timeout = Timeout.InfiniteTimeSpan,
                    DefaultRequestVersion = new Version(2, 0),
                },
                LoggerFactory = new SerilogLoggerFactory()
            });
            var callInvoker = _channel.CreateCallInvoker();

            _gossipClient    = new EventStore.Cluster.Gossip.GossipClient(callInvoker);
            _electionsClient = new EventStore.Cluster.Elections.ElectionsClient(callInvoker);
            _bus             = bus;
        }
예제 #12
0
        public override async Task <InnerResponse> dispatch(InnerRequest innerRequest, ServerCallContext context)
        {
            //Console.WriteLine(innerRequest.ServiceName + " " + innerRequest.MethodName);
            try
            {
                var callInvoker = channel.CreateCallInvoker();

                var request   = new RawMessage(innerRequest.Msg);
                var rawMethod = new RawMethod(innerRequest.ServiceName, innerRequest.MethodName);
                var result    = await callInvoker.AsyncUnaryCall(rawMethod.method, null, new CallOptions(), request);

                return(new InnerResponse {
                    Msg = ByteString.CopyFrom(result.msg)
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
예제 #13
0
        public EventStoreClient(EventStoreClientSettings settings = null)
        {
            settings ??= new EventStoreClientSettings(new UriBuilder {
                Scheme = Uri.UriSchemeHttps,
                Port   = 2113
            }.Uri);
            _channel = GrpcChannel.ForAddress(settings.Address, new GrpcChannelOptions {
                HttpClient = settings.CreateHttpClient?.Invoke()
            });
            var connectionName = settings.ConnectionName ?? $"ES-{Guid.NewGuid()}";

            var callInvoker = settings.Interceptors.Aggregate(
                _channel.CreateCallInvoker()
                .Intercept(new TypedExceptionInterceptor())
                .Intercept(new ConnectionNameInterceptor(connectionName)),
                (invoker, interceptor) => invoker.Intercept(interceptor));

            _client = new Streams.Streams.StreamsClient(callInvoker);
            PersistentSubscriptions = new EventStorePersistentSubscriptionsClient(callInvoker);
            ProjectionsManager      = new EventStoreProjectionManagerClient(callInvoker);
            UsersManager            = new EventStoreUserManagerClient(callInvoker);
        }
        public async Task Invoke(HttpContext httpContext)
        {
            try
            {
                var path = $"{httpContext.Request.RouteValues["service"]}/{httpContext.Request.RouteValues["method"]}";

                MethodHandler handler;
                if (!handlers.TryGetValue(path, out handler))
                {
                    httpContext.Response.StatusCode  = 404;
                    httpContext.Response.ContentType = "text/plain";
                    await httpContext.Response.WriteAsync("Not Found");

                    return;
                }

                // from form...
                object deserializedObject;
                if (httpContext.Request.ContentType == "application/x-www-form-urlencoded")
                {
                    //object parameters
                    var args     = new List <object>();
                    var typeArgs = new List <Type>();

                    foreach (var p in handler.MethodInfo.GetParameters())
                    {
                        typeArgs.Add(p.ParameterType);

                        StringValues stringValues;
                        if (httpContext.Request.Form.TryGetValue(p.Name, out stringValues))
                        {
                            if (p.ParameterType == typeof(string))
                            {
                                args.Add((string)stringValues);
                            }
                            else if (p.ParameterType.GetTypeInfo().IsEnum)
                            {
                                args.Add(Enum.Parse(p.ParameterType, (string)stringValues));
                            }
                            else
                            {
                                var collectionType = GetCollectionType(p.ParameterType);
                                if (stringValues.Count == 1 || collectionType == null)
                                {
                                    var values = (string)stringValues;
                                    if (p.ParameterType == typeof(DateTime) || p.ParameterType == typeof(DateTimeOffset) || p.ParameterType == typeof(DateTime?) || p.ParameterType == typeof(DateTimeOffset?))
                                    {
                                        values = "\"" + values + "\"";
                                    }

                                    args.Add(JsonConvert.DeserializeObject(values, p.ParameterType));
                                }
                                else
                                {
                                    string serializeTarget;
                                    if (collectionType == typeof(string))
                                    {
                                        serializeTarget = "[" + string.Join(", ", stringValues.Select(x => JsonConvert.SerializeObject(x))) + "]"; // escape serialzie
                                    }
                                    else if (collectionType.GetTypeInfo().IsEnum || collectionType == typeof(DateTime) || collectionType == typeof(DateTimeOffset) || collectionType == typeof(DateTime?) || collectionType == typeof(DateTimeOffset?))
                                    {
                                        serializeTarget = "[" + string.Join(", ", stringValues.Select(x => "\"" + x + "\"")) + "]";
                                    }
                                    else
                                    {
                                        serializeTarget = "[" + (string)stringValues + "]";
                                    }

                                    args.Add(JsonConvert.DeserializeObject(serializeTarget, p.ParameterType));
                                }
                            }
                        }
                        else
                        {
                            if (p.HasDefaultValue)
                            {
                                args.Add(p.DefaultValue);
                            }
                            else
                            {
                                args.Add(null);
                            }
                        }
                    }

                    deserializedObject = typeArgs.Count == 1 ?
                                         args[0] : MagicOnionMarshallers.InstantiateDynamicArgumentTuple(typeArgs.ToArray(), args.ToArray());
                }
                else
                {
                    string body;
                    using (var sr = new StreamReader(httpContext.Request.Body, Encoding.UTF8))
                    {
                        body = await sr.ReadToEndAsync();
                    }

                    if (handler.RequestType == typeof(byte[]) && string.IsNullOrWhiteSpace(body))
                    {
                        body = "[]";
                    }
                    deserializedObject = Newtonsoft.Json.JsonConvert.DeserializeObject(body, handler.RequestType);
                }

                // JSON to C# Object to MessagePack
                var requestObject = handler.BoxedSerialize(deserializedObject);

                var method = new Method <byte[], byte[]>(MethodType.Unary, handler.ServiceName, handler.MethodInfo.Name, MagicOnionMarshallers.ThroughMarshaller, MagicOnionMarshallers.ThroughMarshaller);

                // create header
                var metadata = new Metadata();
                foreach (var header in httpContext.Request.Headers.Where(x => !x.Key.StartsWith(":")))
                {
                    metadata.Add(header.Key, header.Value);
                }

                var invoker     = channel.CreateCallInvoker();
                var rawResponse = await invoker.AsyncUnaryCall(method, null, default(CallOptions).WithHeaders(metadata), requestObject);

                // MessagePack -> Object -> Json
                var obj = handler.BoxedDeserialize(rawResponse);
                var v   = JsonConvert.SerializeObject(obj, new[] { new Newtonsoft.Json.Converters.StringEnumConverter() });
                httpContext.Response.ContentType = "application/json";
                await httpContext.Response.WriteAsync(v);
            }
            catch (Exception ex)
            {
                httpContext.Response.StatusCode  = 500;
                httpContext.Response.ContentType = "text/plain";
                await httpContext.Response.WriteAsync(ex.ToString());
            }
        }
 public static TStreamingHub Connect <TStreamingHub, TReceiver>(GrpcChannel channel, TReceiver receiver, string host = null, CallOptions option = default(CallOptions), MessagePackSerializerOptions serializerOptions = null, IMagicOnionClientLogger logger = null)
     where TStreamingHub : IStreamingHub <TStreamingHub, TReceiver>
 {
     return(Connect <TStreamingHub, TReceiver>(channel.CreateCallInvoker(), receiver, host, option, serializerOptions, logger));
 }
예제 #16
0
 public static T Create <T>(GrpcChannel channel, MessagePackSerializerOptions serializerOptions)
     where T : IService <T>
 {
     return(Create <T>(channel.CreateCallInvoker(), serializerOptions, emptyFilters));
 }
예제 #17
0
 public ArgumentPatternManualClient(GrpcChannel channel)
 {
     this.invoker = channel.CreateCallInvoker();
 }
예제 #18
0
 public static T Create <T>(GrpcChannel channel, IClientFilter[] clientFilters)
     where T : IService <T>
 {
     return(Create <T>(channel.CreateCallInvoker(), MessagePackSerializer.DefaultOptions, clientFilters));
 }
예제 #19
0
 public override CallInvoker CreateCallInvoker()
 {
     return(channel.CreateCallInvoker());
 }