Hazelcast C++ Client
Hazelcast C++ Client Library
cluster.cpp
1 /*
2  * Copyright (c) 2008-2022, Hazelcast, Inc. All Rights Reserved.
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 #include <functional>
18 #include <boost/uuid/uuid_io.hpp>
19 #include <boost/functional/hash.hpp>
20 
21 #include "hazelcast/client/cluster.h"
22 #include "hazelcast/client/spi/impl/ClientClusterServiceImpl.h"
23 #include "hazelcast/client/membership_listener.h"
24 #include "hazelcast/client/initial_membership_event.h"
25 #include "hazelcast/client/member.h"
26 #include "hazelcast/client/serialization/serialization.h"
27 #include "hazelcast/client/membership_event.h"
28 #include "hazelcast/client/impl/vector_clock.h"
29 #include "hazelcast/client/member_selectors.h"
30 #include "hazelcast/client/internal/partition/strategy/StringPartitioningStrategy.h"
31 
32 namespace hazelcast {
33  namespace client {
34  cluster::cluster(spi::impl::ClientClusterServiceImpl &cluster_service)
35  : cluster_service_(cluster_service) {
36  }
37 
38  std::vector<member> cluster::get_members() {
39  return cluster_service_.get_member_list();
40  }
41 
42  boost::uuids::uuid cluster::add_membership_listener(membership_listener &&listener) {
43  return cluster_service_.add_membership_listener(std::move(listener));
44  }
45 
46  bool cluster::remove_membership_listener(boost::uuids::uuid registration_id) {
47  return cluster_service_.remove_membership_listener(registration_id);
48  }
49 
50  member::member() : lite_member_(false) {
51  }
52 
53 member::member(address member_address, boost::uuids::uuid uuid, bool lite,
54  std::unordered_map<std::string, std::string> attr,
55  std::unordered_map<endpoint_qualifier, address> address_map) :
56  address_(std::move(member_address)), uuid_(uuid), lite_member_(lite),
57  attributes_(std::move(attr)), address_map_(std::move(address_map)) {
58  }
59 
60  member::member(address member_address) : address_(member_address), lite_member_(false) {
61  }
62 
63  member::member(boost::uuids::uuid uuid) : uuid_(uuid), lite_member_(false) {
64  }
65 
66  const address &member::get_address() const {
67  return address_;
68  }
69 
70  boost::uuids::uuid member::get_uuid() const {
71  return uuid_;
72  }
73 
74  bool member::is_lite_member() const {
75  return lite_member_;
76  }
77 
78  const std::unordered_map<std::string, std::string> &member::get_attributes() const {
79  return attributes_;
80  }
81 
82  std::ostream &operator<<(std::ostream &out, const member &member) {
83  const address &address = member.get_address();
84  out << "Member[";
85  out << address.get_host();
86  out << "]";
87  out << ":";
88  out << address.get_port();
89  out << " - " << boost::uuids::to_string(member.get_uuid());
90  if (member.is_lite_member()) {
91  out << " lite";
92  }
93  return out;
94  }
95 
96  const std::string *member::get_attribute(const std::string &key) const {
97  std::unordered_map<std::string, std::string>::const_iterator it = attributes_.find(key);
98  if (attributes_.end() != it) {
99  return &(it->second);
100  } else {
101  return NULL;
102  }
103  }
104 
105  bool member::lookup_attribute(const std::string &key) const {
106  return attributes_.find(key) != attributes_.end();
107  }
108 
109  bool member::operator<(const member &rhs) const {
110  return uuid_ < rhs.uuid_;
111  }
112 
113  const std::unordered_map<endpoint_qualifier, address> &member::address_map() const {
114  return address_map_;
115  }
116 
117  bool operator==(const member &lhs, const member &rhs) {
118  return lhs.address_ == rhs.address_ &&
119  lhs.uuid_ == rhs.uuid_;
120  }
121 
122  endpoint::endpoint(boost::uuids::uuid uuid, boost::optional<address> socket_address)
123  : uuid_(uuid), socket_address_(std::move(socket_address)) {}
124 
125  boost::uuids::uuid endpoint::get_uuid() const {
126  return uuid_;
127  }
128 
129  const boost::optional<address> &endpoint::get_socket_address() const {
130  return socket_address_;
131  }
132 
133  membership_event::membership_event(cluster &cluster, const member &m, membership_event_type event_type,
134  const std::unordered_map<boost::uuids::uuid, member, boost::hash<boost::uuids::uuid>> &members_list) :
135  cluster_(cluster), member_(m), event_type_(event_type), members_(members_list) {
136  }
137 
139 
140  std::unordered_map<boost::uuids::uuid, member, boost::hash<boost::uuids::uuid>> membership_event::get_members() const {
141  return members_;
142  }
143 
145  return cluster_;
146  }
147 
148  membership_event::membership_event_type membership_event::get_event_type() const {
149  return event_type_;
150  }
151 
153  return member_;
154  }
155 
156  local_endpoint::local_endpoint(boost::uuids::uuid uuid, boost::optional<address> socket_address, std::string name,
157  std::unordered_set<std::string> labels) : endpoint(uuid, std::move(socket_address)), name_(std::move(name)),
158  labels_(std::move(labels)) {}
159 
160  const std::string &local_endpoint::get_name() const {
161  return name_;
162  }
163 
164  namespace impl {
165  vector_clock::vector_clock() = default;
166 
167  vector_clock::vector_clock(const vector_clock::timestamp_vector &replica_logical_timestamps)
168  : replica_timestamp_entries_(replica_logical_timestamps) {
169  for (const vector_clock::timestamp_vector::value_type &replicaTimestamp : replica_logical_timestamps) {
170  replica_timestamps_[replicaTimestamp.first] = replicaTimestamp.second;
171  }
172  }
173 
174  vector_clock::timestamp_vector vector_clock::entry_set() {
175  return replica_timestamp_entries_;
176  }
177 
178  bool vector_clock::is_after(vector_clock &other) {
179  bool anyTimestampGreater = false;
180  for (const vector_clock::timestamp_map::value_type &otherEntry : other.replica_timestamps_) {
181  const auto &replicaId = otherEntry.first;
182  int64_t otherReplicaTimestamp = otherEntry.second;
183  std::pair<bool, int64_t> localReplicaTimestamp = get_timestamp_for_replica(replicaId);
184 
185  if (!localReplicaTimestamp.first ||
186  localReplicaTimestamp.second < otherReplicaTimestamp) {
187  return false;
188  } else if (localReplicaTimestamp.second > otherReplicaTimestamp) {
189  anyTimestampGreater = true;
190  }
191  }
192  // there is at least one local timestamp greater or local vector clock has additional timestamps
193  return anyTimestampGreater || other.replica_timestamps_.size() < replica_timestamps_.size();
194  }
195 
196  std::pair<bool, int64_t> vector_clock::get_timestamp_for_replica(boost::uuids::uuid replica_id) {
197  if (replica_timestamps_.count(replica_id) == 0) {
198  return std::make_pair(false, -1);
199  }
200  return std::make_pair(true, replica_timestamps_[replica_id]);
201  }
202  }
203 
204  bool member_selectors::data_member_selector::select(const member &member) const {
205  return !member.is_lite_member();
206  }
207 
208  const std::unique_ptr<member_selector> member_selectors::DATA_MEMBER_SELECTOR(
209  new member_selectors::data_member_selector());
210 
211  namespace internal {
212  namespace partition {
213  namespace strategy {
214  std::string StringPartitioningStrategy::get_base_name(const std::string &name) {
215  size_t index_of = name.find('@');
216  if (index_of == std::string::npos) {
217  return name;
218  }
219  return name.substr(0, index_of);
220  }
221 
222  std::string StringPartitioningStrategy::get_partition_key(const std::string &key) {
223  size_t firstIndexOf = key.find('@');
224  if (firstIndexOf == std::string::npos) {
225  return key;
226  } else {
227  return key.substr(firstIndexOf + 1);
228  }
229  }
230  }
231  }
232  }
233 
234  bool operator==(const endpoint_qualifier &lhs, const endpoint_qualifier &rhs) {
235  return lhs.type == rhs.type &&
236  lhs.identifier == rhs.identifier;
237  }
238  }
239 }
240 
241 namespace std {
242  std::size_t hash<hazelcast::client::member>::operator()(const hazelcast::client::member &m) const noexcept {
243  std::size_t seed = 0;
244  boost::hash_combine(seed, std::hash<hazelcast::client::address>()(m.get_address()));
245  boost::hash_combine(seed, m.get_uuid());
246  return seed;
247  }
248 
249  std::size_t hash<hazelcast::client::endpoint_qualifier>::operator()(
250  const hazelcast::client::endpoint_qualifier &e) const noexcept {
251  std::size_t seed = 0;
252  boost::hash_combine(seed, e.type);
253  boost::hash_combine(seed, e.identifier);
254  return seed;
255  }
256 }
257 
Represents an address of a client or member in the cluster.
Definition: address.h:36
Hazelcast cluster interface.
Definition: cluster.h:36
cluster(spi::impl::ClientClusterServiceImpl &cluster_service)
Constructor.
Definition: cluster.cpp:34
std::vector< member > get_members()
Set of current members of the cluster.
Definition: cluster.cpp:38
bool remove_membership_listener(boost::uuids::uuid registration_id)
Removes the specified membership_listener.
Definition: cluster.cpp:46
boost::uuids::uuid add_membership_listener(membership_listener &&listener)
Adds membership_listener to listen for membership updates.
Definition: cluster.cpp:42
Endpoint represents a peer in the cluster.
Definition: endpoint.h:34
boost::uuids::uuid get_uuid() const
Returns the UUID of this endpoint.
Definition: cluster.cpp:125
const boost::optional< address > & get_socket_address() const
Returns the socket address for this endpoint.
Definition: cluster.cpp:129
hz_cluster member class.
Definition: member.h:55
bool is_lite_member() const
Lite member is does not hold data.
Definition: cluster.cpp:74
boost::uuids::uuid get_uuid() const
Returns UUID of this member.
Definition: cluster.cpp:70
bool lookup_attribute(const std::string &key) const
check if an attribute is defined for given key.
Definition: cluster.cpp:105
const std::string * get_attribute(const std::string &key) const
Returns the value of the specified key for this member or default constructed value if value is undef...
Definition: cluster.cpp:96
const address & get_address() const
Returns the socket address of this member.
Definition: cluster.cpp:66
membership_event(cluster &cluster, const member &m, membership_event_type event_type, const std::unordered_map< boost::uuids::uuid, member, boost::hash< boost::uuids::uuid >> &members_list)
Internal API.
Definition: cluster.cpp:133
std::unordered_map< boost::uuids::uuid, member, boost::hash< boost::uuids::uuid > > get_members() const
Returns a consistent view of the the members exactly after this MembershipEvent has been processed.
Definition: cluster.cpp:140
cluster & get_cluster()
Returns the cluster of the event.
Definition: cluster.cpp:144
virtual ~membership_event()
Destructor.
membership_event_type get_event_type() const
Returns the membership event type; MembershipEvent::MEMBER_JOINED , MembershipEvent::MEMBER_LEFT.
Definition: cluster.cpp:148
const member & get_member() const
Returns the removed or added member.
Definition: cluster.cpp:152