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