1 // 2 // Copyright 2016 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 #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H 18 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H 19 20 #include <grpc/support/port_platform.h> 21 22 #include <unordered_map> 23 24 #include "absl/container/inlined_vector.h" 25 26 #include <grpc/impl/codegen/grpc_types.h> 27 #include <grpc/support/string_util.h> 28 29 #include "src/core/ext/filters/client_channel/service_config_parser.h" 30 #include "src/core/lib/gprpp/ref_counted.h" 31 #include "src/core/lib/gprpp/ref_counted_ptr.h" 32 #include "src/core/lib/iomgr/error.h" 33 #include "src/core/lib/json/json.h" 34 #include "src/core/lib/slice/slice_internal.h" 35 36 // The main purpose of the code here is to parse the service config in 37 // JSON form, which will look like this: 38 // 39 // { 40 // "loadBalancingPolicy": "string", // optional 41 // "methodConfig": [ // array of one or more method_config objects 42 // { 43 // "name": [ // array of one or more name objects 44 // { 45 // "service": "string", // required 46 // "method": "string", // optional 47 // } 48 // ], 49 // // remaining fields are optional. 50 // // see https://developers.google.com/protocol-buffers/docs/proto3#json 51 // // for format details. 52 // "waitForReady": bool, 53 // "timeout": "duration_string", 54 // "maxRequestMessageBytes": "int64_string", 55 // "maxResponseMessageBytes": "int64_string", 56 // } 57 // ] 58 // } 59 60 namespace grpc_core { 61 62 // TODO(roth): Consider stripping this down further to the completely minimal 63 // interface requied to be exposed as part of the resolver API. 64 class ServiceConfig : public RefCounted<ServiceConfig> { 65 public: 66 /// Creates a new service config from parsing \a json_string. 67 /// Returns null on parse error. 68 static RefCountedPtr<ServiceConfig> Create(const grpc_channel_args* args, 69 absl::string_view json_string, 70 grpc_error** error); 71 72 ServiceConfig(const grpc_channel_args* args, std::string json_string, 73 Json json, grpc_error** error); 74 ~ServiceConfig() override; 75 json_string()76 const std::string& json_string() const { return json_string_; } 77 78 /// Retrieves the global parsed config at index \a index. The 79 /// lifetime of the returned object is tied to the lifetime of the 80 /// ServiceConfig object. GetGlobalParsedConfig(size_t index)81 ServiceConfigParser::ParsedConfig* GetGlobalParsedConfig(size_t index) { 82 GPR_DEBUG_ASSERT(index < parsed_global_configs_.size()); 83 return parsed_global_configs_[index].get(); 84 } 85 86 /// Retrieves the vector of parsed configs for the method identified 87 /// by \a path. The lifetime of the returned vector and contained objects 88 /// is tied to the lifetime of the ServiceConfig object. 89 const ServiceConfigParser::ParsedConfigVector* GetMethodParsedConfigVector( 90 const grpc_slice& path) const; 91 92 private: 93 // Helper functions for parsing the method configs. 94 grpc_error* ParsePerMethodParams(const grpc_channel_args* args); 95 grpc_error* ParseJsonMethodConfig(const grpc_channel_args* args, 96 const Json& json); 97 98 // Returns a path string for the JSON name object specified by json. 99 // Sets *error on error. 100 static std::string ParseJsonMethodName(const Json& json, grpc_error** error); 101 102 std::string json_string_; 103 Json json_; 104 105 absl::InlinedVector<std::unique_ptr<ServiceConfigParser::ParsedConfig>, 106 ServiceConfigParser::kNumPreallocatedParsers> 107 parsed_global_configs_; 108 // A map from the method name to the parsed config vector. Note that we are 109 // using a raw pointer and not a unique pointer so that we can use the same 110 // vector for multiple names. 111 std::unordered_map<grpc_slice, const ServiceConfigParser::ParsedConfigVector*, 112 SliceHash> 113 parsed_method_configs_map_; 114 // Default method config. 115 const ServiceConfigParser::ParsedConfigVector* default_method_config_vector_ = 116 nullptr; 117 // Storage for all the vectors that are being used in 118 // parsed_method_configs_table_. 119 absl::InlinedVector<std::unique_ptr<ServiceConfigParser::ParsedConfigVector>, 120 32> 121 parsed_method_config_vectors_storage_; 122 }; 123 124 } // namespace grpc_core 125 126 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H */ 127