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 #ifndef GRPC_SRC_CORE_EXT_XDS_XDS_RESOURCE_TYPE_IMPL_H 18 #define GRPC_SRC_CORE_EXT_XDS_XDS_RESOURCE_TYPE_IMPL_H 19 #include <grpc/support/port_platform.h> 20 21 #include <memory> 22 23 #include "absl/strings/string_view.h" 24 25 #include "src/core/ext/xds/xds_client.h" 26 #include "src/core/ext/xds/xds_resource_type.h" 27 #include "src/core/lib/gprpp/ref_counted_ptr.h" 28 29 namespace grpc_core { 30 31 // Base class for XdsResourceType implementations. 32 // Handles all down-casting logic for a particular resource type struct. 33 // ResourceTypeStruct must inherit from XdsResourceType::ResourceData, 34 // must be copy-constructible, and must implement operator==(). 35 template <typename Subclass, typename ResourceTypeStruct> 36 class XdsResourceTypeImpl : public XdsResourceType { 37 public: 38 using ResourceType = ResourceTypeStruct; 39 40 // XdsClient watcher that handles down-casting. 41 class WatcherInterface : public XdsClient::ResourceWatcherInterface { 42 public: 43 virtual void OnResourceChanged(ResourceType listener) = 0; 44 45 private: 46 // Get result from XdsClient generic watcher interface, perform 47 // down-casting, and invoke the caller's OnResourceChanged() method. OnGenericResourceChanged(const XdsResourceType::ResourceData * resource)48 void OnGenericResourceChanged( 49 const XdsResourceType::ResourceData* resource) override { 50 OnResourceChanged(*static_cast<const ResourceType*>(resource)); 51 } 52 }; 53 Get()54 static const Subclass* Get() { 55 static const Subclass* g_instance = new Subclass(); 56 return g_instance; 57 } 58 59 // Convenient wrappers around XdsClient generic watcher API that provide 60 // type-safety. StartWatch(XdsClient * xds_client,absl::string_view resource_name,RefCountedPtr<WatcherInterface> watcher)61 static void StartWatch(XdsClient* xds_client, absl::string_view resource_name, 62 RefCountedPtr<WatcherInterface> watcher) { 63 xds_client->WatchResource(Get(), resource_name, std::move(watcher)); 64 } 65 static void CancelWatch(XdsClient* xds_client, 66 absl::string_view resource_name, 67 WatcherInterface* watcher, 68 bool delay_unsubscription = false) { 69 xds_client->CancelResourceWatch(Get(), resource_name, watcher, 70 delay_unsubscription); 71 } 72 ResourcesEqual(const ResourceData * r1,const ResourceData * r2)73 bool ResourcesEqual(const ResourceData* r1, 74 const ResourceData* r2) const override { 75 return *static_cast<const ResourceType*>(r1) == 76 *static_cast<const ResourceType*>(r2); 77 } 78 CopyResource(const ResourceData * resource)79 std::unique_ptr<ResourceData> CopyResource( 80 const ResourceData* resource) const override { 81 return std::make_unique<ResourceType>( 82 *static_cast<const ResourceType*>(resource)); 83 } 84 }; 85 86 } // namespace grpc_core 87 88 #endif // GRPC_SRC_CORE_EXT_XDS_XDS_RESOURCE_TYPE_IMPL_H 89