• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "src/core/ext/filters/fault_injection/fault_injection_service_config_parser.h"
18 
19 #include <grpc/support/port_platform.h>
20 
21 #include <vector>
22 
23 #include "absl/types/optional.h"
24 #include "src/core/lib/channel/channel_args.h"
25 #include "src/core/lib/channel/status_util.h"
26 
27 namespace grpc_core {
28 
29 const JsonLoaderInterface*
JsonLoader(const JsonArgs &)30 FaultInjectionMethodParsedConfig::FaultInjectionPolicy::JsonLoader(
31     const JsonArgs&) {
32   static const auto* loader =
33       JsonObjectLoader<FaultInjectionPolicy>()
34           .OptionalField("abortMessage", &FaultInjectionPolicy::abort_message)
35           .OptionalField("abortCodeHeader",
36                          &FaultInjectionPolicy::abort_code_header)
37           .OptionalField("abortPercentageHeader",
38                          &FaultInjectionPolicy::abort_percentage_header)
39           .OptionalField("abortPercentageNumerator",
40                          &FaultInjectionPolicy::abort_percentage_numerator)
41           .OptionalField("abortPercentageDenominator",
42                          &FaultInjectionPolicy::abort_percentage_denominator)
43           .OptionalField("delay", &FaultInjectionPolicy::delay)
44           .OptionalField("delayHeader", &FaultInjectionPolicy::delay_header)
45           .OptionalField("delayPercentageHeader",
46                          &FaultInjectionPolicy::delay_percentage_header)
47           .OptionalField("delayPercentageNumerator",
48                          &FaultInjectionPolicy::delay_percentage_numerator)
49           .OptionalField("delayPercentageDenominator",
50                          &FaultInjectionPolicy::delay_percentage_denominator)
51           .OptionalField("maxFaults", &FaultInjectionPolicy::max_faults)
52           .Finish();
53   return loader;
54 }
55 
JsonPostLoad(const Json & json,const JsonArgs & args,ValidationErrors * errors)56 void FaultInjectionMethodParsedConfig::FaultInjectionPolicy::JsonPostLoad(
57     const Json& json, const JsonArgs& args, ValidationErrors* errors) {
58   // Parse abort_code.
59   auto abort_code_string = LoadJsonObjectField<std::string>(
60       json.object(), args, "abortCode", errors, /*required=*/false);
61   if (abort_code_string.has_value() &&
62       !grpc_status_code_from_string(abort_code_string->c_str(), &abort_code)) {
63     ValidationErrors::ScopedField field(errors, ".abortCode");
64     errors->AddError("failed to parse status code");
65   }
66   // Validate abort_percentage_denominator.
67   if (abort_percentage_denominator != 100 &&
68       abort_percentage_denominator != 10000 &&
69       abort_percentage_denominator != 1000000) {
70     ValidationErrors::ScopedField field(errors, ".abortPercentageDenominator");
71     errors->AddError("must be one of 100, 10000, or 1000000");
72   }
73   // Validate delay_percentage_denominator.
74   if (delay_percentage_denominator != 100 &&
75       delay_percentage_denominator != 10000 &&
76       delay_percentage_denominator != 1000000) {
77     ValidationErrors::ScopedField field(errors, ".delayPercentageDenominator");
78     errors->AddError("must be one of 100, 10000, or 1000000");
79   }
80 }
81 
JsonLoader(const JsonArgs &)82 const JsonLoaderInterface* FaultInjectionMethodParsedConfig::JsonLoader(
83     const JsonArgs&) {
84   static const auto* loader =
85       JsonObjectLoader<FaultInjectionMethodParsedConfig>()
86           .OptionalField(
87               "faultInjectionPolicy",
88               &FaultInjectionMethodParsedConfig::fault_injection_policies_)
89           .Finish();
90   return loader;
91 }
92 
93 std::unique_ptr<ServiceConfigParser::ParsedConfig>
ParsePerMethodParams(const ChannelArgs & args,const Json & json,ValidationErrors * errors)94 FaultInjectionServiceConfigParser::ParsePerMethodParams(
95     const ChannelArgs& args, const Json& json, ValidationErrors* errors) {
96   // Only parse fault injection policy if the following channel arg is present.
97   if (!args.GetBool(GRPC_ARG_PARSE_FAULT_INJECTION_METHOD_CONFIG)
98            .value_or(false)) {
99     return nullptr;
100   }
101   // Parse fault injection policy from given Json
102   return LoadFromJson<std::unique_ptr<FaultInjectionMethodParsedConfig>>(
103       json, JsonArgs(), errors);
104 }
105 
Register(CoreConfiguration::Builder * builder)106 void FaultInjectionServiceConfigParser::Register(
107     CoreConfiguration::Builder* builder) {
108   builder->service_config_parser()->RegisterParser(
109       std::make_unique<FaultInjectionServiceConfigParser>());
110 }
111 
ParserIndex()112 size_t FaultInjectionServiceConfigParser::ParserIndex() {
113   return CoreConfiguration::Get().service_config_parser().GetParserIndex(
114       parser_name());
115 }
116 
117 }  // namespace grpc_core
118