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