1 //
2 // Copyright 2022 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_HEALTH_STATUS_H
18 #define GRPC_SRC_CORE_EXT_XDS_XDS_HEALTH_STATUS_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include <stdint.h>
23 
24 #include <memory>
25 #include <string>
26 
27 #include "absl/strings/string_view.h"
28 #include "absl/types/optional.h"
29 #include "absl/types/span.h"
30 
31 #include "src/core/lib/resolver/server_address.h"
32 
33 namespace grpc_core {
34 
35 class XdsHealthStatus {
36  public:
37   enum HealthStatus { kUnknown, kHealthy, kDraining };
38 
39   // Returns an XdsHealthStatus for supported enum values, else nullopt.
40   static absl::optional<XdsHealthStatus> FromUpb(uint32_t status);
41   static absl::optional<XdsHealthStatus> FromString(absl::string_view status);
42 
XdsHealthStatus(HealthStatus status)43   explicit XdsHealthStatus(HealthStatus status) : status_(status) {}
44 
status()45   HealthStatus status() const { return status_; }
46 
47   bool operator==(const XdsHealthStatus& other) const {
48     return status_ == other.status_;
49   }
50 
51   const char* ToString() const;
52 
53  private:
54   HealthStatus status_;
55 };
56 
57 class XdsHealthStatusSet {
58  public:
59   XdsHealthStatusSet() = default;
60 
XdsHealthStatusSet(absl::Span<const XdsHealthStatus> statuses)61   explicit XdsHealthStatusSet(absl::Span<const XdsHealthStatus> statuses) {
62     for (XdsHealthStatus status : statuses) {
63       Add(status);
64     }
65   }
66 
67   bool operator==(const XdsHealthStatusSet& other) const {
68     return status_mask_ == other.status_mask_;
69   }
70 
Clear()71   void Clear() { status_mask_ = 0; }
72 
Add(XdsHealthStatus status)73   void Add(XdsHealthStatus status) { status_mask_ |= (0x1 << status.status()); }
74 
Contains(XdsHealthStatus status)75   bool Contains(XdsHealthStatus status) const {
76     return status_mask_ & (0x1 << status.status());
77   }
78 
79  private:
80   int status_mask_ = 0;
81 };
82 
83 bool operator<(const XdsHealthStatus& hs1, const XdsHealthStatus& hs2);
84 
85 class XdsEndpointHealthStatusAttribute
86     : public ServerAddress::AttributeInterface {
87  public:
88   static const char* kKey;
89 
XdsEndpointHealthStatusAttribute(XdsHealthStatus status)90   explicit XdsEndpointHealthStatusAttribute(XdsHealthStatus status)
91       : status_(status) {}
92 
status()93   XdsHealthStatus status() const { return status_; }
94 
Copy()95   std::unique_ptr<AttributeInterface> Copy() const override {
96     return std::make_unique<XdsEndpointHealthStatusAttribute>(status_);
97   }
98 
99   int Cmp(const AttributeInterface* other) const override;
100 
101   std::string ToString() const override;
102 
103  private:
104   XdsHealthStatus status_;
105 };
106 
107 }  // namespace grpc_core
108 
109 #endif  // GRPC_SRC_CORE_EXT_XDS_XDS_HEALTH_STATUS_H
110