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_SRC_CORE_LIB_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H 18 #define GRPC_SRC_CORE_LIB_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H 19 20 #include <grpc/support/port_platform.h> 21 22 #include <stddef.h> 23 24 #include <memory> 25 #include <utility> 26 27 #include "src/core/lib/channel/context.h" 28 #include "src/core/lib/gprpp/chunked_vector.h" 29 #include "src/core/lib/gprpp/ref_counted_ptr.h" 30 #include "src/core/lib/gprpp/unique_type_name.h" 31 #include "src/core/lib/resource_quota/arena.h" 32 #include "src/core/lib/service_config/service_config.h" 33 #include "src/core/lib/service_config/service_config_parser.h" 34 35 namespace grpc_core { 36 37 /// Stores the service config data associated with an individual call. 38 /// A pointer to this object is stored in the call_context 39 /// GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA element, so that filters can 40 /// easily access method and global parameters for the call. 41 /// 42 /// Must be accessed when holding the call combiner (legacy filter) or from 43 /// inside the activity (promise-based filter). 44 class ServiceConfigCallData { 45 public: 46 class CallAttributeInterface { 47 public: 48 virtual ~CallAttributeInterface() = default; 49 virtual UniqueTypeName type() const = 0; 50 }; 51 ServiceConfigCallData(Arena * arena,grpc_call_context_element * call_context)52 ServiceConfigCallData(Arena* arena, grpc_call_context_element* call_context) 53 : call_attributes_(arena) { 54 call_context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value = this; 55 call_context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].destroy = Destroy; 56 } 57 58 virtual ~ServiceConfigCallData() = default; 59 SetServiceConfig(RefCountedPtr<ServiceConfig> service_config,const ServiceConfigParser::ParsedConfigVector * method_configs)60 void SetServiceConfig( 61 RefCountedPtr<ServiceConfig> service_config, 62 const ServiceConfigParser::ParsedConfigVector* method_configs) { 63 service_config_ = std::move(service_config); 64 method_configs_ = method_configs; 65 } 66 service_config()67 ServiceConfig* service_config() { return service_config_.get(); } 68 GetMethodParsedConfig(size_t index)69 ServiceConfigParser::ParsedConfig* GetMethodParsedConfig(size_t index) const { 70 if (method_configs_ == nullptr) return nullptr; 71 return (*method_configs_)[index].get(); 72 } 73 GetGlobalParsedConfig(size_t index)74 ServiceConfigParser::ParsedConfig* GetGlobalParsedConfig(size_t index) const { 75 if (service_config_ == nullptr) return nullptr; 76 return service_config_->GetGlobalParsedConfig(index); 77 } 78 SetCallAttribute(CallAttributeInterface * value)79 void SetCallAttribute(CallAttributeInterface* value) { 80 // Overwrite existing entry if we already have one for this type. 81 for (CallAttributeInterface*& attribute : call_attributes_) { 82 if (value->type() == attribute->type()) { 83 attribute = value; 84 return; 85 } 86 } 87 // Otherwise, add a new entry. 88 call_attributes_.EmplaceBack(value); 89 } 90 GetCallAttribute(UniqueTypeName type)91 CallAttributeInterface* GetCallAttribute(UniqueTypeName type) const { 92 for (CallAttributeInterface* attribute : call_attributes_) { 93 if (attribute->type() == type) return attribute; 94 } 95 return nullptr; 96 } 97 98 private: Destroy(void * ptr)99 static void Destroy(void* ptr) { 100 auto* self = static_cast<ServiceConfigCallData*>(ptr); 101 self->~ServiceConfigCallData(); 102 } 103 104 RefCountedPtr<ServiceConfig> service_config_; 105 const ServiceConfigParser::ParsedConfigVector* method_configs_ = nullptr; 106 ChunkedVector<CallAttributeInterface*, 4> call_attributes_; 107 }; 108 109 } // namespace grpc_core 110 111 #endif // GRPC_SRC_CORE_LIB_SERVICE_CONFIG_SERVICE_CONFIG_CALL_DATA_H 112