1 //
2 //
3 // Copyright 2018 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #ifndef GRPC_SRC_CORE_LIB_RESOLVER_SERVER_ADDRESS_H
20 #define GRPC_SRC_CORE_LIB_RESOLVER_SERVER_ADDRESS_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <stdint.h>
25 
26 #include <map>
27 #include <memory>
28 #include <string>
29 #include <vector>
30 
31 #include "src/core/lib/channel/channel_args.h"
32 #include "src/core/lib/gpr/useful.h"
33 #include "src/core/lib/iomgr/resolved_address.h"
34 
35 namespace grpc_core {
36 
37 //
38 // ServerAddress
39 //
40 
41 // A server address is a grpc_resolved_address with an associated set of
42 // channel args.  Any args present here will be merged into the channel
43 // args when a subchannel is created for this address.
44 class ServerAddress {
45  public:
46   // Base class for resolver-supplied attributes.
47   // Unlike channel args, these attributes don't affect subchannel
48   // uniqueness or behavior.  They are for use by LB policies only.
49   //
50   // Attributes are keyed by a C string that is unique by address, not
51   // by value.  All attributes added with the same key must be of the
52   // same type.
53   class AttributeInterface {
54    public:
55     virtual ~AttributeInterface() = default;
56 
57     // Creates a copy of the attribute.
58     virtual std::unique_ptr<AttributeInterface> Copy() const = 0;
59 
60     // Compares this attribute with another.
61     virtual int Cmp(const AttributeInterface* other) const = 0;
62 
63     // Returns a human-readable representation of the attribute.
64     virtual std::string ToString() const = 0;
65   };
66 
67   ServerAddress(const grpc_resolved_address& address, const ChannelArgs& args,
68                 std::map<const char*, std::unique_ptr<AttributeInterface>>
69                     attributes = {});
70 
71   // Copyable.
72   ServerAddress(const ServerAddress& other);
73   ServerAddress& operator=(const ServerAddress& other);
74 
75   // Movable.
76   ServerAddress(ServerAddress&& other) noexcept;
77   ServerAddress& operator=(ServerAddress&& other) noexcept;
78 
79   bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; }
80 
81   int Cmp(const ServerAddress& other) const;
82 
address()83   const grpc_resolved_address& address() const { return address_; }
args()84   const ChannelArgs& args() const { return args_; }
85 
86   const AttributeInterface* GetAttribute(const char* key) const;
87 
88   // Returns a copy of the address with a modified attribute.
89   // If the new value is null, the attribute is removed.
90   ServerAddress WithAttribute(const char* key,
91                               std::unique_ptr<AttributeInterface> value) const;
92 
93   // TODO(ctiller): Prior to making this a public API we should ensure that the
94   // channel args are not part of the generated string, lest we make that debug
95   // format load-bearing via Hyrum's law.
96   std::string ToString() const;
97 
98  private:
99   grpc_resolved_address address_;
100   ChannelArgs args_;
101   std::map<const char*, std::unique_ptr<AttributeInterface>> attributes_;
102 };
103 
104 //
105 // ServerAddressList
106 //
107 
108 using ServerAddressList = std::vector<ServerAddress>;
109 
110 //
111 // ServerAddressWeightAttribute
112 //
113 class ServerAddressWeightAttribute : public ServerAddress::AttributeInterface {
114  public:
115   static const char* kServerAddressWeightAttributeKey;
116 
ServerAddressWeightAttribute(uint32_t weight)117   explicit ServerAddressWeightAttribute(uint32_t weight) : weight_(weight) {}
118 
weight()119   uint32_t weight() const { return weight_; }
120 
Copy()121   std::unique_ptr<AttributeInterface> Copy() const override {
122     return std::make_unique<ServerAddressWeightAttribute>(weight_);
123   }
124 
Cmp(const AttributeInterface * other)125   int Cmp(const AttributeInterface* other) const override {
126     const auto* other_locality_attr =
127         static_cast<const ServerAddressWeightAttribute*>(other);
128     return QsortCompare(weight_, other_locality_attr->weight_);
129   }
130 
131   std::string ToString() const override;
132 
133  private:
134   uint32_t weight_;
135 };
136 
137 }  // namespace grpc_core
138 
139 #endif  // GRPC_SRC_CORE_LIB_RESOLVER_SERVER_ADDRESS_H
140