Kinetic C/C++ Client
 All Classes Functions Variables Pages
nonblocking_kinetic_connection.cc
1 /*
2  * kinetic-cpp-client
3  * Copyright (C) 2014 Seagate Technology.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  */
20 
21 #include "kinetic/nonblocking_kinetic_connection.h"
22 #include "nonblocking_packet_service.h"
23 #include <memory>
24 #include <glog/logging.h>
25 
26 namespace kinetic {
27 
28 using com::seagate::kinetic::client::proto::Command_MessageType_DELETE;
29 using com::seagate::kinetic::client::proto::Command_MessageType_GET;
30 using com::seagate::kinetic::client::proto::Command_MessageType_GETNEXT;
31 using com::seagate::kinetic::client::proto::Command_MessageType_GETPREVIOUS;
32 using com::seagate::kinetic::client::proto::Command_MessageType_GETKEYRANGE;
33 using com::seagate::kinetic::client::proto::Command_MessageType_GETVERSION;
34 using com::seagate::kinetic::client::proto::Command_MessageType_NOOP;
35 using com::seagate::kinetic::client::proto::Command_MessageType_PUT;
36 using com::seagate::kinetic::client::proto::Command_MessageType_SETUP;
37 using com::seagate::kinetic::client::proto::Command_MessageType_GETLOG;
38 using com::seagate::kinetic::client::proto::Command_MessageType_SECURITY;
39 using com::seagate::kinetic::client::proto::Command_MessageType_PEER2PEERPUSH;
40 using com::seagate::kinetic::client::proto::Command_MessageType_PINOP;
41 using com::seagate::kinetic::client::proto::Command_Status_StatusCode_NOT_AUTHORIZED;
42 using com::seagate::kinetic::client::proto::Command_Status_StatusCode_NOT_FOUND;
43 using com::seagate::kinetic::client::proto::Command_Status_StatusCode_SUCCESS;
44 using com::seagate::kinetic::client::proto::Command_GetLog_Type_UTILIZATIONS;
45 using com::seagate::kinetic::client::proto::Command_GetLog_Type_TEMPERATURES;
46 using com::seagate::kinetic::client::proto::Command_GetLog_Type_CAPACITIES;
47 using com::seagate::kinetic::client::proto::Command_GetLog_Type_CONFIGURATION;
48 using com::seagate::kinetic::client::proto::Command_GetLog_Type_STATISTICS;
49 using com::seagate::kinetic::client::proto::Command_GetLog_Type_MESSAGES;
50 using com::seagate::kinetic::client::proto::Command_GetLog_Type_LIMITS;
51 using com::seagate::kinetic::client::proto::Command_Security_ACL;
52 using com::seagate::kinetic::client::proto::Command_Security_ACL_Permission;
53 using com::seagate::kinetic::client::proto::Command_Security_ACL_Scope;
54 using com::seagate::kinetic::client::proto::Command_Security_ACL_HMACAlgorithm_HmacSHA1;
55 using com::seagate::kinetic::client::proto::Command_Status;
56 using com::seagate::kinetic::client::proto::Command_P2POperation;
57 using com::seagate::kinetic::client::proto::Command_Synchronization;
58 using com::seagate::kinetic::client::proto::Command_Synchronization_FLUSH;
59 using com::seagate::kinetic::client::proto::Command_Synchronization_WRITEBACK;
60 using com::seagate::kinetic::client::proto::Command_Synchronization_WRITETHROUGH;
61 using com::seagate::kinetic::client::proto::Command_PinOperation_PinOpType_UNLOCK_PINOP;
62 using com::seagate::kinetic::client::proto::Command_PinOperation_PinOpType_LOCK_PINOP;
63 using com::seagate::kinetic::client::proto::Command_PinOperation_PinOpType_ERASE_PINOP;
64 using com::seagate::kinetic::client::proto::Command_PinOperation_PinOpType_SECURE_ERASE_PINOP;
65 using com::seagate::kinetic::client::proto::Message_AuthType_PINAUTH;
66 using com::seagate::kinetic::client::proto::Message_AuthType_HMACAUTH;
67 
68 using std::shared_ptr;
69 using std::string;
70 using std::make_shared;
71 using std::unique_ptr;
72 using std::iterator;
73 using std::move;
74 
75 GetHandler::GetHandler(const shared_ptr<GetCallbackInterface> callback)
76  : callback_(callback) {}
77 
78 void GetHandler::Handle(const Command &response, unique_ptr<const string> value) {
79  unique_ptr<KineticRecord> record(new KineticRecord(shared_ptr<const string>(value.release()),
80  make_shared<string>(response.body().keyvalue().dbversion()),
81  make_shared<string>(response.body().keyvalue().tag()),
82  response.body().keyvalue().algorithm()));
83  callback_->Success(response.body().keyvalue().key(), move(record));
84 }
85 
86 void GetHandler::Error(KineticStatus error, Command const * const response) {
87  callback_->Failure(error);
88 }
89 
90 GetVersionHandler::GetVersionHandler(const shared_ptr<GetVersionCallbackInterface> callback)
91  : callback_(callback) {}
92 
93 void GetVersionHandler::Handle(const Command &response, unique_ptr<const string> value) {
94  callback_->Success(response.body().keyvalue().dbversion());
95 }
96 
97 void GetVersionHandler::Error(KineticStatus error, Command const * const response) {
98  callback_->Failure(error);
99 }
100 
101 GetKeyRangeHandler::GetKeyRangeHandler(const shared_ptr<GetKeyRangeCallbackInterface> callback)
102  : callback_(callback) {}
103 
104 void GetKeyRangeHandler::Handle(const Command &response, unique_ptr<const string> value) {
105  int raw_size = response.body().range().keys_size();
106  CHECK_GE(raw_size, 0);
107  size_t key_size = (size_t) raw_size;
108 
109  unique_ptr<vector<string>> keys(new vector<string>);
110  keys->reserve(key_size);
111 
112  for (size_t i = 0; i < key_size; i++) {
113  keys->push_back(response.body().range().keys(i));
114  }
115 
116  callback_->Success(move(keys));
117 }
118 
119 void GetKeyRangeHandler::Error(KineticStatus error, Command const * const response) {
120  callback_->Failure(error);
121 }
122 
123 PutHandler::PutHandler(const shared_ptr<PutCallbackInterface> callback)
124  : callback_(callback) {}
125 
126 void PutHandler::Handle(const Command &response, unique_ptr<const string> value) {
127  callback_->Success();
128 }
129 
130 void PutHandler::Error(KineticStatus error, Command const * const response) {
131  callback_->Failure(error);
132 }
133 
134 SimpleHandler::SimpleHandler(const shared_ptr<SimpleCallbackInterface> callback)
135  : callback_(callback) {}
136 
137 void SimpleHandler::Handle(const Command &response, unique_ptr<const string> value) {
138  callback_->Success();
139 }
140 
141 void SimpleHandler::Error(KineticStatus error, Command const * const response) {
142  callback_->Failure(error);
143 }
144 
145 GetLogHandler::GetLogHandler(const shared_ptr<GetLogCallbackInterface> callback)
146  : callback_(callback) {}
147 
148 void GetLogHandler::Handle(const Command& response, unique_ptr<const string> value) {
149  auto getlog = response.body().getlog();
150  auto configuration = getlog.configuration();
151  unique_ptr<DriveLog> drive_log(new DriveLog);
152  drive_log->configuration.vendor = configuration.vendor();
153  drive_log->configuration.model = configuration.model();
154  drive_log->configuration.serial_number = configuration.serialnumber();
155  drive_log->configuration.version = configuration.version();
156  drive_log->configuration.source_hash = configuration.sourcehash();
157  drive_log->configuration.compilation_date = configuration.compilationdate();
158  drive_log->configuration.port = configuration.port();
159  drive_log->configuration.tls_port = configuration.tlsport();
160 
161  auto capacity = getlog.capacity();
162  drive_log->capacity.nominal_capacity_in_bytes = capacity.nominalcapacityinbytes();
163  drive_log->capacity.portion_full = capacity.portionfull();
164 
165  auto limits = getlog.limits();
166  drive_log->limits.max_key_size = limits.maxkeysize();
167  drive_log->limits.max_value_size = limits.maxvaluesize();
168  drive_log->limits.max_version_size = limits.maxversionsize();
169  drive_log->limits.max_tag_size = limits.maxtagsize();
170  drive_log->limits.max_connections = limits.maxconnections();
171  drive_log->limits.max_outstanding_read_requests = limits.maxoutstandingreadrequests();
172  drive_log->limits.max_outstanding_write_requests = limits.maxoutstandingwriterequests();
173  drive_log->limits.max_message_size = limits.maxmessagesize();
174 
175  for (int i = 0; i < getlog.statistics_size(); i++) {
176  OperationStatistic statistic;
177  statistic.name = Command_MessageType_Name(getlog.statistics(i).messagetype());
178  statistic.count = getlog.statistics(i).count();
179  statistic.bytes = getlog.statistics(i).bytes();
180  drive_log->operation_statistics.push_back(statistic);
181  }
182 
183  for (int i = 0; i < getlog.utilizations_size(); i++) {
184  Utilization utilization;
185  utilization.name = getlog.utilizations(i).name();
186  utilization.percent = getlog.utilizations(i).value();
187  drive_log->utilizations.push_back(utilization);
188  }
189 
190  for (int i = 0; i < getlog.temperatures_size(); i++) {
191  Temperature temperature;
192 
193  temperature.name = getlog.temperatures(i).name();
194  temperature.current_degc = getlog.temperatures(i).current();
195  temperature.target_degc = getlog.temperatures(i).target();
196  temperature.max_degc = getlog.temperatures(i).maximum();
197  temperature.min_degc = getlog.temperatures(i).minimum();
198 
199  drive_log->temperatures.push_back(temperature);
200  }
201 
202  drive_log->messages = getlog.messages();
203 
204  callback_->Success(move(drive_log));
205 }
206 
207 void GetLogHandler::Error(KineticStatus error, Command const * const response) {
208  callback_->Failure(error);
209 }
210 
211 P2PPushHandler::P2PPushHandler(const shared_ptr<P2PPushCallbackInterface> callback)
212  : callback_(callback) {}
213 
214 void P2PPushHandler::Handle(const Command& response, unique_ptr<const string> value) {
215  unique_ptr<vector<KineticStatus>> statuses(new vector<KineticStatus>());
216 
217  Command_P2POperation const &p2pop = response.body().p2poperation();
218  statuses->reserve(p2pop.operation_size());
219 
220  for (int i = 0; i < p2pop.operation_size(); i++) {
221  Command_Status const &status = p2pop.operation(i).status();
222 
223  statuses->push_back(
224  KineticStatus(ConvertFromProtoStatus(status.code()), status.statusmessage()));
225  }
226 
227  callback_->Success(move(statuses), response);
228 }
229 
230 void P2PPushHandler::Error(KineticStatus error, Command const * const response) {
231  callback_->Failure(error, response);
232 }
233 
234 NonblockingKineticConnection::NonblockingKineticConnection(
235  NonblockingPacketServiceInterface *service)
236  : service_(service), empty_str_(make_shared<string>("")), cluster_version_(0) {}
237 
238 NonblockingKineticConnection::~NonblockingKineticConnection() {
239  delete service_;
240 }
241 
242 bool NonblockingKineticConnection::Run(fd_set *read_fds, fd_set *write_fds, int *nfds) {
243  return service_->Run(read_fds, write_fds, nfds);
244 }
245 
246 void NonblockingKineticConnection::SetClientClusterVersion(int64_t cluster_version) {
247  cluster_version_ = cluster_version;
248 }
249 
250 unique_ptr<Command> NonblockingKineticConnection::NewCommand(Command_MessageType message_type) {
251  unique_ptr<Command> cmd(new Command());
252  cmd->mutable_header()->set_messagetype(message_type);
253  cmd->mutable_header()->set_clusterversion(cluster_version_);
254  return move(cmd);
255 }
256 
257 HandlerKey NonblockingKineticConnection::NoOp(const shared_ptr<SimpleCallbackInterface> callback) {
258  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
259 
260  unique_ptr<Message> msg(new Message());
261  msg->set_authtype(Message_AuthType_HMACAUTH);
262 
263  unique_ptr<Command> request = NewCommand(Command_MessageType_NOOP);
264  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
265 }
266 
267 HandlerKey NonblockingKineticConnection::Get(const shared_ptr<const string> key,
268  const shared_ptr<GetCallbackInterface> callback) {
269  return GenericGet(key, callback, Command_MessageType_GET);
270 }
271 
272 HandlerKey NonblockingKineticConnection::Get(const string key,
273  const shared_ptr<GetCallbackInterface> callback) {
274  return this->Get(make_shared<string>(key), callback);
275 }
276 
277 HandlerKey NonblockingKineticConnection::GetNext(const shared_ptr<const string> key,
278  const shared_ptr<GetCallbackInterface> callback) {
279  return GenericGet(key, callback, Command_MessageType_GETNEXT);
280 }
281 
282 HandlerKey NonblockingKineticConnection::GetNext(const string key,
283  const shared_ptr<GetCallbackInterface> callback) {
284  return this->GetNext(make_shared<string>(key), callback);
285 }
286 
287 HandlerKey NonblockingKineticConnection::GetPrevious(const shared_ptr<const string> key,
288  const shared_ptr<GetCallbackInterface> callback) {
289  return GenericGet(key, callback, Command_MessageType_GETPREVIOUS);
290 }
291 
292 HandlerKey NonblockingKineticConnection::GetPrevious(const string key,
293  const shared_ptr<GetCallbackInterface> callback) {
294  return this->GetPrevious(make_shared<string>(key), callback);
295 }
296 
297 HandlerKey NonblockingKineticConnection::GetVersion(const shared_ptr<const string> key,
298  const shared_ptr<GetVersionCallbackInterface> callback) {
299  unique_ptr<GetVersionHandler> handler(new GetVersionHandler(callback));
300  unique_ptr<Message> msg(new Message());
301  msg->set_authtype(Message_AuthType_HMACAUTH);
302 
303  unique_ptr<Command> request = NewCommand(Command_MessageType_GETVERSION);
304  request->mutable_body()->mutable_keyvalue()->set_key(*key);
305 
306  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
307 }
308 
309 HandlerKey NonblockingKineticConnection::GetVersion(const string key,
310  const shared_ptr<GetVersionCallbackInterface> callback) {
311  return this->GetVersion(make_shared<string>(key), callback);
312 }
313 
314 HandlerKey NonblockingKineticConnection::GetKeyRange(const shared_ptr<const string> start_key,
315  bool start_key_inclusive,
316  const shared_ptr<const string> end_key,
317  bool end_key_inclusive,
318  bool reverse_results,
319  int32_t max_results,
320  const shared_ptr<GetKeyRangeCallbackInterface> callback) {
321  unique_ptr<GetKeyRangeHandler> handler(new GetKeyRangeHandler(callback));
322 
323  unique_ptr<Message> msg(new Message());
324  msg->set_authtype(Message_AuthType_HMACAUTH);
325 
326  unique_ptr<Command> request = NewCommand(Command_MessageType_GETKEYRANGE);
327  request->mutable_body()->mutable_range()->set_startkey(*start_key);
328  request->mutable_body()->mutable_range()->set_startkeyinclusive(start_key_inclusive);
329  request->mutable_body()->mutable_range()->set_endkey(*end_key);
330  request->mutable_body()->mutable_range()->set_endkeyinclusive(end_key_inclusive);
331  request->mutable_body()->mutable_range()->set_reverse(reverse_results);
332  request->mutable_body()->mutable_range()->set_maxreturned(max_results);
333 
334  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
335 }
336 
337 HandlerKey NonblockingKineticConnection::GetKeyRange(const string start_key,
338  bool start_key_inclusive,
339  const string end_key,
340  bool end_key_inclusive,
341  bool reverse_results,
342  int32_t max_results,
343  const shared_ptr<GetKeyRangeCallbackInterface> callback) {
344  return this->GetKeyRange(make_shared<string>(start_key), start_key_inclusive,
345  make_shared<string>(end_key), end_key_inclusive, reverse_results, max_results, callback);
346 }
347 
348 HandlerKey NonblockingKineticConnection::Put(const shared_ptr<const string> key,
349  const shared_ptr<const string> current_version, WriteMode mode,
350  const shared_ptr<const KineticRecord> record,
351  const shared_ptr<PutCallbackInterface> callback,
352  PersistMode persistMode) {
353  unique_ptr<PutHandler> handler(new PutHandler(callback));
354 
355  unique_ptr<Message> msg(new Message());
356  msg->set_authtype(Message_AuthType_HMACAUTH);
357 
358  unique_ptr<Command> request = NewCommand(Command_MessageType_PUT);
359 
360  bool force = mode == WriteMode::IGNORE_VERSION;
361  request->mutable_body()->mutable_keyvalue()->set_key(*key);
362  request->mutable_body()->mutable_keyvalue()->set_dbversion(
363  *current_version);
364  request->mutable_body()->mutable_keyvalue()->set_force(force);
365 
366  if (record->version().get() != nullptr) {
367  request->mutable_body()->mutable_keyvalue()->set_newversion(
368  *(record->version()));
369  }
370 
371  request->mutable_body()->mutable_keyvalue()->set_tag(*(record->tag()));
372  request->mutable_body()->mutable_keyvalue()->set_algorithm(
373  record->algorithm());
374 
375  request->mutable_body()->mutable_keyvalue()->set_synchronization(
376  this->GetSynchronizationForPersistMode(persistMode));
377 
378  return service_->Submit(move(msg), move(request), record->value(), move(handler));
379 }
380 
381 HandlerKey NonblockingKineticConnection::Put(const string key,
382  const string current_version, WriteMode mode,
383  const shared_ptr<const KineticRecord> record,
384  const shared_ptr<PutCallbackInterface> callback,
385  PersistMode persistMode) {
386  return this->Put(make_shared<string>(key), make_shared<string>(current_version), mode, record,
387  callback, persistMode);
388 }
389 
390 
391 HandlerKey NonblockingKineticConnection::Put(const shared_ptr<const string> key,
392  const shared_ptr<const string> current_version, WriteMode mode,
393  const shared_ptr<const KineticRecord> record,
394  const shared_ptr<PutCallbackInterface> callback) {
395  // Default to the WRITE_BACK case, which performs better but does
396  // not guarantee immediate persistence
397  return this->Put(key, current_version, mode, record, callback, PersistMode::WRITE_BACK);
398 }
399 
400 HandlerKey NonblockingKineticConnection::Put(const string key,
401  const string current_version, WriteMode mode,
402  const shared_ptr<const KineticRecord> record,
403  const shared_ptr<PutCallbackInterface> callback) {
404  return this->Put(make_shared<string>(key), make_shared<string>(current_version), mode, record,
405  callback);
406 }
407 
408 HandlerKey NonblockingKineticConnection::Delete(const shared_ptr<const string> key,
409  const shared_ptr<const string> version, WriteMode mode,
410  const shared_ptr<SimpleCallbackInterface> callback,
411  PersistMode persistMode) {
412  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
413 
414  unique_ptr<Message> msg(new Message());
415  msg->set_authtype(Message_AuthType_HMACAUTH);
416 
417  unique_ptr<Command> request = NewCommand(Command_MessageType_DELETE);
418 
419  bool force = mode == WriteMode::IGNORE_VERSION;
420  request->mutable_body()->mutable_keyvalue()->set_key(*key);
421  // TODO(marshall) handle null version
422  request->mutable_body()->mutable_keyvalue()->set_dbversion(*version);
423  request->mutable_body()->mutable_keyvalue()->set_force(force);
424  request->mutable_body()->mutable_keyvalue()->set_synchronization(
425  this->GetSynchronizationForPersistMode(persistMode));
426 
427  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
428 }
429 
430 HandlerKey NonblockingKineticConnection::Delete(const string key, const string version,
431  WriteMode mode, const shared_ptr<SimpleCallbackInterface> callback,
432  PersistMode persistMode) {
433  return this->Delete(make_shared<string>(key), make_shared<string>(version),
434  mode, callback, persistMode);
435 }
436 
437 HandlerKey NonblockingKineticConnection::Delete(const shared_ptr<const string> key,
438  const shared_ptr<const string> version, WriteMode mode,
439  const shared_ptr<SimpleCallbackInterface> callback) {
440  // Default to the WRITE_BACK case, which performs better but does
441  // not guarantee immediate persistence
442  return this->Delete(key, version, mode, callback, PersistMode::WRITE_BACK);
443 }
444 
445 HandlerKey NonblockingKineticConnection::Delete(const string key, const string version,
446  WriteMode mode, const shared_ptr<SimpleCallbackInterface> callback) {
447  return this->Delete(make_shared<string>(key), make_shared<string>(version), mode, callback);
448 }
449 
450 HandlerKey NonblockingKineticConnection::SecureErase(const shared_ptr<string> pin,
451  const shared_ptr<SimpleCallbackInterface> callback) {
452  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
453 
454  unique_ptr<Message> msg(new Message());
455  msg->set_authtype(Message_AuthType_PINAUTH);
456  if(pin) msg->mutable_pinauth()->set_pin(*pin);
457 
458  unique_ptr<Command> request = NewCommand(Command_MessageType_PINOP);
459  request->mutable_body()->mutable_pinop()->set_pinoptype(Command_PinOperation_PinOpType_SECURE_ERASE_PINOP);
460 
461  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
462 }
463 
464 HandlerKey NonblockingKineticConnection::SecureErase(const string pin,
465  const shared_ptr<SimpleCallbackInterface> callback) {
466  return this->SecureErase(make_shared<string>(pin), callback);
467 }
468 
469 HandlerKey NonblockingKineticConnection::InstantErase(const shared_ptr<string> pin,
470  const shared_ptr<SimpleCallbackInterface> callback) {
471  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
472 
473  unique_ptr<Message> msg(new Message());
474  msg->set_authtype(Message_AuthType_PINAUTH);
475  if(pin) msg->mutable_pinauth()->set_pin(*pin);
476 
477  unique_ptr<Command> request = NewCommand(Command_MessageType_PINOP);
478  request->mutable_body()->mutable_pinop()->set_pinoptype(Command_PinOperation_PinOpType_ERASE_PINOP);
479 
480  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
481 }
482 
483 HandlerKey NonblockingKineticConnection::InstantErase(const string pin,
484  const shared_ptr<SimpleCallbackInterface> callback) {
485  return this->InstantErase(make_shared<string>(pin), callback);
486 }
487 
488 HandlerKey NonblockingKineticConnection::LockDevice(const shared_ptr<string> pin,
489  const shared_ptr<SimpleCallbackInterface> callback)
490 {
491  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
492 
493  unique_ptr<Message> msg(new Message());
494  msg->set_authtype(Message_AuthType_PINAUTH);
495  if(pin) msg->mutable_pinauth()->set_pin(*pin);
496 
497  unique_ptr<Command> request = NewCommand(Command_MessageType_PINOP);
498  request->mutable_body()->mutable_pinop()->set_pinoptype(Command_PinOperation_PinOpType_LOCK_PINOP);
499  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
500 
501 
502 }
503 HandlerKey NonblockingKineticConnection::LockDevice(const string pin,
504  const shared_ptr<SimpleCallbackInterface> callback)
505 {
506  return this->LockDevice(make_shared<string>(pin), callback);
507 }
508 
509 HandlerKey NonblockingKineticConnection::UnlockDevice(const shared_ptr<string> pin,
510  const shared_ptr<SimpleCallbackInterface> callback)
511 {
512  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
513 
514  unique_ptr<Message> msg(new Message());
515  msg->set_authtype(Message_AuthType_PINAUTH);
516  if(pin) msg->mutable_pinauth()->set_pin(*pin);
517 
518  unique_ptr<Command> request = NewCommand(Command_MessageType_PINOP);
519  request->mutable_body()->mutable_pinop()->set_pinoptype(Command_PinOperation_PinOpType_UNLOCK_PINOP);
520  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
521 }
522 
523 HandlerKey NonblockingKineticConnection::UnlockDevice(const string pin,
524  const shared_ptr<SimpleCallbackInterface> callback)
525 {
526  return this->UnlockDevice(make_shared<string>(pin), callback);
527 }
528 
529 HandlerKey NonblockingKineticConnection::GenericGet(const shared_ptr<const string> key,
530  const shared_ptr<GetCallbackInterface> callback, Command_MessageType message_type) {
531  unique_ptr<GetHandler> handler(new GetHandler(callback));
532 
533  unique_ptr<Message> msg(new Message());
534  msg->set_authtype(Message_AuthType_HMACAUTH);
535  unique_ptr<Command> request = NewCommand(message_type);
536 
537  request->mutable_body()->mutable_keyvalue()->set_key(*key);
538  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
539 }
540 
541 HandlerKey NonblockingKineticConnection::SetClusterVersion(int64_t new_cluster_version,
542  const shared_ptr<SimpleCallbackInterface> callback) {
543  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
544 
545  unique_ptr<Message> msg(new Message());
546  msg->set_authtype(Message_AuthType_HMACAUTH);
547  unique_ptr<Command> request = NewCommand(Command_MessageType_SETUP);
548 
549  request->mutable_body()->mutable_setup()->set_newclusterversion(
550  new_cluster_version);
551  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
552 }
553 
554 HandlerKey NonblockingKineticConnection::GetLog(
555  const shared_ptr<GetLogCallbackInterface> callback) {
556  vector<Command_GetLog_Type> types;
557  types.push_back(Command_GetLog_Type_UTILIZATIONS);
558  types.push_back(Command_GetLog_Type_TEMPERATURES);
559  types.push_back(Command_GetLog_Type_CAPACITIES);
560  types.push_back(Command_GetLog_Type_CONFIGURATION);
561  types.push_back(Command_GetLog_Type_STATISTICS);
562  types.push_back(Command_GetLog_Type_MESSAGES);
563  types.push_back(Command_GetLog_Type_LIMITS);
564 
565  return GetLog(types, callback);
566 }
567 
568 HandlerKey NonblockingKineticConnection::GetLog(const vector<Command_GetLog_Type>& types,
569  const shared_ptr<GetLogCallbackInterface> callback) {
570 
571  unique_ptr<Message> msg(new Message());
572  msg->set_authtype(Message_AuthType_HMACAUTH);
573  unique_ptr<Command> request = NewCommand(Command_MessageType_GETLOG);
574 
575  for(auto type : types){
576  auto mutable_getlog = request->mutable_body()->mutable_getlog();
577  mutable_getlog->add_types(type);
578  }
579 
580  unique_ptr<GetLogHandler> handler(new GetLogHandler(callback));
581  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
582 }
583 
584 HandlerKey NonblockingKineticConnection::UpdateFirmware(
585  const shared_ptr<const string> new_firmware,
586  const shared_ptr<SimpleCallbackInterface> callback) {
587 
588  unique_ptr<Message> msg(new Message());
589  msg->set_authtype(Message_AuthType_HMACAUTH);
590  unique_ptr<Command> request = NewCommand(Command_MessageType_SETUP);
591 
592  request->mutable_body()->mutable_setup()->set_setupoptype(com::seagate::kinetic::client::proto::Command_Setup::FIRMWARE_SETUPOP);
593 
594  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
595  return service_->Submit(move(msg), move(request), new_firmware, move(handler));
596 }
597 
598 HandlerKey NonblockingKineticConnection::SetACLs(const shared_ptr<const list<ACL>> acls,
599  const shared_ptr<SimpleCallbackInterface> callback) {
600 
601  unique_ptr<Message> msg(new Message());
602  msg->set_authtype(Message_AuthType_HMACAUTH);
603  unique_ptr<Command> request = NewCommand(Command_MessageType_SECURITY);
604 
605 
606  for (auto it = acls->begin(); it != acls->end(); ++it) {
607  Command_Security_ACL *acl =
608  request->mutable_body()->mutable_security()->add_acl();
609  acl->set_identity(it->identity);
610  acl->set_key(it->hmac_key);
611  acl->set_hmacalgorithm(Command_Security_ACL_HMACAlgorithm_HmacSHA1);
612 
613  for (auto scope_it = it->scopes.begin(); scope_it != it->scopes.end(); ++scope_it) {
614  Command_Security_ACL_Scope * scope = acl->add_scope();
615  scope->set_offset(scope_it->offset);
616  scope->set_value(scope_it->value);
617 
618  for (auto permission_it = scope_it->permissions.begin();
619  permission_it != scope_it->permissions.end();
620  ++permission_it) {
621  Command_Security_ACL_Permission permission;
622  switch (*permission_it) {
623  case READ:
624  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_READ;
625  break;
626  case WRITE:
627  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_WRITE;
628  break;
629  case DELETE:
630  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_DELETE;
631  break;
632  case RANGE:
633  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_RANGE;
634  break;
635  case SETUP:
636  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_SETUP;
637  break;
638  case P2POP:
639  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_P2POP;
640  break;
641  case GETLOG:
642  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_GETLOG;
643  break;
644  case SECURITY:
645  permission = com::seagate::kinetic::client::proto::Command_Security_ACL_Permission_SECURITY;
646  break;
647  }
648  scope->add_permission(permission);
649  }
650  }
651  }
652 
653  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
654  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
655 }
656 
657 HandlerKey NonblockingKineticConnection::SetLockPIN(const shared_ptr<const string> new_pin, const shared_ptr<const string> current_pin,
658  const shared_ptr<SimpleCallbackInterface> callback)
659 {
660  unique_ptr<Message> msg(new Message());
661  msg->set_authtype(Message_AuthType_HMACAUTH);
662 
663  unique_ptr<Command> request = NewCommand(Command_MessageType_SECURITY);
664  if(current_pin)
665  request->mutable_body()->mutable_security()->set_oldlockpin(*current_pin);
666  if(new_pin)
667  request->mutable_body()->mutable_security()->set_newlockpin(*new_pin);
668 
669  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
670  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
671 }
672 
673 HandlerKey NonblockingKineticConnection::SetLockPIN(const string new_pin, const string current_pin,
674  const shared_ptr<SimpleCallbackInterface> callback)
675 {
676  return this->SetLockPIN(make_shared<string>(new_pin), make_shared<string>(current_pin), callback);
677 }
678 
679 HandlerKey NonblockingKineticConnection::SetErasePIN(const shared_ptr<const string> new_pin,
680  const shared_ptr<const string> current_pin,
681  const shared_ptr<SimpleCallbackInterface> callback)
682 {
683  unique_ptr<Message> msg(new Message());
684  msg->set_authtype(Message_AuthType_HMACAUTH);
685 
686  unique_ptr<Command> request = NewCommand(Command_MessageType_SECURITY);
687  if(current_pin)
688  request->mutable_body()->mutable_security()->set_olderasepin(*current_pin);
689  if(new_pin)
690  request->mutable_body()->mutable_security()->set_newerasepin(*new_pin);
691 
692  unique_ptr<SimpleHandler> handler(new SimpleHandler(callback));
693  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
694 }
695 
696 HandlerKey NonblockingKineticConnection::SetErasePIN(const string new_pin, const string current_pin,
697  const shared_ptr<SimpleCallbackInterface> callback) {
698  return this->SetErasePIN(make_shared<string>(new_pin), make_shared<string>(current_pin), callback);
699 }
700 
701 HandlerKey NonblockingKineticConnection::P2PPush(const P2PPushRequest& push_request,
702  const shared_ptr<P2PPushCallbackInterface> callback) {
703  return this->P2PPush(make_shared<P2PPushRequest>(push_request), callback);
704 }
705 
706 void NonblockingKineticConnection::PopulateP2PMessage(
707  Command_P2POperation *mutable_p2pop, const shared_ptr<const P2PPushRequest> push_request) {
708  mutable_p2pop->mutable_peer()->set_hostname(push_request->host);
709  mutable_p2pop->mutable_peer()->set_port(push_request->port);
710 
711  for (auto it = push_request->operations.begin(); it != push_request->operations.end(); ++it) {
712  auto op = mutable_p2pop->add_operation();
713  op->set_key(it->key);
714  op->set_version(it->version);
715 
716  if (!it->newKey.empty() && it->newKey != it->key) {
717  op->set_newkey(it->newKey);
718  }
719  op->set_force(it->force);
720 
721  if (it->request != nullptr) {
722  auto req = op->mutable_p2pop();
723  PopulateP2PMessage(req, it->request);
724  }
725  }
726 }
727 
728 HandlerKey NonblockingKineticConnection::P2PPush(
729  const shared_ptr<const P2PPushRequest> push_request,
730  const shared_ptr<P2PPushCallbackInterface> callback) {
731 
732  unique_ptr<Message> msg(new Message());
733  msg->set_authtype(Message_AuthType_HMACAUTH);
734  unique_ptr<Command> request = NewCommand(Command_MessageType_PEER2PEERPUSH);
735 
736  auto mutable_p2pop = request->mutable_body()->mutable_p2poperation();
737  PopulateP2PMessage(mutable_p2pop, push_request);
738 
739  unique_ptr<P2PPushHandler> handler(new P2PPushHandler(callback));
740  return service_->Submit(move(msg), move(request), empty_str_, move(handler));
741 }
742 
743 bool NonblockingKineticConnection::RemoveHandler(HandlerKey handler_key) {
744  return service_->Remove(handler_key);
745 }
746 
747 Command_Synchronization NonblockingKineticConnection::GetSynchronizationForPersistMode(PersistMode persistMode) {
748  Command_Synchronization sync_option;
749  switch (persistMode) {
750  case PersistMode::WRITE_BACK:
751  sync_option = Command_Synchronization_WRITEBACK;
752  break;
753  case PersistMode::WRITE_THROUGH:
754  sync_option = Command_Synchronization_WRITETHROUGH;
755  break;
756  case PersistMode::FLUSH:
757  sync_option = Command_Synchronization_FLUSH;
758  break;
759  }
760  return sync_option;
761 }
762 
763 } // namespace kinetic