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 = global::Grpc.Shared.Server.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 <TRequest, TResponse>(method, routePattern, metadata, unaryServerCallHandler.HandleCallAsync); } catch (Exception ex) { throw new InvalidOperationException($"Error binding {method.Name} on {typeof(TService).Name} to HTTP API.", ex); } }
private void btnEdit_Click(object sender, EventArgs e) { if (lvRules.SelectedItems.Count > 0) { int index = (int)lvRules.SelectedItems[0].Tag; if (index < lvRules.Items.Count) { RuleForm form = new RuleForm(); HttpRule rule = httpRules[index]; form.Init(rule); if (form.ShowDialog() == DialogResult.OK) { UpdateListView(httpRules); } } } }
public void Init(HttpRule rule) { Rule = rule; edtName.Text = rule.Name; chbActive.Checked = rule.Active; edtUrlSearchPattern.Text = rule.UrlSearchPattern; cbRequestResponse.Items.Add("Request"); cbRequestResponse.Items.Add("Response"); cbRequestResponse.SelectedIndex = (int)rule.RequestResponse; if (rule.RequestResponse == RequestResponce.Request) { cbRequestResponse.SelectedIndex = (int)rule.Action; cbAction.Items.Add("Поиск/замена"); cbAction.Items.Add("Блокировать"); if (rule.Action == HttpAction.Block) { cbAction.SelectedIndex = (int)rule.Action; edtSearchPattern.Text = ""; edtReplaceStr.Text = ""; edtSearchPattern.Enabled = false; edtReplaceStr.Enabled = false; } else { cbAction.SelectedIndex = (int)rule.Action; edtSearchPattern.Text = rule.SearchPattern; edtReplaceStr.Text = rule.ReplaceStr; edtSearchPattern.Enabled = true; edtReplaceStr.Enabled = true; } } else { cbRequestResponse.SelectedIndex = (int)rule.Action; cbAction.Items.Add("Поиск/замена"); cbAction.SelectedIndex = (int)rule.Action; edtSearchPattern.Text = rule.SearchPattern; edtReplaceStr.Text = rule.ReplaceStr; edtSearchPattern.Enabled = true; edtReplaceStr.Enabled = true; } cbRequestResponse.SelectedIndexChanged += cbRequestResponse_SelectedIndexChanged; cbAction.SelectedIndexChanged += cbAction_SelectedIndexChanged; }
public static bool TryResolvePattern(HttpRule http, [NotNullWhen(true)] out string?pattern, [NotNullWhen(true)] out string?verb) { switch (http.PatternCase) { case HttpRule.PatternOneofCase.Get: pattern = http.Get; verb = "GET"; return(true); case HttpRule.PatternOneofCase.Put: pattern = http.Put; verb = "PUT"; return(true); case HttpRule.PatternOneofCase.Post: pattern = http.Post; verb = "POST"; return(true); case HttpRule.PatternOneofCase.Delete: pattern = http.Delete; verb = "DELETE"; return(true); case HttpRule.PatternOneofCase.Patch: pattern = http.Patch; verb = "PATCH"; return(true); case HttpRule.PatternOneofCase.Custom: pattern = http.Custom.Path; verb = http.Custom.Kind; return(true); default: pattern = null; verb = null; return(false); } }
private void btnAdd_Click(object sender, EventArgs e) { RuleForm form = new RuleForm(); HttpRule rule = new HttpRule() { Name = "Новое правило", Active = true, RequestResponse = RequestResponce.Request, Action = HttpAction.FindReplace, UrlSearchPattern = "Шаблон Url", SearchPattern = "Шаблон поиска", ReplaceStr = "строка для замены" }; form.Init(rule); if (form.ShowDialog() == DialogResult.OK) { httpRules.Add(rule); UpdateListView(httpRules); } }
private static ApiDescription CreateApiDescription(RouteEndpoint routeEndpoint, HttpRule httpRule, MethodDescriptor methodDescriptor, string pattern, string verb) { var apiDescription = new ApiDescription(); apiDescription.HttpMethod = verb; apiDescription.ActionDescriptor = new ActionDescriptor { RouteValues = new Dictionary <string, string?> { // Swagger uses this to group endpoints together. // Group methods together using the service name. ["controller"] = methodDescriptor.Service.FullName }, EndpointMetadata = routeEndpoint.Metadata.ToList() }; apiDescription.RelativePath = pattern.TrimStart('/'); apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat { MediaType = "application/json" }); apiDescription.SupportedResponseTypes.Add(new ApiResponseType { ApiResponseFormats = { new ApiResponseFormat { MediaType = "application/json" } }, ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(methodDescriptor.OutputType.ClrType)), StatusCode = 200 }); var explorerSettings = routeEndpoint.Metadata.GetMetadata <ApiExplorerSettingsAttribute>(); if (explorerSettings != null) { apiDescription.GroupName = explorerSettings.GroupName; } var methodMetadata = routeEndpoint.Metadata.GetMetadata <GrpcMethodMetadata>() !; var routeParameters = ServiceDescriptorHelpers.ResolveRouteParameterDescriptors(routeEndpoint.RoutePattern, methodDescriptor.InputType); foreach (var routeParameter in routeParameters) { var field = routeParameter.Value.Last(); var parameterName = ServiceDescriptorHelpers.FormatUnderscoreName(field.Name, pascalCase: true, preservePeriod: false); var propertyInfo = field.ContainingType.ClrType.GetProperty(parameterName); // If from a property, create model as property to get its XML comments. var identity = propertyInfo != null ? ModelMetadataIdentity.ForProperty(propertyInfo, MessageDescriptorHelpers.ResolveFieldType(field), field.ContainingType.ClrType) : ModelMetadataIdentity.ForType(MessageDescriptorHelpers.ResolveFieldType(field)); apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = routeParameter.Key, ModelMetadata = new GrpcModelMetadata(identity), Source = BindingSource.Path, DefaultValue = string.Empty }); } var bodyDescriptor = ServiceDescriptorHelpers.ResolveBodyDescriptor(httpRule.Body, methodMetadata.ServiceType, methodDescriptor); if (bodyDescriptor != null) { // If from a property, create model as property to get its XML comments. var identity = bodyDescriptor.PropertyInfo != null ? ModelMetadataIdentity.ForProperty(bodyDescriptor.PropertyInfo, bodyDescriptor.Descriptor.ClrType, bodyDescriptor.PropertyInfo.DeclaringType !) : ModelMetadataIdentity.ForType(bodyDescriptor.Descriptor.ClrType); // Or if from a parameter, create model as parameter to get its XML comments. var parameterDescriptor = bodyDescriptor.ParameterInfo != null ? new ControllerParameterDescriptor { ParameterInfo = bodyDescriptor.ParameterInfo } : null; apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = "Input", ModelMetadata = new GrpcModelMetadata(identity), Source = BindingSource.Body, ParameterDescriptor = parameterDescriptor ! });
private void ProcessHttpRule <TRequest, TResponse>(Method <TRequest, TResponse> method, MethodDescriptor methodDescriptor, HttpRule httpRule) where TRequest : class where TResponse : class { if (ServiceDescriptorHelpers.TryResolvePattern(httpRule, out var pattern, out var httpVerb)) { AddMethodCore(method, httpRule, pattern, httpVerb, httpRule.Body, httpRule.ResponseBody, methodDescriptor); } foreach (var additionalRule in httpRule.AdditionalBindings) { ProcessHttpRule(method, methodDescriptor, additionalRule); } }
private static ApiDescription CreateApiDescription(RouteEndpoint routeEndpoint, HttpRule httpRule, MethodDescriptor methodDescriptor, string pattern, string verb) { var apiDescription = new ApiDescription(); apiDescription.HttpMethod = verb; apiDescription.ActionDescriptor = new ActionDescriptor { RouteValues = new Dictionary <string, string> { // Swagger uses this to group endpoints together. // Group methods together using the service name. ["controller"] = methodDescriptor.Service.FullName } }; apiDescription.RelativePath = pattern.TrimStart('/'); apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat { MediaType = "application/json" }); apiDescription.SupportedResponseTypes.Add(new ApiResponseType { ApiResponseFormats = { new ApiResponseFormat { MediaType = "application/json" } }, ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(methodDescriptor.OutputType.ClrType)), StatusCode = 200 }); var routeParameters = ServiceDescriptorHelpers.ResolveRouteParameterDescriptors(routeEndpoint.RoutePattern, methodDescriptor.InputType); foreach (var routeParameter in routeParameters) { var field = routeParameter.Value.Last(); apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = routeParameter.Key, ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(MessageDescriptorHelpers.ResolveFieldType(field))), Source = BindingSource.Path, DefaultValue = string.Empty }); } ServiceDescriptorHelpers.ResolveBodyDescriptor(httpRule.Body, methodDescriptor, out var bodyDescriptor, out _, out _); if (bodyDescriptor != null) { apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = "Input", ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(bodyDescriptor.ClrType)), Source = BindingSource.Body }); } return(apiDescription); }
/// <summary> /// Creates a new instance of <see cref="GrpcJsonTranscodingMetadata"/> with the provided Protobuf /// <see cref="Google.Protobuf.Reflection.MethodDescriptor"/> and <see cref="Google.Api.HttpRule"/>. /// </summary> /// <param name="methodDescriptor">The Protobuf <see cref="Google.Protobuf.Reflection.MethodDescriptor"/>.</param> /// <param name="httpRule">The <see cref="Google.Api.HttpRule"/>.</param> public GrpcJsonTranscodingMetadata(MethodDescriptor methodDescriptor, HttpRule httpRule) { MethodDescriptor = methodDescriptor; HttpRule = httpRule; }
public Task <bool> UpdateHttpRuleAsync(HttpRule model) { throw new NotImplementedException(); }
public Task <bool> CreateHttpRuleAsync(HttpRule model) { throw new Exception(); }
/// <summary> /// Creates a new instance of <see cref="GRpcHttpMetadata" /> with the provided Protobuf /// <see cref="Google.Protobuf.Reflection.MethodDescriptor" /> and <see cref="Google.Api.HttpRule" />. /// </summary> /// <param name="methodDescriptor">The Protobuf <see cref="Google.Protobuf.Reflection.MethodDescriptor" />.</param> /// <param name="httpRule">The <see cref="Google.Api.HttpRule" />.</param> public GRpcHttpMetadata(MethodDescriptor methodDescriptor, HttpRule httpRule) { MethodDescriptor = methodDescriptor; HttpRule = httpRule; }